Unverified Commit 1da86618 authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Christian Brauner
Browse files

fs: Convert aops->write_begin to take a folio



Convert all callers from working on a page to working on one page
of a folio (support for working on an entire folio can come later).
Removes a lot of folio->page->folio conversions.

Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent a225800f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -251,7 +251,7 @@ prototypes::
	void (*readahead)(struct readahead_control *);
	int (*write_begin)(struct file *, struct address_space *mapping,
				loff_t pos, unsigned len,
				struct page **pagep, void **fsdata);
				struct folio **foliop, void **fsdata);
	int (*write_end)(struct file *, struct address_space *mapping,
				loff_t pos, unsigned len, unsigned copied,
				struct folio *folio, void *fsdata);
@@ -280,7 +280,7 @@ read_folio: yes, unlocks shared
writepages:
dirty_folio:		maybe
readahead:		yes, unlocks				shared
write_begin:		locks the page		 exclusive
write_begin:		locks the folio		 exclusive
write_end:		yes, unlocks		 exclusive
bmap:
invalidate_folio:	yes					exclusive
+3 −3
Original line number Diff line number Diff line
@@ -926,12 +926,12 @@ cache in your filesystem. The following members are defined:
	(if they haven't been read already) so that the updated blocks
	can be written out properly.

	The filesystem must return the locked pagecache page for the
	specified offset, in ``*pagep``, for the caller to write into.
	The filesystem must return the locked pagecache folio for the
	specified offset, in ``*foliop``, for the caller to write into.

	It must be able to cope with short writes (where the length
	passed to write_begin is greater than the number of bytes copied
	into the page).
	into the folio).

	A void * may be returned in fsdata, which then gets passed into
	write_end.
+2 −2
Original line number Diff line number Diff line
@@ -451,9 +451,9 @@ static void blkdev_readahead(struct readahead_control *rac)
}

static int blkdev_write_begin(struct file *file, struct address_space *mapping,
		loff_t pos, unsigned len, struct page **pagep, void **fsdata)
		loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
{
	return block_write_begin(mapping, pos, len, pagep, blkdev_get_block);
	return block_write_begin(mapping, pos, len, foliop, blkdev_get_block);
}

static int blkdev_write_end(struct file *file, struct address_space *mapping,
+22 −25
Original line number Diff line number Diff line
@@ -424,7 +424,8 @@ shmem_pwrite(struct drm_i915_gem_object *obj,
	struct address_space *mapping = obj->base.filp->f_mapping;
	const struct address_space_operations *aops = mapping->a_ops;
	char __user *user_data = u64_to_user_ptr(arg->data_ptr);
	u64 remain, offset;
	u64 remain;
	loff_t pos;
	unsigned int pg;

	/* Caller already validated user args */
@@ -457,12 +458,12 @@ shmem_pwrite(struct drm_i915_gem_object *obj,
	 */

	remain = arg->size;
	offset = arg->offset;
	pg = offset_in_page(offset);
	pos = arg->offset;
	pg = offset_in_page(pos);

	do {
		unsigned int len, unwritten;
		struct page *page;
		struct folio *folio;
		void *data, *vaddr;
		int err;
		char __maybe_unused c;
@@ -480,21 +481,19 @@ shmem_pwrite(struct drm_i915_gem_object *obj,
		if (err)
			return err;

		err = aops->write_begin(obj->base.filp, mapping, offset, len,
					&page, &data);
		err = aops->write_begin(obj->base.filp, mapping, pos, len,
					&folio, &data);
		if (err < 0)
			return err;

		vaddr = kmap_local_page(page);
		vaddr = kmap_local_folio(folio, offset_in_folio(folio, pos));
		pagefault_disable();
		unwritten = __copy_from_user_inatomic(vaddr + pg,
						      user_data,
						      len);
		unwritten = __copy_from_user_inatomic(vaddr, user_data, len);
		pagefault_enable();
		kunmap_local(vaddr);

		err = aops->write_end(obj->base.filp, mapping, offset, len,
				      len - unwritten, page_folio(page), data);
		err = aops->write_end(obj->base.filp, mapping, pos, len,
				      len - unwritten, folio, data);
		if (err < 0)
			return err;

@@ -504,7 +503,7 @@ shmem_pwrite(struct drm_i915_gem_object *obj,

		remain -= len;
		user_data += len;
		offset += len;
		pos += len;
		pg = 0;
	} while (remain);

@@ -660,7 +659,7 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *i915,
	struct drm_i915_gem_object *obj;
	struct file *file;
	const struct address_space_operations *aops;
	resource_size_t offset;
	loff_t pos;
	int err;

	GEM_WARN_ON(IS_DGFX(i915));
@@ -672,29 +671,27 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *i915,

	file = obj->base.filp;
	aops = file->f_mapping->a_ops;
	offset = 0;
	pos = 0;
	do {
		unsigned int len = min_t(typeof(size), size, PAGE_SIZE);
		struct page *page;
		void *pgdata, *vaddr;
		struct folio *folio;
		void *fsdata;

		err = aops->write_begin(file, file->f_mapping, offset, len,
					&page, &pgdata);
		err = aops->write_begin(file, file->f_mapping, pos, len,
					&folio, &fsdata);
		if (err < 0)
			goto fail;

		vaddr = kmap(page);
		memcpy(vaddr, data, len);
		kunmap(page);
		memcpy_to_folio(folio, offset_in_folio(folio, pos), data, len);

		err = aops->write_end(file, file->f_mapping, offset, len, len,
				      page_folio(page), pgdata);
		err = aops->write_end(file, file->f_mapping, pos, len, len,
				      folio, fsdata);
		if (err < 0)
			goto fail;

		size -= len;
		data += len;
		offset += len;
		pos += len;
	} while (size);

	return obj;
+2 −3
Original line number Diff line number Diff line
@@ -55,12 +55,11 @@ static void adfs_write_failed(struct address_space *mapping, loff_t to)

static int adfs_write_begin(struct file *file, struct address_space *mapping,
			loff_t pos, unsigned len,
			struct page **pagep, void **fsdata)
			struct folio **foliop, void **fsdata)
{
	int ret;

	*pagep = NULL;
	ret = cont_write_begin(file, mapping, pos, len, pagep, fsdata,
	ret = cont_write_begin(file, mapping, pos, len, foliop, fsdata,
				adfs_get_block,
				&ADFS_I(mapping->host)->mmu_private);
	if (unlikely(ret))
Loading