diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-17 16:25:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-17 16:25:17 -0400 |
commit | eea036475df8995e5b87cd6b8c8e682e071159cd (patch) | |
tree | 1164e7816565678cd2d2ed68b7580b20baefadde /drivers | |
parent | 1be5f0b7575e090fd100a98b303860879b5800de (diff) | |
parent | cd9323fd68aee3c1c6b5b21e5746c9d1b586fb58 (diff) |
Merge branch '3.4-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull two more target-core updates from Nicholas Bellinger:
"The first patch addresses a SPC-2 reservations RELEASE bug in a
special (iscsi specific) multi-ISID setup case that was allowing the
same initiator to be able to incorrect release it's own reservation on
a different SCSI path with enforce_pr_isid=1 operation. This bug was
caught by Bernhard Kohl.
The second patch is to address a bug with FILEIO backends where the
incorrect number of blocks for READ_CAPACITY was being reported after
an underlying device-mapper block_device size change. This patch uses
now i_size_read() in fd_get_blocks() for FILEIO backends with an
underlying block_device, instead of trying to determine this value at
setup time during fd_create_virtdevice(). (hch CC'ed)
Both are CC'ed to stable."
* '3.4-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
target: Fix bug in handling of FILEIO + block_device resize ops
target: Fix SPC-2 RELEASE bug for multi-session iSCSI client setups
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/target/target_core_file.c | 22 | ||||
-rw-r--r-- | drivers/target/target_core_pr.c | 3 |
2 files changed, 19 insertions, 6 deletions
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 7ed58e2df791..f286955331a2 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -169,6 +169,7 @@ static struct se_device *fd_create_virtdevice( | |||
169 | inode = file->f_mapping->host; | 169 | inode = file->f_mapping->host; |
170 | if (S_ISBLK(inode->i_mode)) { | 170 | if (S_ISBLK(inode->i_mode)) { |
171 | struct request_queue *q; | 171 | struct request_queue *q; |
172 | unsigned long long dev_size; | ||
172 | /* | 173 | /* |
173 | * Setup the local scope queue_limits from struct request_queue->limits | 174 | * Setup the local scope queue_limits from struct request_queue->limits |
174 | * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. | 175 | * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. |
@@ -183,13 +184,12 @@ static struct se_device *fd_create_virtdevice( | |||
183 | * one (1) logical sector from underlying struct block_device | 184 | * one (1) logical sector from underlying struct block_device |
184 | */ | 185 | */ |
185 | fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); | 186 | fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); |
186 | fd_dev->fd_dev_size = (i_size_read(file->f_mapping->host) - | 187 | dev_size = (i_size_read(file->f_mapping->host) - |
187 | fd_dev->fd_block_size); | 188 | fd_dev->fd_block_size); |
188 | 189 | ||
189 | pr_debug("FILEIO: Using size: %llu bytes from struct" | 190 | pr_debug("FILEIO: Using size: %llu bytes from struct" |
190 | " block_device blocks: %llu logical_block_size: %d\n", | 191 | " block_device blocks: %llu logical_block_size: %d\n", |
191 | fd_dev->fd_dev_size, | 192 | dev_size, div_u64(dev_size, fd_dev->fd_block_size), |
192 | div_u64(fd_dev->fd_dev_size, fd_dev->fd_block_size), | ||
193 | fd_dev->fd_block_size); | 193 | fd_dev->fd_block_size); |
194 | } else { | 194 | } else { |
195 | if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) { | 195 | if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) { |
@@ -605,10 +605,20 @@ static u32 fd_get_device_type(struct se_device *dev) | |||
605 | static sector_t fd_get_blocks(struct se_device *dev) | 605 | static sector_t fd_get_blocks(struct se_device *dev) |
606 | { | 606 | { |
607 | struct fd_dev *fd_dev = dev->dev_ptr; | 607 | struct fd_dev *fd_dev = dev->dev_ptr; |
608 | unsigned long long blocks_long = div_u64(fd_dev->fd_dev_size, | 608 | struct file *f = fd_dev->fd_file; |
609 | dev->se_sub_dev->se_dev_attrib.block_size); | 609 | struct inode *i = f->f_mapping->host; |
610 | unsigned long long dev_size; | ||
611 | /* | ||
612 | * When using a file that references an underlying struct block_device, | ||
613 | * ensure dev_size is always based on the current inode size in order | ||
614 | * to handle underlying block_device resize operations. | ||
615 | */ | ||
616 | if (S_ISBLK(i->i_mode)) | ||
617 | dev_size = (i_size_read(i) - fd_dev->fd_block_size); | ||
618 | else | ||
619 | dev_size = fd_dev->fd_dev_size; | ||
610 | 620 | ||
611 | return blocks_long; | 621 | return div_u64(dev_size, dev->se_sub_dev->se_dev_attrib.block_size); |
612 | } | 622 | } |
613 | 623 | ||
614 | static struct se_subsystem_api fileio_template = { | 624 | static struct se_subsystem_api fileio_template = { |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 86f0c3b5d500..c3148b10b4b3 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -220,6 +220,9 @@ int target_scsi2_reservation_release(struct se_task *task) | |||
220 | if (dev->dev_reserved_node_acl != sess->se_node_acl) | 220 | if (dev->dev_reserved_node_acl != sess->se_node_acl) |
221 | goto out_unlock; | 221 | goto out_unlock; |
222 | 222 | ||
223 | if (dev->dev_res_bin_isid != sess->sess_bin_isid) | ||
224 | goto out_unlock; | ||
225 | |||
223 | dev->dev_reserved_node_acl = NULL; | 226 | dev->dev_reserved_node_acl = NULL; |
224 | dev->dev_flags &= ~DF_SPC2_RESERVATIONS; | 227 | dev->dev_flags &= ~DF_SPC2_RESERVATIONS; |
225 | if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) { | 228 | if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) { |