summarylogtreecommitdiffstats
path: root/0001-Linux-Use-struct-kiocb-for-aops-write_begin-end.patch
blob: f0228615f7e6254d1208841624c10dd693beb230 (plain)
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