Commit 732c2753 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull more erofs updates from Gao Xiang:

 - Support STATX_DIOALIGN and FS_IOC_GETFSSYSFSPATH

 - Fix a race of LZ4 decompression due to recent refactoring

 - Another multi-page folio adaption in erofs_bread()

* tag 'erofs-for-6.11-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
  erofs: convert comma to semicolon
  erofs: support multi-page folios for erofs_bread()
  erofs: add support for FS_IOC_GETFSSYSFSPATH
  erofs: fix race in z_erofs_get_gbuf()
  erofs: support STATX_DIOALIGN
parents dd90ad50 14e9283f
Loading
Loading
Loading
Loading
+12 −18
Original line number Diff line number Diff line
@@ -21,38 +21,32 @@ void erofs_put_metabuf(struct erofs_buf *buf)
	if (!buf->page)
		return;
	erofs_unmap_metabuf(buf);
	put_page(buf->page);
	folio_put(page_folio(buf->page));
	buf->page = NULL;
}

/*
 * Derive the block size from inode->i_blkbits to make compatible with
 * anonymous inode in fscache mode.
 */
void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset,
		  enum erofs_kmap_type type)
{
	pgoff_t index = offset >> PAGE_SHIFT;
	struct page *page = buf->page;
	struct folio *folio;
	unsigned int nofs_flag;
	struct folio *folio = NULL;

	if (!page || page->index != index) {
	if (buf->page) {
		folio = page_folio(buf->page);
		if (folio_file_page(folio, index) != buf->page)
			erofs_unmap_metabuf(buf);
	}
	if (!folio || !folio_contains(folio, index)) {
		erofs_put_metabuf(buf);

		nofs_flag = memalloc_nofs_save();
		folio = read_cache_folio(buf->mapping, index, NULL, NULL);
		memalloc_nofs_restore(nofs_flag);
		folio = read_mapping_folio(buf->mapping, index, NULL);
		if (IS_ERR(folio))
			return folio;

		/* should already be PageUptodate, no need to lock page */
		page = folio_file_page(folio, index);
		buf->page = page;
	}
	buf->page = folio_file_page(folio, index);

	if (buf->kmap_type == EROFS_NO_KMAP) {
		if (type == EROFS_KMAP)
			buf->base = kmap_local_page(page);
			buf->base = kmap_local_page(buf->page);
		buf->kmap_type = type;
	} else if (buf->kmap_type != type) {
		DBG_BUGON(1);
+1 −1
Original line number Diff line number Diff line
@@ -188,7 +188,7 @@ static int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
			       !rq->partial_decoding);
	buf.in_size = min(rq->inputsize, PAGE_SIZE - rq->pageofs_in);
	rq->inputsize -= buf.in_size;
	buf.in = dctx.kin + rq->pageofs_in,
	buf.in = dctx.kin + rq->pageofs_in;
	dctx.bounce = strm->bounce;
	do {
		dctx.avail_out = buf.out_size - buf.out_pos;
+17 −2
Original line number Diff line number Diff line
@@ -334,14 +334,29 @@ int erofs_getattr(struct mnt_idmap *idmap, const struct path *path,
		  unsigned int query_flags)
{
	struct inode *const inode = d_inode(path->dentry);
	bool compressed =
		erofs_inode_is_data_compressed(EROFS_I(inode)->datalayout);

	if (erofs_inode_is_data_compressed(EROFS_I(inode)->datalayout))
	if (compressed)
		stat->attributes |= STATX_ATTR_COMPRESSED;

	stat->attributes |= STATX_ATTR_IMMUTABLE;
	stat->attributes_mask |= (STATX_ATTR_COMPRESSED |
				  STATX_ATTR_IMMUTABLE);

	/*
	 * Return the DIO alignment restrictions if requested.
	 *
	 * In EROFS, STATX_DIOALIGN is not supported in ondemand mode and
	 * compressed files, so in these cases we report no DIO support.
	 */
	if ((request_mask & STATX_DIOALIGN) && S_ISREG(inode->i_mode)) {
		stat->result_mask |= STATX_DIOALIGN;
		if (!erofs_is_fscache_mode(inode->i_sb) && !compressed) {
			stat->dio_mem_align =
				bdev_logical_block_size(inode->i_sb->s_bdev);
			stat->dio_offset_align = stat->dio_mem_align;
		}
	}
	generic_fillattr(idmap, request_mask, inode, stat);
	return 0;
}
+16 −0
Original line number Diff line number Diff line
@@ -576,6 +576,21 @@ static const struct export_operations erofs_export_ops = {
	.get_parent = erofs_get_parent,
};

static void erofs_set_sysfs_name(struct super_block *sb)
{
	struct erofs_sb_info *sbi = EROFS_SB(sb);

	if (erofs_is_fscache_mode(sb)) {
		if (sbi->domain_id)
			super_set_sysfs_name_generic(sb, "%s,%s",sbi->domain_id,
						     sbi->fsid);
		else
			super_set_sysfs_name_generic(sb, "%s", sbi->fsid);
		return;
	}
	super_set_sysfs_name_id(sb);
}

static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
{
	struct inode *inode;
@@ -643,6 +658,7 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
		sb->s_flags |= SB_POSIXACL;
	else
		sb->s_flags &= ~SB_POSIXACL;
	erofs_set_sysfs_name(sb);

#ifdef CONFIG_EROFS_FS_ZIP
	xa_init(&sbi->managed_pslots);
+3 −0
Original line number Diff line number Diff line
@@ -38,11 +38,13 @@ void *z_erofs_get_gbuf(unsigned int requiredpages)
{
	struct z_erofs_gbuf *gbuf;

	migrate_disable();
	gbuf = &z_erofs_gbufpool[z_erofs_gbuf_id()];
	spin_lock(&gbuf->lock);
	/* check if the buffer is too small */
	if (requiredpages > gbuf->nrpages) {
		spin_unlock(&gbuf->lock);
		migrate_enable();
		/* (for sparse checker) pretend gbuf->lock is still taken */
		__acquire(gbuf->lock);
		return NULL;
@@ -57,6 +59,7 @@ void z_erofs_put_gbuf(void *ptr) __releases(gbuf->lock)
	gbuf = &z_erofs_gbufpool[z_erofs_gbuf_id()];
	DBG_BUGON(gbuf->ptr != ptr);
	spin_unlock(&gbuf->lock);
	migrate_enable();
}

int z_erofs_gbuf_growsize(unsigned int nrpages)