erofs: fix disallowing superblock_share if device= is set

superblock_share together with device= is rejected in
erofs_fc_fill_super():

	if (test_opt(&sbi->opt, SUPERBLOCK_SHARE) &&
	    sbi->devs->extra_devices)
		return -EINVAL;

but extra_devices is kept in sbi->devs, not in sbi->opt, and
erofs_sb_share_test_super() compares only the backing inode, the
fsoffset and sbi->opt.  So once the image is mounted with
superblock_share, a second mount with superblock_share,device= matches
that superblock and get_tree_super() reuses it without calling
fill_super() at all.

The same command line therefore either fails with -EINVAL or succeeds
with device= quietly dropped, depending on whether a compatible mount
already exists.

Refuse to match a context that brought device= options, so that it gets
a superblock of its own and fill_super() decides as it does today.

Only the incoming context can be tested: a shared superblock may have
extra_devices set itself, because erofs_scan_devices() fills the device
table from the image when no device= was given.

Fixes: cd4108319b ("erofs: reuse superblock for file-backed mounts")
Signed-off-by: Zhan Xusheng <[email protected]>
Reviewed-by: Gao Xiang <[email protected]>
Signed-off-by: Gao Xiang (Docker) <[email protected]>
This commit is contained in:
Zhan Xusheng authored and Gao Xiang committed 2026-10-26 11:51:05 +01:00
1 parent 52dceb8808
commit aafea970fb
1 file changed
+2 -1
+2 -1
View File
@@ -827,7 +827,8 @@ static int erofs_sb_share_test_super(struct super_block *sb,
return 0; return 0;
return file_inode(sbi->dif0.file) == file_inode(new_sbi->dif0.file) && return file_inode(sbi->dif0.file) == file_inode(new_sbi->dif0.file) &&
sbi->dif0.fsoff == new_sbi->dif0.fsoff && sbi->dif0.fsoff == new_sbi->dif0.fsoff &&
!memcmp(&sbi->opt, &new_sbi->opt, sizeof(sbi->opt)); !memcmp(&sbi->opt, &new_sbi->opt, sizeof(sbi->opt)) &&
!new_sbi->devs->extra_devices;
} }
static int erofs_file_get_tree(struct fs_context *fc) static int erofs_file_get_tree(struct fs_context *fc)