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

Merge tag 'erofs-for-6.10-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs

Pull more erofs updates from Gao Xiang:
 "The main ones are metadata API conversion to byte offsets by Al Viro.

  Another patch gets rid of unnecessary memory allocation out of DEFLATE
  decompressor. The remaining one is a trivial cleanup.

   - Convert metadata APIs to byte offsets

   - Avoid allocating DEFLATE streams unnecessarily

   - Some erofs_show_options() cleanup"

* tag 'erofs-for-6.10-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
  erofs: avoid allocating DEFLATE streams before mounting
  z_erofs_pcluster_begin(): don't bother with rounding position down
  erofs: don't round offset down for erofs_read_metabuf()
  erofs: don't align offset for erofs_read_metabuf() (simple cases)
  erofs: mechanically convert erofs_read_metabuf() to offsets
  erofs: clean up erofs_show_options()
parents c40b1994 80eb4f62
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -72,10 +72,10 @@ void erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb)
}

void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb,
			 erofs_blk_t blkaddr, enum erofs_kmap_type type)
			 erofs_off_t offset, enum erofs_kmap_type type)
{
	erofs_init_metabuf(buf, sb);
	return erofs_bread(buf, erofs_pos(sb, blkaddr), type);
	return erofs_bread(buf, offset, type);
}

static int erofs_map_blocks_flatmode(struct inode *inode,
@@ -152,7 +152,7 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)
	pos = ALIGN(erofs_iloc(inode) + vi->inode_isize +
		    vi->xattr_isize, unit) + unit * chunknr;

	kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(sb, pos), EROFS_KMAP);
	kaddr = erofs_read_metabuf(&buf, sb, pos, EROFS_KMAP);
	if (IS_ERR(kaddr)) {
		err = PTR_ERR(kaddr);
		goto out;
@@ -163,7 +163,7 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)

	/* handle block map */
	if (!(vi->chunkformat & EROFS_CHUNK_FORMAT_INDEXES)) {
		__le32 *blkaddr = kaddr + erofs_blkoff(sb, pos);
		__le32 *blkaddr = kaddr;

		if (le32_to_cpu(*blkaddr) == EROFS_NULL_ADDR) {
			map->m_flags = 0;
@@ -174,7 +174,7 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)
		goto out_unlock;
	}
	/* parse chunk indexes */
	idx = kaddr + erofs_blkoff(sb, pos);
	idx = kaddr;
	switch (le32_to_cpu(idx->blkaddr)) {
	case EROFS_NULL_ADDR:
		map->m_flags = 0;
@@ -294,11 +294,10 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
		struct erofs_buf buf = __EROFS_BUF_INITIALIZER;

		iomap->type = IOMAP_INLINE;
		ptr = erofs_read_metabuf(&buf, sb,
				erofs_blknr(sb, mdev.m_pa), EROFS_KMAP);
		ptr = erofs_read_metabuf(&buf, sb, mdev.m_pa, EROFS_KMAP);
		if (IS_ERR(ptr))
			return PTR_ERR(ptr);
		iomap->inline_data = ptr + erofs_blkoff(sb, mdev.m_pa);
		iomap->inline_data = ptr;
		iomap->private = buf.base;
	} else {
		iomap->type = IOMAP_MAPPED;
+29 −26
Original line number Diff line number Diff line
@@ -46,39 +46,15 @@ int __init z_erofs_deflate_init(void)
	/* by default, use # of possible CPUs instead */
	if (!z_erofs_deflate_nstrms)
		z_erofs_deflate_nstrms = num_possible_cpus();

	for (; z_erofs_deflate_avail_strms < z_erofs_deflate_nstrms;
	     ++z_erofs_deflate_avail_strms) {
		struct z_erofs_deflate *strm;

		strm = kzalloc(sizeof(*strm), GFP_KERNEL);
		if (!strm)
			goto out_failed;

		/* XXX: in-kernel zlib cannot shrink windowbits currently */
		strm->z.workspace = vmalloc(zlib_inflate_workspacesize());
		if (!strm->z.workspace) {
			kfree(strm);
			goto out_failed;
		}

		spin_lock(&z_erofs_deflate_lock);
		strm->next = z_erofs_deflate_head;
		z_erofs_deflate_head = strm;
		spin_unlock(&z_erofs_deflate_lock);
	}
	return 0;

out_failed:
	erofs_err(NULL, "failed to allocate zlib workspace");
	z_erofs_deflate_exit();
	return -ENOMEM;
}

int z_erofs_load_deflate_config(struct super_block *sb,
			struct erofs_super_block *dsb, void *data, int size)
{
	struct z_erofs_deflate_cfgs *dfl = data;
	static DEFINE_MUTEX(deflate_resize_mutex);
	static bool inited;

