Re: [PATCH v3 2/2] ovl: introduce new "uuid=off" option for inodes index feature

From: Pavel Tikhomirov
Date: Fri Sep 25 2020 - 04:39:20 EST


Thanks for review! I've sent v4 to address all your comments. I've also noticed that I had inconsistent config option naming:

+config OVERLAY_FS_INDEX_UUID_OFF
+static bool ovl_uuid_off_def = IS_ENABLED(CONFIG_OVERLAY_FS_UUID_OFF);

this is also fixed.

On 9/24/20 8:02 PM, Amir Goldstein wrote:
On Thu, Sep 24, 2020 at 7:38 PM Pavel Tikhomirov
<ptikhomirov@xxxxxxxxxxxxx> wrote:

This replaces uuid with null in overelayfs file handles and thus relaxes
uuid checks for overlay index feature. It is only possible in case there
is only one filesystem for all the work/upper/lower directories and bare
file handles from this backing filesystem are uniq. In other case when
we have multiple filesystems lets just fallback to "uuid=on" which is
and equivalent of how it worked before with all uuid checks.

This is needed when overlayfs is/was mounted in a container with index
enabled (e.g.: to be able to resolve inotify watch file handles on it to
paths in CRIU), and this container is copied and started alongside with
the original one. This way the "copy" container can't have the same uuid
on the superblock and mounting the overlayfs from it later would fail.

Note: In our (Virtuozzo) use case users inside a container can create
"regular" overlayfs mounts without any "index=" option, but we still
want to migrate this containers with CRIU so we set "index=on" as kernel
default so that all the container overlayfs mounts get support of file
handles automatically. With "uuid=off" we want the same thing (to be
able to "copy" container with uuid change) - we would set kernel default
so that all the container overlayfs mounts get "uuid=off" automatically.

That is an example of the problem on top of loop+ext4:

dd if=/dev/zero of=loopbackfile.img bs=100M count=10
losetup -fP loopbackfile.img
losetup -a
#/dev/loop0: [64768]:35 (/loop-test/loopbackfile.img)
mkfs.ext4 loopbackfile.img
mkdir loop-mp
mount -o loop /dev/loop0 loop-mp
mkdir loop-mp/{lower,upper,work,merged}
mount -t overlay overlay -oindex=on,lowerdir=loop-mp/lower,\
upperdir=loop-mp/upper,workdir=loop-mp/work loop-mp/merged
umount loop-mp/merged
umount loop-mp
e2fsck -f /dev/loop0
tune2fs -U random /dev/loop0

mount -o loop /dev/loop0 loop-mp
mount -t overlay overlay -oindex=on,lowerdir=loop-mp/lower,\
upperdir=loop-mp/upper,workdir=loop-mp/work loop-mp/merged
#mount: /loop-test/loop-mp/merged:
#mount(2) system call failed: Stale file handle.

If you just change the uuid of the backing filesystem, overlay is not
mounting any more. In Virtuozzo we copy container disks (ploops) when
crate the copy of container and we require fs uuid to be uniq for a new
container.

v2: in v1 I missed actual uuid check skip
v3: rebase to overlayfs-next, replace uuid with null in file handles,
split ovl_fs propagation to function arguments to separate patch, add
separate bool "uuid=on/off" option, move numfs check up, add doc note.

change log does not belong in commit message.
Move after --- please.


CC: Amir Goldstein <amir73il@xxxxxxxxx>
CC: Vivek Goyal <vgoyal@xxxxxxxxxx>
CC: Miklos Szeredi <miklos@xxxxxxxxxx>
CC: linux-unionfs@xxxxxxxxxxxxxxx
CC: linux-kernel@xxxxxxxxxxxxxxx
Signed-off-by: Pavel Tikhomirov <ptikhomirov@xxxxxxxxxxxxx>
---
Documentation/filesystems/overlayfs.rst | 6 ++++++
fs/overlayfs/Kconfig | 17 +++++++++++++++++
fs/overlayfs/copy_up.c | 3 ++-
fs/overlayfs/namei.c | 5 ++++-
fs/overlayfs/ovl_entry.h | 1 +
fs/overlayfs/super.c | 25 +++++++++++++++++++++++++
6 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst
index 580ab9a0fe31..4f9cc20f255c 100644
--- a/Documentation/filesystems/overlayfs.rst
+++ b/Documentation/filesystems/overlayfs.rst
@@ -563,6 +563,12 @@ This verification may cause significant overhead in some cases.
Note: the mount options index=off,nfs_export=on are conflicting for a
read-write mount and will result in an error.

+Note: the mount option uuid=off (or corresponding module param, or kernel
+config) can be used to replace UUID of the underlying filesystem in file
+handles with null, and effectively disable UUID checks. This can be useful in
+case the underlying disk is copied and the UUID of this copy is changed. This
+is only applicable if all lower/upper/work directories are on the same
+filesystem, otherwise it will fallback to normal behaviour.

Volatile mount
--------------
diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig
index dd188c7996b3..888c6e5e71ee 100644
--- a/fs/overlayfs/Kconfig
+++ b/fs/overlayfs/Kconfig
@@ -61,6 +61,23 @@ config OVERLAY_FS_INDEX

If unsure, say N.

+config OVERLAY_FS_INDEX_UUID_OFF

Please get rid of all the double negatives.
config/param uuid_off should be uuid and default to Y.
Otherwise this looks fine to me.

+ bool "Overlayfs: export null uuid in file handles"
+ depends on OVERLAY_FS
+ help
+ If this config option is enabled then overlay will replace uuid with
+ null in overlayfs file handles, effectively disabling uuid checks for
+ them. This affects overlayfs mounted with "index=on". This only can be
+ done if all upper and lower directories are on the same filesystem
+ where basic fhandles are uniq. In case the latter is not true
+ overlayfs would fallback to normal uuid checking mode.
+
+ It is needed to overcome possible change of uuid on superblock of the
+ backing filesystem, e.g. when you copied the virtual disk and mount
+ both the copy of the disk and the original one at the same time.
+
+ If unsure, say N.
+
config OVERLAY_FS_NFS_EXPORT
bool "Overlayfs: turn on NFS export feature by default"
depends on OVERLAY_FS
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 3380039036d6..0b7e7a90a435 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -320,7 +320,8 @@ struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real,
if (is_upper)
fh->fb.flags |= OVL_FH_FLAG_PATH_UPPER;
fh->fb.len = sizeof(fh->fb) + buflen;
- fh->fb.uuid = *uuid;
+ if (ofs->config.uuid)
+ fh->fb.uuid = *uuid;

return fh;

diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index f058bf8e8b87..0262c39886d0 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -159,8 +159,11 @@ struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh,
/*
* Make sure that the stored uuid matches the uuid of the lower
* layer where file handle will be decoded.
+ * In case of index=nouuid option just make sure that stored

leftover index=nouuid

Thanks,
Amir.


--
Best regards, Tikhomirov Pavel
Software Developer, Virtuozzo.