1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
From: Cheyenne Wills <cwills@sinenomine.net>
Date: Tue, 21 Oct 2025 13:55:48 -0600
Subject: Linux: Use struct kiocb * for aops write_begin/end
The Linux 6.17 commit:
fs: change write_begin/write_end interface to take struct kiocb *
(e9d8e2bf23206)
changed the address_space_operations members write_begin and write_end
to use a 'struct kiocb *' instead of a 'struct file *' as the first
parameter.
The passed kiocb structure contains a pointer (ki_filp) to the file
structure that is associated with the operation.
Update the afs_linux_write_begin() and afs_linux_write_end() to accept
a 'struct kiocb *' instead of a 'struct file *', and obtain the file
pointer directly from kiocb.
Add an autoconf test to determine if aops->write_begin()/aops->write_end
uses a struct kiocb * as the first parameter.
Reviewed-on: https://gerrit.openafs.org/16558
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Marcio Brito Barbosa <mbarbosa@sinenomine.net>
(cherry picked from commit 1ad827ded0ed970540b6836250f2395ae31b84bc)
Change-Id: I59d37422a280716dac3398c039fc728911a7bef2
Reviewed-on: https://gerrit.openafs.org/16603
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
(cherry picked from commit a765a9ddd412c8d1e5cb0f5cf497a8606251811e)
---
src/afs/LINUX/osi_vnodeops.c | 29 +++++++++++++++++++++++++++++
src/cf/linux-kernel-func.m4 | 12 ++++++++++++
2 files changed, 41 insertions(+)
diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
index 9508b11..f7f67e6 100644
--- a/src/afs/LINUX/osi_vnodeops.c
+++ b/src/afs/LINUX/osi_vnodeops.c
@@ -3794,15 +3794,34 @@ afs_linux_prepare_write(struct file *file, struct page *page, unsigned from,
return 0;
}
+#if defined(HAVE_LINUX_WRITE_BEGIN_END_KIOCB)
+/*
+ * When aops write_begin and write_end are passed a kiocb, it is implied that
+ * write_begin and write_end take a folio and that __filemap_get_folio is present.
+ */
+# define HAVE_LINUX_WRITE_BEGIN_END_FOLIO
+# define HAVE_LINUX_FILEMAP_GET_FOLIO
+#endif
+
#if defined(HAVE_LINUX_WRITE_BEGIN_END_FOLIO)
+# if defined(HAVE_LINUX_WRITE_BEGIN_END_KIOCB)
+static int
+afs_linux_write_end(const struct kiocb *iocb, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct folio *folio, void *fsdata)
+# else
static int
afs_linux_write_end(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct folio *folio, void *fsdata)
+# endif
{
int code;
unsigned int from = pos & (PAGE_SIZE - 1);
struct page *page = folio_page(folio, 0);
+# if defined(HAVE_LINUX_WRITE_BEGIN_END_KIOCB)
+ struct file *file = iocb->ki_filp;
+# endif
code = afs_linux_commit_write(file, page, from, from + copied);
@@ -3812,15 +3831,25 @@ afs_linux_write_end(struct file *file, struct address_space *mapping,
}
# if defined(HAVE_LINUX_FILEMAP_GET_FOLIO)
+# if defined(HAVE_LINUX_WRITE_BEGIN_END_KIOCB)
+static int
+afs_linux_write_begin(const struct kiocb *iocb, struct address_space *mapping,
+ loff_t pos, unsigned len,
+ struct folio **foliop, void **fsdata)
+# else
static int
afs_linux_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len,
struct folio **foliop, void **fsdata)
+# endif
{
struct page *page;
pgoff_t index = pos >> PAGE_SHIFT;
unsigned int from = pos & (PAGE_SIZE - 1);
int code;
+# if defined(HAVE_LINUX_WRITE_BEGIN_END_KIOCB)
+ struct file *file = iocb->ki_filp;
+# endif
*foliop = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN, mapping_gfp_mask(mapping));
if (IS_ERR(*foliop)) {
diff --git a/src/cf/linux-kernel-func.m4 b/src/cf/linux-kernel-func.m4
index 175db00..0784262 100644
--- a/src/cf/linux-kernel-func.m4
+++ b/src/cf/linux-kernel-func.m4
@@ -367,6 +367,18 @@ AC_CHECK_LINUX_FUNC([readahead_folio],
static struct folio *folio;]],
[[folio = __readahead_folio(NULL);]])
+dnl Linux 6.17 changed aops->write_begin/write_end to take a struct kiocp *
+dnl instead of a struct file *.
+AC_CHECK_LINUX_FUNC([write_begin_end_kiocb],
+ [[#include <linux/fs.h>
+ static const struct kiocb *kiocb;
+ static struct address_space *mapping;
+ static struct folio *foliop;
+ static void *fsdata;
+ static struct address_space_operations *aops;]],
+ [[aops->write_begin(kiocb, mapping, 0, 0, &foliop, fsdata);
+ aops->write_end(kiocb, mapping, 0, 0, 0, foliop, fsdata);]])
+
dnl Consequences - things which get set as a result of the
dnl above tests
AS_IF([test "x$ac_cv_linux_func_d_alloc_anon" = "xno"],
|