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 <amir73il@gmail.com>
This commit is contained in:
Amir Goldstein 2023-07-07 11:26:29 +03:00
parent d9544c1b0d
commit cbb44f0935
4 changed files with 34 additions and 3 deletions

View File

@ -664,7 +664,7 @@ UUID and fsid
The UUID of overlayfs instance itself and the fsid reported by statfs(2) are The UUID of overlayfs instance itself and the fsid reported by statfs(2) are
controlled by the "uuid" mount option, which supports these values: 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. UUID of overlayfs is null. fsid is taken from upper most filesystem.
- "off": - "off":
UUID of overlayfs is null. fsid is taken from upper most filesystem. 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 UUID is stored in xattr "trusted.overlay.uuid", making overlayfs fsid
unique and persistent. This option requires an overlayfs with upper unique and persistent. This option requires an overlayfs with upper
filesystem that supports xattrs. 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 Volatile mount

View File

@ -71,6 +71,7 @@ enum {
enum { enum {
OVL_UUID_OFF, OVL_UUID_OFF,
OVL_UUID_NULL, OVL_UUID_NULL,
OVL_UUID_AUTO,
OVL_UUID_ON, 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) 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;
} }
/* /*

View File

@ -68,6 +68,7 @@ static const struct constant_table ovl_parameter_bool[] = {
static const struct constant_table ovl_parameter_uuid[] = { static const struct constant_table ovl_parameter_uuid[] = {
{ "off", OVL_UUID_OFF }, { "off", OVL_UUID_OFF },
{ "null", OVL_UUID_NULL }, { "null", OVL_UUID_NULL },
{ "auto", OVL_UUID_AUTO },
{ "on", OVL_UUID_ON }, { "on", OVL_UUID_ON },
{} {}
}; };
@ -79,7 +80,7 @@ static const char *ovl_uuid_mode(struct ovl_config *config)
static int ovl_uuid_def(void) static int ovl_uuid_def(void)
{ {
return OVL_UUID_NULL; return OVL_UUID_AUTO;
} }
static const struct constant_table ovl_parameter_xino[] = { static const struct constant_table ovl_parameter_xino[] = {

View File

@ -695,6 +695,28 @@ bool ovl_init_uuid_xattr(struct super_block *sb, struct ovl_fs *ofs,
if (res != -ENODATA) if (res != -ENODATA)
goto fail; 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 */ /* Generate overlay instance uuid */
uuid_gen(&sb->s_uuid); uuid_gen(&sb->s_uuid);