Commit b0504bfe authored by Amir Goldstein's avatar Amir Goldstein
Browse files

ovl: add support for unique fsid per instance



The legacy behavior of ovl_statfs() reports the f_fsid filled by
underlying upper fs. This fsid is not unique among overlayfs instances
on the same upper fs.

With mount option uuid=on, generate a non-persistent uuid per overlayfs
instance and use it as the seed for f_fsid, similar to tmpfs.

This is useful for reporting fanotify events with fid info from different
instances of overlayfs over the same upper fs.

The old behavior of null uuid and upper fs fsid is retained with the
mount option uuid=null, which is the default.

The mount option uuid=off that disables uuid checks in underlying layers
also retains the legacy behavior.

Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
parent 16aac5ad
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -657,6 +657,22 @@ 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.


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)
    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 of underlying layers is ignored.
- "on":
    UUID of overlayfs is generated and used to report a unique fsid.


Volatile mount
--------------

+1 −1
Original line number Diff line number Diff line
@@ -416,7 +416,7 @@ 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;
	if (ofs->config.uuid)
	if (ovl_origin_uuid(ofs))
		fh->fb.uuid = *uuid;

	return fh;
+3 −2
Original line number Diff line number Diff line
@@ -171,7 +171,8 @@ struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh,
	 * layer where file handle will be decoded.
	 * In case of uuid=off option just make sure that stored uuid is null.
	 */
	if (ofs->config.uuid ? !uuid_equal(&fh->fb.uuid, &mnt->mnt_sb->s_uuid) :
	if (ovl_origin_uuid(ofs) ?
	    !uuid_equal(&fh->fb.uuid, &mnt->mnt_sb->s_uuid) :
	    !uuid_is_null(&fh->fb.uuid))
		return NULL;

+16 −0
Original line number Diff line number Diff line
@@ -67,6 +67,12 @@ enum {
	OVL_REDIRECT_ON,
};

enum {
	OVL_UUID_OFF,
	OVL_UUID_NULL,
	OVL_UUID_ON,
};

enum {
	OVL_XINO_OFF,
	OVL_XINO_AUTO,
@@ -534,6 +540,16 @@ static inline bool ovl_redirect_dir(struct ovl_fs *ofs)
	return ofs->config.redirect_mode == OVL_REDIRECT_ON;
}

static inline bool ovl_origin_uuid(struct ovl_fs *ofs)
{
	return ofs->config.uuid != OVL_UUID_OFF;
}

static inline bool ovl_has_fsid(struct ovl_fs *ofs)
{
	return ofs->config.uuid == OVL_UUID_ON;
}

/*
 * With xino=auto, we do best effort to keep all inodes on same st_dev and
 * d_ino consistent with st_ino.
+1 −1
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ struct ovl_config {
	int redirect_mode;
	int verity_mode;
	bool index;
	bool uuid;
	int uuid;
	bool nfs_export;
	int xino;
	bool metacopy;
Loading