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
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

View File

@ -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;
}
/*

View File

@ -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[] = {

View File

@ -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);