linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support
@ 2025-06-24 12:11 陈涛涛 Taotao Chen
  2025-06-24 12:12 ` [PATCH v2 1/5] drm/i915: Use kernel_write() in shmem object create 陈涛涛 Taotao Chen
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-06-24 12:11 UTC (permalink / raw)
  To: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	willy@infradead.org, brauner@kernel.org,
	jani.nikula@linux.intel.com, rodrigo.vivi@intel.com,
	tursulin@ursulin.net, airlied@gmail.com
  Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com, 陈涛涛 Taotao Chen

From: Taotao Chen <chentaotao@didiglobal.com>

This patch series refactors the address_space_operations write_begin()
and write_end() callbacks to take struct kiocb * as their first argument,
allowing IOCB flags such as IOCB_DONTCACHE to propagate to filesystem’s
buffered write path.

Ext4 is updated to implement handling of the IOCB_DONTCACHE flag in its
buffered write path and to advertise support via the FOP_DONTCACHE file
operation flag.

Additionally, the i915 driver’s shmem write paths are updated to bypass
the legacy write_begin/write_end interface in favor of directly calling
write_iter(), using a constructed synchronous kiocb. Another i915 patch
replaces a manual write loop with kernel_write() in shmem object creation.

Tested with ext4 and i915 GEM workloads.

Changes since v1:
- ext4 uses kiocb->ki_flags directly instead of fsdata.
- write_begin/write_end interface is changed to take struct kiocb *
  instead of struct file *.
- i915 shmem_pwrite refactored to use write_iter() directly instead
  of write_begin/write_end.
- i915 GEM shmem object creation replaced manual write loop with
  kernel_write().

Taotao Chen (5):
  drm/i915: Use kernel_write() in shmem object create
  drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter
  fs: change write_begin/write_end interface to take struct kiocb *
  ext4: handle IOCB_DONTCACHE in buffered write path
  ext4: declare support for FOP_DONTCACHE

 Documentation/filesystems/locking.rst     |   4 +-
 Documentation/filesystems/vfs.rst         |   4 +-
 block/fops.c                              |   6 +-
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 112 ++++++----------------
 fs/adfs/inode.c                           |   4 +-
 fs/affs/file.c                            |  12 +--
 fs/bcachefs/fs-io-buffered.c              |   4 +-
 fs/bcachefs/fs-io-buffered.h              |   4 +-
 fs/bfs/file.c                             |   2 +-
 fs/buffer.c                               |  18 ++--
 fs/ceph/addr.c                            |   6 +-
 fs/ecryptfs/mmap.c                        |  10 +-
 fs/exfat/file.c                           |  14 ++-
 fs/exfat/inode.c                          |   6 +-
 fs/ext2/inode.c                           |   6 +-
 fs/ext4/file.c                            |   3 +-
 fs/ext4/inode.c                           |  25 ++---
 fs/f2fs/data.c                            |   4 +-
 fs/fat/inode.c                            |   8 +-
 fs/fuse/file.c                            |   5 +-
 fs/hfs/hfs_fs.h                           |   2 +-
 fs/hfs/inode.c                            |   4 +-
 fs/hfsplus/hfsplus_fs.h                   |   2 +-
 fs/hfsplus/inode.c                        |   4 +-
 fs/hostfs/hostfs_kern.c                   |   6 +-
 fs/hpfs/file.c                            |   8 +-
 fs/hugetlbfs/inode.c                      |   4 +-
 fs/jffs2/file.c                           |   8 +-
 fs/jfs/inode.c                            |   6 +-
 fs/libfs.c                                |   4 +-
 fs/minix/inode.c                          |   2 +-
 fs/nfs/file.c                             |   6 +-
 fs/nilfs2/inode.c                         |   6 +-
 fs/ntfs3/file.c                           |   7 +-
 fs/ntfs3/inode.c                          |   6 +-
 fs/ntfs3/ntfs_fs.h                        |   4 +-
 fs/ocfs2/aops.c                           |   4 +-
 fs/omfs/file.c                            |   2 +-
 fs/orangefs/inode.c                       |   6 +-
 fs/ubifs/file.c                           |   4 +-
 fs/udf/inode.c                            |   9 +-
 fs/ufs/inode.c                            |   6 +-
 fs/vboxsf/file.c                          |   4 +-
 include/linux/buffer_head.h               |   4 +-
 include/linux/fs.h                        |   6 +-
 mm/filemap.c                              |   4 +-
 mm/shmem.c                                |   4 +-
 47 files changed, 176 insertions(+), 213 deletions(-)

-- 
2.34.1

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 1/5] drm/i915: Use kernel_write() in shmem object create
  2025-06-24 12:11 [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
@ 2025-06-24 12:12 ` 陈涛涛 Taotao Chen
  2025-06-24 12:23   ` Matthew Wilcox
  2025-06-24 12:12 ` [PATCH v2 2/5] drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter 陈涛涛 Taotao Chen
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-06-24 12:12 UTC (permalink / raw)
  To: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	willy@infradead.org, brauner@kernel.org,
	jani.nikula@linux.intel.com, rodrigo.vivi@intel.com,
	tursulin@ursulin.net, airlied@gmail.com
  Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com, 陈涛涛 Taotao Chen

From: Taotao Chen <chentaotao@didiglobal.com>

Replace the write_begin/write_end loop in
i915_gem_object_create_shmem_from_data() with call to kernel_write().

This function initializes shmem-backed GEM objects. kernel_write()
simplifies the code by removing manual folio handling.

Part of a series refactoring address_space_operations write_begin and
write_end callbacks to use struct kiocb for passing write context and
flags.

Signed-off-by: Taotao Chen <chentaotao@didiglobal.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 31 ++++++-----------------
 1 file changed, 8 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 19a3eb82dc6a..d08ade934d15 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -637,8 +637,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;
-	loff_t pos;
+	loff_t pos = 0;
 	int err;
 
 	GEM_WARN_ON(IS_DGFX(i915));
@@ -649,29 +648,15 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *i915,
 	GEM_BUG_ON(obj->write_domain != I915_GEM_DOMAIN_CPU);
 
 	file = obj->base.filp;
