Re: [RFC PATCH 1/3] libfs: rework dcache_readdir to use an internal function with callback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi James,

Thanks for persisting with this.


On Tue, 18 Mar 2025 at 20:44, James Bottomley
<James.Bottomley@xxxxxxxxxxxxxxxxxxxxx> wrote:
>
> No functional change.  Preparatory to using the internal function to
> iterate a directory with just a dentry not a file.
>
> Signed-off-by: James Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx>
> ---
>  fs/libfs.c | 41 +++++++++++++++++++++++++++++------------
>  1 file changed, 29 insertions(+), 12 deletions(-)
>
> diff --git a/fs/libfs.c b/fs/libfs.c
> index 8444f5cc4064..816bfe6c0430 100644
> --- a/fs/libfs.c
> +++ b/fs/libfs.c
> @@ -189,28 +189,21 @@ EXPORT_SYMBOL(dcache_dir_lseek);
>   * for ramfs-type trees they can't go away without unlink() or rmdir(),
>   * both impossible due to the lock on directory.
>   */
> -
> -int dcache_readdir(struct file *file, struct dir_context *ctx)
> +static void internal_readdir(struct dentry *dentry, struct dentry *cursor,

It might make sense to make this __always_inline, so that the callback
argument is guaranteed to become a compile time constant when the
caller is dcache_readdir(). Otherwise, the indirect call overhead
might impact its performance.

> +                            void *data, bool start,
> +                            bool (*callback)(void *, struct dentry *))
>  {
> -       struct dentry *dentry = file->f_path.dentry;
> -       struct dentry *cursor = file->private_data;
>         struct dentry *next = NULL;
>         struct hlist_node **p;
>
> -       if (!dir_emit_dots(file, ctx))
> -               return 0;
> -
> -       if (ctx->pos == 2)
> +       if (start)
>                 p = &dentry->d_children.first;
>         else
>                 p = &cursor->d_sib.next;
>
>         while ((next = scan_positives(cursor, p, 1, next)) != NULL) {
> -               if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
> -                             d_inode(next)->i_ino,
> -                             fs_umode_to_dtype(d_inode(next)->i_mode)))
> +               if (!callback(data, next))
>                         break;
> -               ctx->pos++;
>                 p = &next->d_sib.next;
>         }
>         spin_lock(&dentry->d_lock);
> @@ -219,6 +212,30 @@ int dcache_readdir(struct file *file, struct dir_context *ctx)
>                 hlist_add_before(&cursor->d_sib, &next->d_sib);
>         spin_unlock(&dentry->d_lock);
>         dput(next);
> +}
> +
> +static bool dcache_readdir_callback(void *data, struct dentry *entry)
> +{
> +       struct dir_context *ctx = data;
> +
> +       if (!dir_emit(ctx, entry->d_name.name, entry->d_name.len,
> +                     d_inode(entry)->i_ino,
> +                     fs_umode_to_dtype(d_inode(entry)->i_mode)))
> +               return false;
> +       ctx->pos++;
> +       return true;
> +}
> +
> +int dcache_readdir(struct file *file, struct dir_context *ctx)
> +{
> +       struct dentry *dentry = file->f_path.dentry;
> +       struct dentry *cursor = file->private_data;
> +
> +       if (!dir_emit_dots(file, ctx))
> +               return 0;
> +
> +       internal_readdir(dentry, cursor, ctx, ctx->pos == 2,
> +                        dcache_readdir_callback);
>
>         return 0;
>  }
> --
> 2.43.0
>




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux