* [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support
@ 2025-07-16 9:36 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 1/5] drm/i915: Use kernel_write() in shmem object create 陈涛涛 Taotao Chen
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-07-16 9:36 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, frank.li@vivo.com,
陈涛涛 Taotao Chen, kernel test robot
From: Taotao Chen <chentaotao@didiglobal.com>
This patch series refactors the address_space_operations write_begin()
and write_end() callbacks to take const struct kiocb * as their first
argument, allowing IOCB flags such as IOCB_DONTCACHE to propagate to the
filesystem's buffered I/O path.
Ext4 is updated to implement handling of the IOCB_DONTCACHE flag and
advertises 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() with a constructed synchronous kiocb. Another i915
change replaces a manual write loop with kernel_write() during GEM shmem
object creation.
Tested with ext4 and i915 GEM workloads.
This patch series is based on the vfs-6.17.misc branch.
The kernel test robot reported issues in previous versions, which are fixed
in this updated patchset.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202507142128.Zr5StnYh-lkp@intel.com/
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202507142040.wppyoX1s-lkp@intel.com/
Changes since v5:
- Patch 2/5: Fix build errors in i915_gem_shmem.c by adding
#include <linux/uio.h> to define iov_iter and related symbols.
- Patch 3/5: Fix ubifs_write_end() by adding const to the argument
to match the updated write_end() interface.
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 *
mm/pagemap: add write_begin_get_folio() helper function
ext4: support uncached buffered I/O
Documentation/filesystems/locking.rst | 4 +-
Documentation/filesystems/vfs.rst | 6 +-
block/fops.c | 13 ++-
drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 115 ++++++----------------
fs/adfs/inode.c | 9 +-
fs/affs/file.c | 26 ++---
fs/bcachefs/fs-io-buffered.c | 4 +-
fs/bcachefs/fs-io-buffered.h | 4 +-
fs/bfs/file.c | 7 +-
fs/buffer.c | 26 ++---
fs/ceph/addr.c | 10 +-
fs/ecryptfs/mmap.c | 10 +-
fs/exfat/file.c | 11 +--
fs/exfat/inode.c | 16 +--
fs/ext2/inode.c | 11 ++-
fs/ext4/file.c | 3 +-
fs/ext4/inode.c | 30 +++---
fs/f2fs/data.c | 8 +-
fs/fat/inode.c | 18 ++--
fs/fuse/file.c | 14 ++-
fs/hfs/hfs_fs.h | 2 +-
fs/hfs/inode.c | 4 +-
fs/hfsplus/hfsplus_fs.h | 6 +-
fs/hfsplus/inode.c | 8 +-
fs/hostfs/hostfs_kern.c | 8 +-
fs/hpfs/file.c | 18 ++--
fs/hugetlbfs/inode.c | 9 +-
fs/jffs2/file.c | 28 +++---
fs/jfs/inode.c | 16 +--
fs/libfs.c | 11 ++-
fs/minix/inode.c | 7 +-
fs/nfs/file.c | 8 +-
fs/nilfs2/inode.c | 8 +-
fs/ntfs3/file.c | 4 +-
fs/ntfs3/inode.c | 7 +-
fs/ntfs3/ntfs_fs.h | 10 +-
fs/ocfs2/aops.c | 6 +-
fs/omfs/file.c | 7 +-
fs/orangefs/inode.c | 16 +--
fs/ubifs/file.c | 8 +-
fs/udf/inode.c | 11 ++-
fs/ufs/inode.c | 16 +--
fs/vboxsf/file.c | 5 +-
include/linux/buffer_head.h | 4 +-
include/linux/fs.h | 11 ++-
include/linux/pagemap.h | 27 +++++
mm/filemap.c | 4 +-
mm/shmem.c | 12 +--
48 files changed, 330 insertions(+), 296 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v6 1/5] drm/i915: Use kernel_write() in shmem object create
2025-07-16 9:36 [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
@ 2025-07-16 9:36 ` 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 2/5] drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter 陈涛涛 Taotao Chen
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-07-16 9:36 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, frank.li@vivo.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 | 33 +++++++----------------
1 file changed, 9 insertions(+), 24 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..1e8f66ac48ca 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -637,9 +637,8 @@ 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;
- int err;
+ loff_t pos = 0;
+ ssize_t err;
GEM_WARN_ON(IS_DGFX(i915));
obj = i915_gem_object_create_shmem(i915, round_up(size, PAGE_SIZE));
@@ -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] 7+ messages in thread
* [PATCH v6 2/5] drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter
2025-07-16 9:36 [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 1/5] drm/i915: Use kernel_write() in shmem object create 陈涛涛 Taotao Chen
@ 2025-07-16 9:36 ` 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 3/5] fs: change write_begin/write_end interface to take struct kiocb * 陈涛涛 Taotao Chen
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-07-16 9:36 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, frank.li@vivo.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 | 82 ++++++-----------------
1 file changed, 22 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 1e8f66ac48ca..9cbb0f68a5bb 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -6,6 +6,7 @@
#include <linux/pagevec.h>
#include <linux/shmem_fs.h>
#include <linux/swap.h>
+#include <linux/uio.h>
#include <drm/drm_cache.h>
@@ -400,12 +401,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 +429,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] 7+ messages in thread
* [PATCH v6 3/5] fs: change write_begin/write_end interface to take struct kiocb *
2025-07-16 9:36 [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 1/5] drm/i915: Use kernel_write() in shmem object create 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 2/5] drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter 陈涛涛 Taotao Chen
@ 2025-07-16 9:36 ` 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 4/5] mm/pagemap: add write_begin_get_folio() helper function 陈涛涛 Taotao Chen
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-07-16 9:36 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, frank.li@vivo.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 | 6 +++---
block/fops.c | 13 ++++++++-----
fs/adfs/inode.c | 9 +++++----
fs/affs/file.c | 26 ++++++++++++++-----------
fs/bcachefs/fs-io-buffered.c | 4 ++--
fs/bcachefs/fs-io-buffered.h | 4 ++--
fs/bfs/file.c | 7 ++++---
fs/buffer.c | 26 ++++++++++++-------------
fs/ceph/addr.c | 10 +++++++---
fs/ecryptfs/mmap.c | 10 +++++-----
fs/exfat/file.c | 11 +++++------
fs/exfat/inode.c | 16 ++++++++-------
fs/ext2/inode.c | 11 ++++++-----
fs/ext4/inode.c | 18 +++++++++--------
fs/f2fs/data.c | 8 +++++---
fs/fat/inode.c | 18 +++++++++--------
fs/fuse/file.c | 14 +++++++++-----
fs/hfs/hfs_fs.h | 2 +-
fs/hfs/inode.c | 4 ++--
fs/hfsplus/hfsplus_fs.h | 6 ++++--
fs/hfsplus/inode.c | 8 +++++---
fs/hostfs/hostfs_kern.c | 8 +++++---
fs/hpfs/file.c | 18 +++++++++--------
fs/hugetlbfs/inode.c | 9 +++++----
fs/jffs2/file.c | 28 +++++++++++++++------------
fs/jfs/inode.c | 16 ++++++++-------
fs/libfs.c | 11 ++++++-----
fs/minix/inode.c | 7 ++++---
fs/nfs/file.c | 8 ++++++--
fs/nilfs2/inode.c | 8 +++++---
fs/ntfs3/file.c | 4 ++--
fs/ntfs3/inode.c | 7 ++++---
fs/ntfs3/ntfs_fs.h | 10 ++++++----
fs/ocfs2/aops.c | 6 ++++--
fs/omfs/file.c | 7 ++++---
fs/orangefs/inode.c | 16 ++++++++-------
fs/ubifs/file.c | 8 +++++---
fs/udf/inode.c | 11 +++++++----
fs/ufs/inode.c | 16 ++++++++-------
fs/vboxsf/file.c | 5 +++--
include/linux/buffer_head.h | 4 ++--
include/linux/fs.h | 11 ++++++-----
mm/filemap.c | 4 ++--
mm/shmem.c | 12 ++++++------
45 files changed, 267 insertions(+), 202 deletions(-)
diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
index 2e567e341c3b..580581281ed7 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)(const 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)(const 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 dd9da7e04a99..57604b07bdc9 100644
--- a/Documentation/filesystems/vfs.rst
+++ b/Documentation/filesystems/vfs.rst
@@ -823,10 +823,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)(const 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,
+ struct page **pagep, void **fsdata);
+ int (*write_end)(const 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 35cea0cb304d..f34e7315c83c 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -496,15 +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,
- loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
+static int blkdev_write_begin(const 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,
- loff_t pos, unsigned len, unsigned copied, struct folio *folio,
- void *fsdata)
+static int blkdev_write_end(const 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(pos, len, copied, folio);
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index 21527189e430..6830f8bc8d4e 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -53,13 +53,14 @@ 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,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int adfs_write_begin(const 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..219ea0353906 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -415,13 +415,14 @@ affs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
return ret;
}
-static int affs_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int affs_write_begin(const 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 +431,15 @@ 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,
- loff_t pos, unsigned int len, unsigned int copied,
+static int affs_write_end(const 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 +647,8 @@ 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(const struct kiocb *iocb,
+ struct address_space *mapping,
loff_t pos, unsigned len,
struct folio **foliop, void **fsdata)
{
@@ -684,9 +687,10 @@ 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,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+static int affs_write_end_ofs(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct folio *folio, void *fsdata)
{
struct inode *inode = mapping->host;
struct super_block *sb = inode->i_sb;
diff --git a/fs/bcachefs/fs-io-buffered.c b/fs/bcachefs/fs-io-buffered.c
index 66bacdd49f78..1c54b9b5bd69 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(const 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(const 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..14de91c27656 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(const 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(const 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..10dc0151ea55 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -170,9 +170,10 @@ 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,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int bfs_write_begin(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len,
+ struct folio **foliop, void **fsdata)
{
int ret;
diff --git a/fs/buffer.c b/fs/buffer.c
index 565fe88773c2..ead4dc85debd 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2297,9 +2297,9 @@ int block_write_end(loff_t pos, unsigned len, unsigned copied,
}
EXPORT_SYMBOL(block_write_end);
-int generic_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+int generic_write_end(const struct kiocb *iocb, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct folio *folio, void *fsdata)
{
struct inode *inode = mapping->host;
loff_t old_size = inode->i_size;
@@ -2494,7 +2494,8 @@ 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(const struct kiocb *iocb,
+ struct address_space *mapping,
loff_t pos, loff_t *bytes)
{
struct inode *inode = mapping->host;
@@ -2518,12 +2519,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;
@@ -2551,12 +2552,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;
@@ -2571,17 +2572,16 @@ 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,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata,
- get_block_t *get_block, loff_t *bytes)
+int cont_write_begin(const 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)
{
struct inode *inode = mapping->host;
unsigned int blocksize = i_blocksize(inode);
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..02468c848cce 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -1864,10 +1864,12 @@ 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(const 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 +1887,12 @@ 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,
- loff_t pos, unsigned len, unsigned copied,
+static int ceph_write_end(const 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..2c2b12fedeae 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(const 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(const 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..70f53edd0a10 100644
--- a/fs/exfat/file.c
+++ b/fs/exfat/file.c
@@ -532,11 +532,10 @@ 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 inode *inode, loff_t new_valid_size)
{
int err;
loff_t pos;
- struct inode *inode = file_inode(file);
struct exfat_inode_info *ei = EXFAT_I(inode);
struct address_space *mapping = inode->i_mapping;
const struct address_space_operations *ops = mapping->a_ops;
@@ -551,14 +550,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(NULL, 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(NULL, mapping, pos, len, len, folio, NULL);
if (err < 0)
goto out;
pos += len;
@@ -604,7 +603,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(inode, pos);
if (ret < 0 && ret != -ENOSPC) {
exfat_err(inode->i_sb,
"write: fail to zero from %llu to %llu(%zd)",
@@ -665,7 +664,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(inode, 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..c10844e1e16c 100644
--- a/fs/exfat/inode.c
+++ b/fs/exfat/inode.c
@@ -446,9 +446,10 @@ static void exfat_write_failed(struct address_space *mapping, loff_t to)
}
}
-static int exfat_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned int len,
- struct folio **foliop, void **fsdata)
+static int exfat_write_begin(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned int len,
+ struct folio **foliop, void **fsdata)
{
int ret;
@@ -463,15 +464,16 @@ 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,
- loff_t pos, unsigned int len, unsigned int copied,
- struct folio *folio, void *fsdata)
+static int exfat_write_end(const 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 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..d35ca26eee3c 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(const struct kiocb *iocb, struct address_space *mapping,
loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
{
int ret;
@@ -926,13 +926,14 @@ ext2_write_begin(struct file *file, struct address_space *mapping,
return ret;
}
-static int ext2_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+static int ext2_write_end(const 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 e6aa7ca6d842..9a16efd072bb 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1252,7 +1252,8 @@ 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(const struct kiocb *iocb,
+ struct address_space *mapping,
loff_t pos, unsigned len,
struct folio **foliop, void **fsdata)
{
@@ -1400,12 +1401,12 @@ 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().
+ * `iocb` 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(const struct kiocb *iocb,
struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct folio *folio, void *fsdata)
@@ -1510,7 +1511,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(const struct kiocb *iocb,
struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct folio *folio, void *fsdata)
@@ -3036,7 +3037,8 @@ 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(const struct kiocb *iocb,
+ struct address_space *mapping,
loff_t pos, unsigned len,
struct folio **foliop, void **fsdata)
{
@@ -3054,7 +3056,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;
@@ -3195,7 +3197,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(const struct kiocb *iocb,
struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct folio *folio, void *fsdata)
@@ -3204,7 +3206,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..711ad80b38d0 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3519,8 +3519,10 @@ 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,
- loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
+static int f2fs_write_begin(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, struct folio **foliop,
+ void **fsdata)
{
struct inode *inode = mapping->host;
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -3656,7 +3658,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(const 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..9648ed097816 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -219,13 +219,14 @@ static void fat_write_failed(struct address_space *mapping, loff_t to)
}
}
-static int fat_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int fat_write_begin(const 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 +234,14 @@ 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,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+static int fat_write_end(const 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..21c6f8654bfe 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2213,10 +2213,13 @@ 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,
- loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
+static int fuse_write_begin(const 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,9 +2259,10 @@ 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,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+static int fuse_write_end(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct folio *folio, void *fsdata)
{
struct inode *inode = folio->mapping->host;
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index a0c7cb0f79fc..c3fd3172fdd6 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(const 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..096f338134f9 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(const 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..3d5c65aef3b2 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -473,8 +473,10 @@ 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,
- loff_t pos, unsigned len, struct folio **foliop, void **fsdata);
+int hfsplus_write_begin(const 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);
void hfsplus_delete_inode(struct inode *inode);
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index f331e9574217..97d75bb2c388 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -38,12 +38,14 @@ static void hfsplus_write_failed(struct address_space *mapping, loff_t to)
}
}
-int hfsplus_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, struct folio **foliop, void **fsdata)
+int hfsplus_write_begin(const 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..6c2cf0cdf3d6 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -445,7 +445,8 @@ 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(const struct kiocb *iocb,
+ struct address_space *mapping,
loff_t pos, unsigned len,
struct folio **foliop, void **fsdata)
{
@@ -458,7 +459,8 @@ 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(const struct kiocb *iocb,
+ struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct folio *folio, void *fsdata)
{
@@ -468,7 +470,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..7b95a3d2e2a6 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -188,13 +188,14 @@ 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,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int hpfs_write_begin(const 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 +204,14 @@ 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,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+static int hpfs_write_end(const 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..541aae502d4d 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(const struct kiocb *iocb,
struct address_space *mapping,
loff_t pos, unsigned len,
struct folio **foliop, void **fsdata)
@@ -319,9 +319,10 @@ static int hugetlbfs_write_begin(struct file *file,
return -EINVAL;
}
-static int hugetlbfs_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+static int hugetlbfs_write_end(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct folio *folio, void *fsdata)
{
BUG();
return -EINVAL;
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 13c18ccc13b0..adec3af9bf8d 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -21,12 +21,14 @@
#include <linux/jffs2.h>
#include "nodelist.h"
-static int jffs2_write_end(struct file *filp, 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,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata);
+static int jffs2_write_end(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct folio *folio, void *fsdata);
+static int jffs2_write_begin(const 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);
int jffs2_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
@@ -121,9 +123,10 @@ 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,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int jffs2_write_begin(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len,
+ struct folio **foliop, void **fsdata)
{
struct folio *folio;
struct inode *inode = mapping->host;
@@ -235,9 +238,10 @@ 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,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+static int jffs2_write_end(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct folio *folio, void *fsdata)
{
/* Actually commit the write from the page cache page we're looking at.
* For now, we write the full page out each time. It sucks, but it's simple
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 60fc92dee24d..083e7fa54709 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -290,9 +290,10 @@ static void jfs_write_failed(struct address_space *mapping, loff_t to)
}
}
-static int jfs_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int jfs_write_begin(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len,
+ struct folio **foliop, void **fsdata)
{
int ret;
@@ -303,13 +304,14 @@ 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,
- loff_t pos, unsigned len, unsigned copied, struct folio *folio,
- void *fsdata)
+static int jfs_write_end(const 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 f99ecc300647..52196566ccbc 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(const struct kiocb *iocb, struct address_space *mapping,
loff_t pos, unsigned len,
struct folio **foliop, void **fsdata)
{
@@ -935,7 +935,7 @@ EXPORT_SYMBOL(simple_write_begin);
/**
* simple_write_end - .write_end helper for non-block-device FSes
- * @file: See .write_end of address_space_operations
+ * @iocb: kernel I/O control block
* @mapping: "
* @pos: "
* @len: "
@@ -956,9 +956,10 @@ EXPORT_SYMBOL(simple_write_begin);
*
* Use *ONLY* with simple_read_folio()
*/
-static int simple_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+static int simple_write_end(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct folio *folio, void *fsdata)
{
struct inode *inode = folio->mapping->host;
loff_t last_pos = pos + copied;
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index f007e389d5d2..df9d11479caf 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -442,9 +442,10 @@ static void minix_write_failed(struct address_space *mapping, loff_t to)
}
}
-static int minix_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int minix_write_begin(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len,
+ struct folio **foliop, void **fsdata)
{
int ret;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 033feeab8c34..2bd557ca1af9 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -342,12 +342,14 @@ 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(const 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 +379,12 @@ 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(const 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..c2ccafdf4a19 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -218,7 +218,8 @@ 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(const struct kiocb *iocb,
+ struct address_space *mapping,
loff_t pos, unsigned len,
struct folio **foliop, void **fsdata)
@@ -237,7 +238,8 @@ 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(const struct kiocb *iocb,
+ struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct folio *folio, void *fsdata)
{
@@ -248,7 +250,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..1590c2a3c48f 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -154,13 +154,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(NULL, 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(NULL, 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..dad088e64b3c 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(const struct kiocb *iocb, struct address_space *mapping,
loff_t pos, u32 len, struct folio **foliop, void **fsdata)
{
int err;
@@ -957,7 +957,8 @@ 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(const 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 +990,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..921257773eec 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -702,10 +702,12 @@ 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,
- loff_t pos, u32 len, struct folio **foliop, void **fsdata);
-int ntfs_write_end(struct file *file, struct address_space *mapping, loff_t pos,
- u32 len, u32 copied, struct folio *folio, void *fsdata);
+int ntfs_write_begin(const struct kiocb *iocb, struct address_space *mapping,
+ loff_t pos, u32 len, struct folio **foliop,
+ void **fsdata);
+int ntfs_write_end(const 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);
int inode_read_data(struct inode *inode, void *data, size_t bytes);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 40b6bce12951..2203438738f6 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1856,7 +1856,8 @@ 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(const struct kiocb *iocb,
+ struct address_space *mapping,
loff_t pos, unsigned len,
struct folio **foliop, void **fsdata)
{
@@ -2047,7 +2048,8 @@ 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(const 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..8d70f816b0c9 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -310,9 +310,10 @@ static void omfs_write_failed(struct address_space *mapping, loff_t to)
}
}
-static int omfs_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int omfs_write_begin(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len,
+ struct folio **foliop, void **fsdata)
{
int ret;
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 08a6f372a352..a7ab63776735 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -285,9 +285,10 @@ static int orangefs_read_folio(struct file *file, struct folio *folio)
return ret;
}
-static int orangefs_write_begin(struct file *file,
- struct address_space *mapping, loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int orangefs_write_begin(const struct kiocb *iocb,
+ struct address_space *mapping, loff_t pos,
+ unsigned len, struct folio **foliop,
+ void **fsdata)
{
struct orangefs_write_range *wr;
struct folio *folio;
@@ -340,9 +341,10 @@ static int orangefs_write_begin(struct file *file,
return 0;
}
-static int orangefs_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied, struct folio *folio,
- void *fsdata)
+static int orangefs_write_end(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct folio *folio, void *fsdata)
{
struct inode *inode = folio->mapping->host;
loff_t last_pos = pos + copied;
@@ -372,7 +374,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..cee8bec1ea26 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -404,7 +404,8 @@ 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(const struct kiocb *iocb,
+ struct address_space *mapping,
loff_t pos, unsigned len,
struct folio **foliop, void **fsdata)
{
@@ -514,8 +515,9 @@ static void cancel_budget(struct ubifs_info *c, struct folio *folio,
}
}
-static int ubifs_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
+static int ubifs_write_end(const struct kiocb *iocb,
+ struct address_space *mapping, loff_t pos,
+ unsigned len, unsigned copied,
struct folio *folio, void *fsdata)
{
struct inode *inode = mapping->host;
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 4386dd845e40..356b75676fa9 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -244,10 +244,12 @@ 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(const 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 +273,16 @@ 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(const 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..8361c00e8fa6 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -474,9 +474,10 @@ static void ufs_write_failed(struct address_space *mapping, loff_t to)
}
}
-static int ufs_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+static int ufs_write_begin(const struct kiocb *iocb,
+ struct address_space *mapping,
+ loff_t pos, unsigned len,
+ struct folio **foliop, void **fsdata)
{
int ret;
@@ -487,13 +488,14 @@ 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,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+static int ufs_write_end(const 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..af01e3beaa42 100644
--- a/fs/vboxsf/file.c
+++ b/fs/vboxsf/file.c
@@ -300,12 +300,13 @@ 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(const 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 178eb90e9cf3..b16b88bfbc3e 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -263,11 +263,11 @@ int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len,
int __block_write_begin(struct folio *folio, loff_t pos, unsigned len,
get_block_t *get_block);
int block_write_end(loff_t pos, unsigned len, unsigned copied, struct folio *);
-int generic_write_end(struct file *, struct address_space *,
+int generic_write_end(const 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(const 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 09e3e80b0528..df8c503100c4 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -444,10 +444,10 @@ struct address_space_operations {
void (*readahead)(struct readahead_control *);
- int (*write_begin)(struct file *, struct address_space *mapping,
+ int (*write_begin)(const 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)(const struct kiocb *, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct folio *folio, void *fsdata);
@@ -3598,9 +3598,10 @@ 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,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata);
+extern int simple_write_begin(const 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;
extern int always_delete_dentry(const struct dentry *);
extern struct inode *alloc_anon_inode(struct super_block *);
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 0c5fb4ffa03a..2229425e1b29 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3266,9 +3266,9 @@ 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,
- loff_t pos, unsigned len,
- struct folio **foliop, void **fsdata)
+shmem_write_begin(const struct kiocb *iocb, struct address_space *mapping,
+ loff_t pos, unsigned len,
+ struct folio **foliop, void **fsdata)
{
struct inode *inode = mapping->host;
struct shmem_inode_info *info = SHMEM_I(inode);
@@ -3300,9 +3300,9 @@ shmem_write_begin(struct file *file, struct address_space *mapping,
}
static int
-shmem_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct folio *folio, void *fsdata)
+shmem_write_end(const struct kiocb *iocb, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct folio *folio, void *fsdata)
{
struct inode *inode = mapping->host;
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v6 4/5] mm/pagemap: add write_begin_get_folio() helper function
2025-07-16 9:36 [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
` (2 preceding siblings ...)
2025-07-16 9:36 ` [PATCH v6 3/5] fs: change write_begin/write_end interface to take struct kiocb * 陈涛涛 Taotao Chen
@ 2025-07-16 9:36 ` 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 5/5] ext4: support uncached buffered I/O 陈涛涛 Taotao Chen
2025-07-16 12:50 ` [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support Christian Brauner
5 siblings, 0 replies; 7+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-07-16 9:36 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, frank.li@vivo.com,
陈涛涛 Taotao Chen
From: Taotao Chen <chentaotao@didiglobal.com>
Add write_begin_get_folio() to simplify the common folio lookup logic
used by filesystem ->write_begin() implementations.
This helper wraps __filemap_get_folio() with common flags such as
FGP_WRITEBEGIN, conditional FGP_DONTCACHE, and set folio order based
on the write length.
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>
---
include/linux/pagemap.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index e63fbfbd5b0f..ce2bcdcadb73 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -750,6 +750,33 @@ struct folio *__filemap_get_folio(struct address_space *mapping, pgoff_t index,
struct page *pagecache_get_page(struct address_space *mapping, pgoff_t index,
fgf_t fgp_flags, gfp_t gfp);
+/**
+ * write_begin_get_folio - Get folio for write_begin with flags.
+ * @iocb: The kiocb passed from write_begin (may be NULL).
+ * @mapping: The address space to search.
+ * @index: The page cache index.
+ * @len: Length of data being written.
+ *
+ * This is a helper for filesystem write_begin() implementations.
+ * It wraps __filemap_get_folio(), setting appropriate flags in
+ * the write begin context.
+ *
+ * Return: A folio or an ERR_PTR.
+ */
+static inline struct folio *write_begin_get_folio(const struct kiocb *iocb,
+ struct address_space *mapping, pgoff_t index, size_t len)
+{
+ fgf_t fgp_flags = FGP_WRITEBEGIN;
+
+ fgp_flags |= fgf_set_order(len);
+
+ if (iocb && iocb->ki_flags & IOCB_DONTCACHE)
+ fgp_flags |= FGP_DONTCACHE;
+
+ return __filemap_get_folio(mapping, index, fgp_flags,
+ mapping_gfp_mask(mapping));
+}
+
/**
* filemap_get_folio - Find and get a folio.
* @mapping: The address_space to search.
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v6 5/5] ext4: support uncached buffered I/O
2025-07-16 9:36 [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
` (3 preceding siblings ...)
2025-07-16 9:36 ` [PATCH v6 4/5] mm/pagemap: add write_begin_get_folio() helper function 陈涛涛 Taotao Chen
@ 2025-07-16 9:36 ` 陈涛涛 Taotao Chen
2025-07-16 12:50 ` [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support Christian Brauner
5 siblings, 0 replies; 7+ messages in thread
From: 陈涛涛 Taotao Chen @ 2025-07-16 9:36 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, frank.li@vivo.com,
陈涛涛 Taotao Chen
From: Taotao Chen <chentaotao@didiglobal.com>
Set FOP_DONTCACHE in ext4_file_operations to declare support for
uncached buffered I/O.
To handle this flag, update ext4_write_begin() and ext4_da_write_begin()
to use write_begin_get_folio(), which encapsulates FGP_DONTCACHE logic
based on iocb->ki_flags.
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 ++-
fs/ext4/inode.c | 12 +++---------
2 files changed, 5 insertions(+), 10 deletions(-)
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 = {
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 9a16efd072bb..5c7024051f1e 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1264,7 +1264,6 @@ static int ext4_write_begin(const struct kiocb *iocb,
struct folio *folio;
pgoff_t index;
unsigned from, to;
- fgf_t fgp = FGP_WRITEBEGIN;
ret = ext4_emergency_state(inode->i_sb);
if (unlikely(ret))
@@ -1288,16 +1287,14 @@ static int ext4_write_begin(const struct kiocb *iocb,
}
/*
- * __filemap_get_folio() can take a long time if the
+ * write_begin_get_folio() can take a long time if the
* system is thrashing due to memory pressure, or if the folio
* is being written back. So grab it first before we start
* the transaction handle. This also allows us to allocate
* the folio (if needed) without using GFP_NOFS.
*/
retry_grab:
- fgp |= fgf_set_order(len);
- folio = __filemap_get_folio(mapping, index, fgp,
- mapping_gfp_mask(mapping));
+ folio = write_begin_get_folio(iocb, mapping, index, len);
if (IS_ERR(folio))
return PTR_ERR(folio);
@@ -3046,7 +3043,6 @@ static int ext4_da_write_begin(const struct kiocb *iocb,
struct folio *folio;
pgoff_t index;
struct inode *inode = mapping->host;
- fgf_t fgp = FGP_WRITEBEGIN;
ret = ext4_emergency_state(inode->i_sb);
if (unlikely(ret))
@@ -3072,9 +3068,7 @@ static int ext4_da_write_begin(const struct kiocb *iocb,
}
retry:
- fgp |= fgf_set_order(len);
- folio = __filemap_get_folio(mapping, index, fgp,
- mapping_gfp_mask(mapping));
+ folio = write_begin_get_folio(iocb, mapping, index, len);
if (IS_ERR(folio))
return PTR_ERR(folio);
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support
2025-07-16 9:36 [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
` (4 preceding siblings ...)
2025-07-16 9:36 ` [PATCH v6 5/5] ext4: support uncached buffered I/O 陈涛涛 Taotao Chen
@ 2025-07-16 12:50 ` Christian Brauner
5 siblings, 0 replies; 7+ messages in thread
From: Christian Brauner @ 2025-07-16 12:50 UTC (permalink / raw)
To: 陈涛涛 Taotao Chen
Cc: Christian Brauner, linux-fsdevel, linux-ext4, linux-block,
intel-gfx, dri-devel, linux-mm, linux-doc, linux-kernel,
chentao325, frank.li, kernel test robot, tytso, hch,
adilger.kernel, willy, jani.nikula, rodrigo.vivi, tursulin,
airlied
On Wed, 16 Jul 2025 09:36:01 +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 const struct kiocb * as their first
> argument, allowing IOCB flags such as IOCB_DONTCACHE to propagate to the
> filesystem's buffered I/O path.
>
> [...]
Applied to the vfs-6.17.misc branch of the vfs/vfs.git tree.
Patches in the vfs-6.17.misc branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-6.17.misc
[1/5] drm/i915: Use kernel_write() in shmem object create
https://git.kernel.org/vfs/vfs/c/e7b840fd4956
[2/5] drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter
https://git.kernel.org/vfs/vfs/c/048832a3f400
[3/5] fs: change write_begin/write_end interface to take struct kiocb *
https://git.kernel.org/vfs/vfs/c/e9d8e2bf2320
[4/5] mm/pagemap: add write_begin_get_folio() helper function
https://git.kernel.org/vfs/vfs/c/b799474b9aeb
[5/5] ext4: support uncached buffered I/O
https://git.kernel.org/vfs/vfs/c/ae21c0c0ac56
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-07-16 12:50 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-16 9:36 [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 1/5] drm/i915: Use kernel_write() in shmem object create 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 2/5] drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 3/5] fs: change write_begin/write_end interface to take struct kiocb * 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 4/5] mm/pagemap: add write_begin_get_folio() helper function 陈涛涛 Taotao Chen
2025-07-16 9:36 ` [PATCH v6 5/5] ext4: support uncached buffered I/O 陈涛涛 Taotao Chen
2025-07-16 12:50 ` [PATCH v6 0/5] fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support Christian Brauner
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).