From: Amir Goldstein Date: Fri, 7 Jul 2023 08:26:29 +0000 (+0300) Subject: ovl: auto generate uuid for new overlay filesystems X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=cbb44f0935974bba997f8db0458fac5739ae0009;p=linux.git ovl: auto generate uuid for new overlay filesystems Add a new mount option uuid=auto, which is the default. If a persistent UUID xattr is found it is used. Otherwise, an existing ovelrayfs with copied up subdirs in upper dir that was never mounted with uuid=on retains the null UUID. A new overlayfs with no copied up subdirs, generates the persistent UUID on first mount. Signed-off-by: Amir Goldstein --- diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst index 8275ed735f774..35853906accb3 100644 --- a/Documentation/filesystems/overlayfs.rst +++ b/Documentation/filesystems/overlayfs.rst @@ -664,7 +664,7 @@ UUID and fsid The UUID of overlayfs instance itself and the fsid reported by statfs(2) are controlled by the "uuid" mount option, which supports these values: -- "null": (default) +- "null": UUID of overlayfs is null. fsid is taken from upper most filesystem. - "off": UUID of overlayfs is null. fsid is taken from upper most filesystem. @@ -674,6 +674,12 @@ controlled by the "uuid" mount option, which supports these values: UUID is stored in xattr "trusted.overlay.uuid", making overlayfs fsid unique and persistent. This option requires an overlayfs with upper filesystem that supports xattrs. +- "auto": (default) + UUID is taken from xattr "trusted.overlay.uuid" if it exists. + Upgrade to "uuid=on" on first time mount of new overlay filesystem that + meets the prerequites. + Downgrade to "uuid=null" for existing overlay filesystems that were never + mounted with "uuid=on". Volatile mount diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 8b026d758eaf0..72f57d919aa91 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -71,6 +71,7 @@ enum { enum { OVL_UUID_OFF, OVL_UUID_NULL, + OVL_UUID_AUTO, OVL_UUID_ON, }; @@ -550,7 +551,8 @@ static inline bool ovl_origin_uuid(struct ovl_fs *ofs) static inline bool ovl_has_fsid(struct ovl_fs *ofs) { - return ofs->config.uuid == OVL_UUID_ON; + return ofs->config.uuid == OVL_UUID_ON || + ofs->config.uuid == OVL_UUID_AUTO; } /* diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c index 5a59c87c1dfee..3fc01feb5f124 100644 --- a/fs/overlayfs/params.c +++ b/fs/overlayfs/params.c @@ -68,6 +68,7 @@ static const struct constant_table ovl_parameter_bool[] = { static const struct constant_table ovl_parameter_uuid[] = { { "off", OVL_UUID_OFF }, { "null", OVL_UUID_NULL }, + { "auto", OVL_UUID_AUTO }, { "on", OVL_UUID_ON }, {} }; @@ -79,7 +80,7 @@ static const char *ovl_uuid_mode(struct ovl_config *config) static int ovl_uuid_def(void) { - return OVL_UUID_NULL; + return OVL_UUID_AUTO; } static const struct constant_table ovl_parameter_xino[] = { diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 8602982ae579d..9ebb9598e7ece 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -695,6 +695,28 @@ bool ovl_init_uuid_xattr(struct super_block *sb, struct ovl_fs *ofs, if (res != -ENODATA) goto fail; + /* + * With uuid=auto, if uuid xattr is found, it will be used. + * If uuid xattrs is not found, generate a persistent uuid only on mount + * of new overlays where upper root dir is not yet marked as impure. + * An upper dir is marked as impure on copy up or lookup of its subdirs. + */ + if (ofs->config.uuid == OVL_UUID_AUTO) { + res = ovl_path_getxattr(ofs, upperpath, OVL_XATTR_IMPURE, NULL, + 0); + if (res > 0) { + /* Any mount of old overlay - downgrade to uuid=null */ + ofs->config.uuid = OVL_UUID_NULL; + return true; + } else if (res == -ENODATA) { + /* First mount of new overlay - upgrade to uuid=on */ + ofs->config.uuid = OVL_UUID_ON; + } else if (res < 0) { + goto fail; + } + + } + /* Generate overlay instance uuid */ uuid_gen(&sb->s_uuid);