Merge tag 'nfsd-4.6-1' of git://linux-nfs.org/~bfields/linux
[cascardo/linux.git] / fs / nfs / blocklayout / extent_tree.c
index 35ab51c..720b3ff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Christoph Hellwig.
+ * Copyright (c) 2014-2016 Christoph Hellwig.
  */
 
 #include <linux/vmalloc.h>
@@ -462,10 +462,12 @@ out:
        return err;
 }
 
-static size_t ext_tree_layoutupdate_size(size_t count)
+static size_t ext_tree_layoutupdate_size(struct pnfs_block_layout *bl, size_t count)
 {
-       return sizeof(__be32) /* number of entries */ +
-               PNFS_BLOCK_EXTENT_SIZE * count;
+       if (bl->bl_scsi_layout)
+               return sizeof(__be32) + PNFS_SCSI_RANGE_SIZE * count;
+       else
+               return sizeof(__be32) + PNFS_BLOCK_EXTENT_SIZE * count;
 }
 
 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,
        }
 }
 
+static __be32 *encode_block_extent(struct pnfs_block_extent *be, __be32 *p)
+{
+       p = xdr_encode_opaque_fixed(p, be->be_device->deviceid.data,
+                       NFS4_DEVICEID4_SIZE);
+       p = xdr_encode_hyper(p, be->be_f_offset << SECTOR_SHIFT);
+       p = xdr_encode_hyper(p, be->be_length << SECTOR_SHIFT);
+       p = xdr_encode_hyper(p, 0LL);
+       *p++ = cpu_to_be32(PNFS_BLOCK_READWRITE_DATA);
+       return p;
+}
+
+static __be32 *encode_scsi_range(struct pnfs_block_extent *be, __be32 *p)
+{
+       p = xdr_encode_hyper(p, be->be_f_offset << SECTOR_SHIFT);
+       return xdr_encode_hyper(p, be->be_length << SECTOR_SHIFT);
+}
+
 static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p,
                size_t buffer_size, size_t *count)
 {
@@ -496,19 +515,16 @@ static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p,
                        continue;
 
                (*count)++;
-               if (ext_tree_layoutupdate_size(*count) > buffer_size) {
+               if (ext_tree_layoutupdate_size(bl, *count) > buffer_size) {
                        /* keep counting.. */
                        ret = -ENOSPC;
                        continue;
                }
 
-               p = xdr_encode_opaque_fixed(p, be->be_device->deviceid.data,
-                               NFS4_DEVICEID4_SIZE);
-               p = xdr_encode_hyper(p, be->be_f_offset << SECTOR_SHIFT);
-               p = xdr_encode_hyper(p, be->be_length << SECTOR_SHIFT);
-               p = xdr_encode_hyper(p, 0LL);
-               *p++ = cpu_to_be32(PNFS_BLOCK_READWRITE_DATA);
-
+               if (bl->bl_scsi_layout)
+                       p = encode_scsi_range(be, p);
+               else
+                       p = encode_block_extent(be, p);
                be->be_tag = EXTENT_COMMITTING;
        }
        spin_unlock(&bl->bl_ext_lock);
@@ -537,7 +553,7 @@ retry:
        if (unlikely(ret)) {
                ext_tree_free_commitdata(arg, buffer_size);
 
-               buffer_size = ext_tree_layoutupdate_size(count);
+               buffer_size = ext_tree_layoutupdate_size(bl, count);
                count = 0;
 
                arg->layoutupdate_pages =
@@ -556,7 +572,7 @@ retry:
        }
 
        *start_p = cpu_to_be32(count);
-       arg->layoutupdate_len = ext_tree_layoutupdate_size(count);
+       arg->layoutupdate_len = ext_tree_layoutupdate_size(bl, count);
 
        if (unlikely(arg->layoutupdate_pages != &arg->layoutupdate_page)) {
                void *p = start_p, *end = p + arg->layoutupdate_len;