@@ -347,13 +347,15 @@ EXPORT_SYMBOL_GPL(_copy_from_pages);
347
347
* 'len' bytes. The extra data is not lost, but is instead
348
348
* moved into the inlined pages and/or the tail.
349
349
*/
350
- static void
350
+ static unsigned int
351
351
xdr_shrink_bufhead (struct xdr_buf * buf , size_t len )
352
352
{
353
353
struct kvec * head , * tail ;
354
354
size_t copy , offs ;
355
355
unsigned int pglen = buf -> page_len ;
356
+ unsigned int result ;
356
357
358
+ result = 0 ;
357
359
tail = buf -> tail ;
358
360
head = buf -> head ;
359
361
@@ -367,6 +369,7 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
367
369
copy = tail -> iov_len - len ;
368
370
memmove ((char * )tail -> iov_base + len ,
369
371
tail -> iov_base , copy );
372
+ result += copy ;
370
373
}
371
374
/* Copy from the inlined pages into the tail */
372
375
copy = len ;
@@ -377,11 +380,13 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
377
380
copy = 0 ;
378
381
else if (copy > tail -> iov_len - offs )
379
382
copy = tail -> iov_len - offs ;
380
- if (copy != 0 )
383
+ if (copy != 0 ) {
381
384
_copy_from_pages ((char * )tail -> iov_base + offs ,
382
385
buf -> pages ,
383
386
buf -> page_base + pglen + offs - len ,
384
387
copy );
388
+ result += copy ;
389
+ }
385
390
/* Do we also need to copy data from the head into the tail ? */
386
391
if (len > pglen ) {
387
392
offs = copy = len - pglen ;
@@ -391,6 +396,7 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
391
396
(char * )head -> iov_base +
392
397
head -> iov_len - offs ,
393
398
copy );
399
+ result += copy ;
394
400
}
395
401
}
396
402
/* Now handle pages */
@@ -406,12 +412,15 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
406
412
_copy_to_pages (buf -> pages , buf -> page_base ,
407
413
(char * )head -> iov_base + head -> iov_len - len ,
408
414
copy );
415
+ result += copy ;
409
416
}
410
417
head -> iov_len -= len ;
411
418
buf -> buflen -= len ;
412
419
/* Have we truncated the message? */
413
420
if (buf -> len > buf -> buflen )
414
421
buf -> len = buf -> buflen ;
422
+
423
+ return result ;
415
424
}
416
425
417
426
/**
@@ -423,14 +432,16 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
423
432
* 'len' bytes. The extra data is not lost, but is instead
424
433
* moved into the tail.
425
434
*/
426
- static void
435
+ static unsigned int
427
436
xdr_shrink_pagelen (struct xdr_buf * buf , size_t len )
428
437
{
429
438
struct kvec * tail ;
430
439
size_t copy ;
431
440
unsigned int pglen = buf -> page_len ;
432
441
unsigned int tailbuf_len ;
442
+ unsigned int result ;
433
443
444
+ result = 0 ;
434
445
tail = buf -> tail ;
435
446
BUG_ON (len > pglen );
436
447
@@ -448,18 +459,22 @@ xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)
448
459
if (tail -> iov_len > len ) {
449
460
char * p = (char * )tail -> iov_base + len ;
450
461
memmove (p , tail -> iov_base , tail -> iov_len - len );
462
+ result += tail -> iov_len - len ;
451
463
} else
452
464
copy = tail -> iov_len ;
453
465
/* Copy from the inlined pages into the tail */
454
466
_copy_from_pages ((char * )tail -> iov_base ,
455
467
buf -> pages , buf -> page_base + pglen - len ,
456
468
copy );
469
+ result += copy ;
457
470
}
458
471
buf -> page_len -= len ;
459
472
buf -> buflen -= len ;
460
473
/* Have we truncated the message? */
461
474
if (buf -> len > buf -> buflen )
462
475
buf -> len = buf -> buflen ;
476
+
477
+ return result ;
463
478
}
464
479
465
480
void
@@ -959,13 +974,17 @@ static unsigned int xdr_align_pages(struct xdr_stream *xdr, unsigned int len)
959
974
struct kvec * iov ;
960
975
unsigned int nwords = XDR_QUADLEN (len );
961
976
unsigned int cur = xdr_stream_pos (xdr );
977
+ unsigned int copied , offset ;
962
978
963
979
if (xdr -> nwords == 0 )
964
980
return 0 ;
981
+
965
982
/* Realign pages to current pointer position */
966
- iov = buf -> head ;
983
+ iov = buf -> head ;
967
984
if (iov -> iov_len > cur ) {
968
- xdr_shrink_bufhead (buf , iov -> iov_len - cur );
985
+ offset = iov -> iov_len - cur ;
986
+ copied = xdr_shrink_bufhead (buf , offset );
987
+ trace_rpc_xdr_alignment (xdr , offset , copied );
969
988
xdr -> nwords = XDR_QUADLEN (buf -> len - cur );
970
989
}
971
990
@@ -977,7 +996,9 @@ static unsigned int xdr_align_pages(struct xdr_stream *xdr, unsigned int len)
977
996
len = buf -> page_len ;
978
997
else if (nwords < xdr -> nwords ) {
979
998
/* Truncate page data and move it into the tail */
980
- xdr_shrink_pagelen (buf , buf -> page_len - len );
999
+ offset = buf -> page_len - len ;
1000
+ copied = xdr_shrink_pagelen (buf , offset );
1001
+ trace_rpc_xdr_alignment (xdr , offset , copied );
981
1002
xdr -> nwords = XDR_QUADLEN (buf -> len - cur );
982
1003
}
983
1004
return len ;
0 commit comments