aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/blocklayout/extent_tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/blocklayout/extent_tree.c')
-rw-r--r--fs/nfs/blocklayout/extent_tree.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/fs/nfs/blocklayout/extent_tree.c b/fs/nfs/blocklayout/extent_tree.c
index 35ab51c04814..720b3ff55fa9 100644
--- a/fs/nfs/blocklayout/extent_tree.c
+++ b/fs/nfs/blocklayout/extent_tree.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014 Christoph Hellwig. 2 * Copyright (c) 2014-2016 Christoph Hellwig.
3 */ 3 */
4 4
5#include <linux/vmalloc.h> 5#include <linux/vmalloc.h>
@@ -462,10 +462,12 @@ out:
462 return err; 462 return err;
463} 463}
464 464
465static size_t ext_tree_layoutupdate_size(size_t count) 465static size_t ext_tree_layoutupdate_size(struct pnfs_block_layout *bl, size_t count)
466{ 466{
467 return sizeof(__be32) /* number of entries */ + 467 if (bl->bl_scsi_layout)
468 PNFS_BLOCK_EXTENT_SIZE * count; 468 return sizeof(__be32) + PNFS_SCSI_RANGE_SIZE * count;
469 else
470 return sizeof(__be32) + PNFS_BLOCK_EXTENT_SIZE * count;
469} 471}
470 472
471static void ext_tree_free_commitdata(struct nfs4_layoutcommit_args *arg, 473static void ext_tree_free_commitdata(struct nfs4_layoutcommit_args *arg,
@@ -483,6 +485,23 @@ static void ext_tree_free_commitdata(struct nfs4_layoutcommit_args *arg,
483 } 485 }
484} 486}
485 487
488static __be32 *encode_block_extent(struct pnfs_block_extent *be, __be32 *p)
489{
490 p = xdr_encode_opaque_fixed(p, be->be_device->deviceid.data,
491 NFS4_DEVICEID4_SIZE);
492 p = xdr_encode_hyper(p, be->be_f_offset << SECTOR_SHIFT);
493 p = xdr_encode_hyper(p, be->be_length << SECTOR_SHIFT);
494 p = xdr_encode_hyper(p, 0LL);
495 *p++ = cpu_to_be32(PNFS_BLOCK_READWRITE_DATA);
496 return p;
497}
498
499static __be32 *encode_scsi_range(struct pnfs_block_extent *be, __be32 *p)
500{
501 p = xdr_encode_hyper(p, be->be_f_offset << SECTOR_SHIFT);
502 return xdr_encode_hyper(p, be->be_length << SECTOR_SHIFT);
503}
504
486static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p, 505static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p,
487 size_t buffer_size, size_t *count) 506 size_t buffer_size, size_t *count)
488{ 507{
@@ -496,19 +515,16 @@ static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p,
496 continue; 515 continue;
497 516
498 (*count)++; 517 (*count)++;
499 if (ext_tree_layoutupdate_size(*count) > buffer_size) { 518 if (ext_tree_layoutupdate_size(bl, *count) > buffer_size) {
500 /* keep counting.. */ 519 /* keep counting.. */
501 ret = -ENOSPC; 520 ret = -ENOSPC;
502 continue; 521 continue;
503 } 522 }
504 523
505 p = xdr_encode_opaque_fixed(p, be->be_device->deviceid.data, 524 if (bl->bl_scsi_layout)
506 NFS4_DEVICEID4_SIZE); 525 p = encode_scsi_range(be, p);
507 p = xdr_encode_hyper(p, be->be_f_offset << SECTOR_SHIFT); 526 else
508 p = xdr_encode_hyper(p, be->be_length << SECTOR_SHIFT); 527 p = encode_block_extent(be, p);
509 p = xdr_encode_hyper(p, 0LL);
510 *p++ = cpu_to_be32(PNFS_BLOCK_READWRITE_DATA);
511
512 be->be_tag = EXTENT_COMMITTING; 528 be->be_tag = EXTENT_COMMITTING;
513 } 529 }
514 spin_unlock(&bl->bl_ext_lock); 530 spin_unlock(&bl->bl_ext_lock);
@@ -537,7 +553,7 @@ retry:
537 if (unlikely(ret)) { 553 if (unlikely(ret)) {
538 ext_tree_free_commitdata(arg, buffer_size); 554 ext_tree_free_commitdata(arg, buffer_size);
539 555
540 buffer_size = ext_tree_layoutupdate_size(count); 556 buffer_size = ext_tree_layoutupdate_size(bl, count);
541 count = 0; 557 count = 0;
542 558
543 arg->layoutupdate_pages = 559 arg->layoutupdate_pages =
@@ -556,7 +572,7 @@ retry:
556 } 572 }
557 573
558 *start_p = cpu_to_be32(count); 574 *start_p = cpu_to_be32(count);
559 arg->layoutupdate_len = ext_tree_layoutupdate_size(count); 575 arg->layoutupdate_len = ext_tree_layoutupdate_size(bl, count);
560 576
561 if (unlikely(arg->layoutupdate_pages != &arg->layoutupdate_page)) { 577 if (unlikely(arg->layoutupdate_pages != &arg->layoutupdate_page)) {
562 void *p = start_p, *end = p + arg->layoutupdate_len; 578 void *p = start_p, *end = p + arg->layoutupdate_len;