Re: [RFC][PATCH 1/3] ovl: support encoding non-decodeable file handles

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

 



On Tue, Apr 25, 2023 at 4:22 PM Amir Goldstein <amir73il@xxxxxxxxx> wrote:
>
> When all layers support file handles, we support encoding non-decodeable
> file handles (a.k.a. fid) even with nfs_export=off.
>
> When file handles do not need to be decoded, we do not need to copy up
> redirected lower directories on encode, and we encode also non-indexed
> upper with lower file handle, so fid will not change on copy up.
>
> This enables reporting fanotify events with file handles on overlayfs
> with default config/mount options.
>
> Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>
> ---

FYI, the exportfs support for non-decodable file handles has been merged.

This follow up series which adds support for non-decodable file handles
to overlayfs has been pushed to:
https://github.com/amir73il/linux/commits/ovl_encode_fid
and to overlayfs-next (pending review by Miklos).

fanotify (over ovl) tests are available at:
https://github.com/amir73il/ltp/commits/ovl_encode_fid

Thanks,
Amir.

>  fs/overlayfs/export.c    | 26 ++++++++++++++++++++------
>  fs/overlayfs/inode.c     |  2 +-
>  fs/overlayfs/overlayfs.h |  1 +
>  fs/overlayfs/ovl_entry.h |  1 +
>  fs/overlayfs/super.c     |  9 +++++++++
>  5 files changed, 32 insertions(+), 7 deletions(-)
>
> diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c
> index defd4e231ad2..dfd05ad2b722 100644
> --- a/fs/overlayfs/export.c
> +++ b/fs/overlayfs/export.c
> @@ -173,28 +173,37 @@ static int ovl_connect_layer(struct dentry *dentry)
>   * U = upper file handle
>   * L = lower file handle
>   *
> - * (*) Connecting an overlay dir from real lower dentry is not always
> + * (*) Decoding a connected overlay dir from real lower dentry is not always
>   * possible when there are redirects in lower layers and non-indexed merge dirs.
>   * To mitigate those case, we may copy up the lower dir ancestor before encode
> - * a lower dir file handle.
> + * of a decodeable file handle for non-upper dir.
>   *
>   * Return 0 for upper file handle, > 0 for lower file handle or < 0 on error.
>   */
>  static int ovl_check_encode_origin(struct dentry *dentry)
>  {
>         struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
> +       bool decodeable = ofs->config.nfs_export;
> +
> +       /* Lower file handle for non-upper non-decodeable */
> +       if (!ovl_dentry_upper(dentry) && !decodeable)
> +               return 0;
>
>         /* Upper file handle for pure upper */
>         if (!ovl_dentry_lower(dentry))
>                 return 0;
>
>         /*
> -        * Upper file handle for non-indexed upper.
> -        *
>          * Root is never indexed, so if there's an upper layer, encode upper for
>          * root.
>          */
> -       if (ovl_dentry_upper(dentry) &&
> +       if (dentry == dentry->d_sb->s_root)
> +               return 0;
> +
> +       /*
> +        * Upper decodeable file handle for non-indexed upper.
> +        */
> +       if (ovl_dentry_upper(dentry) && decodeable &&
>             !ovl_test_flag(OVL_INDEX, d_inode(dentry)))
>                 return 0;
>
> @@ -204,7 +213,7 @@ static int ovl_check_encode_origin(struct dentry *dentry)
>          * ovl_connect_layer() will try to make origin's layer "connected" by
>          * copying up a "connectable" ancestor.
>          */
> -       if (d_is_dir(dentry) && ovl_upper_mnt(ofs))
> +       if (d_is_dir(dentry) && ovl_upper_mnt(ofs) && decodeable)
>                 return ovl_connect_layer(dentry);
>
>         /* Lower file handle for indexed and non-upper dir/non-dir */
> @@ -875,3 +884,8 @@ const struct export_operations ovl_export_operations = {
>         .get_name       = ovl_get_name,
>         .get_parent     = ovl_get_parent,
>  };
> +
> +/* encode_fh() encodes non-decodeable file handles with nfs_export=off */
> +const struct export_operations ovl_export_fid_operations = {
> +       .encode_fh      = ovl_encode_fh,
> +};
> diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
> index 541cf3717fc2..b6bec4064390 100644
> --- a/fs/overlayfs/inode.c
> +++ b/fs/overlayfs/inode.c
> @@ -1304,7 +1304,7 @@ static bool ovl_hash_bylower(struct super_block *sb, struct dentry *upper,
>                 return false;
>
>         /* No, if non-indexed upper with NFS export */
> -       if (sb->s_export_op && upper)
> +       if (ofs->config.nfs_export && upper)
>                 return false;
>
>         /* Otherwise, hash by lower inode for fsnotify */
> diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
> index 4d0b278f5630..87d44b889129 100644
> --- a/fs/overlayfs/overlayfs.h
> +++ b/fs/overlayfs/overlayfs.h
> @@ -734,3 +734,4 @@ int ovl_set_origin(struct ovl_fs *ofs, struct dentry *lower,
>
>  /* export.c */
>  extern const struct export_operations ovl_export_operations;
> +extern const struct export_operations ovl_export_fid_operations;
> diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
> index fd11fe6d6d45..5cc0b6e65488 100644
> --- a/fs/overlayfs/ovl_entry.h
> +++ b/fs/overlayfs/ovl_entry.h
> @@ -67,6 +67,7 @@ struct ovl_fs {
>         const struct cred *creator_cred;
>         bool tmpfile;
>         bool noxattr;
> +       bool nofh;
>         /* Did we take the inuse lock? */
>         bool upperdir_locked;
>         bool workdir_locked;
> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
> index f1d9f75f8786..5ed8c2650293 100644
> --- a/fs/overlayfs/super.c
> +++ b/fs/overlayfs/super.c
> @@ -954,6 +954,7 @@ static int ovl_lower_dir(const char *name, struct path *path,
>                 pr_warn("fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n",
>                         name);
>         }
> +       ofs->nofh |= !fh_type;
>         /*
>          * Decoding origin file handle is required for persistent st_ino.
>          * Without persistent st_ino, xino=auto falls back to xino=off.
> @@ -1391,6 +1392,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
>                 ofs->config.index = false;
>                 pr_warn("upper fs does not support file handles, falling back to index=off.\n");
>         }
> +       ofs->nofh |= !fh_type;
>
>         /* Check if upper fs has 32bit inode numbers */
>         if (fh_type != FILEID_INO32_GEN)
> @@ -2049,8 +2051,15 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
>                 ofs->config.nfs_export = false;
>         }
>
> +       /*
> +        * Support encoding decodeable file handles with nfs_export=on
> +        * and encoding non-decodeable file handles with nfs_export=off
> +        * if all layers support file handles.
> +        */
>         if (ofs->config.nfs_export)
>                 sb->s_export_op = &ovl_export_operations;
> +       else if (!ofs->nofh)
> +               sb->s_export_op = &ovl_export_fid_operations;
>
>         /* Never override disk quota limits or use reserved space */
>         cap_lower(cred->cap_effective, CAP_SYS_RESOURCE);
> --
> 2.34.1
>




[Index of Archives]     [Linux Filesystems Devel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux