]>
Commit | Line | Data |
---|---|---|
eefdbb8e GKH |
1 | From c836777830428372074d5129ac513e1472c99791 Mon Sep 17 00:00:00 2001 |
2 | From: Akinobu Mita <akinobu.mita@gmail.com> | |
3 | Date: Mon, 13 Apr 2015 23:21:57 +0900 | |
4 | Subject: target/file: Fix SG table for prot_buf initialization | |
5 | ||
6 | From: Akinobu Mita <akinobu.mita@gmail.com> | |
7 | ||
8 | commit c836777830428372074d5129ac513e1472c99791 upstream. | |
9 | ||
10 | In fd_do_prot_rw(), it allocates prot_buf which is used to copy from | |
11 | se_cmd->t_prot_sg by sbc_dif_copy_prot(). The SG table for prot_buf | |
12 | is also initialized by allocating 'se_cmd->t_prot_nents' entries of | |
13 | scatterlist and setting the data length of each entry to PAGE_SIZE | |
14 | at most. | |
15 | ||
16 | However if se_cmd->t_prot_sg contains a clustered entry (i.e. | |
17 | sg->length > PAGE_SIZE), the SG table for prot_buf can't be | |
18 | initialized correctly and sbc_dif_copy_prot() can't copy to prot_buf. | |
19 | (This actually happened with TCM loopback fabric module) | |
20 | ||
21 | As prot_buf is allocated by kzalloc() and it's physically contiguous, | |
22 | we only need a single scatterlist entry. | |
23 | ||
24 | Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> | |
25 | Cc: Sagi Grimberg <sagig@mellanox.com> | |
26 | Cc: "Martin K. Petersen" <martin.petersen@oracle.com> | |
27 | Cc: Christoph Hellwig <hch@lst.de> | |
28 | Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> | |
29 | Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> | |
30 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
31 | ||
32 | --- | |
33 | drivers/target/target_core_file.c | 21 ++++++--------------- | |
34 | 1 file changed, 6 insertions(+), 15 deletions(-) | |
35 | ||
36 | --- a/drivers/target/target_core_file.c | |
37 | +++ b/drivers/target/target_core_file.c | |
38 | @@ -264,11 +264,10 @@ static int fd_do_prot_rw(struct se_cmd * | |
39 | struct se_device *se_dev = cmd->se_dev; | |
40 | struct fd_dev *dev = FD_DEV(se_dev); | |
41 | struct file *prot_fd = dev->fd_prot_file; | |
42 | - struct scatterlist *sg; | |
43 | loff_t pos = (cmd->t_task_lba * se_dev->prot_length); | |
44 | unsigned char *buf; | |
45 | - u32 prot_size, len, size; | |
46 | - int rc, ret = 1, i; | |
47 | + u32 prot_size; | |
48 | + int rc, ret = 1; | |
49 | ||
50 | prot_size = (cmd->data_length / se_dev->dev_attrib.block_size) * | |
51 | se_dev->prot_length; | |
52 | @@ -281,24 +280,16 @@ static int fd_do_prot_rw(struct se_cmd * | |
53 | } | |
54 | buf = fd_prot->prot_buf; | |
55 | ||
56 | - fd_prot->prot_sg_nents = cmd->t_prot_nents; | |
57 | - fd_prot->prot_sg = kzalloc(sizeof(struct scatterlist) * | |
58 | - fd_prot->prot_sg_nents, GFP_KERNEL); | |
59 | + fd_prot->prot_sg_nents = 1; | |
60 | + fd_prot->prot_sg = kzalloc(sizeof(struct scatterlist), | |
61 | + GFP_KERNEL); | |
62 | if (!fd_prot->prot_sg) { | |
63 | pr_err("Unable to allocate fd_prot->prot_sg\n"); | |
64 | kfree(fd_prot->prot_buf); | |
65 | return -ENOMEM; | |
66 | } | |
67 | sg_init_table(fd_prot->prot_sg, fd_prot->prot_sg_nents); | |
68 | - size = prot_size; | |
69 | - | |
70 | - for_each_sg(fd_prot->prot_sg, sg, fd_prot->prot_sg_nents, i) { | |
71 | - | |
72 | - len = min_t(u32, PAGE_SIZE, size); | |
73 | - sg_set_buf(sg, buf, len); | |
74 | - size -= len; | |
75 | - buf += len; | |
76 | - } | |
77 | + sg_set_buf(fd_prot->prot_sg, buf, prot_size); | |
78 | } | |
79 | ||
80 | if (is_write) { |