summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2025-07-16 15:48:24 +0300
committerChristian Brauner <brauner@kernel.org>2025-07-16 15:48:24 +0300
commit981569a06f704ac9c4eed249f47426e1be1a5636 (patch)
tree0ec8d85041debe49759630d4124c2dd3c164dcab /include/linux
parentf2e467a48287c868818085aa35389a224d226732 (diff)
parentae21c0c0ac56aa734327e9c8b7dfef4270ab54d4 (diff)
downloadlinux-981569a06f704ac9c4eed249f47426e1be1a5636.tar.xz
Merge patch series "fs: refactor write_begin/write_end and add ext4 IOCB_DONTCACHE support"
陈涛涛 Taotao Chen <chentaotao@didiglobal.com> says: 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. * patches from https://lore.kernel.org/20250716093559.217344-1-chentaotao@didiglobal.com: ext4: support uncached buffered I/O mm/pagemap: add write_begin_get_folio() helper function fs: change write_begin/write_end interface to take struct kiocb * drm/i915: Refactor shmem_pwrite() to use kiocb and write_iter drm/i915: Use kernel_write() in shmem object create Link: https://lore.kernel.org/20250716093559.217344-1-chentaotao@didiglobal.com Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/buffer_head.h4
-rw-r--r--include/linux/fs.h11
-rw-r--r--include/linux/pagemap.h27
3 files changed, 35 insertions, 7 deletions
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/include/linux/pagemap.h b/include/linux/pagemap.h
index e63fbfbd5b0f..ce2bcdcadb73 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -751,6 +751,33 @@ 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.
* @index: The page index.