diff options
Diffstat (limited to 'fs/nfs/blocklayout/extent_tree.c')
-rw-r--r-- | fs/nfs/blocklayout/extent_tree.c | 44 |
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 | ||
465 | static size_t ext_tree_layoutupdate_size(size_t count) | 465 | static 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 | ||
471 | static void ext_tree_free_commitdata(struct nfs4_layoutcommit_args *arg, | 473 | static 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 | ||
488 | static __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 | |||
499 | static __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 | |||
486 | static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p, | 505 | static 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; |