summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-15 13:48:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-15 13:48:36 -0400
commit21b9f1c7e319f654de3b2574fe8d4e4114c9143f (patch)
tree7017dda7a6a811a59504f39d58eb65cbbbaffacd /fs
parenteeba2dfa6a0d1cf40056e3a00ec21206c640eeca (diff)
parent4776cab43fd3111618112737a257dc3ef368eddd (diff)
Merge tag 'afs-fixes-20180514' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull AFS fixes from David Howells: "Here's a set of patches that fix a number of bugs in the in-kernel AFS client, including: - Fix directory locking to not use individual page locks for directory reading/scanning but rather to use a semaphore on the afs_vnode struct as the directory contents must be read in a single blob and data from different reads must not be mixed as the entire contents may be shuffled about between reads. - Fix address list parsing to handle port specifiers correctly. - Only give up callback records on a server if we actually talked to that server (we might not be able to access a server). - Fix some callback handling bugs, including refcounting, whole-volume callbacks and when callbacks actually get broken in response to a CB.CallBack op. - Fix some server/address rotation bugs, including giving up if we can't probe a server; giving up if a server says it doesn't have a volume, but there are more servers to try. - Fix the decoding of fetched statuses to be OpenAFS compatible. - Fix the handling of server lookups in Cache Manager ops (such as CB.InitCallBackState3) to use a UUID if possible and to handle no server being found. - Fix a bug in server lookup where not all addresses are compared. - Fix the non-encryption of calls that prevents some servers from being accessed (this also requires an AF_RXRPC patch that has already gone in through the net tree). There's also a patch that adds tracepoints to log Cache Manager ops that don't find a matching server, either by UUID or by address" * tag 'afs-fixes-20180514' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: afs: Fix the non-encryption of calls afs: Fix CB.CallBack handling afs: Fix whole-volume callback handling afs: Fix afs_find_server search loop afs: Fix the handling of an unfound server in CM operations afs: Add a tracepoint to record callbacks from unlisted servers afs: Fix the handling of CB.InitCallBackState3 to find the server by UUID afs: Fix VNOVOL handling in address rotation afs: Fix AFSFetchStatus decoder to provide OpenAFS compatibility afs: Fix server rotation's handling of fileserver probe failure afs: Fix refcounting in callback registration afs: Fix giving up callbacks on server destruction afs: Fix address list parsing afs: Fix directory page locking
Diffstat (limited to 'fs')
-rw-r--r--fs/afs/addr_list.c25
-rw-r--r--fs/afs/callback.c84
-rw-r--r--fs/afs/cmservice.c67
-rw-r--r--fs/afs/dir.c54
-rw-r--r--fs/afs/file.c2
-rw-r--r--fs/afs/flock.c6
-rw-r--r--fs/afs/fsclient.c31
-rw-r--r--fs/afs/inode.c19
-rw-r--r--fs/afs/internal.h25
-rw-r--r--fs/afs/rotate.c20
-rw-r--r--fs/afs/rxrpc.c18
-rw-r--r--fs/afs/security.c7
-rw-r--r--fs/afs/server.c21
-rw-r--r--fs/afs/server_list.c7
-rw-r--r--fs/afs/super.c4
-rw-r--r--fs/afs/write.c2
16 files changed, 224 insertions, 168 deletions
diff --git a/fs/afs/addr_list.c b/fs/afs/addr_list.c
index 3bedfed608a2..7587fb665ff1 100644
--- a/fs/afs/addr_list.c
+++ b/fs/afs/addr_list.c
@@ -121,7 +121,7 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len,
121 p = text; 121 p = text;
122 do { 122 do {
123 struct sockaddr_rxrpc *srx = &alist->addrs[alist->nr_addrs]; 123 struct sockaddr_rxrpc *srx = &alist->addrs[alist->nr_addrs];
124 char tdelim = delim; 124 const char *q, *stop;
125 125
126 if (*p == delim) { 126 if (*p == delim) {
127 p++; 127 p++;
@@ -130,28 +130,33 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len,
130 130
131 if (*p == '[') { 131 if (*p == '[') {
132 p++; 132 p++;
133 tdelim = ']'; 133 q = memchr(p, ']', end - p);
134 } else {
135 for (q = p; q < end; q++)
136 if (*q == '+' || *q == delim)
137 break;
134 } 138 }
135 139
136 if (in4_pton(p, end - p, 140 if (in4_pton(p, q - p,
137 (u8 *)&srx->transport.sin6.sin6_addr.s6_addr32[3], 141 (u8 *)&srx->transport.sin6.sin6_addr.s6_addr32[3],
138 tdelim, &p)) { 142 -1, &stop)) {
139 srx->transport.sin6.sin6_addr.s6_addr32[0] = 0; 143 srx->transport.sin6.sin6_addr.s6_addr32[0] = 0;
140 srx->transport.sin6.sin6_addr.s6_addr32[1] = 0; 144 srx->transport.sin6.sin6_addr.s6_addr32[1] = 0;
141 srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); 145 srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff);
142 } else if (in6_pton(p, end - p, 146 } else if (in6_pton(p, q - p,
143 srx->transport.sin6.sin6_addr.s6_addr, 147 srx->transport.sin6.sin6_addr.s6_addr,
144 tdelim, &p)) { 148 -1, &stop)) {
145 /* Nothing to do */ 149 /* Nothing to do */
146 } else { 150 } else {
147 goto bad_address; 151 goto bad_address;
148 } 152 }
149 153
150 if (tdelim == ']') { 154 if (stop != q)
151 if (p == end || *p != ']') 155 goto bad_address;
152 goto bad_address; 156
157 p = q;
158 if (q < end && *q == ']')
153 p++; 159 p++;
154 }
155 160
156 if (p < end) { 161 if (p < end) {
157 if (*p == '+') { 162 if (*p == '+') {
diff --git a/fs/afs/callback.c b/fs/afs/callback.c
index abd9a84f4e88..571437dcb252 100644
--- a/fs/afs/callback.c
+++ b/fs/afs/callback.c
@@ -23,36 +23,55 @@
23/* 23/*
24 * Set up an interest-in-callbacks record for a volume on a server and 24 * Set up an interest-in-callbacks record for a volume on a server and
25 * register it with the server. 25 * register it with the server.
26 * - Called with volume->server_sem held. 26 * - Called with vnode->io_lock held.
27 */ 27 */
28int afs_register_server_cb_interest(struct afs_vnode *vnode, 28int afs_register_server_cb_interest(struct afs_vnode *vnode,
29 struct afs_server_entry *entry) 29 struct afs_server_list *slist,
30 unsigned int index)
30{ 31{
31 struct afs_cb_interest *cbi = entry->cb_interest, *vcbi, *new, *x; 32 struct afs_server_entry *entry = &slist->servers[index];
33 struct afs_cb_interest *cbi, *vcbi, *new, *old;
32 struct afs_server *server = entry->server; 34 struct afs_server *server = entry->server;
33 35
34again: 36again:
37 if (vnode->cb_interest &&
38 likely(vnode->cb_interest == entry->cb_interest))
39 return 0;
40
41 read_lock(&slist->lock);
42 cbi = afs_get_cb_interest(entry->cb_interest);
43 read_unlock(&slist->lock);
44
35 vcbi = vnode->cb_interest; 45 vcbi = vnode->cb_interest;
36 if (vcbi) { 46 if (vcbi) {
37 if (vcbi == cbi) 47 if (vcbi == cbi) {
48 afs_put_cb_interest(afs_v2net(vnode), cbi);
38 return 0; 49 return 0;
50 }
39 51
52 /* Use a new interest in the server list for the same server
53 * rather than an old one that's still attached to a vnode.
54 */
40 if (cbi && vcbi->server == cbi->server) { 55 if (cbi && vcbi->server == cbi->server) {
41 write_seqlock(&vnode->cb_lock); 56 write_seqlock(&vnode->cb_lock);
42 vnode->cb_interest = afs_get_cb_interest(cbi); 57 old = vnode->cb_interest;
58 vnode->cb_interest = cbi;
43 write_sequnlock(&vnode->cb_lock); 59 write_sequnlock(&vnode->cb_lock);
44 afs_put_cb_interest(afs_v2net(vnode), cbi); 60 afs_put_cb_interest(afs_v2net(vnode), old);
45 return 0; 61 return 0;
46 } 62 }
47 63
64 /* Re-use the one attached to the vnode. */
48 if (!cbi && vcbi->server == server) { 65 if (!cbi && vcbi->server == server) {
49 afs_get_cb_interest(vcbi); 66 write_lock(&slist->lock);
50 x = cmpxchg(&entry->cb_interest, cbi, vcbi); 67 if (entry->cb_interest) {
51 if (x != cbi) { 68 write_unlock(&slist->lock);
52 cbi = x; 69 afs_put_cb_interest(afs_v2net(vnode), cbi);
53 afs_put_cb_interest(afs_v2net(vnode), vcbi);
54 goto again; 70 goto again;
55 } 71 }
72
73 entry->cb_interest = cbi;
74 write_unlock(&slist->lock);
56 return 0; 75 return 0;
57 } 76 }
58 } 77 }
@@ -72,13 +91,16 @@ again:
72 list_add_tail(&new->cb_link, &server->cb_interests); 91 list_add_tail(&new->cb_link, &server->cb_interests);
73 write_unlock(&server->cb_break_lock); 92 write_unlock(&server->cb_break_lock);
74 93
75 x = cmpxchg(&entry->cb_interest, cbi, new); 94 write_lock(&slist->lock);
76 if (x == cbi) { 95 if (!entry->cb_interest) {
96 entry->cb_interest = afs_get_cb_interest(new);
77 cbi = new; 97 cbi = new;
98 new = NULL;
78 } else { 99 } else {
79 cbi = x; 100 cbi = afs_get_cb_interest(entry->cb_interest);
80 afs_put_cb_interest(afs_v2net(vnode), new);
81 } 101 }
102 write_unlock(&slist->lock);
103 afs_put_cb_interest(afs_v2net(vnode), new);
82 } 104 }
83 105
84 ASSERT(cbi); 106 ASSERT(cbi);
@@ -88,11 +110,14 @@ again:
88 */ 110 */
89 write_seqlock(&vnode->cb_lock); 111 write_seqlock(&vnode->cb_lock);
90 112
91 vnode->cb_interest = afs_get_cb_interest(cbi); 113 old = vnode->cb_interest;
114 vnode->cb_interest = cbi;
92 vnode->cb_s_break = cbi->server->cb_s_break; 115 vnode->cb_s_break = cbi->server->cb_s_break;
116 vnode->cb_v_break = vnode->volume->cb_v_break;
93 clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 117 clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
94 118
95 write_sequnlock(&vnode->cb_lock); 119 write_sequnlock(&vnode->cb_lock);
120 afs_put_cb_interest(afs_v2net(vnode), old);
96 return 0; 121 return 0;
97} 122}
98 123
@@ -171,13 +196,24 @@ static void afs_break_one_callback(struct afs_server *server,
171 if (cbi->vid != fid->vid) 196 if (cbi->vid != fid->vid)
172 continue; 197 continue;
173 198
174 data.volume = NULL; 199 if (fid->vnode == 0 && fid->unique == 0) {
175 data.fid = *fid; 200 /* The callback break applies to an entire volume. */
176 inode = ilookup5_nowait(cbi->sb, fid->vnode, afs_iget5_test, &data); 201 struct afs_super_info *as = AFS_FS_S(cbi->sb);
177 if (inode) { 202 struct afs_volume *volume = as->volume;
178 vnode = AFS_FS_I(inode); 203
179 afs_break_callback(vnode); 204 write_lock(&volume->cb_break_lock);
180 iput(inode); 205 volume->cb_v_break++;
206 write_unlock(&volume->cb_break_lock);
207 } else {
208 data.volume = NULL;
209 data.fid = *fid;
210 inode = ilookup5_nowait(cbi->sb, fid->vnode,
211 afs_iget5_test, &data);
212 if (inode) {
213 vnode = AFS_FS_I(inode);
214 afs_break_callback(vnode);
215 iput(inode);
216 }
181 } 217 }
182 } 218 }
183 219
@@ -195,6 +231,8 @@ void afs_break_callbacks(struct afs_server *server, size_t count,
195 ASSERT(server != NULL); 231 ASSERT(server != NULL);
196 ASSERTCMP(count, <=, AFSCBMAX); 232 ASSERTCMP(count, <=, AFSCBMAX);
197 233
234 /* TODO: Sort the callback break list by volume ID */
235
198 for (; count > 0; callbacks++, count--) { 236 for (; count > 0; callbacks++, count--) {
199 _debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }", 237 _debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }",
200 callbacks->fid.vid, 238 callbacks->fid.vid,
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index 357de908df3a..c332c95a6940 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -133,21 +133,10 @@ bool afs_cm_incoming_call(struct afs_call *call)
133} 133}
134 134
135/* 135/*
136 * clean up a cache manager call 136 * Clean up a cache manager call.
137 */ 137 */
138static void afs_cm_destructor(struct afs_call *call) 138static void afs_cm_destructor(struct afs_call *call)
139{ 139{
140 _enter("");
141
142 /* Break the callbacks here so that we do it after the final ACK is
143 * received. The step number here must match the final number in
144 * afs_deliver_cb_callback().
145 */
146 if (call->unmarshall == 5) {
147 ASSERT(call->cm_server && call->count && call->request);
148 afs_break_callbacks(call->cm_server, call->count, call->request);
149 }
150
151 kfree(call->buffer); 140 kfree(call->buffer);
152 call->buffer = NULL; 141 call->buffer = NULL;
153} 142}
@@ -161,14 +150,14 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
161 150
162 _enter(""); 151 _enter("");
163 152
164 /* be sure to send the reply *before* attempting to spam the AFS server 153 /* We need to break the callbacks before sending the reply as the
165 * with FSFetchStatus requests on the vnodes with broken callbacks lest 154 * server holds up change visibility till it receives our reply so as
166 * the AFS server get into a vicious cycle of trying to break further 155 * to maintain cache coherency.
167 * callbacks because it hadn't received completion of the CBCallBack op 156 */
168 * yet */ 157 if (call->cm_server)
169 afs_send_empty_reply(call); 158 afs_break_callbacks(call->cm_server, call->count, call->request);
170 159
171 afs_break_callbacks(call->cm_server, call->count, call->request); 160 afs_send_empty_reply(call);
172 afs_put_call(call); 161 afs_put_call(call);
173 _leave(""); 162 _leave("");
174} 163}
@@ -180,7 +169,6 @@ static int afs_deliver_cb_callback(struct afs_call *call)
180{ 169{
181 struct afs_callback_break *cb; 170 struct afs_callback_break *cb;
182 struct sockaddr_rxrpc srx; 171 struct sockaddr_rxrpc srx;
183 struct afs_server *server;
184 __be32 *bp; 172 __be32 *bp;
185 int ret, loop; 173 int ret, loop;
186 174
@@ -267,15 +255,6 @@ static int afs_deliver_cb_callback(struct afs_call *call)
267 255
268 call->offset = 0; 256 call->offset = 0;
269 call->unmarshall++; 257 call->unmarshall++;
270
271 /* Record that the message was unmarshalled successfully so
272 * that the call destructor can know do the callback breaking
273 * work, even if the final ACK isn't received.
274 *
275 * If the step number changes, then afs_cm_destructor() must be
276 * updated also.
277 */
278 call->unmarshall++;
279 case 5: 258 case 5:
280 break; 259 break;
281 } 260 }
@@ -286,10 +265,9 @@ static int afs_deliver_cb_callback(struct afs_call *call)
286 /* we'll need the file server record as that tells us which set of 265 /* we'll need the file server record as that tells us which set of
287 * vnodes to operate upon */ 266 * vnodes to operate upon */
288 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); 267 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
289 server = afs_find_server(call->net, &srx); 268 call->cm_server = afs_find_server(call->net, &srx);
290 if (!server) 269 if (!call->cm_server)
291 return -ENOTCONN; 270 trace_afs_cm_no_server(call, &srx);
292 call->cm_server = server;
293 271
294 return afs_queue_call_work(call); 272 return afs_queue_call_work(call);
295} 273}
@@ -303,7 +281,8 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
303 281
304 _enter("{%p}", call->cm_server); 282 _enter("{%p}", call->cm_server);
305 283
306 afs_init_callback_state(call->cm_server); 284 if (call->cm_server)
285 afs_init_callback_state(call->cm_server);
307 afs_send_empty_reply(call); 286 afs_send_empty_reply(call);
308 afs_put_call(call); 287 afs_put_call(call);
309 _leave(""); 288 _leave("");
@@ -315,7 +294,6 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
315static int afs_deliver_cb_init_call_back_state(struct afs_call *call) 294static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
316{ 295{
317 struct sockaddr_rxrpc srx; 296 struct sockaddr_rxrpc srx;
318 struct afs_server *server;
319 int ret; 297 int ret;
320 298
321 _enter(""); 299 _enter("");
@@ -328,10 +306,9 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
328 306
329 /* we'll need the file server record as that tells us which set of 307 /* we'll need the file server record as that tells us which set of
330 * vnodes to operate upon */ 308 * vnodes to operate upon */
331 server = afs_find_server(call->net, &srx); 309 call->cm_server = afs_find_server(call->net, &srx);
332 if (!server) 310 if (!call->cm_server)
333 return -ENOTCONN; 311 trace_afs_cm_no_server(call, &srx);
334 call->cm_server = server;
335 312
336 return afs_queue_call_work(call); 313 return afs_queue_call_work(call);
337} 314}
@@ -341,8 +318,6 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
341 */ 318 */
342static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) 319static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
343{ 320{
344 struct sockaddr_rxrpc srx;
345 struct afs_server *server;
346 struct afs_uuid *r; 321 struct afs_uuid *r;
347 unsigned loop; 322 unsigned loop;
348 __be32 *b; 323 __be32 *b;
@@ -398,11 +373,11 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
398 373
399 /* we'll need the file server record as that tells us which set of 374 /* we'll need the file server record as that tells us which set of
400 * vnodes to operate upon */ 375 * vnodes to operate upon */
401 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); 376 rcu_read_lock();
402 server = afs_find_server(call->net, &srx); 377 call->cm_server = afs_find_server_by_uuid(call->net, call->request);
403 if (!server) 378 rcu_read_unlock();
404 return -ENOTCONN; 379 if (!call->cm_server)
405 call->cm_server = server; 380 trace_afs_cm_no_server_u(call, call->request);
406 381
407 return afs_queue_call_work(call); 382 return afs_queue_call_work(call);
408} 383}
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 5889f70d4d27..7d623008157f 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -180,6 +180,7 @@ static int afs_dir_open(struct inode *inode, struct file *file)
180 * get reclaimed during the iteration. 180 * get reclaimed during the iteration.
181 */ 181 */
182static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key) 182static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
183 __acquires(&dvnode->validate_lock)
183{ 184{
184 struct afs_read *req; 185 struct afs_read *req;
185 loff_t i_size; 186 loff_t i_size;
@@ -261,18 +262,21 @@ retry:
261 /* If we're going to reload, we need to lock all the pages to prevent 262 /* If we're going to reload, we need to lock all the pages to prevent
262 * races. 263 * races.
263 */ 264 */
264 if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) { 265 ret = -ERESTARTSYS;
265 ret = -ERESTARTSYS; 266 if (down_read_killable(&dvnode->validate_lock) < 0)
266 for (i = 0; i < req->nr_pages; i++) 267 goto error;
267 if (lock_page_killable(req->pages[i]) < 0)
268 goto error_unlock;
269 268
270 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 269 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
271 goto success; 270 goto success;
271
272 up_read(&dvnode->validate_lock);
273 if (down_write_killable(&dvnode->validate_lock) < 0)
274 goto error;
272 275
276 if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) {
273 ret = afs_fetch_data(dvnode, key, req); 277 ret = afs_fetch_data(dvnode, key, req);
274 if (ret < 0) 278 if (ret < 0)
275 goto error_unlock_all; 279 goto error_unlock;
276 280
277 task_io_account_read(PAGE_SIZE * req->nr_pages); 281 task_io_account_read(PAGE_SIZE * req->nr_pages);
278 282
@@ -284,33 +288,26 @@ retry:
284 for (i = 0; i < req->nr_pages; i++) 288 for (i = 0; i < req->nr_pages; i++)
285 if (!afs_dir_check_page(dvnode, req->pages[i], 289 if (!afs_dir_check_page(dvnode, req->pages[i],
286 req->actual_len)) 290 req->actual_len))
287 goto error_unlock_all; 291 goto error_unlock;
288 292
289 // TODO: Trim excess pages 293 // TODO: Trim excess pages
290 294
291 set_bit(AFS_VNODE_DIR_VALID, &dvnode->flags); 295 set_bit(AFS_VNODE_DIR_VALID, &dvnode->flags);
292 } 296 }
293 297
298 downgrade_write(&dvnode->validate_lock);
294success: 299success:
295 i = req->nr_pages;
296 while (i > 0)
297 unlock_page(req->pages[--i]);
298 return req; 300 return req;
299 301
300error_unlock_all:
301 i = req->nr_pages;
302error_unlock: 302error_unlock:
303 while (i > 0) 303 up_write(&dvnode->validate_lock);
304 unlock_page(req->pages[--i]);
305error: 304error:
306 afs_put_read(req); 305 afs_put_read(req);
307 _leave(" = %d", ret); 306 _leave(" = %d", ret);
308 return ERR_PTR(ret); 307 return ERR_PTR(ret);
309 308
310content_has_grown: 309content_has_grown:
311 i = req->nr_pages; 310 up_write(&dvnode->validate_lock);
312 while (i > 0)
313 unlock_page(req->pages[--i]);
314 afs_put_read(req); 311 afs_put_read(req);
315 goto retry; 312 goto retry;
316} 313}
@@ -473,6 +470,7 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
473 } 470 }
474 471
475out: 472out:
473 up_read(&dvnode->validate_lock);
476 afs_put_read(req); 474 afs_put_read(req);
477 _leave(" = %d", ret); 475 _leave(" = %d", ret);
478 return ret; 476 return ret;
@@ -1143,7 +1141,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1143 ret = -ERESTARTSYS; 1141 ret = -ERESTARTSYS;
1144 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1142 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1145 while (afs_select_fileserver(&fc)) { 1143 while (afs_select_fileserver(&fc)) {
1146 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1144 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1147 afs_fs_create(&fc, dentry->d_name.name, mode, data_version, 1145 afs_fs_create(&fc, dentry->d_name.name, mode, data_version,
1148 &newfid, &newstatus, &newcb); 1146 &newfid, &newstatus, &newcb);
1149 } 1147 }
@@ -1213,7 +1211,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
1213 ret = -ERESTARTSYS; 1211 ret = -ERESTARTSYS;
1214 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1212 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1215 while (afs_select_fileserver(&fc)) { 1213 while (afs_select_fileserver(&fc)) {
1216 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1214 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1217 afs_fs_remove(&fc, dentry->d_name.name, true, 1215 afs_fs_remove(&fc, dentry->d_name.name, true,
1218 data_version); 1216 data_version);
1219 } 1217 }
@@ -1316,7 +1314,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
1316 ret = -ERESTARTSYS; 1314 ret = -ERESTARTSYS;
1317 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1315 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1318 while (afs_select_fileserver(&fc)) { 1316 while (afs_select_fileserver(&fc)) {
1319 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1317 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1320 afs_fs_remove(&fc, dentry->d_name.name, false, 1318 afs_fs_remove(&fc, dentry->d_name.name, false,
1321 data_version); 1319 data_version);
1322 } 1320 }
@@ -1373,7 +1371,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
1373 ret = -ERESTARTSYS; 1371 ret = -ERESTARTSYS;
1374 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1372 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1375 while (afs_select_fileserver(&fc)) { 1373 while (afs_select_fileserver(&fc)) {
1376 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1374 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1377 afs_fs_create(&fc, dentry->d_name.name, mode, data_version, 1375 afs_fs_create(&fc, dentry->d_name.name, mode, data_version,
1378 &newfid, &newstatus, &newcb); 1376 &newfid, &newstatus, &newcb);
1379 } 1377 }
@@ -1443,8 +1441,8 @@ static int afs_link(struct dentry *from, struct inode *dir,
1443 } 1441 }
1444 1442
1445 while (afs_select_fileserver(&fc)) { 1443 while (afs_select_fileserver(&fc)) {
1446 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1444 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1447 fc.cb_break_2 = vnode->cb_break + vnode->cb_s_break; 1445 fc.cb_break_2 = afs_calc_vnode_cb_break(vnode);
1448 afs_fs_link(&fc, vnode, dentry->d_name.name, data_version); 1446 afs_fs_link(&fc, vnode, dentry->d_name.name, data_version);
1449 } 1447 }
1450 1448
@@ -1512,7 +1510,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
1512 ret = -ERESTARTSYS; 1510 ret = -ERESTARTSYS;
1513 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1511 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1514 while (afs_select_fileserver(&fc)) { 1512 while (afs_select_fileserver(&fc)) {
1515 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1513 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1516 afs_fs_symlink(&fc, dentry->d_name.name, 1514 afs_fs_symlink(&fc, dentry->d_name.name,
1517 content, data_version, 1515 content, data_version,
1518 &newfid, &newstatus); 1516 &newfid, &newstatus);
@@ -1588,8 +1586,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1588 } 1586 }
1589 } 1587 }
1590 while (afs_select_fileserver(&fc)) { 1588 while (afs_select_fileserver(&fc)) {
1591 fc.cb_break = orig_dvnode->cb_break + orig_dvnode->cb_s_break; 1589 fc.cb_break = afs_calc_vnode_cb_break(orig_dvnode);
1592 fc.cb_break_2 = new_dvnode->cb_break + new_dvnode->cb_s_break; 1590 fc.cb_break_2 = afs_calc_vnode_cb_break(new_dvnode);
1593 afs_fs_rename(&fc, old_dentry->d_name.name, 1591 afs_fs_rename(&fc, old_dentry->d_name.name,
1594 new_dvnode, new_dentry->d_name.name, 1592 new_dvnode, new_dentry->d_name.name,
1595 orig_data_version, new_data_version); 1593 orig_data_version, new_data_version);
diff --git a/fs/afs/file.c b/fs/afs/file.c
index c24c08016dd9..7d4f26198573 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -238,7 +238,7 @@ int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *de
238 ret = -ERESTARTSYS; 238 ret = -ERESTARTSYS;
239 if (afs_begin_vnode_operation(&fc, vnode, key)) { 239 if (afs_begin_vnode_operation(&fc, vnode, key)) {
240 while (afs_select_fileserver(&fc)) { 240 while (afs_select_fileserver(&fc)) {
241 fc.cb_break = vnode->cb_break + vnode->cb_s_break; 241 fc.cb_break = afs_calc_vnode_cb_break(vnode);
242 afs_fs_fetch_data(&fc, desc); 242 afs_fs_fetch_data(&fc, desc);
243 } 243 }
244 244
diff --git a/fs/afs/flock.c b/fs/afs/flock.c
index 7a0e017070ec..dc62d15a964b 100644
--- a/fs/afs/flock.c
+++ b/fs/afs/flock.c
@@ -86,7 +86,7 @@ static int afs_set_lock(struct afs_vnode *vnode, struct key *key,
86 ret = -ERESTARTSYS; 86 ret = -ERESTARTSYS;
87 if (afs_begin_vnode_operation(&fc, vnode, key)) { 87 if (afs_begin_vnode_operation(&fc, vnode, key)) {
88 while (afs_select_fileserver(&fc)) { 88 while (afs_select_fileserver(&fc)) {
89 fc.cb_break = vnode->cb_break + vnode->cb_s_break; 89 fc.cb_break = afs_calc_vnode_cb_break(vnode);
90 afs_fs_set_lock(&fc, type); 90 afs_fs_set_lock(&fc, type);
91 } 91 }
92 92
@@ -117,7 +117,7 @@ static int afs_extend_lock(struct afs_vnode *vnode, struct key *key)
117 ret = -ERESTARTSYS; 117 ret = -ERESTARTSYS;
118 if (afs_begin_vnode_operation(&fc, vnode, key)) { 118 if (afs_begin_vnode_operation(&fc, vnode, key)) {
119 while (afs_select_current_fileserver(&fc)) { 119 while (afs_select_current_fileserver(&fc)) {
120 fc.cb_break = vnode->cb_break + vnode->cb_s_break; 120 fc.cb_break = afs_calc_vnode_cb_break(vnode);
121 afs_fs_extend_lock(&fc); 121 afs_fs_extend_lock(&fc);
122 } 122 }
123 123
@@ -148,7 +148,7 @@ static int afs_release_lock(struct afs_vnode *vnode, struct key *key)
148 ret = -ERESTARTSYS; 148 ret = -ERESTARTSYS;
149 if (afs_begin_vnode_operation(&fc, vnode, key)) { 149 if (afs_begin_vnode_operation(&fc, vnode, key)) {
150 while (afs_select_current_fileserver(&fc)) { 150 while (afs_select_current_fileserver(&fc)) {
151 fc.cb_break = vnode->cb_break + vnode->cb_s_break; 151 fc.cb_break = afs_calc_vnode_cb_break(vnode);
152 afs_fs_release_lock(&fc); 152 afs_fs_release_lock(&fc);
153 } 153 }
154 154
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index efacdb7c1dee..b273e1d60478 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -134,6 +134,7 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call,
134 struct afs_read *read_req) 134 struct afs_read *read_req)
135{ 135{
136 const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp; 136 const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;
137 bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus);
137 u64 data_version, size; 138 u64 data_version, size;
138 u32 type, abort_code; 139 u32 type, abort_code;
139 u8 flags = 0; 140 u8 flags = 0;
@@ -142,13 +143,32 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call,
142 if (vnode) 143 if (vnode)
143 write_seqlock(&vnode->cb_lock); 144 write_seqlock(&vnode->cb_lock);
144 145
146 abort_code = ntohl(xdr->abort_code);
147
145 if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) { 148 if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) {
149 if (xdr->if_version == htonl(0) &&
150 abort_code != 0 &&
151 inline_error) {
152 /* The OpenAFS fileserver has a bug in FS.InlineBulkStatus
153 * whereby it doesn't set the interface version in the error
154 * case.
155 */
156 status->abort_code = abort_code;
157 ret = 0;
158 goto out;
159 }
160
146 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); 161 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
147 goto bad; 162 goto bad;
148 } 163 }
149 164
165 if (abort_code != 0 && inline_error) {
166 status->abort_code = abort_code;
167 ret = 0;
168 goto out;
169 }
170
150 type = ntohl(xdr->type); 171 type = ntohl(xdr->type);
151 abort_code = ntohl(xdr->abort_code);
152 switch (type) { 172 switch (type) {
153 case AFS_FTYPE_FILE: 173 case AFS_FTYPE_FILE:
154 case AFS_FTYPE_DIR: 174 case AFS_FTYPE_DIR:
@@ -165,13 +185,6 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call,
165 } 185 }
166 status->type = type; 186 status->type = type;
167 break; 187 break;
168 case AFS_FTYPE_INVALID:
169 if (abort_code != 0) {
170 status->abort_code = abort_code;
171 ret = 0;
172 goto out;
173 }
174 /* Fall through */
175 default: 188 default:
176 goto bad; 189 goto bad;
177 } 190 }
@@ -248,7 +261,7 @@ static void xdr_decode_AFSCallBack(struct afs_call *call,
248 261
249 write_seqlock(&vnode->cb_lock); 262 write_seqlock(&vnode->cb_lock);
250 263
251 if (call->cb_break == (vnode->cb_break + cbi->server->cb_s_break)) { 264 if (call->cb_break == afs_cb_break_sum(vnode, cbi)) {
252 vnode->cb_version = ntohl(*bp++); 265 vnode->cb_version = ntohl(*bp++);
253 cb_expiry = ntohl(*bp++); 266 cb_expiry = ntohl(*bp++);
254 vnode->cb_type = ntohl(*bp++); 267 vnode->cb_type = ntohl(*bp++);
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 06194cfe9724..479b7fdda124 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -108,7 +108,7 @@ int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool new_inode)
108 ret = -ERESTARTSYS; 108 ret = -ERESTARTSYS;
109 if (afs_begin_vnode_operation(&fc, vnode, key)) { 109 if (afs_begin_vnode_operation(&fc, vnode, key)) {
110 while (afs_select_fileserver(&fc)) { 110 while (afs_select_fileserver(&fc)) {
111 fc.cb_break = vnode->cb_break + vnode->cb_s_break; 111 fc.cb_break = afs_calc_vnode_cb_break(vnode);
112 afs_fs_fetch_file_status(&fc, NULL, new_inode); 112 afs_fs_fetch_file_status(&fc, NULL, new_inode);
113 } 113 }
114 114
@@ -393,15 +393,18 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
393 read_seqlock_excl(&vnode->cb_lock); 393 read_seqlock_excl(&vnode->cb_lock);
394 394
395 if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { 395 if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
396 if (vnode->cb_s_break != vnode->cb_interest->server->cb_s_break) { 396 if (vnode->cb_s_break != vnode->cb_interest->server->cb_s_break ||
397 vnode->cb_v_break != vnode->volume->cb_v_break) {
397 vnode->cb_s_break = vnode->cb_interest->server->cb_s_break; 398 vnode->cb_s_break = vnode->cb_interest->server->cb_s_break;
399 vnode->cb_v_break = vnode->volume->cb_v_break;
400 valid = false;
398 } else if (vnode->status.type == AFS_FTYPE_DIR && 401 } else if (vnode->status.type == AFS_FTYPE_DIR &&
399 test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) && 402 test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) &&
400 vnode->cb_expires_at - 10 > now) { 403 vnode->cb_expires_at - 10 > now) {
401 valid = true; 404 valid = true;
402 } else if (!test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) && 405 } else if (!test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) &&
403 vnode->cb_expires_at - 10 > now) { 406 vnode->cb_expires_at - 10 > now) {
404 valid = true; 407 valid = true;
405 } 408 }
406 } else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { 409 } else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
407 valid = true; 410 valid = true;
@@ -415,7 +418,7 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
415 if (valid) 418 if (valid)
416 goto valid; 419 goto valid;
417 420
418 mutex_lock(&vnode->validate_lock); 421 down_write(&vnode->validate_lock);
419 422
420 /* if the promise has expired, we need to check the server again to get 423 /* if the promise has expired, we need to check the server again to get
421 * a new promise - note that if the (parent) directory's metadata was 424 * a new promise - note that if the (parent) directory's metadata was
@@ -444,13 +447,13 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
444 * different */ 447 * different */
445 if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) 448 if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags))
446 afs_zap_data(vnode); 449 afs_zap_data(vnode);
447 mutex_unlock(&vnode->validate_lock); 450 up_write(&vnode->validate_lock);
448valid: 451valid:
449 _leave(" = 0"); 452 _leave(" = 0");
450 return 0; 453 return 0;
451 454
452error_unlock: 455error_unlock:
453 mutex_unlock(&vnode->validate_lock); 456 up_write(&vnode->validate_lock);
454 _leave(" = %d", ret); 457 _leave(" = %d", ret);
455 return ret; 458 return ret;
456} 459}
@@ -574,7 +577,7 @@ int afs_setattr(struct dentry *dentry, struct iattr *attr)
574 ret = -ERESTARTSYS; 577 ret = -ERESTARTSYS;
575 if (afs_begin_vnode_operation(&fc, vnode, key)) { 578 if (afs_begin_vnode_operation(&fc, vnode, key)) {
576 while (afs_select_fileserver(&fc)) { 579 while (afs_select_fileserver(&fc)) {
577 fc.cb_break = vnode->cb_break + vnode->cb_s_break; 580 fc.cb_break = afs_calc_vnode_cb_break(vnode);
578 afs_fs_setattr(&fc, attr); 581 afs_fs_setattr(&fc, attr);
579 } 582 }
580 583
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index f8086ec95e24..e3f8a46663db 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -396,6 +396,7 @@ struct afs_server {
396#define AFS_SERVER_FL_PROBED 5 /* The fileserver has been probed */ 396#define AFS_SERVER_FL_PROBED 5 /* The fileserver has been probed */
397#define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */ 397#define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */
398#define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */ 398#define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */
399#define AFS_SERVER_FL_MAY_HAVE_CB 8 /* May have callbacks on this fileserver */
399 atomic_t usage; 400 atomic_t usage;
400 u32 addr_version; /* Address list version */ 401 u32 addr_version; /* Address list version */
401 402
@@ -433,6 +434,7 @@ struct afs_server_list {
433 unsigned short index; /* Server currently in use */ 434 unsigned short index; /* Server currently in use */
434 unsigned short vnovol_mask; /* Servers to be skipped due to VNOVOL */ 435 unsigned short vnovol_mask; /* Servers to be skipped due to VNOVOL */
435 unsigned int seq; /* Set to ->servers_seq when installed */ 436 unsigned int seq; /* Set to ->servers_seq when installed */
437 rwlock_t lock;
436 struct afs_server_entry servers[]; 438 struct afs_server_entry servers[];
437}; 439};
438 440
@@ -459,6 +461,9 @@ struct afs_volume {
459 rwlock_t servers_lock; /* Lock for ->servers */ 461 rwlock_t servers_lock; /* Lock for ->servers */
460 unsigned int servers_seq; /* Incremented each time ->servers changes */ 462 unsigned int servers_seq; /* Incremented each time ->servers changes */
461 463
464 unsigned cb_v_break; /* Break-everything counter. */
465 rwlock_t cb_break_lock;
466
462 afs_voltype_t type; /* type of volume */ 467 afs_voltype_t type; /* type of volume */
463 short error; 468 short error;
464 char type_force; /* force volume type (suppress R/O -> R/W) */ 469 char type_force; /* force volume type (suppress R/O -> R/W) */
@@ -494,7 +499,7 @@ struct afs_vnode {
494#endif 499#endif
495 struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */ 500 struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */
496 struct mutex io_lock; /* Lock for serialising I/O on this mutex */ 501 struct mutex io_lock; /* Lock for serialising I/O on this mutex */
497 struct mutex validate_lock; /* lock for validating this vnode */ 502 struct rw_semaphore validate_lock; /* lock for validating this vnode */
498 spinlock_t wb_lock; /* lock for wb_keys */ 503 spinlock_t wb_lock; /* lock for wb_keys */
499 spinlock_t lock; /* waitqueue/flags lock */ 504 spinlock_t lock; /* waitqueue/flags lock */
500 unsigned long flags; 505 unsigned long flags;
@@ -519,6 +524,7 @@ struct afs_vnode {
519 /* outstanding callback notification on this file */ 524 /* outstanding callback notification on this file */
520 struct afs_cb_interest *cb_interest; /* Server on which this resides */ 525 struct afs_cb_interest *cb_interest; /* Server on which this resides */
521 unsigned int cb_s_break; /* Mass break counter on ->server */ 526 unsigned int cb_s_break; /* Mass break counter on ->server */
527 unsigned int cb_v_break; /* Mass break counter on ->volume */
522 unsigned int cb_break; /* Break counter on vnode */ 528 unsigned int cb_break; /* Break counter on vnode */
523 seqlock_t cb_lock; /* Lock for ->cb_interest, ->status, ->cb_*break */ 529 seqlock_t cb_lock; /* Lock for ->cb_interest, ->status, ->cb_*break */
524 530
@@ -648,16 +654,29 @@ extern void afs_init_callback_state(struct afs_server *);
648extern void afs_break_callback(struct afs_vnode *); 654extern void afs_break_callback(struct afs_vnode *);
649extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*); 655extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*);
650 656
651extern int afs_register_server_cb_interest(struct afs_vnode *, struct afs_server_entry *); 657extern int afs_register_server_cb_interest(struct afs_vnode *,
658 struct afs_server_list *, unsigned int);
652extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *); 659extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *);
653extern void afs_clear_callback_interests(struct afs_net *, struct afs_server_list *); 660extern void afs_clear_callback_interests(struct afs_net *, struct afs_server_list *);
654 661
655static inline struct afs_cb_interest *afs_get_cb_interest(struct afs_cb_interest *cbi) 662static inline struct afs_cb_interest *afs_get_cb_interest(struct afs_cb_interest *cbi)
656{ 663{
657 refcount_inc(&cbi->usage); 664 if (cbi)
665 refcount_inc(&cbi->usage);
658 return cbi; 666 return cbi;
659} 667}
660 668
669static inline unsigned int afs_calc_vnode_cb_break(struct afs_vnode *vnode)
670{
671 return vnode->cb_break + vnode->cb_s_break + vnode->cb_v_break;
672}
673
674static inline unsigned int afs_cb_break_sum(struct afs_vnode *vnode,
675 struct afs_cb_interest *cbi)
676{
677 return vnode->cb_break + cbi->server->cb_s_break + vnode->volume->cb_v_break;
678}
679
661/* 680/*
662 * cell.c 681 * cell.c
663 */ 682 */
diff --git a/fs/afs/rotate.c b/fs/afs/rotate.c
index ac0feac9d746..e065bc0768e6 100644
--- a/fs/afs/rotate.c
+++ b/fs/afs/rotate.c
@@ -179,7 +179,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
179 */ 179 */
180 if (fc->flags & AFS_FS_CURSOR_VNOVOL) { 180 if (fc->flags & AFS_FS_CURSOR_VNOVOL) {
181 fc->ac.error = -EREMOTEIO; 181 fc->ac.error = -EREMOTEIO;
182 goto failed; 182 goto next_server;
183 } 183 }
184 184
185 write_lock(&vnode->volume->servers_lock); 185 write_lock(&vnode->volume->servers_lock);
@@ -201,7 +201,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
201 */ 201 */
202 if (vnode->volume->servers == fc->server_list) { 202 if (vnode->volume->servers == fc->server_list) {
203 fc->ac.error = -EREMOTEIO; 203 fc->ac.error = -EREMOTEIO;
204 goto failed; 204 goto next_server;
205 } 205 }
206 206
207 /* Try again */ 207 /* Try again */
@@ -350,8 +350,8 @@ use_server:
350 * break request before we've finished decoding the reply and 350 * break request before we've finished decoding the reply and
351 * installing the vnode. 351 * installing the vnode.
352 */ 352 */
353 fc->ac.error = afs_register_server_cb_interest( 353 fc->ac.error = afs_register_server_cb_interest(vnode, fc->server_list,
354 vnode, &fc->server_list->servers[fc->index]); 354 fc->index);
355 if (fc->ac.error < 0) 355 if (fc->ac.error < 0)
356 goto failed; 356 goto failed;
357 357
@@ -369,8 +369,16 @@ use_server:
369 if (!test_bit(AFS_SERVER_FL_PROBED, &server->flags)) { 369 if (!test_bit(AFS_SERVER_FL_PROBED, &server->flags)) {
370 fc->ac.alist = afs_get_addrlist(alist); 370 fc->ac.alist = afs_get_addrlist(alist);
371 371
372 if (!afs_probe_fileserver(fc)) 372 if (!afs_probe_fileserver(fc)) {
373 goto failed; 373 switch (fc->ac.error) {
374 case -ENOMEM:
375 case -ERESTARTSYS:
376 case -EINTR:
377 goto failed;
378 default:
379 goto next_server;
380 }
381 }
374 } 382 }
375 383
376 if (!fc->ac.alist) 384 if (!fc->ac.alist)
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index 5c6263972ec9..08735948f15d 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -41,6 +41,7 @@ int afs_open_socket(struct afs_net *net)
41{ 41{
42 struct sockaddr_rxrpc srx; 42 struct sockaddr_rxrpc srx;
43 struct socket *socket; 43 struct socket *socket;
44 unsigned int min_level;
44 int ret; 45 int ret;
45 46
46 _enter(""); 47 _enter("");
@@ -60,6 +61,12 @@ int afs_open_socket(struct afs_net *net)
60 srx.transport.sin6.sin6_family = AF_INET6; 61 srx.transport.sin6.sin6_family = AF_INET6;
61 srx.transport.sin6.sin6_port = htons(AFS_CM_PORT); 62 srx.transport.sin6.sin6_port = htons(AFS_CM_PORT);
62 63
64 min_level = RXRPC_SECURITY_ENCRYPT;
65 ret = kernel_setsockopt(socket, SOL_RXRPC, RXRPC_MIN_SECURITY_LEVEL,
66 (void *)&min_level, sizeof(min_level));
67 if (ret < 0)
68 goto error_2;
69
63 ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx)); 70 ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx));
64 if (ret == -EADDRINUSE) { 71 if (ret == -EADDRINUSE) {
65 srx.transport.sin6.sin6_port = 0; 72 srx.transport.sin6.sin6_port = 0;
@@ -482,8 +489,12 @@ static void afs_deliver_to_call(struct afs_call *call)
482 state = READ_ONCE(call->state); 489 state = READ_ONCE(call->state);
483 switch (ret) { 490 switch (ret) {
484 case 0: 491 case 0:
485 if (state == AFS_CALL_CL_PROC_REPLY) 492 if (state == AFS_CALL_CL_PROC_REPLY) {
493 if (call->cbi)
494 set_bit(AFS_SERVER_FL_MAY_HAVE_CB,
495 &call->cbi->server->flags);
486 goto call_complete; 496 goto call_complete;
497 }
487 ASSERTCMP(state, >, AFS_CALL_CL_PROC_REPLY); 498 ASSERTCMP(state, >, AFS_CALL_CL_PROC_REPLY);
488 goto done; 499 goto done;
489 case -EINPROGRESS: 500 case -EINPROGRESS:
@@ -493,11 +504,6 @@ static void afs_deliver_to_call(struct afs_call *call)
493 case -ECONNABORTED: 504 case -ECONNABORTED:
494 ASSERTCMP(state, ==, AFS_CALL_COMPLETE); 505 ASSERTCMP(state, ==, AFS_CALL_COMPLETE);
495 goto done; 506 goto done;
496 case -ENOTCONN:
497 abort_code = RX_CALL_DEAD;
498 rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
499 abort_code, ret, "KNC");
500 goto local_abort;
501 case -ENOTSUPP: 507 case -ENOTSUPP:
502 abort_code = RXGEN_OPCODE; 508 abort_code = RXGEN_OPCODE;
503 rxrpc_kernel_abort_call(call->net->socket, call->rxcall, 509 rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
diff --git a/fs/afs/security.c b/fs/afs/security.c
index cea2fff313dc..1992b0ffa543 100644
--- a/fs/afs/security.c
+++ b/fs/afs/security.c
@@ -147,8 +147,7 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key,
147 break; 147 break;
148 } 148 }
149 149
150 if (cb_break != (vnode->cb_break + 150 if (cb_break != afs_cb_break_sum(vnode, vnode->cb_interest)) {
151 vnode->cb_interest->server->cb_s_break)) {
152 changed = true; 151 changed = true;
153 break; 152 break;
154 } 153 }
@@ -178,7 +177,7 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key,
178 } 177 }
179 } 178 }
180 179
181 if (cb_break != (vnode->cb_break + vnode->cb_interest->server->cb_s_break)) 180 if (cb_break != afs_cb_break_sum(vnode, vnode->cb_interest))
182 goto someone_else_changed_it; 181 goto someone_else_changed_it;
183 182
184 /* We need a ref on any permits list we want to copy as we'll have to 183 /* We need a ref on any permits list we want to copy as we'll have to
@@ -257,7 +256,7 @@ found:
257 256
258 spin_lock(&vnode->lock); 257 spin_lock(&vnode->lock);
259 zap = rcu_access_pointer(vnode->permit_cache); 258 zap = rcu_access_pointer(vnode->permit_cache);
260 if (cb_break == (vnode->cb_break + vnode->cb_interest->server->cb_s_break) && 259 if (cb_break == afs_cb_break_sum(vnode, vnode->cb_interest) &&
261 zap == permits) 260 zap == permits)
262 rcu_assign_pointer(vnode->permit_cache, replacement); 261 rcu_assign_pointer(vnode->permit_cache, replacement);
263 else 262 else
diff --git a/fs/afs/server.c b/fs/afs/server.c
index 629c74986cff..3af4625e2f8c 100644
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -67,12 +67,6 @@ struct afs_server *afs_find_server(struct afs_net *net,
67 sizeof(struct in6_addr)); 67 sizeof(struct in6_addr));
68 if (diff == 0) 68 if (diff == 0)
69 goto found; 69 goto found;
70 if (diff < 0) {
71 // TODO: Sort the list
72 //if (i == alist->nr_ipv4)
73 // goto not_found;
74 break;
75 }
76 } 70 }
77 } 71 }
78 } else { 72 } else {
@@ -87,17 +81,10 @@ struct afs_server *afs_find_server(struct afs_net *net,
87 (u32 __force)b->sin6_addr.s6_addr32[3]); 81 (u32 __force)b->sin6_addr.s6_addr32[3]);
88 if (diff == 0) 82 if (diff == 0)
89 goto found; 83 goto found;
90 if (diff < 0) {
91 // TODO: Sort the list
92 //if (i == 0)
93 // goto not_found;
94 break;
95 }
96 } 84 }
97 } 85 }
98 } 86 }
99 87
100 //not_found:
101 server = NULL; 88 server = NULL;
102 found: 89 found:
103 if (server && !atomic_inc_not_zero(&server->usage)) 90 if (server && !atomic_inc_not_zero(&server->usage))
@@ -395,14 +382,16 @@ static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
395 struct afs_addr_list *alist = rcu_access_pointer(server->addresses); 382 struct afs_addr_list *alist = rcu_access_pointer(server->addresses);
396 struct afs_addr_cursor ac = { 383 struct afs_addr_cursor ac = {
397 .alist = alist, 384 .alist = alist,
398 .addr = &alist->addrs[0],
399 .start = alist->index, 385 .start = alist->index,
400 .index = alist->index, 386 .index = 0,
387 .addr = &alist->addrs[alist->index],
401 .error = 0, 388 .error = 0,
402 }; 389 };
403 _enter("%p", server); 390 _enter("%p", server);
404 391
405 afs_fs_give_up_all_callbacks(net, server, &ac, NULL); 392 if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags))
393 afs_fs_give_up_all_callbacks(net, server, &ac, NULL);
394
406 call_rcu(&server->rcu, afs_server_rcu); 395 call_rcu(&server->rcu, afs_server_rcu);
407 afs_dec_servers_outstanding(net); 396 afs_dec_servers_outstanding(net);
408} 397}
diff --git a/fs/afs/server_list.c b/fs/afs/server_list.c
index 0f8dc4c8f07c..8a5760aa5832 100644
--- a/fs/afs/server_list.c
+++ b/fs/afs/server_list.c
@@ -49,6 +49,7 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell,
49 goto error; 49 goto error;
50 50
51 refcount_set(&slist->usage, 1); 51 refcount_set(&slist->usage, 1);
52 rwlock_init(&slist->lock);
52 53
53 /* Make sure a records exists for each server in the list. */ 54 /* Make sure a records exists for each server in the list. */
54 for (i = 0; i < vldb->nr_servers; i++) { 55 for (i = 0; i < vldb->nr_servers; i++) {
@@ -64,9 +65,11 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell,
64 goto error_2; 65 goto error_2;
65 } 66 }
66 67
67 /* Insertion-sort by server pointer */ 68 /* Insertion-sort by UUID */
68 for (j = 0; j < slist->nr_servers; j++) 69 for (j = 0; j < slist->nr_servers; j++)
69 if (slist->servers[j].server >= server) 70 if (memcmp(&slist->servers[j].server->uuid,
71 &server->uuid,
72 sizeof(server->uuid)) >= 0)
70 break; 73 break;
71 if (j < slist->nr_servers) { 74 if (j < slist->nr_servers) {
72 if (slist->servers[j].server == server) { 75 if (slist->servers[j].server == server) {
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 65081ec3c36e..9e5d7966621c 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -590,7 +590,7 @@ static void afs_i_init_once(void *_vnode)
590 memset(vnode, 0, sizeof(*vnode)); 590 memset(vnode, 0, sizeof(*vnode));
591 inode_init_once(&vnode->vfs_inode); 591 inode_init_once(&vnode->vfs_inode);
592 mutex_init(&vnode->io_lock); 592 mutex_init(&vnode->io_lock);
593 mutex_init(&vnode->validate_lock); 593 init_rwsem(&vnode->validate_lock);
594 spin_lock_init(&vnode->wb_lock); 594 spin_lock_init(&vnode->wb_lock);
595 spin_lock_init(&vnode->lock); 595 spin_lock_init(&vnode->lock);
596 INIT_LIST_HEAD(&vnode->wb_keys); 596 INIT_LIST_HEAD(&vnode->wb_keys);
@@ -688,7 +688,7 @@ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf)
688 if (afs_begin_vnode_operation(&fc, vnode, key)) { 688 if (afs_begin_vnode_operation(&fc, vnode, key)) {
689 fc.flags |= AFS_FS_CURSOR_NO_VSLEEP; 689 fc.flags |= AFS_FS_CURSOR_NO_VSLEEP;
690 while (afs_select_fileserver(&fc)) { 690 while (afs_select_fileserver(&fc)) {
691 fc.cb_break = vnode->cb_break + vnode->cb_s_break; 691 fc.cb_break = afs_calc_vnode_cb_break(vnode);
692 afs_fs_get_volume_status(&fc, &vs); 692 afs_fs_get_volume_status(&fc, &vs);
693 } 693 }
694 694
diff --git a/fs/afs/write.c b/fs/afs/write.c
index c164698dc304..8b39e6ebb40b 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -351,7 +351,7 @@ found_key:
351 ret = -ERESTARTSYS; 351 ret = -ERESTARTSYS;
352 if (afs_begin_vnode_operation(&fc, vnode, wbk->key)) { 352 if (afs_begin_vnode_operation(&fc, vnode, wbk->key)) {
353 while (afs_select_fileserver(&fc)) { 353 while (afs_select_fileserver(&fc)) {
354 fc.cb_break = vnode->cb_break + vnode->cb_s_break; 354 fc.cb_break = afs_calc_vnode_cb_break(vnode);
355 afs_fs_store_data(&fc, mapping, first, last, offset, to); 355 afs_fs_store_data(&fc, mapping, first, last, offset, to);
356 } 356 }
357 357