Commit eea03647 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 1be5f0b7 cd9323fd
...@@ -169,6 +169,7 @@ static struct se_device *fd_create_virtdevice( ...@@ -169,6 +169,7 @@ static struct se_device *fd_create_virtdevice(
inode = file->f_mapping->host; inode = file->f_mapping->host;
if (S_ISBLK(inode->i_mode)) { if (S_ISBLK(inode->i_mode)) {
struct request_queue *q; struct request_queue *q;
unsigned long long dev_size;
/* /*
* Setup the local scope queue_limits from struct request_queue->limits * Setup the local scope queue_limits from struct request_queue->limits
* to pass into transport_add_device_to_core_hba() as struct se_dev_limits. * 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,13 +184,12 @@ static struct se_device *fd_create_virtdevice(
* one (1) logical sector from underlying struct block_device * one (1) logical sector from underlying struct block_device
*/ */
fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev);
fd_dev->fd_dev_size = (i_size_read(file->f_mapping->host) - dev_size = (i_size_read(file->f_mapping->host) -
fd_dev->fd_block_size); fd_dev->fd_block_size);
pr_debug("FILEIO: Using size: %llu bytes from struct" pr_debug("FILEIO: Using size: %llu bytes from struct"
" block_device blocks: %llu logical_block_size: %d\n", " block_device blocks: %llu logical_block_size: %d\n",
fd_dev->fd_dev_size, dev_size, div_u64(dev_size, fd_dev->fd_block_size),
div_u64(fd_dev->fd_dev_size, fd_dev->fd_block_size),
fd_dev->fd_block_size); fd_dev->fd_block_size);
} else { } else {
if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) { if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) {
...@@ -605,10 +605,20 @@ static u32 fd_get_device_type(struct se_device *dev) ...@@ -605,10 +605,20 @@ static u32 fd_get_device_type(struct se_device *dev)
static sector_t fd_get_blocks(struct se_device *dev) static sector_t fd_get_blocks(struct se_device *dev)
{ {
struct fd_dev *fd_dev = dev->dev_ptr; struct fd_dev *fd_dev = dev->dev_ptr;
unsigned long long blocks_long = div_u64(fd_dev->fd_dev_size, struct file *f = fd_dev->fd_file;
dev->se_sub_dev->se_dev_attrib.block_size); struct inode *i = f->f_mapping->host;
unsigned long long dev_size;
/*
* When using a file that references an underlying struct block_device,
* ensure dev_size is always based on the current inode size in order
* to handle underlying block_device resize operations.
*/
if (S_ISBLK(i->i_mode))
dev_size = (i_size_read(i) - fd_dev->fd_block_size);
else
dev_size = fd_dev->fd_dev_size;
return blocks_long; return div_u64(dev_size, dev->se_sub_dev->se_dev_attrib.block_size);
} }
static struct se_subsystem_api fileio_template = { static struct se_subsystem_api fileio_template = {
......
...@@ -220,6 +220,9 @@ int target_scsi2_reservation_release(struct se_task *task) ...@@ -220,6 +220,9 @@ int target_scsi2_reservation_release(struct se_task *task)
if (dev->dev_reserved_node_acl != sess->se_node_acl) if (dev->dev_reserved_node_acl != sess->se_node_acl)
goto out_unlock; goto out_unlock;
if (dev->dev_res_bin_isid != sess->sess_bin_isid)
goto out_unlock;
dev->dev_reserved_node_acl = NULL; dev->dev_reserved_node_acl = NULL;
dev->dev_flags &= ~DF_SPC2_RESERVATIONS; dev->dev_flags &= ~DF_SPC2_RESERVATIONS;
if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) { if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment