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>
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.
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
enum {
OVL_UUID_OFF,
OVL_UUID_NULL,
+ OVL_UUID_AUTO,
OVL_UUID_ON,
};
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;
}
/*
static const struct constant_table ovl_parameter_uuid[] = {
{ "off", OVL_UUID_OFF },
{ "null", OVL_UUID_NULL },
+ { "auto", OVL_UUID_AUTO },
{ "on", OVL_UUID_ON },
{}
};
static int ovl_uuid_def(void)
{
- return OVL_UUID_NULL;
+ return OVL_UUID_AUTO;
}
static const struct constant_table ovl_parameter_xino[] = {
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);