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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
From 2415e6b43fc7abfff6765c9c1cd5ff63c44a8a0c Mon Sep 17 00:00:00 2001
From: Cheyenne Wills <cwills@sinenomine.net>
Date: Thu, 31 Jul 2025 10:20:13 -0600
Subject: [PATCH 13/18] linux: refactor afs_linux_writepage
In preparation for a future commit, refactor afs_linux_writepage() by
moving the code that handles locking/obtaining the credential structure,
and unlocking the vcache/releasing the credential structure into their
own functions, afs_linux_begin_writeback() and afs_linux_end_writeback().
As a precaution, set the pointer to the creds to NULL after freeing it.
There are no functional changes other than setting *acredp = NULL after
the free.
Reviewed-on: https://gerrit.openafs.org/16436
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
(cherry picked from commit eb0bd53b8d03d764861a45cf91faeecda415f5d7)
Change-Id: I7b78fd3d37c3fb53ca03f27c7dbc360f69c24a20
Reviewed-on: https://gerrit.openafs.org/16499
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
(cherry picked from commit 691e90fa1c58d9afb2e26fe6b9022329364ac048)
---
src/afs/LINUX/osi_vnodeops.c | 88 +++++++++++++++++++++++-------------
1 file changed, 57 insertions(+), 31 deletions(-)
diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
index 070a2ca75..d36fbbe66 100644
--- a/src/afs/LINUX/osi_vnodeops.c
+++ b/src/afs/LINUX/osi_vnodeops.c
@@ -3417,6 +3417,60 @@ afs_linux_writepage_sync(struct inode *ip, struct page *pp,
return code;
}
+static int
+afs_linux_begin_writeback(struct vcache *vcp, cred_t **acredp)
+{
+ int code;
+
+ AFS_GLOCK();
+ ObtainWriteLock(&vcp->lock, 537);
+ code = afs_linux_prepare_writeback(vcp);
+ if (code == AOP_WRITEPAGE_ACTIVATE) {
+ goto done;
+ }
+
+ /* Grab the creds structure currently held in the vnode, and
+ * get a reference to it, in case it goes away ... */
+ *acredp = vcp->cred;
+ if (*acredp != NULL) {
+ crhold(*acredp);
+ } else {
+ *acredp = crref();
+ }
+
+ done:
+ ReleaseWriteLock(&vcp->lock);
+ AFS_GUNLOCK();
+ return code;
+}
+
+static int
+afs_linux_end_writeback(struct vcache *vcp, cred_t **acredp, int written_size, unsigned int requested_size)
+{
+ int code;
+
+ AFS_GLOCK();
+ ObtainWriteLock(&vcp->lock, 538);
+
+ /* As much as we might like to ignore a file server error here,
+ * and just try again when we close(), unfortunately StoreAllSegments
+ * will invalidate our chunks if the server returns a permanent error,
+ * so we need to at least try and get that error back to the user
+ */
+ if (written_size == requested_size) {
+ code = afs_linux_dopartialwrite(vcp, *acredp);
+ } else {
+ code = 0;
+ }
+
+ afs_linux_complete_writeback(vcp);
+ ReleaseWriteLock(&vcp->lock);
+ crfree(*acredp);
+ *acredp = NULL;
+ AFS_GUNLOCK();
+ return code;
+}
+
static int
#ifdef AOP_WRITEPAGE_TAKES_WRITEBACK_CONTROL
afs_linux_writepage(struct page *pp, struct writeback_control *wbc)
@@ -3427,7 +3481,7 @@ afs_linux_writepage(struct page *pp)
struct address_space *mapping = pp->mapping;
struct inode *inode;
struct vcache *vcp;
- cred_t *credp;
+ cred_t *credp = NULL;
unsigned int to = PAGE_SIZE;
loff_t isize;
int code = 0;
@@ -3446,27 +3500,13 @@ afs_linux_writepage(struct page *pp)
goto done;
}
- AFS_GLOCK();
- ObtainWriteLock(&vcp->lock, 537);
- code = afs_linux_prepare_writeback(vcp);
+ code = afs_linux_begin_writeback(vcp, &credp);
if (code == AOP_WRITEPAGE_ACTIVATE) {
/* WRITEPAGE_ACTIVATE is the only return value that permits us
* to return with the page still locked */
- ReleaseWriteLock(&vcp->lock);
- AFS_GUNLOCK();
return code;
}
- /* Grab the creds structure currently held in the vnode, and
- * get a reference to it, in case it goes away ... */
- credp = vcp->cred;
- if (credp)
- crhold(credp);
- else
- credp = crref();
- ReleaseWriteLock(&vcp->lock);
- AFS_GUNLOCK();
-
set_page_writeback(pp);
SetPageUptodate(pp);
@@ -3484,21 +3524,7 @@ afs_linux_writepage(struct page *pp)
code = afs_linux_page_writeback(inode, pp, 0, to, credp);
- AFS_GLOCK();
- ObtainWriteLock(&vcp->lock, 538);
-
- /* As much as we might like to ignore a file server error here,
- * and just try again when we close(), unfortunately StoreAllSegments
- * will invalidate our chunks if the server returns a permanent error,
- * so we need to at least try and get that error back to the user
- */
- if (code == to)
- code1 = afs_linux_dopartialwrite(vcp, credp);
-
- afs_linux_complete_writeback(vcp);
- ReleaseWriteLock(&vcp->lock);
- crfree(credp);
- AFS_GUNLOCK();
+ code1 = afs_linux_end_writeback(vcp, &credp, code, to);
done:
end_page_writeback(pp);
--
2.51.0
|