Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[linux.git] / drivers / target / target_core_rd.c
index 66a5aba5a0d9c6a6708582a026b25b0f6a17075e..b920db3388cdc19d4bef721a6c6d55680cfd2d8c 100644 (file)
@@ -242,7 +242,7 @@ static void rd_release_prot_space(struct rd_dev *rd_dev)
        rd_dev->sg_prot_count = 0;
 }
 
-static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length)
+static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length, int block_size)
 {
        struct rd_dev_sg_table *sg_table;
        u32 total_sg_needed, sg_tables;
@@ -252,8 +252,13 @@ static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length)
 
        if (rd_dev->rd_flags & RDF_NULLIO)
                return 0;
-
-       total_sg_needed = rd_dev->rd_page_count / prot_length;
+       /*
+        * prot_length=8byte dif data
+        * tot sg needed = rd_page_count * (PGSZ/block_size) *
+        *                 (prot_length/block_size) + pad
+        * PGSZ canceled each other.
+        */
+       total_sg_needed = (rd_dev->rd_page_count * prot_length / block_size) + 1;
 
        sg_tables = (total_sg_needed / max_sg_per_table) + 1;
 
@@ -606,7 +611,8 @@ static int rd_init_prot(struct se_device *dev)
         if (!dev->dev_attrib.pi_prot_type)
                return 0;
 
-       return rd_build_prot_space(rd_dev, dev->prot_length);
+       return rd_build_prot_space(rd_dev, dev->prot_length,
+                                  dev->dev_attrib.block_size);
 }
 
 static void rd_free_prot(struct se_device *dev)