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
128
129
130
131
|
From 1be318fe828a8df4b74f5f696d524dcdb94a133f Mon Sep 17 00:00:00 2001
From: Cheyenne Wills <cwills@sinenomine.net>
Date: Thu, 2 Oct 2025 10:15:27 -0600
Subject: [PATCH] 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.
Change-Id: I53878ca8f671d05e318e783895d9e2fa280ac359
---
src/afs/LINUX/osi_vnodeops.c | 28 ++++++++++++++++++++++++----
src/cf/linux-kernel-func.m4 | 12 ++++++++++++
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
index 9508b11d2..a776355a6 100644
--- a/src/afs/LINUX/osi_vnodeops.c
+++ b/src/afs/LINUX/osi_vnodeops.c
@@ -3794,15 +3794,25 @@ afs_linux_prepare_write(struct file *file, struct page *page, unsigned from,
return 0;
}
-#if defined(HAVE_LINUX_WRITE_BEGIN_END_FOLIO)
+#if defined(HAVE_LINUX_WRITE_BEGIN_END_KIOCB) || 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);
@@ -3811,16 +3821,26 @@ afs_linux_write_end(struct file *file, struct address_space *mapping,
return code;
}
-# if defined(HAVE_LINUX_FILEMAP_GET_FOLIO)
+# if defined(HAVE_LINUX_WRITE_BEGIN_END_KIOCB) || 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)) {
@@ -3864,7 +3884,7 @@ afs_linux_write_begin(struct file *file, struct address_space *mapping,
return code;
}
-# endif /* HAVE_LINUX_FILEMAP_GET_FOLIO */
+# endif /* HAVE_LINUX_WRITE_BEGIN_END_KIOCB || HAVE_LINUX_FILEMAP_GET_FOLIO */
#elif defined(STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_WRITE_BEGIN)
@@ -3919,7 +3939,7 @@ afs_linux_write_begin(struct file *file, struct address_space *mapping,
return code;
}
-#endif /* HAVE_LINUX_WRITE_BEGIN_END_FOLIO */
+#endif /* HAVE_LINUX_WRITE_BEGIN_END_KIOCB || HAVE_LINUX_WRITE_BEGIN_END_FOLIO */
#ifndef STRUCT_DENTRY_OPERATIONS_HAS_D_AUTOMOUNT
static void *
diff --git a/src/cf/linux-kernel-func.m4 b/src/cf/linux-kernel-func.m4
index 175db00ea..135b67e81 100644
--- a/src/cf/linux-kernel-func.m4
+++ b/src/cf/linux-kernel-func.m4
@@ -336,6 +336,18 @@ AC_CHECK_LINUX_FUNC([write_begin_end_folio],
[[aops->write_begin(file, mapping, 0, 0, &foliop, fsdata);
aops->write_end(file, mapping, 0, 0, 0, foliop, fsdata);]])
+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>
+ const static 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 Linux 5.16 added folio_wait_locked and updated wait_on_page_locked to be
dnl just a wrapper for folio_wait_locked. Linux 6.15 removed wait_on_paged_locked
AC_CHECK_LINUX_FUNC([folio_wait_locked],
--
2.51.0
|