	if (!dfl || size < sizeof(struct z_erofs_deflate_cfgs)) {
		erofs_err(sb, "invalid deflate cfgs, size=%u", size);
@@ -89,9 +65,36 @@ int z_erofs_load_deflate_config(struct super_block *sb,
		erofs_err(sb, "unsupported windowbits %u", dfl->windowbits);
		return -EOPNOTSUPP;
	}
	mutex_lock(&deflate_resize_mutex);
	if (!inited) {
		for (; z_erofs_deflate_avail_strms < z_erofs_deflate_nstrms;
		     ++z_erofs_deflate_avail_strms) {
			struct z_erofs_deflate *strm;

			strm = kzalloc(sizeof(*strm), GFP_KERNEL);
			if (!strm)
				goto failed;
			/* XXX: in-kernel zlib cannot customize windowbits */
			strm->z.workspace = vmalloc(zlib_inflate_workspacesize());
			if (!strm->z.workspace) {
				kfree(strm);
				goto failed;
			}

			spin_lock(&z_erofs_deflate_lock);
			strm->next = z_erofs_deflate_head;
			z_erofs_deflate_head = strm;
			spin_unlock(&z_erofs_deflate_lock);
		}
		inited = true;
	}
	mutex_unlock(&deflate_resize_mutex);
	erofs_info(sb, "EXPERIMENTAL DEFLATE feature in use. Use at your own risk!");
	return 0;
failed:
	mutex_unlock(&deflate_resize_mutex);
	z_erofs_deflate_exit();
	return -ENOMEM;
}

int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
+3 −9
Original line number Diff line number Diff line
@@ -273,21 +273,15 @@ static int erofs_fscache_data_read_slice(struct erofs_fscache_rq *req)
	if (map.m_flags & EROFS_MAP_META) {
		struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
		struct iov_iter iter;
		erofs_blk_t blknr;
		size_t offset, size;
		size_t size = map.m_llen;
		void *src;

		/* For tail packing layout, the offset may be non-zero. */
		offset = erofs_blkoff(sb, map.m_pa);
		blknr = erofs_blknr(sb, map.m_pa);
		size = map.m_llen;

		src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP);
		src = erofs_read_metabuf(&buf, sb, map.m_pa, EROFS_KMAP);
		if (IS_ERR(src))
			return PTR_ERR(src);

		iov_iter_xarray(&iter, ITER_DEST, &mapping->i_pages, pos, PAGE_SIZE);
		if (copy_to_iter(src + offset, size, &iter) != size) {
		if (copy_to_iter(src, size, &iter) != size) {
			erofs_put_metabuf(&buf);
			return -EFAULT;
		}
+2 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ static void *erofs_read_inode(struct erofs_buf *buf,
	blkaddr = erofs_blknr(sb, inode_loc);
	*ofs = erofs_blkoff(sb, inode_loc);

	kaddr = erofs_read_metabuf(buf, sb, blkaddr, EROFS_KMAP);
	kaddr = erofs_read_metabuf(buf, sb, erofs_pos(sb, blkaddr), EROFS_KMAP);
	if (IS_ERR(kaddr)) {
		erofs_err(sb, "failed to get inode (nid: %llu) page, err %ld",
			  vi->nid, PTR_ERR(kaddr));
@@ -66,7 +66,7 @@ static void *erofs_read_inode(struct erofs_buf *buf,
				goto err_out;
			}
			memcpy(copied, dic, gotten);
			kaddr = erofs_read_metabuf(buf, sb, blkaddr + 1,
			kaddr = erofs_read_metabuf(buf, sb, erofs_pos(sb, blkaddr + 1),
						   EROFS_KMAP);
			if (IS_ERR(kaddr)) {
				erofs_err(sb, "failed to get inode payload block (nid: %llu), err %ld",
+1 −4
Original line number Diff line number Diff line
@@ -64,15 +64,12 @@ enum {
};

struct erofs_mount_opts {
#ifdef CONFIG_EROFS_FS_ZIP
	/* current strategy of how to use managed cache */
	unsigned char cache_strategy;
	/* strategy of sync decompression (0 - auto, 1 - force on, 2 - force off) */
	unsigned int sync_decompress;

	/* threshold for decompression synchronously */
	unsigned int max_sync_decompress_pages;
#endif
	unsigned int mount_opt;
};

@@ -406,7 +403,7 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset,
		  enum erofs_kmap_type type);
void erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb);
void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb,
			 erofs_blk_t blkaddr, enum erofs_kmap_type type);
			 erofs_off_t offset, enum erofs_kmap_type type);
int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *dev);
int erofs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
		 u64 start, u64 len);
Loading