-	aops = file->f_mapping->a_ops;
-	pos = 0;
-	do {
-		unsigned int len = min_t(typeof(size), size, PAGE_SIZE);
-		struct folio *folio;
-		void *fsdata;
-
-		err = aops->write_begin(file, file->f_mapping, pos, len,
-					&folio, &fsdata);
-		if (err < 0)
-			goto fail;
+	err = kernel_write(file, data, size, &pos);
 
-		memcpy_to_folio(folio, offset_in_folio(folio, pos), data, len);
+	if (err < 0)
+		goto fail;
 
-		err = aops->write_end(file, file->f_mapping, pos, len, len,
-				      folio, fsdata);
-		if (err < 0)
-			goto fail;
-
-		size -= len;
-		data += len;
-		pos += len;
-	} while (size);
+	if (err != size) {
+		err = -EIO;
+		goto fail;
+	}
 
 	return obj;
 
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 2/5] drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter
  2025-06-24 12:11 [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
  2025-06-24 12:12 ` [PATCH v2 1/5] drm/i915: Use kernel_write() in shmem object create 陈涛涛 Taotao Chen
@ 2025-06-24 12:12 ` 陈涛涛 Taotao Chen
  2025-06-24 12:12 ` [PATCH v2 3/5] fs: change write_begin/write_end interface to take struct kiocb * 陈涛涛 Taotao Chen
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-06-24 12:12 UTC (permalink / raw)
  To: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	willy@infradead.org, brauner@kernel.org,
	jani.nikula@linux.intel.com, rodrigo.vivi@intel.com,
	tursulin@ursulin.net, airlied@gmail.com
  Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com, 陈涛涛 Taotao Chen

From: Taotao Chen <chentaotao@didiglobal.com>

Refactors shmem_pwrite() to replace the ->write_begin/end logic
with a write_iter-based implementation using kiocb and iov_iter.

While kernel_write() was considered, it caused about 50% performance
regression. vfs_write() is not exported for kernel use. Therefore,
file->f_op->write_iter() is called directly with a synchronously
initialized kiocb to preserve performance and remove write_begin
usage.

Performance results use gem_pwrite on Intel CPU i7-10700
(average of 10 runs):

- ./gem_pwrite --run-subtest bench -s 16384
  Before: 0.205s, After: 0.214s

- ./gem_pwrite --run-subtest bench -s 524288
  Before: 6.1021s, After: 4.8047s

Part of a series refactoring address_space_operations write_begin and
write_end callbacks to use struct kiocb for passing write context and
flags.

Signed-off-by: Taotao Chen <chentaotao@didiglobal.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 81 ++++++-----------------
 1 file changed, 21 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index d08ade934d15..92d6a481a842 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -400,12 +400,12 @@ static int
 shmem_pwrite(struct drm_i915_gem_object *obj,
 	     const struct drm_i915_gem_pwrite *arg)
 {
-	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;
-	loff_t pos;
-	unsigned int pg;
+	struct file *file = obj->base.filp;
+	struct kiocb kiocb;
+	struct iov_iter iter;
+	ssize_t written;
+	u64 size = arg->size;
 
 	/* Caller already validated user args */
 	GEM_BUG_ON(!access_ok(user_data, arg->size));
@@ -428,63 +428,24 @@ shmem_pwrite(struct drm_i915_gem_object *obj,
 	if (obj->mm.madv != I915_MADV_WILLNEED)
 		return -EFAULT;
 
-	/*
-	 * Before the pages are instantiated the object is treated as being
-	 * in the CPU domain. The pages will be clflushed as required before
-	 * use, and we can freely write into the pages directly. If userspace
-	 * races pwrite with any other operation; corruption will ensue -
-	 * that is userspace's prerogative!
-	 */
+	if (size > MAX_RW_COUNT)
+		return -EFBIG;
 
-	remain = arg->size;
-	pos = arg->offset;
-	pg = offset_in_page(pos);
+	if (!file->f_op->write_iter)
+		return -EINVAL;
 
-	do {
-		unsigned int len, unwritten;
-		struct folio *folio;
-		void *data, *vaddr;
-		int err;
-		char __maybe_unused c;
-
-		len = PAGE_SIZE - pg;
-		if (len > remain)
-			len = remain;
-
-		/* Prefault the user page to reduce potential recursion */
-		err = __get_user(c, user_data);
-		if (err)
-			return err;
-
-		err = __get_user(c, user_data + len - 1);
-		if (err)
-			return err;
-
-		err = aops->write_begin(obj->base.filp, mapping, pos, len,
-					&folio, &data);
-		if (err < 0)
-			return err;
-
-		vaddr = kmap_local_folio(folio, offset_in_folio(folio, pos));
-		pagefault_disable();
-		unwritten = __copy_from_user_inatomic(vaddr, user_data, len);
-		pagefault_enable();
-		kunmap_local(vaddr);
-
-		err = aops->write_end(obj->base.filp, mapping, pos, len,
-				      len - unwritten, folio, data);
-		if (err < 0)
-			return err;
-
-		/* We don't handle -EFAULT, leave it to the caller to check */
-		if (unwritten)
-			return -ENODEV;
-
-		remain -= len;
-		user_data += len;
-		pos += len;
-		pg = 0;
-	} while (remain);
+	init_sync_kiocb(&kiocb, file);
+	kiocb.ki_pos = arg->offset;
+	iov_iter_ubuf(&iter, ITER_SOURCE, (void __user *)user_data, size);
+
+	written = file->f_op->write_iter(&kiocb, &iter);
+	BUG_ON(written == -EIOCBQUEUED);
+
+	if (written != size)
+		return -EIO;
+
+	if (written < 0)
+		return written;
 
 	return 0;
 }
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 3/5] fs: change write_begin/write_end interface to take struct kiocb *
  2025-06-24 12:11 [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
  2025-06-24 12:12 ` [PATCH v2 1/5] drm/i915: Use kernel_write() in shmem object create 陈涛涛 Taotao Chen
  2025-06-24 12:12 ` [PATCH v2 2/5] drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter 陈涛涛 Taotao Chen
@ 2025-06-24 12:12 ` 陈涛涛 Taotao Chen
  2025-06-24 12:51   ` Matthew Wilcox
  2025-06-24 12:12 ` [PATCH v2 4/5] ext4: handle IOCB_DONTCACHE in buffered write path 陈涛涛 Taotao Chen
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-06-24 12:12 UTC (permalink / raw)
  To: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	willy@infradead.org, brauner@kernel.org,
	jani.nikula@linux.intel.com, rodrigo.vivi@intel.com,
	tursulin@ursulin.net, airlied@gmail.com
  Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com, 陈涛涛 Taotao Chen

From: Taotao Chen <chentaotao@didiglobal.com>

Change the address_space_operations callbacks write_begin() and
write_end() to take struct kiocb * as the first argument instead of
struct file *.

Update all affected function prototypes, implementations, call sites,
and related documentation across VFS, filesystems, and block layer.

Part of a series refactoring address_space_operations write_begin and
write_end callbacks to use struct kiocb for passing write context and
flags.

Signed-off-by: Taotao Chen <chentaotao@didiglobal.com>
---
 Documentation/filesystems/locking.rst |  4 ++--
 Documentation/filesystems/vfs.rst     |  4 ++--
 block/fops.c                          |  6 +++---
 fs/adfs/inode.c                       |  4 ++--
 fs/affs/file.c                        | 12 ++++++------
 fs/bcachefs/fs-io-buffered.c          |  4 ++--
 fs/bcachefs/fs-io-buffered.h          |  4 ++--
 fs/bfs/file.c                         |  2 +-
 fs/buffer.c                           | 18 +++++++++---------
 fs/ceph/addr.c                        |  6 ++++--
 fs/ecryptfs/mmap.c                    | 10 +++++-----
 fs/exfat/file.c                       | 14 +++++++++-----
 fs/exfat/inode.c                      |  6 +++---
 fs/ext2/inode.c                       |  6 +++---
 fs/ext4/inode.c                       | 19 ++++++++-----------
 fs/f2fs/data.c                        |  4 ++--
 fs/fat/inode.c                        |  8 ++++----
 fs/fuse/file.c                        |  5 +++--
 fs/hfs/hfs_fs.h                       |  2 +-
 fs/hfs/inode.c                        |  4 ++--
 fs/hfsplus/hfsplus_fs.h               |  2 +-
 fs/hfsplus/inode.c                    |  4 ++--
 fs/hostfs/hostfs_kern.c               |  6 +++---
 fs/hpfs/file.c                        |  8 ++++----
 fs/hugetlbfs/inode.c                  |  4 ++--
 fs/jffs2/file.c                       |  8 ++++----
 fs/jfs/inode.c                        |  6 +++---
 fs/libfs.c                            |  4 ++--
 fs/minix/inode.c                      |  2 +-
 fs/nfs/file.c                         |  6 ++++--
 fs/nilfs2/inode.c                     |  6 +++---
 fs/ntfs3/file.c                       |  7 +++++--
 fs/ntfs3/inode.c                      |  6 +++---
 fs/ntfs3/ntfs_fs.h                    |  4 ++--
 fs/ocfs2/aops.c                       |  4 ++--
 fs/omfs/file.c                        |  2 +-
 fs/orangefs/inode.c                   |  6 +++---
 fs/ubifs/file.c                       |  4 ++--
 fs/udf/inode.c                        |  9 +++++----
 fs/ufs/inode.c                        |  6 +++---
 fs/vboxsf/file.c                      |  4 ++--
 include/linux/buffer_head.h           |  4 ++--
 include/linux/fs.h                    |  6 +++---
 mm/filemap.c                          |  4 ++--
 mm/shmem.c                            |  4 ++--
 45 files changed, 139 insertions(+), 129 deletions(-)

diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
index 2e567e341c3b..d8593f8e5be4 100644
--- a/Documentation/filesystems/locking.rst
+++ b/Documentation/filesystems/locking.rst
@@ -253,10 +253,10 @@ prototypes::
 	int (*writepages)(struct address_space *, struct writeback_control *);
 	bool (*dirty_folio)(struct address_space *, struct folio *folio);
 	void (*readahead)(struct readahead_control *);
-	int (*write_begin)(struct file *, struct address_space *mapping,
+	int (*write_begin)(struct kiocb *, struct address_space *mapping,
 				loff_t pos, unsigned len,
 				struct folio **foliop, void **fsdata);
-	int (*write_end)(struct file *, struct address_space *mapping,
+	int (*write_end)(struct kiocb *, struct address_space *mapping,
 				loff_t pos, unsigned len, unsigned copied,
 				struct folio *folio, void *fsdata);
 	sector_t (*bmap)(struct address_space *, sector_t);
diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
index fd32a9a17bfb..df206ff79f24 100644
--- a/Documentation/filesystems/vfs.rst
+++ b/Documentation/filesystems/vfs.rst
@@ -822,10 +822,10 @@ cache in your filesystem.  The following members are defined:
 		int (*writepages)(struct address_space *, struct writeback_control *);
 		bool (*dirty_folio)(struct address_space *, struct folio *);
 		void (*readahead)(struct readahead_control *);
-		int (*write_begin)(struct file *, struct address_space *mapping,
+		int (*write_begin)(struct kiocb *, struct address_space *mapping,
 				   loff_t pos, unsigned len,
 				struct page **pagep, void **fsdata);
-		int (*write_end)(struct file *, struct address_space *mapping,
+		int (*write_end)(struct kiocb *, struct address_space *mapping,
 				 loff_t pos, unsigned len, unsigned copied,
 				 struct folio *folio, void *fsdata);
 		sector_t (*bmap)(struct address_space *, sector_t);
diff --git a/block/fops.c b/block/fops.c
index 1309861d4c2c..25ebee01e647 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -496,18 +496,18 @@ static void blkdev_readahead(struct readahead_control *rac)
 	mpage_readahead(rac, blkdev_get_block);
 }
 
-static int blkdev_write_begin(struct file *file, struct address_space *mapping,
+static int blkdev_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
 {
 	return block_write_begin(mapping, pos, len, foliop, blkdev_get_block);
 }
 
-static int blkdev_write_end(struct file *file, struct address_space *mapping,
+static int blkdev_write_end(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, unsigned copied, struct folio *folio,
 		void *fsdata)
 {
 	int ret;
-	ret = block_write_end(file, mapping, pos, len, copied, folio, fsdata);
+	ret = block_write_end(iocb->ki_filp, mapping, pos, len, copied, folio, fsdata);
 
 	folio_unlock(folio);
 	folio_put(folio);
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index 21527189e430..0bd20d8ac8fb 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -53,13 +53,13 @@ static void adfs_write_failed(struct address_space *mapping, loff_t to)
 		truncate_pagecache(inode, inode->i_size);
 }
 
-static int adfs_write_begin(struct file *file, struct address_space *mapping,
+static int adfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
 	int ret;
 
-	ret = cont_write_begin(file, mapping, pos, len, foliop, fsdata,
+	ret = cont_write_begin(iocb, mapping, pos, len, foliop, fsdata,
 				adfs_get_block,
 				&ADFS_I(mapping->host)->mmu_private);
 	if (unlikely(ret))
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 7a71018e3f67..d8bbf5a51a33 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -415,13 +415,13 @@ affs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 	return ret;
 }
 
-static int affs_write_begin(struct file *file, struct address_space *mapping,
+static int affs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
 	int ret;
 
-	ret = cont_write_begin(file, mapping, pos, len, foliop, fsdata,
+	ret = cont_write_begin(iocb, mapping, pos, len, foliop, fsdata,
 				affs_get_block,
 				&AFFS_I(mapping->host)->mmu_private);
 	if (unlikely(ret))
@@ -430,14 +430,14 @@ static int affs_write_begin(struct file *file, struct address_space *mapping,
 	return ret;
 }
 
-static int affs_write_end(struct file *file, struct address_space *mapping,
+static int affs_write_end(struct kiocb *iocb, struct address_space *mapping,
 			  loff_t pos, unsigned int len, unsigned int copied,
 			  struct folio *folio, void *fsdata)
 {
 	struct inode *inode = mapping->host;
 	int ret;
 
-	ret = generic_write_end(file, mapping, pos, len, copied, folio, fsdata);
+	ret = generic_write_end(iocb, mapping, pos, len, copied, folio, fsdata);
 
 	/* Clear Archived bit on file writes, as AmigaOS would do */
 	if (AFFS_I(inode)->i_protect & FIBF_ARCHIVED) {
@@ -645,7 +645,7 @@ static int affs_read_folio_ofs(struct file *file, struct folio *folio)
 	return err;
 }
 
-static int affs_write_begin_ofs(struct file *file, struct address_space *mapping,
+static int affs_write_begin_ofs(struct kiocb *iocb, struct address_space *mapping,
 				loff_t pos, unsigned len,
 				struct folio **foliop, void **fsdata)
 {
@@ -684,7 +684,7 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping
 	return err;
 }
 
-static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
+static int affs_write_end_ofs(struct kiocb *iocb, struct address_space *mapping,
 				loff_t pos, unsigned len, unsigned copied,
 				struct folio *folio, void *fsdata)
 {
diff --git a/fs/bcachefs/fs-io-buffered.c b/fs/bcachefs/fs-io-buffered.c
index 66bacdd49f78..601fd881318b 100644
--- a/fs/bcachefs/fs-io-buffered.c
+++ b/fs/bcachefs/fs-io-buffered.c
@@ -674,7 +674,7 @@ int bch2_writepages(struct address_space *mapping, struct writeback_control *wbc
 
 /* buffered writes: */
 
-int bch2_write_begin(struct file *file, struct address_space *mapping,
+int bch2_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		     loff_t pos, unsigned len,
 		     struct folio **foliop, void **fsdata)
 {
@@ -757,7 +757,7 @@ int bch2_write_begin(struct file *file, struct address_space *mapping,
 	return bch2_err_class(ret);
 }
 
-int bch2_write_end(struct file *file, struct address_space *mapping,
+int bch2_write_end(struct kiocb *iocb, struct address_space *mapping,
 		   loff_t pos, unsigned len, unsigned copied,
 		   struct folio *folio, void *fsdata)
 {
diff --git a/fs/bcachefs/fs-io-buffered.h b/fs/bcachefs/fs-io-buffered.h
index 3207ebbb4ab4..17723936038b 100644
--- a/fs/bcachefs/fs-io-buffered.h
+++ b/fs/bcachefs/fs-io-buffered.h
@@ -10,9 +10,9 @@ int bch2_read_folio(struct file *, struct folio *);
 int bch2_writepages(struct address_space *, struct writeback_control *);
 void bch2_readahead(struct readahead_control *);
 
-int bch2_write_begin(struct file *, struct address_space *, loff_t pos,
+int bch2_write_begin(struct kiocb *, struct address_space *, loff_t pos,
 		     unsigned len, struct folio **, void **);
-int bch2_write_end(struct file *, struct address_space *, loff_t,
+int bch2_write_end(struct kiocb *, struct address_space *, loff_t,
 		   unsigned len, unsigned copied, struct folio *, void *);
 
 ssize_t bch2_write_iter(struct kiocb *, struct iov_iter *);
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index fa66a09e496a..0a8ae8c2346b 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -170,7 +170,7 @@ static void bfs_write_failed(struct address_space *mapping, loff_t to)
 		truncate_pagecache(inode, inode->i_size);
 }
 
-static int bfs_write_begin(struct file *file, struct address_space *mapping,
+static int bfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
diff --git a/fs/buffer.c b/fs/buffer.c
index 8cf4a1dc481e..b42b502fad2f 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2304,7 +2304,7 @@ int block_write_end(struct file *file, struct address_space *mapping,
 }
 EXPORT_SYMBOL(block_write_end);
 
-int generic_write_end(struct file *file, struct address_space *mapping,
+int generic_write_end(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
 {
@@ -2312,7 +2312,7 @@ int generic_write_end(struct file *file, struct address_space *mapping,
 	loff_t old_size = inode->i_size;
 	bool i_size_changed = false;
 
-	copied = block_write_end(file, mapping, pos, len, copied, folio, fsdata);
+	copied = block_write_end(iocb->ki_filp, mapping, pos, len, copied, folio, fsdata);
 
 	/*
 	 * No need to use i_size_read() here, the i_size cannot change under us
@@ -2501,7 +2501,7 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size)
 }
 EXPORT_SYMBOL(generic_cont_expand_simple);
 
-static int cont_expand_zero(struct file *file, struct address_space *mapping,
+static int cont_expand_zero(struct kiocb *iocb, struct address_space *mapping,
 			    loff_t pos, loff_t *bytes)
 {
 	struct inode *inode = mapping->host;
@@ -2525,12 +2525,12 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping,
 		}
 		len = PAGE_SIZE - zerofrom;
 
-		err = aops->write_begin(file, mapping, curpos, len,
+		err = aops->write_begin(iocb, mapping, curpos, len,
 					    &folio, &fsdata);
 		if (err)
 			goto out;
 		folio_zero_range(folio, offset_in_folio(folio, curpos), len);
-		err = aops->write_end(file, mapping, curpos, len, len,
+		err = aops->write_end(iocb, mapping, curpos, len, len,
 						folio, fsdata);
 		if (err < 0)
 			goto out;
@@ -2558,12 +2558,12 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping,
 		}
 		len = offset - zerofrom;
 
-		err = aops->write_begin(file, mapping, curpos, len,
+		err = aops->write_begin(iocb, mapping, curpos, len,
 					    &folio, &fsdata);
 		if (err)
 			goto out;
 		folio_zero_range(folio, offset_in_folio(folio, curpos), len);
-		err = aops->write_end(file, mapping, curpos, len, len,
+		err = aops->write_end(iocb, mapping, curpos, len, len,
 						folio, fsdata);
 		if (err < 0)
 			goto out;
@@ -2578,7 +2578,7 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping,
  * For moronic filesystems that do not allow holes in file.
  * We may have to extend the file.
  */
-int cont_write_begin(struct file *file, struct address_space *mapping,
+int cont_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata,
 			get_block_t *get_block, loff_t *bytes)
@@ -2588,7 +2588,7 @@ int cont_write_begin(struct file *file, struct address_space *mapping,
 	unsigned int zerofrom;
 	int err;
 
-	err = cont_expand_zero(file, mapping, pos, bytes);
+	err = cont_expand_zero(iocb, mapping, pos, bytes);
 	if (err)
 		return err;
 
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 60a621b00c65..865044364cfa 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -1864,10 +1864,11 @@ static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned
  * We are only allowed to write into/dirty the page if the page is
  * clean, or already dirty within the same snap context.
  */
-static int ceph_write_begin(struct file *file, struct address_space *mapping,
+static int ceph_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			    loff_t pos, unsigned len,
 			    struct folio **foliop, void **fsdata)
 {
+	struct file *file = iocb->ki_filp;
 	struct inode *inode = file_inode(file);
 	struct ceph_inode_info *ci = ceph_inode(inode);
 	int r;
@@ -1885,10 +1886,11 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping,
  * we don't do anything in here that simple_write_end doesn't do
  * except adjust dirty page accounting
  */
-static int ceph_write_end(struct file *file, struct address_space *mapping,
+static int ceph_write_end(struct kiocb *iocb, struct address_space *mapping,
 			  loff_t pos, unsigned len, unsigned copied,
 			  struct folio *folio, void *fsdata)
 {
+	struct file *file = iocb->ki_filp;
 	struct inode *inode = file_inode(file);
 	struct ceph_client *cl = ceph_inode_to_client(inode);
 	bool check_cap = false;
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 60f0ac8744b5..670e2ae35aff 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -228,7 +228,7 @@ static int fill_zeros_to_end_of_page(struct folio *folio, unsigned int to)
 
 /**
  * ecryptfs_write_begin
- * @file: The eCryptfs file
+ * @iocb: I/O control block for the eCryptfs file
  * @mapping: The eCryptfs object
  * @pos: The file offset at which to start writing
  * @len: Length of the write
@@ -239,7 +239,7 @@ static int fill_zeros_to_end_of_page(struct folio *folio, unsigned int to)
  *
  * Returns zero on success; non-zero otherwise
  */
-static int ecryptfs_write_begin(struct file *file,
+static int ecryptfs_write_begin(struct kiocb *iocb,
 			struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
@@ -322,7 +322,7 @@ static int ecryptfs_write_begin(struct file *file,
 	 * Note, this will increase i_size. */
 	if (index != 0) {
 		if (prev_page_end_size > i_size_read(mapping->host)) {
-			rc = ecryptfs_truncate(file->f_path.dentry,
+			rc = ecryptfs_truncate(iocb->ki_filp->f_path.dentry,
 					       prev_page_end_size);
 			if (rc) {
 				printk(KERN_ERR "%s: Error on attempt to "
@@ -429,7 +429,7 @@ int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode)
 
 /**
  * ecryptfs_write_end
- * @file: The eCryptfs file object
+ * @iocb: I/O control block for the eCryptfs file
  * @mapping: The eCryptfs object
  * @pos: The file position
  * @len: The length of the data (unused)
@@ -437,7 +437,7 @@ int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode)
  * @folio: The eCryptfs folio
  * @fsdata: The fsdata (unused)
  */
-static int ecryptfs_write_end(struct file *file,
+static int ecryptfs_write_end(struct kiocb *iocb,
 			struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
diff --git a/fs/exfat/file.c b/fs/exfat/file.c
index 841a5b18e3df..8ffa4a2dfbad 100644
--- a/fs/exfat/file.c
+++ b/fs/exfat/file.c
@@ -532,10 +532,11 @@ int exfat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
 	return blkdev_issue_flush(inode->i_sb->s_bdev);
 }
 
-static int exfat_extend_valid_size(struct file *file, loff_t new_valid_size)
+static int exfat_extend_valid_size(struct kiocb *iocb, loff_t new_valid_size)
 {
 	int err;
 	loff_t pos;
+	struct file *file = iocb->ki_filp;
 	struct inode *inode = file_inode(file);
 	struct exfat_inode_info *ei = EXFAT_I(inode);
 	struct address_space *mapping = inode->i_mapping;
@@ -551,14 +552,14 @@ static int exfat_extend_valid_size(struct file *file, loff_t new_valid_size)
 		if (pos + len > new_valid_size)
 			len = new_valid_size - pos;
 
-		err = ops->write_begin(file, mapping, pos, len, &folio, NULL);
+		err = ops->write_begin(iocb, mapping, pos, len, &folio, NULL);
 		if (err)
 			goto out;
 
 		off = offset_in_folio(folio, pos);
 		folio_zero_new_buffers(folio, off, off + len);
 
-		err = ops->write_end(file, mapping, pos, len, len, folio, NULL);
+		err = ops->write_end(iocb, mapping, pos, len, len, folio, NULL);
 		if (err < 0)
 			goto out;
 		pos += len;
@@ -604,7 +605,7 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
 	}
 
 	if (pos > valid_size) {
-		ret = exfat_extend_valid_size(file, pos);
+		ret = exfat_extend_valid_size(iocb, pos);
 		if (ret < 0 && ret != -ENOSPC) {
 			exfat_err(inode->i_sb,
 				"write: fail to zero from %llu to %llu(%zd)",
@@ -655,8 +656,11 @@ static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf)
 	struct file *file = vma->vm_file;
 	struct inode *inode = file_inode(file);
 	struct exfat_inode_info *ei = EXFAT_I(inode);
+	struct kiocb iocb;
 	loff_t start, end;
 
+	init_sync_kiocb(&iocb, file);
+
 	if (!inode_trylock(inode))
 		return VM_FAULT_RETRY;
 
@@ -665,7 +669,7 @@ static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf)
 			start + vma->vm_end - vma->vm_start);
 
 	if (ei->valid_size < end) {
-		err = exfat_extend_valid_size(file, end);
+		err = exfat_extend_valid_size(&iocb, end);
 		if (err < 0) {
 			inode_unlock(inode);
 			return vmf_fs_error(err);
diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c
index b22c02d6000f..354edcccc5e3 100644
--- a/fs/exfat/inode.c
+++ b/fs/exfat/inode.c
@@ -446,7 +446,7 @@ static void exfat_write_failed(struct address_space *mapping, loff_t to)
 	}
 }
 
-static int exfat_write_begin(struct file *file, struct address_space *mapping,
+static int exfat_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned int len,
 		struct folio **foliop, void **fsdata)
 {
@@ -463,7 +463,7 @@ static int exfat_write_begin(struct file *file, struct address_space *mapping,
 	return ret;
 }
 
-static int exfat_write_end(struct file *file, struct address_space *mapping,
+static int exfat_write_end(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned int len, unsigned int copied,
 		struct folio *folio, void *fsdata)
 {
@@ -471,7 +471,7 @@ static int exfat_write_end(struct file *file, struct address_space *mapping,
 	struct exfat_inode_info *ei = EXFAT_I(inode);
 	int err;
 
-	err = generic_write_end(file, mapping, pos, len, copied, folio, fsdata);
+	err = generic_write_end(iocb, mapping, pos, len, copied, folio, fsdata);
 	if (err < len)
 		exfat_write_failed(mapping, pos+len);
 
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 30f8201c155f..66106157c7f0 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -915,7 +915,7 @@ static void ext2_readahead(struct readahead_control *rac)
 }
 
 static int
-ext2_write_begin(struct file *file, struct address_space *mapping,
+ext2_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
 {
 	int ret;
@@ -926,13 +926,13 @@ ext2_write_begin(struct file *file, struct address_space *mapping,
 	return ret;
 }
 
-static int ext2_write_end(struct file *file, struct address_space *mapping,
+static int ext2_write_end(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
 {
 	int ret;
 
-	ret = generic_write_end(file, mapping, pos, len, copied, folio, fsdata);
+	ret = generic_write_end(iocb, mapping, pos, len, copied, folio, fsdata);
 	if (ret < len)
 		ext2_write_failed(mapping, pos + len);
 	return ret;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index be9a4cba35fd..7ff7009f9799 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1252,7 +1252,7 @@ int ext4_block_write_begin(handle_t *handle, struct folio *folio,
  * and the ext4_write_end().  So doing the jbd2_journal_start at the start of
  * ext4_write_begin() is the right place.
  */
-static int ext4_write_begin(struct file *file, struct address_space *mapping,
+static int ext4_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			    loff_t pos, unsigned len,
 			    struct folio **foliop, void **fsdata)
 {
@@ -1399,13 +1399,10 @@ static int write_end_fn(handle_t *handle, struct inode *inode,
 }
 
 /*
- * We need to pick up the new inode size which generic_commit_write gave us
- * `file' can be NULL - eg, when called from page_symlink().
- *
  * ext4 never places buffers on inode->i_mapping->i_private_list.  metadata
  * buffers are managed internally.
  */
-static int ext4_write_end(struct file *file,
+static int ext4_write_end(struct kiocb *iocb,
 			  struct address_space *mapping,
 			  loff_t pos, unsigned len, unsigned copied,
 			  struct folio *folio, void *fsdata)
@@ -1424,7 +1421,7 @@ static int ext4_write_end(struct file *file,
 		return ext4_write_inline_data_end(inode, pos, len, copied,
 						  folio);
 
-	copied = block_write_end(file, mapping, pos, len, copied, folio, fsdata);
+	copied = block_write_end(iocb->ki_filp, mapping, pos, len, copied, folio, fsdata);
 	/*
 	 * it's important to update i_size while still holding folio lock:
 	 * page writeout could otherwise come in and zero beyond i_size.
@@ -1510,7 +1507,7 @@ static void ext4_journalled_zero_new_buffers(handle_t *handle,
 	} while (bh != head);
 }
 
-static int ext4_journalled_write_end(struct file *file,
+static int ext4_journalled_write_end(struct kiocb *iocb,
 				     struct address_space *mapping,
 				     loff_t pos, unsigned len, unsigned copied,
 				     struct folio *folio, void *fsdata)
@@ -3036,7 +3033,7 @@ static int ext4_nonda_switch(struct super_block *sb)
 	return 0;
 }
 
-static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
+static int ext4_da_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			       loff_t pos, unsigned len,
 			       struct folio **foliop, void **fsdata)
 {
@@ -3054,7 +3051,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
 
 	if (ext4_nonda_switch(inode->i_sb) || ext4_verity_in_progress(inode)) {
 		*fsdata = (void *)FALL_BACK_TO_NONDELALLOC;
-		return ext4_write_begin(file, mapping, pos,
+		return ext4_write_begin(iocb, mapping, pos,
 					len, foliop, fsdata);
 	}
 	*fsdata = (void *)0;
@@ -3196,7 +3193,7 @@ static int ext4_da_do_write_end(struct address_space *mapping,
 	return copied;
 }
 
-static int ext4_da_write_end(struct file *file,
+static int ext4_da_write_end(struct kiocb *iocb,
 			     struct address_space *mapping,
 			     loff_t pos, unsigned len, unsigned copied,
 			     struct folio *folio, void *fsdata)
@@ -3205,7 +3202,7 @@ static int ext4_da_write_end(struct file *file,
 	int write_mode = (int)(unsigned long)fsdata;
 
 	if (write_mode == FALL_BACK_TO_NONDELALLOC)
-		return ext4_write_end(file, mapping, pos,
+		return ext4_write_end(iocb, mapping, pos,
 				      len, copied, folio, fsdata);
 
 	trace_ext4_da_write_end(inode, pos, len, copied);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 31e892842625..46cc1498982f 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3519,7 +3519,7 @@ static int prepare_atomic_write_begin(struct f2fs_sb_info *sbi,
 	return 0;
 }
 
-static int f2fs_write_begin(struct file *file, struct address_space *mapping,
+static int f2fs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
 {
 	struct inode *inode = mapping->host;
@@ -3656,7 +3656,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
 	return err;
 }
 
-static int f2fs_write_end(struct file *file,
+static int f2fs_write_end(struct kiocb *iocb,
 			struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 3852bb66358c..3d35ee967fec 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -219,13 +219,13 @@ static void fat_write_failed(struct address_space *mapping, loff_t to)
 	}
 }
 
-static int fat_write_begin(struct file *file, struct address_space *mapping,
+static int fat_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
 	int err;
 
-	err = cont_write_begin(file, mapping, pos, len,
+	err = cont_write_begin(iocb, mapping, pos, len,
 				foliop, fsdata, fat_get_block,
 				&MSDOS_I(mapping->host)->mmu_private);
 	if (err < 0)
@@ -233,13 +233,13 @@ static int fat_write_begin(struct file *file, struct address_space *mapping,
 	return err;
 }
 
-static int fat_write_end(struct file *file, struct address_space *mapping,
+static int fat_write_end(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
 {
 	struct inode *inode = mapping->host;
 	int err;
-	err = generic_write_end(file, mapping, pos, len, copied, folio, fsdata);
+	err = generic_write_end(iocb, mapping, pos, len, copied, folio, fsdata);
 	if (err < len)
 		fat_write_failed(mapping, pos + len);
 	if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index f102afc03359..96f21d532541 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2213,10 +2213,11 @@ static int fuse_writepages(struct address_space *mapping,
  * It's worthy to make sure that space is reserved on disk for the write,
  * but how to implement it without killing performance need more thinking.
  */
-static int fuse_write_begin(struct file *file, struct address_space *mapping,
+static int fuse_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
 {
 	pgoff_t index = pos >> PAGE_SHIFT;
+	struct file *file = iocb->ki_filp;
 	struct fuse_conn *fc = get_fuse_conn(file_inode(file));
 	struct folio *folio;
 	loff_t fsize;
@@ -2256,7 +2257,7 @@ static int fuse_write_begin(struct file *file, struct address_space *mapping,
 	return err;
 }
 
-static int fuse_write_end(struct file *file, struct address_space *mapping,
+static int fuse_write_end(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, unsigned copied,
 		struct folio *folio, void *fsdata)
 {
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index a0c7cb0f79fc..ed44481b4e5d 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -201,7 +201,7 @@ extern int hfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
 extern const struct address_space_operations hfs_aops;
 extern const struct address_space_operations hfs_btree_aops;
 
-int hfs_write_begin(struct file *file, struct address_space *mapping,
+int hfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, struct folio **foliop, void **fsdata);
 extern struct inode *hfs_new_inode(struct inode *, const struct qstr *, umode_t);
 extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *);
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index a81ce7a740b9..8409e4412366 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -44,12 +44,12 @@ static void hfs_write_failed(struct address_space *mapping, loff_t to)
 	}
 }
 
-int hfs_write_begin(struct file *file, struct address_space *mapping,
+int hfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
 {
 	int ret;
 
-	ret = cont_write_begin(file, mapping, pos, len, foliop, fsdata,
+	ret = cont_write_begin(iocb, mapping, pos, len, foliop, fsdata,
 				hfs_get_block,
 				&HFS_I(mapping->host)->phys_size);
 	if (unlikely(ret))
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 2f089bff0095..6824de7dbc67 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -473,7 +473,7 @@ extern const struct address_space_operations hfsplus_aops;
 extern const struct address_space_operations hfsplus_btree_aops;
 extern const struct dentry_operations hfsplus_dentry_operations;
 
-int hfsplus_write_begin(struct file *file, struct address_space *mapping,
+int hfsplus_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, struct folio **foliop, void **fsdata);
 struct inode *hfsplus_new_inode(struct super_block *sb, struct inode *dir,
 				umode_t mode);
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index f331e9574217..26cc150856b9 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -38,12 +38,12 @@ static void hfsplus_write_failed(struct address_space *mapping, loff_t to)
 	}
 }
 
-int hfsplus_write_begin(struct file *file, struct address_space *mapping,
+int hfsplus_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
 {
 	int ret;
 
-	ret = cont_write_begin(file, mapping, pos, len, foliop, fsdata,
+	ret = cont_write_begin(iocb, mapping, pos, len, foliop, fsdata,
 				hfsplus_get_block,
 				&HFSPLUS_I(mapping->host)->phys_size);
 	if (unlikely(ret))
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 702c41317589..2e79ebfc35a5 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -445,7 +445,7 @@ static int hostfs_read_folio(struct file *file, struct folio *folio)
 	return ret;
 }
 
-static int hostfs_write_begin(struct file *file, struct address_space *mapping,
+static int hostfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			      loff_t pos, unsigned len,
 			      struct folio **foliop, void **fsdata)
 {
@@ -458,7 +458,7 @@ static int hostfs_write_begin(struct file *file, struct address_space *mapping,
 	return 0;
 }
 
-static int hostfs_write_end(struct file *file, struct address_space *mapping,
+static int hostfs_write_end(struct kiocb *iocb, struct address_space *mapping,
 			    loff_t pos, unsigned len, unsigned copied,
 			    struct folio *folio, void *fsdata)
 {
@@ -468,7 +468,7 @@ static int hostfs_write_end(struct file *file, struct address_space *mapping,
 	int err;
 
 	buffer = kmap_local_folio(folio, from);
-	err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer, copied);
+	err = write_file(FILE_HOSTFS_I(iocb->ki_filp)->fd, &pos, buffer, copied);
 	kunmap_local(buffer);
 
 	if (!folio_test_uptodate(folio) && err == folio_size(folio))
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index 449a3fc1b8d9..ad7ac13827ec 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -188,13 +188,13 @@ static void hpfs_write_failed(struct address_space *mapping, loff_t to)
 	hpfs_unlock(inode->i_sb);
 }
 
-static int hpfs_write_begin(struct file *file, struct address_space *mapping,
+static int hpfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
 	int ret;
 
-	ret = cont_write_begin(file, mapping, pos, len, foliop, fsdata,
+	ret = cont_write_begin(iocb, mapping, pos, len, foliop, fsdata,
 				hpfs_get_block,
 				&hpfs_i(mapping->host)->mmu_private);
 	if (unlikely(ret))
@@ -203,13 +203,13 @@ static int hpfs_write_begin(struct file *file, struct address_space *mapping,
 	return ret;
 }
 
-static int hpfs_write_end(struct file *file, struct address_space *mapping,
+static int hpfs_write_end(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
 {
 	struct inode *inode = mapping->host;
 	int err;
-	err = generic_write_end(file, mapping, pos, len, copied, folio, fsdata);
+	err = generic_write_end(iocb, mapping, pos, len, copied, folio, fsdata);
 	if (err < len)
 		hpfs_write_failed(mapping, pos + len);
 	if (!(err < 0)) {
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index e4de5425838d..f281ec2ad9bb 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -311,7 +311,7 @@ static ssize_t hugetlbfs_read_iter(struct kiocb *iocb, struct iov_iter *to)
 	return retval;
 }
 
-static int hugetlbfs_write_begin(struct file *file,
+static int hugetlbfs_write_begin(struct kiocb *iocb,
 			struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
@@ -319,7 +319,7 @@ static int hugetlbfs_write_begin(struct file *file,
 	return -EINVAL;
 }
 
-static int hugetlbfs_write_end(struct file *file, struct address_space *mapping,
+static int hugetlbfs_write_end(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
 {
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 13c18ccc13b0..8b0179558850 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -21,10 +21,10 @@
 #include <linux/jffs2.h>
 #include "nodelist.h"
 
-static int jffs2_write_end(struct file *filp, struct address_space *mapping,
+static int jffs2_write_end(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata);
-static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
+static int jffs2_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata);
 static int jffs2_read_folio(struct file *filp, struct folio *folio);
@@ -121,7 +121,7 @@ static int jffs2_read_folio(struct file *file, struct folio *folio)
 	return ret;
 }
 
-static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
+static int jffs2_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
@@ -235,7 +235,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
 	return ret;
 }
 
-static int jffs2_write_end(struct file *filp, struct address_space *mapping,
+static int jffs2_write_end(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
 {
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 60fc92dee24d..ac494186926b 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -290,7 +290,7 @@ static void jfs_write_failed(struct address_space *mapping, loff_t to)
 	}
 }
 
-static int jfs_write_begin(struct file *file, struct address_space *mapping,
+static int jfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 				loff_t pos, unsigned len,
 				struct folio **foliop, void **fsdata)
 {
@@ -303,13 +303,13 @@ static int jfs_write_begin(struct file *file, struct address_space *mapping,
 	return ret;
 }
 
-static int jfs_write_end(struct file *file, struct address_space *mapping,
+static int jfs_write_end(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, unsigned copied, struct folio *folio,
 		void *fsdata)
 {
 	int ret;
 
-	ret = generic_write_end(file, mapping, pos, len, copied, folio, fsdata);
+	ret = generic_write_end(iocb, mapping, pos, len, copied, folio, fsdata);
 	if (ret < len)
 		jfs_write_failed(mapping, pos + len);
 	return ret;
diff --git a/fs/libfs.c b/fs/libfs.c
index 9ea0ecc325a8..ebf60d51c7bd 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -910,7 +910,7 @@ static int simple_read_folio(struct file *file, struct folio *folio)
 	return 0;
 }
 
-int simple_write_begin(struct file *file, struct address_space *mapping,
+int simple_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
@@ -955,7 +955,7 @@ EXPORT_SYMBOL(simple_write_begin);
  *
  * Use *ONLY* with simple_read_folio()
  */
-static int simple_write_end(struct file *file, struct address_space *mapping,
+static int simple_write_end(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
 {
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index f007e389d5d2..01011b5d045e 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -442,7 +442,7 @@ static void minix_write_failed(struct address_space *mapping, loff_t to)
 	}
 }
 
-static int minix_write_begin(struct file *file, struct address_space *mapping,
+static int minix_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 033feeab8c34..e8ba7e758be0 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -342,12 +342,13 @@ static bool nfs_want_read_modify_write(struct file *file, struct folio *folio,
  * If the writer ends up delaying the write, the writer needs to
  * increment the page use counts until he is done with the page.
  */
-static int nfs_write_begin(struct file *file, struct address_space *mapping,
+static int nfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			   loff_t pos, unsigned len, struct folio **foliop,
 			   void **fsdata)
 {
 	fgf_t fgp = FGP_WRITEBEGIN;
 	struct folio *folio;
+	struct file *file = iocb->ki_filp;
 	int once_thru = 0;
 	int ret;
 
@@ -377,10 +378,11 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping,
 	return ret;
 }
 
-static int nfs_write_end(struct file *file, struct address_space *mapping,
+static int nfs_write_end(struct kiocb *iocb, struct address_space *mapping,
 			 loff_t pos, unsigned len, unsigned copied,
 			 struct folio *folio, void *fsdata)
 {
+	struct file *file = iocb->ki_filp;
 	struct nfs_open_context *ctx = nfs_file_open_context(file);
 	unsigned offset = offset_in_folio(folio, pos);
 	int status;
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 6613b8fcceb0..0ee4dea7f364 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -218,7 +218,7 @@ void nilfs_write_failed(struct address_space *mapping, loff_t to)
 	}
 }
 
-static int nilfs_write_begin(struct file *file, struct address_space *mapping,
+static int nilfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			     loff_t pos, unsigned len,
 			     struct folio **foliop, void **fsdata)
 
@@ -237,7 +237,7 @@ static int nilfs_write_begin(struct file *file, struct address_space *mapping,
 	return err;
 }
 
-static int nilfs_write_end(struct file *file, struct address_space *mapping,
+static int nilfs_write_end(struct kiocb *iocb, struct address_space *mapping,
 			   loff_t pos, unsigned len, unsigned copied,
 			   struct folio *folio, void *fsdata)
 {
@@ -248,7 +248,7 @@ static int nilfs_write_end(struct file *file, struct address_space *mapping,
 
 	nr_dirty = nilfs_page_count_clean_buffers(folio, start,
 						  start + copied);
-	copied = generic_write_end(file, mapping, pos, len, copied, folio,
+	copied = generic_write_end(iocb, mapping, pos, len, copied, folio,
 				   fsdata);
 	nilfs_set_file_dirty(inode, nr_dirty);
 	err = nilfs_transaction_commit(inode->i_sb);
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index 1e99a35691cd..6729123d6872 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -113,6 +113,7 @@ static int ntfs_extend_initialized_size(struct file *file,
 	struct inode *inode = &ni->vfs_inode;
 	struct address_space *mapping = inode->i_mapping;
 	struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info;
+	struct kiocb iocb;
 	loff_t pos = valid;
 	int err;
 
@@ -126,6 +127,8 @@ static int ntfs_extend_initialized_size(struct file *file,
 
 	WARN_ON(is_compressed(ni));
 
+	init_sync_kiocb(&iocb, file);
+
 	for (;;) {
 		u32 zerofrom, len;
 		struct folio *folio;
@@ -154,13 +157,13 @@ static int ntfs_extend_initialized_size(struct file *file,
 		if (pos + len > new_valid)
 			len = new_valid - pos;
 
-		err = ntfs_write_begin(file, mapping, pos, len, &folio, NULL);
+		err = ntfs_write_begin(&iocb, mapping, pos, len, &folio, NULL);
 		if (err)
 			goto out;
 
 		folio_zero_range(folio, zerofrom, folio_size(folio) - zerofrom);
 
-		err = ntfs_write_end(file, mapping, pos, len, len, folio, NULL);
+		err = ntfs_write_end(&iocb, mapping, pos, len, len, folio, NULL);
 		if (err < 0)
 			goto out;
 		pos += len;
diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
index 0f0d27d4644a..82c09c2fcadb 100644
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -912,7 +912,7 @@ static int ntfs_get_block_write_begin(struct inode *inode, sector_t vbn,
 				  bh_result, create, GET_BLOCK_WRITE_BEGIN);
 }
 
-int ntfs_write_begin(struct file *file, struct address_space *mapping,
+int ntfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		     loff_t pos, u32 len, struct folio **foliop, void **fsdata)
 {
 	int err;
@@ -957,7 +957,7 @@ int ntfs_write_begin(struct file *file, struct address_space *mapping,
 /*
  * ntfs_write_end - Address_space_operations::write_end.
  */
-int ntfs_write_end(struct file *file, struct address_space *mapping, loff_t pos,
+int ntfs_write_end(struct kiocb *iocb, struct address_space *mapping, loff_t pos,
 		   u32 len, u32 copied, struct folio *folio, void *fsdata)
 {
 	struct inode *inode = mapping->host;
@@ -989,7 +989,7 @@ int ntfs_write_end(struct file *file, struct address_space *mapping, loff_t pos,
 		folio_unlock(folio);
 		folio_put(folio);
 	} else {
-		err = generic_write_end(file, mapping, pos, len, copied, folio,
+		err = generic_write_end(iocb, mapping, pos, len, copied, folio,
 					fsdata);
 	}
 
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index 36b8052660d5..704dcd509f99 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -702,9 +702,9 @@ struct inode *ntfs_iget5(struct super_block *sb, const struct MFT_REF *ref,
 int ntfs_set_size(struct inode *inode, u64 new_size);
 int ntfs_get_block(struct inode *inode, sector_t vbn,
 		   struct buffer_head *bh_result, int create);
-int ntfs_write_begin(struct file *file, struct address_space *mapping,
+int ntfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 		     loff_t pos, u32 len, struct folio **foliop, void **fsdata);
-int ntfs_write_end(struct file *file, struct address_space *mapping, loff_t pos,
+int ntfs_write_end(struct kiocb *iocb, struct address_space *mapping, loff_t pos,
 		   u32 len, u32 copied, struct folio *folio, void *fsdata);
 int ntfs3_write_inode(struct inode *inode, struct writeback_control *wbc);
 int ntfs_sync_inode(struct inode *inode);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 40b6bce12951..306b433949f2 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1856,7 +1856,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
 	return ret;
 }
 
-static int ocfs2_write_begin(struct file *file, struct address_space *mapping,
+static int ocfs2_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			     loff_t pos, unsigned len,
 			     struct folio **foliop, void **fsdata)
 {
@@ -2047,7 +2047,7 @@ int ocfs2_write_end_nolock(struct address_space *mapping, loff_t pos,
 	return copied;
 }
 
-static int ocfs2_write_end(struct file *file, struct address_space *mapping,
+static int ocfs2_write_end(struct kiocb *iocb, struct address_space *mapping,
 			   loff_t pos, unsigned len, unsigned copied,
 			   struct folio *folio, void *fsdata)
 {
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 98358d405b6a..3ae86bc2460a 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -310,7 +310,7 @@ static void omfs_write_failed(struct address_space *mapping, loff_t to)
 	}
 }
 
-static int omfs_write_begin(struct file *file, struct address_space *mapping,
+static int omfs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 08a6f372a352..f6d6d54d652a 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -285,7 +285,7 @@ static int orangefs_read_folio(struct file *file, struct folio *folio)
 	return ret;
 }
 
-static int orangefs_write_begin(struct file *file,
+static int orangefs_write_begin(struct kiocb *iocb,
 		struct address_space *mapping, loff_t pos, unsigned len,
 		struct folio **foliop, void **fsdata)
 {
@@ -340,7 +340,7 @@ static int orangefs_write_begin(struct file *file,
 	return 0;
 }
 
-static int orangefs_write_end(struct file *file, struct address_space *mapping,
+static int orangefs_write_end(struct kiocb *iocb, struct address_space *mapping,
 		loff_t pos, unsigned len, unsigned copied, struct folio *folio,
 		void *fsdata)
 {
@@ -372,7 +372,7 @@ static int orangefs_write_end(struct file *file, struct address_space *mapping,
 	folio_unlock(folio);
 	folio_put(folio);
 
-	mark_inode_dirty_sync(file_inode(file));
+	mark_inode_dirty_sync(file_inode(iocb->ki_filp));
 	return copied;
 }
 
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index bf311c38d9a8..28dab3aabee0 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -404,7 +404,7 @@ static int allocate_budget(struct ubifs_info *c, struct folio *folio,
  * there is a plenty of flash space and the budget will be acquired quickly,
  * without forcing write-back. The slow path does not make this assumption.
  */
-static int ubifs_write_begin(struct file *file, struct address_space *mapping,
+static int ubifs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			     loff_t pos, unsigned len,
 			     struct folio **foliop, void **fsdata)
 {
@@ -514,7 +514,7 @@ static void cancel_budget(struct ubifs_info *c, struct folio *folio,
 	}
 }
 
-static int ubifs_write_end(struct file *file, struct address_space *mapping,
+static int ubifs_write_end(struct kiocb *iocb, struct address_space *mapping,
 			   loff_t pos, unsigned len, unsigned copied,
 			   struct folio *folio, void *fsdata)
 {
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 4386dd845e40..13ea9aaa30e2 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -244,10 +244,11 @@ static void udf_readahead(struct readahead_control *rac)
 	mpage_readahead(rac, udf_get_block);
 }
 
-static int udf_write_begin(struct file *file, struct address_space *mapping,
+static int udf_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			   loff_t pos, unsigned len,
 			   struct folio **foliop, void **fsdata)
 {
+	struct file *file = iocb->ki_filp;
 	struct udf_inode_info *iinfo = UDF_I(file_inode(file));
 	struct folio *folio;
 	int ret;
@@ -271,15 +272,15 @@ static int udf_write_begin(struct file *file, struct address_space *mapping,
 	return 0;
 }
 
-static int udf_write_end(struct file *file, struct address_space *mapping,
+static int udf_write_end(struct kiocb *iocb, struct address_space *mapping,
 			 loff_t pos, unsigned len, unsigned copied,
 			 struct folio *folio, void *fsdata)
 {
-	struct inode *inode = file_inode(file);
+	struct inode *inode = file_inode(iocb->ki_filp);
 	loff_t last_pos;
 
 	if (UDF_I(inode)->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB)
-		return generic_write_end(file, mapping, pos, len, copied, folio,
+		return generic_write_end(iocb, mapping, pos, len, copied, folio,
 					 fsdata);
 	last_pos = pos + copied;
 	if (last_pos > inode->i_size)
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 7dc38fdef2ea..8b10833ff586 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -474,7 +474,7 @@ static void ufs_write_failed(struct address_space *mapping, loff_t to)
 	}
 }
 
-static int ufs_write_begin(struct file *file, struct address_space *mapping,
+static int ufs_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
@@ -487,13 +487,13 @@ static int ufs_write_begin(struct file *file, struct address_space *mapping,
 	return ret;
 }
 
-static int ufs_write_end(struct file *file, struct address_space *mapping,
+static int ufs_write_end(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
 {
 	int ret;
 
-	ret = generic_write_end(file, mapping, pos, len, copied, folio, fsdata);
+	ret = generic_write_end(iocb, mapping, pos, len, copied, folio, fsdata);
 	if (ret < len)
 		ufs_write_failed(mapping, pos + len);
 	return ret;
diff --git a/fs/vboxsf/file.c b/fs/vboxsf/file.c
index b492794f8e9a..115f8fa6fd5d 100644
--- a/fs/vboxsf/file.c
+++ b/fs/vboxsf/file.c
@@ -300,12 +300,12 @@ static int vboxsf_writepages(struct address_space *mapping,
 	return error;
 }
 
-static int vboxsf_write_end(struct file *file, struct address_space *mapping,
+static int vboxsf_write_end(struct kiocb *iocb, struct address_space *mapping,
 			    loff_t pos, unsigned int len, unsigned int copied,
 			    struct folio *folio, void *fsdata)
 {
 	struct inode *inode = mapping->host;
-	struct vboxsf_handle *sf_handle = file->private_data;
+	struct vboxsf_handle *sf_handle = iocb->ki_filp->private_data;
 	size_t from = offset_in_folio(folio, pos);
 	u32 nwritten = len;
 	u8 *buf;
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 0029ff880e27..56f7a65bd875 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -265,11 +265,11 @@ int __block_write_begin(struct folio *folio, loff_t pos, unsigned len,
 int block_write_end(struct file *, struct address_space *,
 				loff_t, unsigned len, unsigned copied,
 				struct folio *, void *);
-int generic_write_end(struct file *, struct address_space *,
+int generic_write_end(struct kiocb *, struct address_space *,
 				loff_t, unsigned len, unsigned copied,
 				struct folio *, void *);
 void folio_zero_new_buffers(struct folio *folio, size_t from, size_t to);
-int cont_write_begin(struct file *, struct address_space *, loff_t,
+int cont_write_begin(struct kiocb *, struct address_space *, loff_t,
 			unsigned, struct folio **, void **,
 			get_block_t *, loff_t *);
 int generic_cont_expand_simple(struct inode *inode, loff_t size);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b085f161ed22..4e85a64cf2d1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -446,10 +446,10 @@ struct address_space_operations {
 
 	void (*readahead)(struct readahead_control *);
 
-	int (*write_begin)(struct file *, struct address_space *mapping,
+	int (*write_begin)(struct kiocb *, struct address_space *mapping,
 				loff_t pos, unsigned len,
 				struct folio **foliop, void **fsdata);
-	int (*write_end)(struct file *, struct address_space *mapping,
+	int (*write_end)(struct kiocb *, struct address_space *mapping,
 				loff_t pos, unsigned len, unsigned copied,
 				struct folio *folio, void *fsdata);
 
@@ -3602,7 +3602,7 @@ extern void simple_recursive_removal(struct dentry *,
 extern int noop_fsync(struct file *, loff_t, loff_t, int);
 extern ssize_t noop_direct_IO(struct kiocb *iocb, struct iov_iter *iter);
 extern int simple_empty(struct dentry *);
-extern int simple_write_begin(struct file *file, struct address_space *mapping,
+extern int simple_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata);
 extern const struct address_space_operations ram_aops;
diff --git a/mm/filemap.c b/mm/filemap.c
index bada249b9fb7..ba089d75fc86 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -4109,7 +4109,7 @@ ssize_t generic_perform_write(struct kiocb *iocb, struct iov_iter *i)
 			break;
 		}
 
-		status = a_ops->write_begin(file, mapping, pos, bytes,
+		status = a_ops->write_begin(iocb, mapping, pos, bytes,
 						&folio, &fsdata);
 		if (unlikely(status < 0))
 			break;
@@ -4130,7 +4130,7 @@ ssize_t generic_perform_write(struct kiocb *iocb, struct iov_iter *i)
 		copied = copy_folio_from_iter_atomic(folio, offset, bytes, i);
 		flush_dcache_folio(folio);
 
-		status = a_ops->write_end(file, mapping, pos, bytes, copied,
+		status = a_ops->write_end(iocb, mapping, pos, bytes, copied,
 						folio, fsdata);
 		if (unlikely(status != copied)) {
 			iov_iter_revert(i, copied - max(status, 0L));
diff --git a/mm/shmem.c b/mm/shmem.c
index 3a5a65b1f41a..90f0f058838b 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3270,7 +3270,7 @@ static const struct inode_operations shmem_symlink_inode_operations;
 static const struct inode_operations shmem_short_symlink_operations;
 
 static int
-shmem_write_begin(struct file *file, struct address_space *mapping,
+shmem_write_begin(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len,
 			struct folio **foliop, void **fsdata)
 {
@@ -3304,7 +3304,7 @@ shmem_write_begin(struct file *file, struct address_space *mapping,
 }
 
 static int
-shmem_write_end(struct file *file, struct address_space *mapping,
+shmem_write_end(struct kiocb *iocb, struct address_space *mapping,
 			loff_t pos, unsigned len, unsigned copied,
 			struct folio *folio, void *fsdata)
 {
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 4/5] ext4: handle IOCB_DONTCACHE in buffered write path
  2025-06-24 12:11 [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
                   ` (2 preceding siblings ...)
  2025-06-24 12:12 ` [PATCH v2 3/5] fs: change write_begin/write_end interface to take struct kiocb * 陈涛涛 Taotao Chen
@ 2025-06-24 12:12 ` 陈涛涛 Taotao Chen
  2025-06-25 14:35   ` Theodore Ts'o
  2025-06-24 12:12 ` [PATCH v2 5/5] ext4: declare support for FOP_DONTCACHE 陈涛涛 Taotao Chen
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-06-24 12:12 UTC (permalink / raw)
  To: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	willy@infradead.org, brauner@kernel.org,
	jani.nikula@linux.intel.com, rodrigo.vivi@intel.com,
	tursulin@ursulin.net, airlied@gmail.com
  Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com, 陈涛涛 Taotao Chen

From: Taotao Chen <chentaotao@didiglobal.com>

Add support for the IOCB_DONTCACHE flag in ext4_write_begin() and
ext4_da_write_begin(). When set in the kiocb, the FGP_DONTCACHE bit
is passed to the page cache lookup, preventing written pages from
being retained in the cache.

Only the handling logic is implemented here; the behavior remains
inactive until ext4 advertises support via FOP_DONTCACHE.

This change relies on prior patches that refactor the write_begin
interface to use struct kiocb and introduce DONTCACHE handling in ext4.

Part of a series refactoring address_space_operations write_begin and
write_end callbacks to use struct kiocb for passing write context and
flags.

Signed-off-by: Taotao Chen <chentaotao@didiglobal.com>
---
 fs/ext4/inode.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 7ff7009f9799..3a82b52565cc 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1269,6 +1269,9 @@ static int ext4_write_begin(struct kiocb *iocb, struct address_space *mapping,
 	if (unlikely(ret))
 		return ret;
 
+	if (iocb->ki_flags & IOCB_DONTCACHE)
+		fgp |= FGP_DONTCACHE;
+
 	trace_ext4_write_begin(inode, pos, len);
 	/*
 	 * Reserve one block more for addition to orphan list in case
@@ -3066,6 +3069,9 @@ static int ext4_da_write_begin(struct kiocb *iocb, struct address_space *mapping
 			return 0;
 	}
 
+	if (iocb->ki_flags & IOCB_DONTCACHE)
+		fgp |= FGP_DONTCACHE;
+
 retry:
 	fgp |= fgf_set_order(len);
 	folio = __filemap_get_folio(mapping, index, fgp,
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 5/5] ext4: declare support for FOP_DONTCACHE
  2025-06-24 12:11 [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
                   ` (3 preceding siblings ...)
  2025-06-24 12:12 ` [PATCH v2 4/5] ext4: handle IOCB_DONTCACHE in buffered write path 陈涛涛 Taotao Chen
@ 2025-06-24 12:12 ` 陈涛涛 Taotao Chen
  2025-06-24 12:53   ` Matthew Wilcox
  2025-06-25 14:36   ` Theodore Ts'o
  2025-06-24 12:54 ` [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support Matthew Wilcox
  2025-06-25  6:56 ` hch
  6 siblings, 2 replies; 17+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-06-24 12:12 UTC (permalink / raw)
  To: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	willy@infradead.org, brauner@kernel.org,
	jani.nikula@linux.intel.com, rodrigo.vivi@intel.com,
	tursulin@ursulin.net, airlied@gmail.com
  Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com, 陈涛涛 Taotao Chen

From: Taotao Chen <chentaotao@didiglobal.com>

Set the FOP_DONTCACHE flag in ext4_file_operations to indicate that
ext4 supports IOCB_DONTCACHE handling in buffered write paths.

Part of a series refactoring address_space_operations write_begin and
write_end callbacks to use struct kiocb for passing write context and
flags.

Signed-off-by: Taotao Chen <chentaotao@didiglobal.com>
---
 fs/ext4/file.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 21df81347147..274b41a476c8 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -977,7 +977,8 @@ const struct file_operations ext4_file_operations = {
 	.splice_write	= iter_file_splice_write,
 	.fallocate	= ext4_fallocate,
 	.fop_flags	= FOP_MMAP_SYNC | FOP_BUFFER_RASYNC |
-			  FOP_DIO_PARALLEL_WRITE,
+			  FOP_DIO_PARALLEL_WRITE |
+			  FOP_DONTCACHE,
 };
 
 const struct inode_operations ext4_file_inode_operations = {
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 1/5] drm/i915: Use kernel_write() in shmem object create
  2025-06-24 12:12 ` [PATCH v2 1/5] drm/i915: Use kernel_write() in shmem object create 陈涛涛 Taotao Chen
@ 2025-06-24 12:23   ` Matthew Wilcox
  2025-06-25 10:41     ` Chentaotao
  0 siblings, 1 reply; 17+ messages in thread
From: Matthew Wilcox @ 2025-06-24 12:23 UTC (permalink / raw)
  To: 陈涛涛 Taotao Chen
  Cc: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	brauner@kernel.org, jani.nikula@linux.intel.com,
	rodrigo.vivi@intel.com, tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com

On Tue, Jun 24, 2025 at 12:12:04PM +0000, 陈涛涛 Taotao Chen wrote:
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
> @@ -637,8 +637,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;
> -	loff_t pos;
> +	loff_t pos = 0;
>  	int err;

I think 'err' needs to become ssize_t to avoid writes larger than 2GB
from being misinterpreted as errors.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 3/5] fs: change write_begin/write_end interface to take struct kiocb *
  2025-06-24 12:12 ` [PATCH v2 3/5] fs: change write_begin/write_end interface to take struct kiocb * 陈涛涛 Taotao Chen
@ 2025-06-24 12:51   ` Matthew Wilcox
  2025-06-25  8:04     ` Christian Brauner
  0 siblings, 1 reply; 17+ messages in thread
From: Matthew Wilcox @ 2025-06-24 12:51 UTC (permalink / raw)
  To: 陈涛涛 Taotao Chen
  Cc: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	brauner@kernel.org, jani.nikula@linux.intel.com,
	rodrigo.vivi@intel.com, tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com

On Tue, Jun 24, 2025 at 12:12:08PM +0000, 陈涛涛 Taotao Chen wrote:
> -static int blkdev_write_end(struct file *file, struct address_space *mapping,
> +static int blkdev_write_end(struct kiocb *iocb, struct address_space *mapping,
>  		loff_t pos, unsigned len, unsigned copied, struct folio *folio,
>  		void *fsdata)
>  {
>  	int ret;
> -	ret = block_write_end(file, mapping, pos, len, copied, folio, fsdata);
> +	ret = block_write_end(iocb->ki_filp, mapping, pos, len, copied, folio, fsdata);

... huh.  I thought block_write_end() had to have the same prototype as
->write_end because it was used by some filesystems as the ->write_end.
I see that's not true (any more?).  Maybe I was confused with
generic_write_end().  Anyway, block_write_end() doesn't use it's file
argument, and never will, so we can just remove it.

> +++ b/include/linux/fs.h
> @@ -446,10 +446,10 @@ struct address_space_operations {
>  
>  	void (*readahead)(struct readahead_control *);
>  
> -	int (*write_begin)(struct file *, struct address_space *mapping,
> +	int (*write_begin)(struct kiocb *, struct address_space *mapping,
>  				loff_t pos, unsigned len,
>  				struct folio **foliop, void **fsdata);
> -	int (*write_end)(struct file *, struct address_space *mapping,
> +	int (*write_end)(struct kiocb *, struct address_space *mapping,
>  				loff_t pos, unsigned len, unsigned copied,
>  				struct folio *folio, void *fsdata);

Should we make this a 'const struct kiocb *'?  I don't see a need for
filesystems to be allowed to modify the kiocb in future, but perhaps
other people have different opinions.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 5/5] ext4: declare support for FOP_DONTCACHE
  2025-06-24 12:12 ` [PATCH v2 5/5] ext4: declare support for FOP_DONTCACHE 陈涛涛 Taotao Chen
@ 2025-06-24 12:53   ` Matthew Wilcox
  2025-06-25 10:46     ` Chen Taotao
  2025-06-25 14:36   ` Theodore Ts'o
  1 sibling, 1 reply; 17+ messages in thread
From: Matthew Wilcox @ 2025-06-24 12:53 UTC (permalink / raw)
  To: 陈涛涛 Taotao Chen
  Cc: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	brauner@kernel.org, jani.nikula@linux.intel.com,
	rodrigo.vivi@intel.com, tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com

On Tue, Jun 24, 2025 at 12:12:10PM +0000, 陈涛涛 Taotao Chen wrote:
> From: Taotao Chen <chentaotao@didiglobal.com>
> 
> Set the FOP_DONTCACHE flag in ext4_file_operations to indicate that
> ext4 supports IOCB_DONTCACHE handling in buffered write paths.

I think this patch should be combined with the previous patch so we
see all the change needed to support DONTCACHE in one patch.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support
  2025-06-24 12:11 [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
                   ` (4 preceding siblings ...)
  2025-06-24 12:12 ` [PATCH v2 5/5] ext4: declare support for FOP_DONTCACHE 陈涛涛 Taotao Chen
@ 2025-06-24 12:54 ` Matthew Wilcox
  2025-06-25  6:56 ` hch
  6 siblings, 0 replies; 17+ messages in thread
From: Matthew Wilcox @ 2025-06-24 12:54 UTC (permalink / raw)
  To: 陈涛涛 Taotao Chen
  Cc: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	brauner@kernel.org, jani.nikula@linux.intel.com,
	rodrigo.vivi@intel.com, tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com

On Tue, Jun 24, 2025 at 12:11:59PM +0000, 陈涛涛 Taotao Chen wrote:
> From: Taotao Chen <chentaotao@didiglobal.com>
> 
> This patch series refactors the address_space_operations write_begin()
> and write_end() callbacks to take struct kiocb * as their first argument,
> allowing IOCB flags such as IOCB_DONTCACHE to propagate to filesystem’s
> buffered write path.
> 
> Ext4 is updated to implement handling of the IOCB_DONTCACHE flag in its
> buffered write path and to advertise support via the FOP_DONTCACHE file
> operation flag.
> 
> Additionally, the i915 driver’s shmem write paths are updated to bypass
> the legacy write_begin/write_end interface in favor of directly calling
> write_iter(), using a constructed synchronous kiocb. Another i915 patch
> replaces a manual write loop with kernel_write() in shmem object creation.

Thanks, this is a really good cleanup.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support
  2025-06-24 12:11 [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
                   ` (5 preceding siblings ...)
  2025-06-24 12:54 ` [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support Matthew Wilcox
@ 2025-06-25  6:56 ` hch
  6 siblings, 0 replies; 17+ messages in thread
From: hch @ 2025-06-25  6:56 UTC (permalink / raw)
  To: 陈涛涛 Taotao Chen
  Cc: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	willy@infradead.org, brauner@kernel.org,
	jani.nikula@linux.intel.com, rodrigo.vivi@intel.com,
	tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com

Thanks, I really like the i915 work to stop the shmem abuse.

I still hate it that we just change the write_begin/end ops while still
in the address_space ops vs passing explicit callbacks, because that
means we'll some other version of that abuse back sooner or later :(


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 3/5] fs: change write_begin/write_end interface to take struct kiocb *
  2025-06-24 12:51   ` Matthew Wilcox
@ 2025-06-25  8:04     ` Christian Brauner
  2025-06-27  2:40       ` Chen Taotao
  0 siblings, 1 reply; 17+ messages in thread
From: Christian Brauner @ 2025-06-25  8:04 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: 陈涛涛 Taotao Chen, tytso@mit.edu,
	hch@infradead.org, adilger.kernel@dilger.ca,
	jani.nikula@linux.intel.com, rodrigo.vivi@intel.com,
	tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com

On Tue, Jun 24, 2025 at 01:51:51PM +0100, Matthew Wilcox wrote:
> On Tue, Jun 24, 2025 at 12:12:08PM +0000, 陈涛涛 Taotao Chen wrote:
> > -static int blkdev_write_end(struct file *file, struct address_space *mapping,
> > +static int blkdev_write_end(struct kiocb *iocb, struct address_space *mapping,
> >  		loff_t pos, unsigned len, unsigned copied, struct folio *folio,
> >  		void *fsdata)
> >  {
> >  	int ret;
> > -	ret = block_write_end(file, mapping, pos, len, copied, folio, fsdata);
> > +	ret = block_write_end(iocb->ki_filp, mapping, pos, len, copied, folio, fsdata);
> 
> ... huh.  I thought block_write_end() had to have the same prototype as
> ->write_end because it was used by some filesystems as the ->write_end.
> I see that's not true (any more?).  Maybe I was confused with
> generic_write_end().  Anyway, block_write_end() doesn't use it's file
> argument, and never will, so we can just remove it.
> 
> > +++ b/include/linux/fs.h
> > @@ -446,10 +446,10 @@ struct address_space_operations {
> >  
> >  	void (*readahead)(struct readahead_control *);
> >  
> > -	int (*write_begin)(struct file *, struct address_space *mapping,
> > +	int (*write_begin)(struct kiocb *, struct address_space *mapping,
> >  				loff_t pos, unsigned len,
> >  				struct folio **foliop, void **fsdata);
> > -	int (*write_end)(struct file *, struct address_space *mapping,
> > +	int (*write_end)(struct kiocb *, struct address_space *mapping,
> >  				loff_t pos, unsigned len, unsigned copied,
> >  				struct folio *folio, void *fsdata);
> 
> Should we make this a 'const struct kiocb *'?  I don't see a need for
> filesystems to be allowed to modify the kiocb in future, but perhaps
> other people have different opinions.

Given I picked up Willy's change I'll wait for a resubmit of this series
on top of vfs-6.17.misc unless I hear otherwise?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 1/5] drm/i915: Use kernel_write() in shmem object create
  2025-06-24 12:23   ` Matthew Wilcox
@ 2025-06-25 10:41     ` Chentaotao
  0 siblings, 0 replies; 17+ messages in thread
From: Chentaotao @ 2025-06-25 10:41 UTC (permalink / raw)
  To: Matthew Wilcox, 陈涛涛 Taotao Chen
  Cc: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	brauner@kernel.org, jani.nikula@linux.intel.com,
	rodrigo.vivi@intel.com, tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org


在 2025/6/24 20:23, Matthew Wilcox 写道:
> On Tue, Jun 24, 2025 at 12:12:04PM +0000, 陈涛涛 Taotao Chen wrote:
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
>> @@ -637,8 +637,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;
>> -	loff_t pos;
>> +	loff_t pos = 0;
>>   	int err;
> I think 'err' needs to become ssize_t to avoid writes larger than 2GB
> from being misinterpreted as errors.

Thanks for the great catch! I’ve changed int err; to ssize_t err; as you 
suggested.




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 5/5] ext4: declare support for FOP_DONTCACHE
  2025-06-24 12:53   ` Matthew Wilcox
@ 2025-06-25 10:46     ` Chen Taotao
  0 siblings, 0 replies; 17+ messages in thread
From: Chen Taotao @ 2025-06-25 10:46 UTC (permalink / raw)
  To: Matthew Wilcox, 陈涛涛 Taotao Chen
  Cc: tytso@mit.edu, hch@infradead.org, adilger.kernel@dilger.ca,
	brauner@kernel.org, jani.nikula@linux.intel.com,
	rodrigo.vivi@intel.com, tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org


在 2025/6/24 20:53, Matthew Wilcox 写道:
> On Tue, Jun 24, 2025 at 12:12:10PM +0000, 陈涛涛 Taotao Chen wrote:
>> From: Taotao Chen<chentaotao@didiglobal.com>
>>
>> Set the FOP_DONTCACHE flag in ext4_file_operations to indicate that
>> ext4 supports IOCB_DONTCACHE handling in buffered write paths.
> I think this patch should be combined with the previous patch so we
> see all the change needed to support DONTCACHE in one patch.

I’ll merge the patches to keep the DONTCACHE support self-contained. Thanks!




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 4/5] ext4: handle IOCB_DONTCACHE in buffered write path
  2025-06-24 12:12 ` [PATCH v2 4/5] ext4: handle IOCB_DONTCACHE in buffered write path 陈涛涛 Taotao Chen
@ 2025-06-25 14:35   ` Theodore Ts'o
  0 siblings, 0 replies; 17+ messages in thread
From: Theodore Ts'o @ 2025-06-25 14:35 UTC (permalink / raw)
  To: 陈涛涛 Taotao Chen
  Cc: hch@infradead.org, adilger.kernel@dilger.ca, willy@infradead.org,
	brauner@kernel.org, jani.nikula@linux.intel.com,
	rodrigo.vivi@intel.com, tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com

On Tue, Jun 24, 2025 at 12:12:09PM +0000, 陈涛涛 Taotao Chen wrote:
> From: Taotao Chen <chentaotao@didiglobal.com>
> 
> Add support for the IOCB_DONTCACHE flag in ext4_write_begin() and
> ext4_da_write_begin(). When set in the kiocb, the FGP_DONTCACHE bit
> is passed to the page cache lookup, preventing written pages from
> being retained in the cache.
> 
> Only the handling logic is implemented here; the behavior remains
> inactive until ext4 advertises support via FOP_DONTCACHE.
> 
> This change relies on prior patches that refactor the write_begin
> interface to use struct kiocb and introduce DONTCACHE handling in ext4.
> 
> Part of a series refactoring address_space_operations write_begin and
> write_end callbacks to use struct kiocb for passing write context and
> flags.
> 
> Signed-off-by: Taotao Chen <chentaotao@didiglobal.com>

Acked-by: Theodore Ts'o <tytso@mit.edu>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 5/5] ext4: declare support for FOP_DONTCACHE
  2025-06-24 12:12 ` [PATCH v2 5/5] ext4: declare support for FOP_DONTCACHE 陈涛涛 Taotao Chen
  2025-06-24 12:53   ` Matthew Wilcox
@ 2025-06-25 14:36   ` Theodore Ts'o
  1 sibling, 0 replies; 17+ messages in thread
From: Theodore Ts'o @ 2025-06-25 14:36 UTC (permalink / raw)
  To: 陈涛涛 Taotao Chen
  Cc: hch@infradead.org, adilger.kernel@dilger.ca, willy@infradead.org,
	brauner@kernel.org, jani.nikula@linux.intel.com,
	rodrigo.vivi@intel.com, tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	chentao325@qq.com

On Tue, Jun 24, 2025 at 12:12:10PM +0000, 陈涛涛 Taotao Chen wrote:
> From: Taotao Chen <chentaotao@didiglobal.com>
> 
> Set the FOP_DONTCACHE flag in ext4_file_operations to indicate that
> ext4 supports IOCB_DONTCACHE handling in buffered write paths.
> 
> Part of a series refactoring address_space_operations write_begin and
> write_end callbacks to use struct kiocb for passing write context and
> flags.
> 
> Signed-off-by: Taotao Chen <chentaotao@didiglobal.com>

I agree that it would be better to combine the ext4 patches.

Acked-by: Theodore Ts'o <tytso@mit.edu>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 3/5] fs: change write_begin/write_end interface to take struct kiocb *
  2025-06-25  8:04     ` Christian Brauner
@ 2025-06-27  2:40       ` Chen Taotao
  0 siblings, 0 replies; 17+ messages in thread
From: Chen Taotao @ 2025-06-27  2:40 UTC (permalink / raw)
  To: Christian Brauner, Matthew Wilcox
  Cc: 陈涛涛 Taotao Chen, tytso@mit.edu,
	hch@infradead.org, adilger.kernel@dilger.ca,
	jani.nikula@linux.intel.com, rodrigo.vivi@intel.com,
	tursulin@ursulin.net, airlied@gmail.com,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	linux-block@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-mm@kvack.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org


在 2025/6/25 16:04, Christian Brauner 写道:
> On Tue, Jun 24, 2025 at 01:51:51PM +0100, Matthew Wilcox wrote:
>> On Tue, Jun 24, 2025 at 12:12:08PM +0000, 陈涛涛 Taotao Chen wrote:
>>> -static int blkdev_write_end(struct file *file, struct address_space *mapping,
>>> +static int blkdev_write_end(struct kiocb *iocb, struct address_space *mapping,
>>>   		loff_t pos, unsigned len, unsigned copied, struct folio *folio,
>>>   		void *fsdata)
>>>   {
>>>   	int ret;
>>> -	ret = block_write_end(file, mapping, pos, len, copied, folio, fsdata);
>>> +	ret = block_write_end(iocb->ki_filp, mapping, pos, len, copied, folio, fsdata);
>> ... huh.  I thought block_write_end() had to have the same prototype as
>> ->write_end because it was used by some filesystems as the ->write_end.
>> I see that's not true (any more?).  Maybe I was confused with
>> generic_write_end().  Anyway, block_write_end() doesn't use it's file
>> argument, and never will, so we can just remove it.
>>
>>> +++ b/include/linux/fs.h
>>> @@ -446,10 +446,10 @@ struct address_space_operations {
>>>   
>>>   	void (*readahead)(struct readahead_control *);
>>>   
>>> -	int (*write_begin)(struct file *, struct address_space *mapping,
>>> +	int (*write_begin)(struct kiocb *, struct address_space *mapping,
>>>   				loff_t pos, unsigned len,
>>>   				struct folio **foliop, void **fsdata);
>>> -	int (*write_end)(struct file *, struct address_space *mapping,
>>> +	int (*write_end)(struct kiocb *, struct address_space *mapping,
>>>   				loff_t pos, unsigned len, unsigned copied,
>>>   				struct folio *folio, void *fsdata);
>> Should we make this a 'const struct kiocb *'?  I don't see a need for
>> filesystems to be allowed to modify the kiocb in future, but perhaps
>> other people have different opinions.
> Given I picked up Willy's change I'll wait for a resubmit of this series
> on top of vfs-6.17.misc unless I hear otherwise?
Sure, I’ll update the series on top of vfs-6.17.misc and resend it as 
soon as possible.

Best regards,
Taotao Chen


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2025-06-27  2:47 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-24 12:11 [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
2025-06-24 12:12 ` [PATCH v2 1/5] drm/i915: Use kernel_write() in shmem object create 陈涛涛 Taotao Chen
2025-06-24 12:23   ` Matthew Wilcox
2025-06-25 10:41     ` Chentaotao
2025-06-24 12:12 ` [PATCH v2 2/5] drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter 陈涛涛 Taotao Chen
2025-06-24 12:12 ` [PATCH v2 3/5] fs: change write_begin/write_end interface to take struct kiocb * 陈涛涛 Taotao Chen
2025-06-24 12:51   ` Matthew Wilcox
2025-06-25  8:04     ` Christian Brauner
2025-06-27  2:40       ` Chen Taotao
2025-06-24 12:12 ` [PATCH v2 4/5] ext4: handle IOCB_DONTCACHE in buffered write path 陈涛涛 Taotao Chen
2025-06-25 14:35   ` Theodore Ts'o
2025-06-24 12:12 ` [PATCH v2 5/5] ext4: declare support for FOP_DONTCACHE 陈涛涛 Taotao Chen
2025-06-24 12:53   ` Matthew Wilcox
2025-06-25 10:46     ` Chen Taotao
2025-06-25 14:36   ` Theodore Ts'o
2025-06-24 12:54 ` [PATCH v2 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support Matthew Wilcox
2025-06-25  6:56 ` hch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).