Skip to content

Commit 12bdcf3

Browse files
committed
afs: Set up the iov_iter before calling afs_extract_data()
afs_extract_data sets up a temporary iov_iter and passes it to AF_RXRPC each time it is called to describe the remaining buffer to be filled. Instead: (1) Put an iterator in the afs_call struct. (2) Set the iterator for each marshalling stage to load data into the appropriate places. A number of convenience functions are provided to this end (eg. afs_extract_to_buf()). This iterator is then passed to afs_extract_data(). (3) Use the new ITER_DISCARD iterator to discard any excess data provided by FetchData. Signed-off-by: David Howells <dhowells@redhat.com>
1 parent 160cb95 commit 12bdcf3

File tree

6 files changed

+236
-309
lines changed

6 files changed

+236
-309
lines changed

fs/afs/cmservice.c

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,13 @@ static int afs_deliver_cb_callback(struct afs_call *call)
176176

177177
switch (call->unmarshall) {
178178
case 0:
179-
call->offset = 0;
179+
afs_extract_to_tmp(call);
180180
call->unmarshall++;
181181

182182
/* extract the FID array and its count in two steps */
183183
case 1:
184184
_debug("extract FID count");
185-
ret = afs_extract_data(call, &call->tmp, 4, true);
185+
ret = afs_extract_data(call, true);
186186
if (ret < 0)
187187
return ret;
188188

@@ -196,13 +196,12 @@ static int afs_deliver_cb_callback(struct afs_call *call)
196196
GFP_KERNEL);
197197
if (!call->buffer)
198198
return -ENOMEM;
199-
call->offset = 0;
199+
afs_extract_to_buf(call, call->count * 3 * 4);
200200
call->unmarshall++;
201201

202202
case 2:
203203
_debug("extract FID array");
204-
ret = afs_extract_data(call, call->buffer,
205-
call->count * 3 * 4, true);
204+
ret = afs_extract_data(call, true);
206205
if (ret < 0)
207206
return ret;
208207

@@ -222,13 +221,13 @@ static int afs_deliver_cb_callback(struct afs_call *call)
222221
cb->cb.type = AFSCM_CB_UNTYPED;
223222
}
224223

225-
call->offset = 0;
224+
afs_extract_to_tmp(call);
226225
call->unmarshall++;
227226

228227
/* extract the callback array and its count in two steps */
229228
case 3:
230229
_debug("extract CB count");
231-
ret = afs_extract_data(call, &call->tmp, 4, true);
230+
ret = afs_extract_data(call, true);
232231
if (ret < 0)
233232
return ret;
234233

@@ -237,13 +236,12 @@ static int afs_deliver_cb_callback(struct afs_call *call)
237236
if (call->count2 != call->count && call->count2 != 0)
238237
return afs_protocol_error(call, -EBADMSG,
239238
afs_eproto_cb_count);
240-
call->offset = 0;
239+
afs_extract_to_buf(call, call->count2 * 3 * 4);
241240
call->unmarshall++;
242241

243242
case 4:
244243
_debug("extract CB array");
245-
ret = afs_extract_data(call, call->buffer,
246-
call->count2 * 3 * 4, false);
244+
ret = afs_extract_data(call, false);
247245
if (ret < 0)
248246
return ret;
249247

@@ -256,7 +254,6 @@ static int afs_deliver_cb_callback(struct afs_call *call)
256254
cb->cb.type = ntohl(*bp++);
257255
}
258256

259-
call->offset = 0;
260257
call->unmarshall++;
261258
case 5:
262259
break;
@@ -303,7 +300,8 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
303300

304301
rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
305302

306-
ret = afs_extract_data(call, NULL, 0, false);
303+
afs_extract_discard(call, 0);
304+
ret = afs_extract_data(call, false);
307305
if (ret < 0)
308306
return ret;
309307

@@ -332,16 +330,15 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
332330

333331
switch (call->unmarshall) {
334332
case 0:
335-
call->offset = 0;
336333
call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
337334
if (!call->buffer)
338335
return -ENOMEM;
336+
afs_extract_to_buf(call, 11 * sizeof(__be32));
339337
call->unmarshall++;
340338

341339
case 1:
342340
_debug("extract UUID");
343-
ret = afs_extract_data(call, call->buffer,
344-
11 * sizeof(__be32), false);
341+
ret = afs_extract_data(call, false);
345342
switch (ret) {
346343
case 0: break;
347344
case -EAGAIN: return 0;
@@ -364,7 +361,6 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
364361
for (loop = 0; loop < 6; loop++)
365362
r->node[loop] = ntohl(b[loop + 5]);
366363

367-
call->offset = 0;
368364
call->unmarshall++;
369365

370366
case 2:
@@ -407,7 +403,8 @@ static int afs_deliver_cb_probe(struct afs_call *call)
407403

408404
_enter("");
409405

410-
ret = afs_extract_data(call, NULL, 0, false);
406+
afs_extract_discard(call, 0);
407+
ret = afs_extract_data(call, false);
411408
if (ret < 0)
412409
return ret;
413410

@@ -455,16 +452,15 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call)
455452

456453
switch (call->unmarshall) {
457454
case 0:
458-
call->offset = 0;
459455
call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
460456
if (!call->buffer)
461457
return -ENOMEM;
458+
afs_extract_to_buf(call, 11 * sizeof(__be32));
462459
call->unmarshall++;
463460

464461
case 1:
465462
_debug("extract UUID");
466-
ret = afs_extract_data(call, call->buffer,
467-
11 * sizeof(__be32), false);
463+
ret = afs_extract_data(call, false);
468464
switch (ret) {
469465
case 0: break;
470466
case -EAGAIN: return 0;
@@ -487,7 +483,6 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call)
487483
for (loop = 0; loop < 6; loop++)
488484
r->node[loop] = ntohl(b[loop + 5]);
489485

490-
call->offset = 0;
491486
call->unmarshall++;
492487

493488
case 2:
@@ -572,7 +567,8 @@ static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
572567

573568
_enter("");
574569

575-
ret = afs_extract_data(call, NULL, 0, false);
570+
afs_extract_discard(call, 0);
571+
ret = afs_extract_data(call, false);
576572
if (ret < 0)
577573
return ret;
578574

0 commit comments

Comments
 (0)