diff options
| author | Amir Goldstein <amir73il@gmail.com> | 2026-01-20 15:58:31 +0100 |
|---|---|---|
| committer | Amir Goldstein <amir73il@gmail.com> | 2026-02-06 13:48:23 +0100 |
| commit | 869056dbbd636f8f256b695f39c102eb3ce2edd0 (patch) | |
| tree | 55cc6687fe5806b44f21bac26caa10e3130bc524 /fs/overlayfs | |
| parent | fcb70a56f4d81450114034b2c61f48ce7444a0e2 (diff) | |
| download | lwn-869056dbbd636f8f256b695f39c102eb3ce2edd0.tar.gz lwn-869056dbbd636f8f256b695f39c102eb3ce2edd0.zip | |
ovl: relax requirement for uuid=off,index=on
uuid=off,index=on required that all upper/lower directories are on the
same filesystem.
Relax the requirement so that only all the lower directories need to be
on the same filesystem.
Reported-by: André Almeida <andrealmeid@igalia.com>
Link: https://lore.kernel.org/r/20260114-tonyk-get_disk_uuid-v1-3-e6a319e25d57@igalia.com/
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Diffstat (limited to 'fs/overlayfs')
| -rw-r--r-- | fs/overlayfs/namei.c | 21 | ||||
| -rw-r--r-- | fs/overlayfs/overlayfs.h | 2 | ||||
| -rw-r--r-- | fs/overlayfs/super.c | 15 |
3 files changed, 21 insertions, 17 deletions
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index e9a69c95be91..74c514603ac2 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -158,6 +158,18 @@ invalid: goto out; } +bool ovl_uuid_match(struct ovl_fs *ofs, const struct super_block *sb, + const uuid_t *uuid) +{ + /* + * Make sure that the stored uuid matches the uuid of the lower + * layer where file handle will be decoded. + * In case of uuid=off option just make sure that stored uuid is null. + */ + return ovl_origin_uuid(ofs) ? uuid_equal(uuid, &sb->s_uuid) : + uuid_is_null(uuid); +} + struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh, struct vfsmount *mnt, bool connected) { @@ -167,14 +179,7 @@ struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh, if (!capable(CAP_DAC_READ_SEARCH)) return NULL; - /* - * Make sure that the stored uuid matches the uuid of the lower - * layer where file handle will be decoded. - * In case of uuid=off option just make sure that stored uuid is null. - */ - if (ovl_origin_uuid(ofs) ? - !uuid_equal(&fh->fb.uuid, &mnt->mnt_sb->s_uuid) : - !uuid_is_null(&fh->fb.uuid)) + if (!ovl_uuid_match(ofs, mnt->mnt_sb, &fh->fb.uuid)) return NULL; bytes = (fh->fb.len - offsetof(struct ovl_fb, fid)); diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index f9ac9bdde830..cf1066152210 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -710,6 +710,8 @@ static inline int ovl_check_fh_len(struct ovl_fh *fh, int fh_len) return ovl_check_fb_len(&fh->fb, fh_len - OVL_FH_WIRE_OFFSET); } +bool ovl_uuid_match(struct ovl_fs *ofs, const struct super_block *sb, + const uuid_t *uuid); struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh, struct vfsmount *mnt, bool connected); int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected, diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index ba9146f22a2c..c9f166a1390a 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -940,7 +940,7 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid) * disable lower file handle decoding on all of them. */ if (ofs->fs[i].is_lower && - uuid_equal(&ofs->fs[i].sb->s_uuid, uuid)) { + ovl_uuid_match(ofs, ofs->fs[i].sb, uuid)) { ofs->fs[i].bad_uuid = true; return false; } @@ -952,6 +952,7 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid) static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) { struct super_block *sb = path->mnt->mnt_sb; + const uuid_t *uuid = ovl_origin_uuid(ofs) ? &sb->s_uuid : &uuid_null; unsigned int i; dev_t dev; int err; @@ -963,7 +964,7 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) return i; } - if (!ovl_lower_uuid_ok(ofs, &sb->s_uuid)) { + if (!ovl_lower_uuid_ok(ofs, uuid)) { bad_uuid = true; if (ofs->config.xino == OVL_XINO_AUTO) { ofs->config.xino = OVL_XINO_OFF; @@ -975,9 +976,8 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) warn = true; } if (warn) { - pr_warn("%s uuid detected in lower fs '%pd2', falling back to xino=%s,index=off,nfs_export=off.\n", - uuid_is_null(&sb->s_uuid) ? "null" : - "conflicting", + pr_warn("%s uuid in non-single lower fs '%pd2', falling back to xino=%s,index=off,nfs_export=off.\n", + uuid_is_null(uuid) ? "null" : "conflicting", path->dentry, ovl_xino_mode(&ofs->config)); } } @@ -1469,10 +1469,7 @@ static int ovl_fill_super_creds(struct fs_context *fc, struct super_block *sb) if (!ovl_upper_mnt(ofs)) sb->s_flags |= SB_RDONLY; - if (!ovl_origin_uuid(ofs) && ofs->numfs > 1) { - pr_warn("The uuid=off requires a single fs for lower and upper, falling back to uuid=null.\n"); - ofs->config.uuid = OVL_UUID_NULL; - } else if (ovl_has_fsid(ofs) && ovl_upper_mnt(ofs)) { + if (ovl_has_fsid(ofs) && ovl_upper_mnt(ofs)) { /* Use per instance persistent uuid/fsid */ ovl_init_uuid_xattr(sb, ofs, &ctx->upper); } |
