Commit 5fbad44d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull erofs fixes from Gao Xiang:
 "Two patches fixes issues reported by syzbot, one fixes a missing
  `domain_id` mount option in documentation and a minor cleanup:

   - Fix wrong iomap->length calculation post EOF, which could cause a
     WARN_ON in iomap_iter_done() (Siddh)

   - Fix improper kvcalloc() use with __GFP_NOFAIL (me)

   - Add missing `domain_id` mount option in documentation (Jingbo)

   - Clean up fscache option parsing (Jingbo)"

* tag 'erofs-for-6.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
  erofs: clean up parsing of fscache related options
  erofs: add documentation for 'domain_id' mount option
  erofs: fix kvcalloc() misuse with __GFP_NOFAIL
  erofs/zmap.c: Fix incorrect offset calculation
parents 84bd7e08 e02ac3e7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -120,6 +120,8 @@ dax={always,never} Use direct access (no page cache). See
dax                    A legacy option which is an alias for ``dax=always``.
device=%s              Specify a path to an extra device to be used together.
fsid=%s                Specify a filesystem image ID for Fscache back-end.
domain_id=%s           Specify a domain ID in fscache mode so that different images
                       with the same blobs under a given domain ID can share storage.
===================    =========================================================

Sysfs Entries
+6 −7
Original line number Diff line number Diff line
@@ -577,26 +577,25 @@ static int erofs_fc_parse_param(struct fs_context *fc,
		}
		++ctx->devs->extra_devices;
		break;
	case Opt_fsid:
#ifdef CONFIG_EROFS_FS_ONDEMAND
	case Opt_fsid:
		kfree(ctx->fsid);
		ctx->fsid = kstrdup(param->string, GFP_KERNEL);
		if (!ctx->fsid)
			return -ENOMEM;
#else
		errorfc(fc, "fsid option not supported");
#endif
		break;
	case Opt_domain_id:
#ifdef CONFIG_EROFS_FS_ONDEMAND
		kfree(ctx->domain_id);
		ctx->domain_id = kstrdup(param->string, GFP_KERNEL);
		if (!ctx->domain_id)
			return -ENOMEM;
		break;
#else
		errorfc(fc, "domain_id option not supported");
#endif
	case Opt_fsid:
	case Opt_domain_id:
		errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name);
		break;
#endif
	default:
		return -ENOPARAM;
	}
+6 −6
Original line number Diff line number Diff line
@@ -1032,11 +1032,11 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,

	if (!be->decompressed_pages)
		be->decompressed_pages =
			kvcalloc(be->nr_pages, sizeof(struct page *),
			kcalloc(be->nr_pages, sizeof(struct page *),
				GFP_KERNEL | __GFP_NOFAIL);
	if (!be->compressed_pages)
		be->compressed_pages =
			kvcalloc(pclusterpages, sizeof(struct page *),
			kcalloc(pclusterpages, sizeof(struct page *),
				GFP_KERNEL | __GFP_NOFAIL);

	z_erofs_parse_out_bvecs(be);
@@ -1085,7 +1085,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,
	}
	if (be->compressed_pages < be->onstack_pages ||
	    be->compressed_pages >= be->onstack_pages + Z_EROFS_ONSTACK_PAGES)
		kvfree(be->compressed_pages);
		kfree(be->compressed_pages);
	z_erofs_fill_other_copies(be, err);

	for (i = 0; i < be->nr_pages; ++i) {
@@ -1104,7 +1104,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,
	}

	if (be->decompressed_pages != be->onstack_pages)
		kvfree(be->decompressed_pages);
		kfree(be->decompressed_pages);

	pcl->length = 0;
	pcl->partial = true;
+7 −3
Original line number Diff line number Diff line
@@ -793,12 +793,16 @@ static int z_erofs_iomap_begin_report(struct inode *inode, loff_t offset,
		iomap->type = IOMAP_HOLE;
		iomap->addr = IOMAP_NULL_ADDR;
		/*
		 * No strict rule how to describe extents for post EOF, yet
		 * we need do like below. Otherwise, iomap itself will get
		 * No strict rule on how to describe extents for post EOF, yet
		 * we need to do like below. Otherwise, iomap itself will get
		 * into an endless loop on post EOF.
		 *
		 * Calculate the effective offset by subtracting extent start
		 * (map.m_la) from the requested offset, and add it to length.
		 * (NB: offset >= map.m_la always)
		 */
		if (iomap->offset >= inode->i_size)
			iomap->length = length + map.m_la - offset;
			iomap->length = length + offset - map.m_la;
	}
	iomap->flags = 0;
	return 0;