Skip to content

Commit de52cf9

Browse files
author
Al Viro
committed
Merge tag 'afs-fixes-20180514' into afs-proc
backmerge AFS fixes that went into mainline and deal with the conflict in fs/afs/fsclient.c Signed-off-by: Al Viro <[email protected]>
2 parents 5b86d4f + 4776cab commit de52cf9

File tree

17 files changed

+264
-167
lines changed

17 files changed

+264
-167
lines changed

fs/afs/addr_list.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len,
121121
p = text;
122122
do {
123123
struct sockaddr_rxrpc *srx = &alist->addrs[alist->nr_addrs];
124-
char tdelim = delim;
124+
const char *q, *stop;
125125

126126
if (*p == delim) {
127127
p++;
@@ -130,28 +130,33 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len,
130130

131131
if (*p == '[') {
132132
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;
134138
}
135139

136-
if (in4_pton(p, end - p,
140+
if (in4_pton(p, q - p,
137141
(u8 *)&srx->transport.sin6.sin6_addr.s6_addr32[3],
138-
tdelim, &p)) {
142+
-1, &stop)) {
139143
srx->transport.sin6.sin6_addr.s6_addr32[0] = 0;
140144
srx->transport.sin6.sin6_addr.s6_addr32[1] = 0;
141145
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,
143147
srx->transport.sin6.sin6_addr.s6_addr,
144-
tdelim, &p)) {
148+
-1, &stop)) {
145149
/* Nothing to do */
146150
} else {
147151
goto bad_address;
148152
}
149153

150-
if (tdelim == ']') {
151-
if (p == end || *p != ']')
152-
goto bad_address;
154+
if (stop != q)
155+
goto bad_address;
156+
157+
p = q;
158+
if (q < end && *q == ']')
153159
p++;
154-
}
155160

156161
if (p < end) {
157162
if (*p == '+') {

fs/afs/callback.c

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,55 @@
2323
/*
2424
* Set up an interest-in-callbacks record for a volume on a server and
2525
* register it with the server.
26-
* - Called with volume->server_sem held.
26+
* - Called with vnode->io_lock held.
2727
*/
2828
int 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)
3031
{
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;
3234
struct afs_server *server = entry->server;
3335

3436
again:
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+
3545
vcbi = vnode->cb_interest;
3646
if (vcbi) {
37-
if (vcbi == cbi)
47+
if (vcbi == cbi) {
48+
afs_put_cb_interest(afs_v2net(vnode), cbi);
3849
return 0;
50+
}
3951

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+
*/
4055
if (cbi && vcbi->server == cbi->server) {
4156
write_seqlock(&vnode->cb_lock);
42-
vnode->cb_interest = afs_get_cb_interest(cbi);
57+
old = vnode->cb_interest;
58+
vnode->cb_interest = cbi;
4359
write_sequnlock(&vnode->cb_lock);
44-
afs_put_cb_interest(afs_v2net(vnode), cbi);
60+
afs_put_cb_interest(afs_v2net(vnode), old);
4561
return 0;
4662
}
4763

64+
/* Re-use the one attached to the vnode. */
4865
if (!cbi && vcbi->server == server) {
49-
afs_get_cb_interest(vcbi);
50-
x = cmpxchg(&entry->cb_interest, cbi, vcbi);
51-
if (x != cbi) {
52-
cbi = x;
53-
afs_put_cb_interest(afs_v2net(vnode), vcbi);
66+
write_lock(&slist->lock);
67+
if (entry->cb_interest) {
68+
write_unlock(&slist->lock);
69+
afs_put_cb_interest(afs_v2net(vnode), cbi);
5470
goto again;
5571
}
72+
73+
entry->cb_interest = cbi;
74+
write_unlock(&slist->lock);
5675
return 0;
5776
}
5877
}
@@ -72,13 +91,16 @@ int afs_register_server_cb_interest(struct afs_vnode *vnode,
7291
list_add_tail(&new->cb_link, &server->cb_interests);
7392
write_unlock(&server->cb_break_lock);
7493

75-
x = cmpxchg(&entry->cb_interest, cbi, new);
76-
if (x == cbi) {
94+
write_lock(&slist->lock);
95+
if (!entry->cb_interest) {
96+
entry->cb_interest = afs_get_cb_interest(new);
7797
cbi = new;
98+
new = NULL;
7899
} else {
79-
cbi = x;
80-
afs_put_cb_interest(afs_v2net(vnode), new);
100+
cbi = afs_get_cb_interest(entry->cb_interest);
81101
}
102+
write_unlock(&slist->lock);
103+
afs_put_cb_interest(afs_v2net(vnode), new);
82104
}
83105

84106
ASSERT(cbi);
@@ -88,11 +110,14 @@ int afs_register_server_cb_interest(struct afs_vnode *vnode,
88110
*/
89111
write_seqlock(&vnode->cb_lock);
90112

91-
vnode->cb_interest = afs_get_cb_interest(cbi);
113+
old = vnode->cb_interest;
114+
vnode->cb_interest = cbi;
92115
vnode->cb_s_break = cbi->server->cb_s_break;
116+
vnode->cb_v_break = vnode->volume->cb_v_break;
93117
clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
94118

95119
write_sequnlock(&vnode->cb_lock);
120+
afs_put_cb_interest(afs_v2net(vnode), old);
96121
return 0;
97122
}
98123

@@ -171,13 +196,24 @@ static void afs_break_one_callback(struct afs_server *server,
171196
if (cbi->vid != fid->vid)
172197
continue;
173198

174-
data.volume = NULL;
175-
data.fid = *fid;
176-
inode = ilookup5_nowait(cbi->sb, fid->vnode, afs_iget5_test, &data);
177-
if (inode) {
178-
vnode = AFS_FS_I(inode);
179-
afs_break_callback(vnode);
180-
iput(inode);
199+
if (fid->vnode == 0 && fid->unique == 0) {
200+
/* The callback break applies to an entire volume. */
201+
struct afs_super_info *as = AFS_FS_S(cbi->sb);
202+
struct afs_volume *volume = as->volume;
203+
204+
write_lock(&volume->cb_break_lock);
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+
}
181217
}
182218
}
183219

@@ -195,6 +231,8 @@ void afs_break_callbacks(struct afs_server *server, size_t count,
195231
ASSERT(server != NULL);
196232
ASSERTCMP(count, <=, AFSCBMAX);
197233

234+
/* TODO: Sort the callback break list by volume ID */
235+
198236
for (; count > 0; callbacks++, count--) {
199237
_debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }",
200238
callbacks->fid.vid,

fs/afs/cmservice.c

Lines changed: 21 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -133,21 +133,10 @@ bool afs_cm_incoming_call(struct afs_call *call)
133133
}
134134

135135
/*
136-
* clean up a cache manager call
136+
* Clean up a cache manager call.
137137
*/
138138
static void afs_cm_destructor(struct afs_call *call)
139139
{
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-
151140
kfree(call->buffer);
152141
call->buffer = NULL;
153142
}
@@ -161,14 +150,14 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
161150

162151
_enter("");
163152

164-
/* be sure to send the reply *before* attempting to spam the AFS server
165-
* with FSFetchStatus requests on the vnodes with broken callbacks lest
166-
* the AFS server get into a vicious cycle of trying to break further
167-
* callbacks because it hadn't received completion of the CBCallBack op
168-
* yet */
169-
afs_send_empty_reply(call);
153+
/* We need to break the callbacks before sending the reply as the
154+
* server holds up change visibility till it receives our reply so as
155+
* to maintain cache coherency.
156+
*/
157+
if (call->cm_server)
158+
afs_break_callbacks(call->cm_server, call->count, call->request);
170159

171-
afs_break_callbacks(call->cm_server, call->count, call->request);
160+
afs_send_empty_reply(call);
172161
afs_put_call(call);
173162
_leave("");
174163
}
@@ -180,7 +169,6 @@ static int afs_deliver_cb_callback(struct afs_call *call)
180169
{
181170
struct afs_callback_break *cb;
182171
struct sockaddr_rxrpc srx;
183-
struct afs_server *server;
184172
__be32 *bp;
185173
int ret, loop;
186174

@@ -267,15 +255,6 @@ static int afs_deliver_cb_callback(struct afs_call *call)
267255

268256
call->offset = 0;
269257
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++;
279258
case 5:
280259
break;
281260
}
@@ -286,10 +265,9 @@ static int afs_deliver_cb_callback(struct afs_call *call)
286265
/* we'll need the file server record as that tells us which set of
287266
* vnodes to operate upon */
288267
rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
289-
server = afs_find_server(call->net, &srx);
290-
if (!server)
291-
return -ENOTCONN;
292-
call->cm_server = server;
268+
call->cm_server = afs_find_server(call->net, &srx);
269+
if (!call->cm_server)
270+
trace_afs_cm_no_server(call, &srx);
293271

294272
return afs_queue_call_work(call);
295273
}
@@ -303,7 +281,8 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
303281

304282
_enter("{%p}", call->cm_server);
305283

306-
afs_init_callback_state(call->cm_server);
284+
if (call->cm_server)
285+
afs_init_callback_state(call->cm_server);
307286
afs_send_empty_reply(call);
308287
afs_put_call(call);
309288
_leave("");
@@ -315,7 +294,6 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
315294
static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
316295
{
317296
struct sockaddr_rxrpc srx;
318-
struct afs_server *server;
319297
int ret;
320298

321299
_enter("");
@@ -328,10 +306,9 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
328306

329307
/* we'll need the file server record as that tells us which set of
330308
* vnodes to operate upon */
331-
server = afs_find_server(call->net, &srx);
332-
if (!server)
333-
return -ENOTCONN;
334-
call->cm_server = server;
309+
call->cm_server = afs_find_server(call->net, &srx);
310+
if (!call->cm_server)
311+
trace_afs_cm_no_server(call, &srx);
335312

336313
return afs_queue_call_work(call);
337314
}
@@ -341,8 +318,6 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
341318
*/
342319
static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
343320
{
344-
struct sockaddr_rxrpc srx;
345-
struct afs_server *server;
346321
struct afs_uuid *r;
347322
unsigned loop;
348323
__be32 *b;
@@ -398,11 +373,11 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
398373

399374
/* we'll need the file server record as that tells us which set of
400375
* vnodes to operate upon */
401-
rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
402-
server = afs_find_server(call->net, &srx);
403-
if (!server)
404-
return -ENOTCONN;
405-
call->cm_server = server;
376+
rcu_read_lock();
377+
call->cm_server = afs_find_server_by_uuid(call->net, call->request);
378+
rcu_read_unlock();
379+
if (!call->cm_server)
380+
trace_afs_cm_no_server_u(call, call->request);
406381

407382
return afs_queue_call_work(call);
408383
}

0 commit comments

Comments
 (0)