Commit f4d0ec0a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'erofs-for-7.0-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs

Pull erofs fixes from Gao Xiang:

 - Do not share the page cache if the real @aops differs

 - Fix the incomplete condition for interlaced plain extents

 - Get rid of more unnecessary #ifdefs

* tag 'erofs-for-7.0-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
  erofs: fix interlaced plain identification for encoded extents
  erofs: remove more unnecessary #ifdefs
  erofs: allow sharing page cache with the same aops only
parents d9d32e5b 4a2d046e
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -222,6 +222,7 @@ static int erofs_read_inode(struct inode *inode)

static int erofs_fill_inode(struct inode *inode)
{
	const struct address_space_operations *aops;
	int err;

	trace_erofs_fill_inode(inode);
@@ -254,7 +255,11 @@ static int erofs_fill_inode(struct inode *inode)
	}

	mapping_set_large_folios(inode->i_mapping);
	return erofs_inode_set_aops(inode, inode, false);
	aops = erofs_get_aops(inode, false);
	if (IS_ERR(aops))
		return PTR_ERR(aops);
	inode->i_mapping->a_ops = aops;
	return 0;
}

/*
+7 −9
Original line number Diff line number Diff line
@@ -471,26 +471,24 @@ static inline void *erofs_vm_map_ram(struct page **pages, unsigned int count)
	return NULL;
}

static inline int erofs_inode_set_aops(struct inode *inode,
				       struct inode *realinode, bool no_fscache)
static inline const struct address_space_operations *
erofs_get_aops(struct inode *realinode, bool no_fscache)
{
	if (erofs_inode_is_data_compressed(EROFS_I(realinode)->datalayout)) {
		if (!IS_ENABLED(CONFIG_EROFS_FS_ZIP))
			return -EOPNOTSUPP;
			return ERR_PTR(-EOPNOTSUPP);
		DO_ONCE_LITE_IF(realinode->i_blkbits != PAGE_SHIFT,
			  erofs_info, realinode->i_sb,
			  "EXPERIMENTAL EROFS subpage compressed block support in use. Use at your own risk!");
		inode->i_mapping->a_ops = &z_erofs_aops;
		return 0;
		return &z_erofs_aops;
	}
	inode->i_mapping->a_ops = &erofs_aops;
	if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && !no_fscache &&
	    erofs_is_fscache_mode(realinode->i_sb))
		inode->i_mapping->a_ops = &erofs_fscache_access_aops;
		return &erofs_fscache_access_aops;
	if (IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) &&
	    erofs_is_fileio_mode(EROFS_SB(realinode->i_sb)))
		inode->i_mapping->a_ops = &erofs_fileio_aops;
	return 0;
		return &erofs_fileio_aops;
	return &erofs_aops;
}

int erofs_register_sysfs(struct super_block *sb);
+9 −5
Original line number Diff line number Diff line
@@ -40,10 +40,14 @@ bool erofs_ishare_fill_inode(struct inode *inode)
{
	struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);
	struct erofs_inode *vi = EROFS_I(inode);
	const struct address_space_operations *aops;
	struct erofs_inode_fingerprint fp;
	struct inode *sharedinode;
	unsigned long hash;

	aops = erofs_get_aops(inode, true);
	if (IS_ERR(aops))
		return false;
	if (erofs_xattr_fill_inode_fingerprint(&fp, inode, sbi->domain_id))
		return false;
	hash = xxh32(fp.opaque, fp.size, 0);
@@ -56,15 +60,15 @@ bool erofs_ishare_fill_inode(struct inode *inode)
	}

	if (inode_state_read_once(sharedinode) & I_NEW) {
		if (erofs_inode_set_aops(sharedinode, inode, true)) {
			iget_failed(sharedinode);
			kfree(fp.opaque);
			return false;
		}
		sharedinode->i_mapping->a_ops = aops;
		sharedinode->i_size = vi->vfs_inode.i_size;
		unlock_new_inode(sharedinode);
	} else {
		kfree(fp.opaque);
		if (aops != sharedinode->i_mapping->a_ops) {
			iput(sharedinode);
			return false;
		}
		if (sharedinode->i_size != vi->vfs_inode.i_size) {
			_erofs_printk(inode->i_sb, KERN_WARNING
				"size(%lld:%lld) not matches for the same fingerprint\n",
+36 −49
Original line number Diff line number Diff line
@@ -424,26 +424,23 @@ static const struct fs_parameter_spec erofs_fs_parameters[] = {

static bool erofs_fc_set_dax_mode(struct fs_context *fc, unsigned int mode)
{
#ifdef CONFIG_FS_DAX
	if (IS_ENABLED(CONFIG_FS_DAX)) {
		struct erofs_sb_info *sbi = fc->s_fs_info;

	switch (mode) {
	case EROFS_MOUNT_DAX_ALWAYS:
		if (mode == EROFS_MOUNT_DAX_ALWAYS) {
			set_opt(&sbi->opt, DAX_ALWAYS);
			clear_opt(&sbi->opt, DAX_NEVER);
			return true;
	case EROFS_MOUNT_DAX_NEVER:
		} else if (mode == EROFS_MOUNT_DAX_NEVER) {
			set_opt(&sbi->opt, DAX_NEVER);
			clear_opt(&sbi->opt, DAX_ALWAYS);
			return true;
	default:
		}
		DBG_BUGON(1);
		return false;
	}
#else
	errorfc(fc, "dax options not supported");
	return false;
#endif
}

static int erofs_fc_parse_param(struct fs_context *fc,
@@ -460,31 +457,26 @@ static int erofs_fc_parse_param(struct fs_context *fc,

	switch (opt) {
	case Opt_user_xattr:
#ifdef CONFIG_EROFS_FS_XATTR
		if (result.boolean)
		if (!IS_ENABLED(CONFIG_EROFS_FS_XATTR))
			errorfc(fc, "{,no}user_xattr options not supported");
		else if (result.boolean)
			set_opt(&sbi->opt, XATTR_USER);
		else
			clear_opt(&sbi->opt, XATTR_USER);
#else
		errorfc(fc, "{,no}user_xattr options not supported");
#endif
		break;
	case Opt_acl:
#ifdef CONFIG_EROFS_FS_POSIX_ACL
		if (result.boolean)
		if (!IS_ENABLED(CONFIG_EROFS_FS_POSIX_ACL))
			errorfc(fc, "{,no}acl options not supported");
		else if (result.boolean)
			set_opt(&sbi->opt, POSIX_ACL);
		else
			clear_opt(&sbi->opt, POSIX_ACL);
#else
		errorfc(fc, "{,no}acl options not supported");
#endif
		break;
	case Opt_cache_strategy:
#ifdef CONFIG_EROFS_FS_ZIP
		sbi->opt.cache_strategy = result.uint_32;
#else
		if (!IS_ENABLED(CONFIG_EROFS_FS_ZIP))
			errorfc(fc, "compression not supported, cache_strategy ignored");
#endif
		else
			sbi->opt.cache_strategy = result.uint_32;
		break;
	case Opt_dax:
		if (!erofs_fc_set_dax_mode(fc, EROFS_MOUNT_DAX_ALWAYS))
@@ -533,24 +525,21 @@ static int erofs_fc_parse_param(struct fs_context *fc,
		break;
#endif
	case Opt_directio:
#ifdef CONFIG_EROFS_FS_BACKED_BY_FILE
		if (result.boolean)
		if (!IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE))
			errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name);
		else if (result.boolean)
			set_opt(&sbi->opt, DIRECT_IO);
		else
			clear_opt(&sbi->opt, DIRECT_IO);
#else
		errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name);
#endif
		break;
	case Opt_fsoffset:
		sbi->dif0.fsoff = result.uint_64;
		break;
	case Opt_inode_share:
#ifdef CONFIG_EROFS_FS_PAGE_CACHE_SHARE
		set_opt(&sbi->opt, INODE_SHARE);
#else
		if (!IS_ENABLED(CONFIG_EROFS_FS_PAGE_CACHE_SHARE))
			errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name);
#endif
		else
			set_opt(&sbi->opt, INODE_SHARE);
		break;
	}
	return 0;
@@ -809,8 +798,7 @@ static int erofs_fc_get_tree(struct fs_context *fc)
	ret = get_tree_bdev_flags(fc, erofs_fc_fill_super,
		IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) ?
			GET_TREE_BDEV_QUIET_LOOKUP : 0);
#ifdef CONFIG_EROFS_FS_BACKED_BY_FILE
	if (ret == -ENOTBLK) {
	if (IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) && ret == -ENOTBLK) {
		struct file *file;

		if (!fc->source)
@@ -824,7 +812,6 @@ static int erofs_fc_get_tree(struct fs_context *fc)
		    sbi->dif0.file->f_mapping->a_ops->read_folio)
			return get_tree_nodev(fc, erofs_fc_fill_super);
	}
#endif
	return ret;
}

@@ -1108,12 +1095,12 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root)
		seq_puts(seq, ",dax=never");
	if (erofs_is_fileio_mode(sbi) && test_opt(opt, DIRECT_IO))
		seq_puts(seq, ",directio");
#ifdef CONFIG_EROFS_FS_ONDEMAND
	if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND)) {
		if (sbi->fsid)
			seq_printf(seq, ",fsid=%s", sbi->fsid);
		if (sbi->domain_id)
			seq_printf(seq, ",domain_id=%s", sbi->domain_id);
#endif
	}
	if (sbi->dif0.fsoff)
		seq_printf(seq, ",fsoffset=%llu", sbi->dif0.fsoff);
	if (test_opt(opt, INODE_SHARE))
+5 −4
Original line number Diff line number Diff line
@@ -513,6 +513,7 @@ static int z_erofs_map_blocks_ext(struct inode *inode,
	unsigned int recsz = z_erofs_extent_recsize(vi->z_advise);
	erofs_off_t pos = round_up(Z_EROFS_MAP_HEADER_END(erofs_iloc(inode) +
				   vi->inode_isize + vi->xattr_isize), recsz);
	unsigned int bmask = sb->s_blocksize - 1;
	bool in_mbox = erofs_inode_in_metabox(inode);
	erofs_off_t lend = inode->i_size;
	erofs_off_t l, r, mid, pa, la, lstart;
@@ -596,17 +597,17 @@ static int z_erofs_map_blocks_ext(struct inode *inode,
			map->m_flags |= EROFS_MAP_MAPPED |
				EROFS_MAP_FULL_MAPPED | EROFS_MAP_ENCODED;
			fmt = map->m_plen >> Z_EROFS_EXTENT_PLEN_FMT_BIT;
			if (map->m_plen & Z_EROFS_EXTENT_PLEN_PARTIAL)
				map->m_flags |= EROFS_MAP_PARTIAL_REF;
			map->m_plen &= Z_EROFS_EXTENT_PLEN_MASK;
			if (fmt)
				map->m_algorithmformat = fmt - 1;
			else if (interlaced && !erofs_blkoff(sb, map->m_pa))
			else if (interlaced && !((map->m_pa | map->m_plen) & bmask))
				map->m_algorithmformat =
					Z_EROFS_COMPRESSION_INTERLACED;
			else
				map->m_algorithmformat =
					Z_EROFS_COMPRESSION_SHIFTED;
			if (map->m_plen & Z_EROFS_EXTENT_PLEN_PARTIAL)
				map->m_flags |= EROFS_MAP_PARTIAL_REF;
			map->m_plen &= Z_EROFS_EXTENT_PLEN_MASK;
		}
	}
	map->m_llen = lend - map->m_la;