On Tue, Apr 25, 2023 at 4:22 PM Amir Goldstein <amir73il@xxxxxxxxx> wrote: > > With index=on, overlayfs instances are non-migratable, meaning that > the layers cannot be copied without breaking the index. > > So when indexdir exists, store a persistent uuid in xattr on the > indexdir to give the overlayfs instance a persistent identifier. > > This also makes f_fsid persistent and more reliable for reporting > fid info in fanotify events. > > With mount option uuid=nogen, a persistent uuid is not be initialized > on indexdir, but if a persistent uuid already exists, it will be used. > This behavior (along with the grammatical mistakes) was changed in https://github.com/amir73il/linux/commits/ovl_encode_fid uuid=off or uuid=null both set ovl fsid to null regardless of persistent uuid xattr. Whether we need this backward compact option or not is to be determined. > Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> > --- > fs/overlayfs/overlayfs.h | 3 +++ > fs/overlayfs/super.c | 7 +++++++ > fs/overlayfs/util.c | 41 ++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 51 insertions(+) > > diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h > index dcdb02d0ddf8..9927472a3aaa 100644 > --- a/fs/overlayfs/overlayfs.h > +++ b/fs/overlayfs/overlayfs.h > @@ -36,6 +36,7 @@ enum ovl_xattr { > OVL_XATTR_IMPURE, > OVL_XATTR_NLINK, > OVL_XATTR_UPPER, > + OVL_XATTR_UUID, > OVL_XATTR_METACOPY, > OVL_XATTR_PROTATTR, > }; > @@ -431,6 +432,8 @@ bool ovl_already_copied_up(struct dentry *dentry, int flags); > bool ovl_path_check_dir_xattr(struct ovl_fs *ofs, const struct path *path, > enum ovl_xattr ox); > bool ovl_path_check_origin_xattr(struct ovl_fs *ofs, const struct path *path); > +bool ovl_init_uuid_xattr(struct super_block *sb, struct ovl_fs *ofs, > + struct dentry *upperdentry, bool set); > > static inline bool ovl_check_origin_xattr(struct ovl_fs *ofs, > struct dentry *upperdentry) > diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c > index ad2250f98b38..8364620e8722 100644 > --- a/fs/overlayfs/super.c > +++ b/fs/overlayfs/super.c > @@ -1535,6 +1535,9 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs, > if (err) > pr_err("failed to verify index dir 'upper' xattr\n"); > > + /* Best effort get or set persistent uuid */ > + ovl_init_uuid_xattr(sb, ofs, ofs->indexdir, true); > + > /* Cleanup bad/stale/orphan index entries */ > if (!err) > err = ovl_indexdir_cleanup(ofs); > @@ -2052,6 +2055,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) > ovl_uuid_str[ofs->config.uuid]); > } > > + /* > + * This uuid may be overridden by a persistent uuid stored in xattr on > + * index dir and it may be persisted in xattr on first index=on mount. > + */ > if (ovl_want_uuid_gen(ofs)) > uuid_gen(&sb->s_uuid); > > diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c > index 923d66d131c1..8902db4b2975 100644 > --- a/fs/overlayfs/util.c > +++ b/fs/overlayfs/util.c > @@ -589,6 +589,45 @@ bool ovl_path_check_origin_xattr(struct ovl_fs *ofs, const struct path *path) > return false; > } > > +/* > + * Load persistent uuid from xattr into s_uuid if found, possibly overriding > + * the random generated value in s_uuid. > + * Otherwise, if @set is true and s_uuid contains a valid value, store this > + * value in xattr. > + */ > +bool ovl_init_uuid_xattr(struct super_block *sb, struct ovl_fs *ofs, > + struct dentry *upperdentry, bool set) > +{ > + struct path path = { > + .dentry = upperdentry, > + .mnt = ovl_upper_mnt(ofs), > + }; > + uuid_t uuid; > + int res; > + > + res = ovl_path_getxattr(ofs, &path, OVL_XATTR_UUID, uuid.b, UUID_SIZE); > + if (res == UUID_SIZE) { > + uuid_copy(&sb->s_uuid, &uuid); > + return true; > + } > + > + if (res == -ENODATA) { > + if (!set || uuid_is_null(&sb->s_uuid)) > + return false; > + > + res = ovl_setxattr(ofs, upperdentry, OVL_XATTR_UUID, > + sb->s_uuid.b, UUID_SIZE); > + if (res == 0) > + return true; > + } else { > + set = false; > + } > + > + pr_warn("failed to %s uuid (%pd2, err=%i)\n", > + set ? "set" : "get", upperdentry, res); > + return false; > +} > + > bool ovl_path_check_dir_xattr(struct ovl_fs *ofs, const struct path *path, > enum ovl_xattr ox) > { > @@ -611,6 +650,7 @@ bool ovl_path_check_dir_xattr(struct ovl_fs *ofs, const struct path *path, > #define OVL_XATTR_IMPURE_POSTFIX "impure" > #define OVL_XATTR_NLINK_POSTFIX "nlink" > #define OVL_XATTR_UPPER_POSTFIX "upper" > +#define OVL_XATTR_UUID_POSTFIX "uuid" > #define OVL_XATTR_METACOPY_POSTFIX "metacopy" > #define OVL_XATTR_PROTATTR_POSTFIX "protattr" > > @@ -625,6 +665,7 @@ const char *const ovl_xattr_table[][2] = { > OVL_XATTR_TAB_ENTRY(OVL_XATTR_IMPURE), > OVL_XATTR_TAB_ENTRY(OVL_XATTR_NLINK), > OVL_XATTR_TAB_ENTRY(OVL_XATTR_UPPER), > + OVL_XATTR_TAB_ENTRY(OVL_XATTR_UUID), > OVL_XATTR_TAB_ENTRY(OVL_XATTR_METACOPY), > OVL_XATTR_TAB_ENTRY(OVL_XATTR_PROTATTR), > }; > -- > 2.34.1 >