Commit c6993c4c authored by Yuezhang Mo's avatar Yuezhang Mo Committed by Gao Xiang
Browse files

erofs: Fallback to normal access if DAX is not supported on extra device



If using multiple devices, we should check if the extra device support
DAX instead of checking the primary device when deciding if to use DAX
to access a file.

If an extra device does not support DAX we should fallback to normal
access otherwise the data on that device will be inaccessible.

Signed-off-by: default avatarYuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: default avatarFriendy Su <friendy.su@sony.com>
Reviewed-by: default avatarJacky Cao <jacky.cao@sony.com>
Reviewed-by: default avatarDaniel Palmer <daniel.palmer@sony.com>
Reviewed-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: default avatarHongbo Li <lihongbo22@huawei.com>
Link: https://lore.kernel.org/r/20250804082030.3667257-2-Yuezhang.Mo@sony.com


Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent 8f5ae30d
Loading
Loading
Loading
Loading
+14 −10
Original line number Diff line number Diff line
@@ -174,6 +174,11 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
		if (!erofs_is_fileio_mode(sbi)) {
			dif->dax_dev = fs_dax_get_by_bdev(file_bdev(file),
					&dif->dax_part_off, NULL, NULL);
			if (!dif->dax_dev && test_opt(&sbi->opt, DAX_ALWAYS)) {
				erofs_info(sb, "DAX unsupported by %s. Turning off DAX.",
					   dif->path);
				clear_opt(&sbi->opt, DAX_ALWAYS);
			}
		} else if (!S_ISREG(file_inode(file)->i_mode)) {
			fput(file);
			return -EINVAL;
@@ -210,8 +215,13 @@ static int erofs_scan_devices(struct super_block *sb,
			  ondisk_extradevs, sbi->devs->extra_devices);
		return -EINVAL;
	}
	if (!ondisk_extradevs)
	if (!ondisk_extradevs) {
		if (test_opt(&sbi->opt, DAX_ALWAYS) && !sbi->dif0.dax_dev) {
			erofs_info(sb, "DAX unsupported by block device. Turning off DAX.");
			clear_opt(&sbi->opt, DAX_ALWAYS);
		}
		return 0;
	}

	if (!sbi->devs->extra_devices && !erofs_is_fscache_mode(sb))
		sbi->devs->flatdev = true;
@@ -338,7 +348,6 @@ static int erofs_read_superblock(struct super_block *sb)
	if (ret < 0)
		goto out;

	/* handle multiple devices */
	ret = erofs_scan_devices(sb, dsb);

	if (erofs_sb_has_48bit(sbi))
@@ -671,15 +680,10 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
			return invalfc(fc, "cannot use fsoffset in fscache mode");
	}

	if (test_opt(&sbi->opt, DAX_ALWAYS)) {
		if (!sbi->dif0.dax_dev) {
			errorfc(fc, "DAX unsupported by block device. Turning off DAX.");
			clear_opt(&sbi->opt, DAX_ALWAYS);
		} else if (sbi->blkszbits != PAGE_SHIFT) {
			errorfc(fc, "unsupported blocksize for DAX");
	if (test_opt(&sbi->opt, DAX_ALWAYS) && sbi->blkszbits != PAGE_SHIFT) {
		erofs_info(sb, "unsupported blocksize for DAX");
		clear_opt(&sbi->opt, DAX_ALWAYS);
	}
	}

	sb->s_time_gran = 1;
	sb->s_xattr = erofs_xattr_handlers;