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 <amir73il@xxxxxxxxx> --- Documentation/filesystems/overlayfs.rst | 8 +++++++- fs/overlayfs/overlayfs.h | 4 +++- fs/overlayfs/params.c | 3 ++- fs/overlayfs/util.c | 22 ++++++++++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst index 8275ed735f77..35853906accb 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 8b026d758eaf..72f57d919aa9 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 5a59c87c1dfe..3fc01feb5f12 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 8602982ae579..9ebb9598e7ec 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); -- 2.34.1