Unverified Commit 3e673d65 authored by Christian Brauner's avatar Christian Brauner
Browse files

Merge branch 'work.write.end'

Matthew Wilcox (Oracle) <willy@infradead.org> says:

On top of the ufs, minix, sysv and qnx6 directory handling patches, this
patch series converts us to using folios for write_begin and write_end.
That's the last mention of 'struct page' in several filesystems.

* work.write.end: (54 commits)
  buffer: Convert __block_write_begin() to take a folio
  ocfs2: Convert ocfs2_write_zero_page to use a folio
  fs: Convert aops->write_begin to take a folio
  fs: Convert aops->write_end to take a folio
  vboxsf: Use a folio in vboxsf_write_end()
  orangefs: Convert orangefs_write_begin() to use a folio
  orangefs: Convert orangefs_write_end() to use a folio
  jffs2: Convert jffs2_write_begin() to use a folio
  jffs2: Convert jffs2_write_end() to use a folio
  hostfs: Convert hostfs_write_end() to use a folio
  fuse: Convert fuse_write_begin() to use a folio
  fuse: Convert fuse_write_end() to use a folio
  f2fs: Convert f2fs_write_begin() to use a folio
  f2fs: Convert f2fs_write_end() to use a folio
  ecryptfs: Use a folio in ecryptfs_write_begin()
  ecryptfs: Convert ecryptfs_write_end() to use a folio
  buffer: Convert block_write_end() to take a folio
  ntfs3: Remove reset_log_file()
  nilfs2: Use a folio in nilfs_recover_dsync_blocks()
  buffer: Use a folio in generic_write_end()
  ...

Link: https://lore.kernel.org/r/20240717154716.237943-1-willy@infradead.org


Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parents 8400291e 9f04609f
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -251,10 +251,10 @@ 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 page *page, void *fsdata);
				struct folio *folio, void *fsdata);
	sector_t (*bmap)(struct address_space *, sector_t);
	void (*invalidate_folio) (struct folio *, size_t start, size_t len);
	bool (*release_folio)(struct folio *, gfp_t);
@@ -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
+6 −6
Original line number Diff line number Diff line
@@ -810,7 +810,7 @@ cache in your filesystem. The following members are defined:
				struct page **pagep, void **fsdata);
		int (*write_end)(struct file *, struct address_space *mapping,
				 loff_t pos, unsigned len, unsigned copied,
				 struct page *page, void *fsdata);
				 struct folio *folio, void *fsdata);
		sector_t (*bmap)(struct address_space *, sector_t);
		void (*invalidate_folio) (struct folio *, size_t start, size_t len);
		bool (*release_folio)(struct folio *, gfp_t);
@@ -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.
@@ -944,8 +944,8 @@ cache in your filesystem. The following members are defined:
	called.  len is the original len passed to write_begin, and
	copied is the amount that was able to be copied.

	The filesystem must take care of unlocking the page and
	releasing it refcount, and updating i_size.
	The filesystem must take care of unlocking the folio,
	decrementing its refcount, and updating i_size.

	Returns < 0 on failure, otherwise the number of bytes (<=
	'copied') that were able to be copied into pagecache.
+6 −6
Original line number Diff line number Diff line
@@ -451,20 +451,20 @@ 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,
		loff_t pos, unsigned len, unsigned copied, struct page *page,
		loff_t pos, unsigned len, unsigned copied, struct folio *folio,
		void *fsdata)
{
	int ret;
	ret = block_write_end(file, mapping, pos, len, copied, page, fsdata);
	ret = block_write_end(file, mapping, pos, len, copied, folio, fsdata);

	unlock_page(page);
	put_page(page);
	folio_unlock(folio);
	folio_put(folio);

	return ret;
}
+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, 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, 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