On Thu, 2012-05-17 at 01:58 -0400, Christoph Hellwig wrote: > On Wed, May 16, 2012 at 11:08:03PM +0000, Nicholas A. Bellinger wrote: > > From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> > > > > This patch fixes a bug in the handling of FILEIO w/ underlying block_device > > resize operations where the original fd_dev->fd_dev_size was incorrectly being > > used in fd_get_blocks() for READ_CAPACITY response payloads. > > > > It changes fd_get_blocks() to always set fd_dev->fd_dev_size based on the > > current inode size when an underlying block_device is being referenced. > > I think you should simply stop using fd_dev_size, storing it when it > recalculated all the time just causes confusion. > Fair enough. How about the following incremental patch to avoid fd_dev->fd_dev_size usage for S_ISBLK() cases..? Thanks, diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 077b348..686dba1 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -164,6 +164,7 @@ static struct se_device *fd_create_virtdevice( inode = file->f_mapping->host; if (S_ISBLK(inode->i_mode)) { struct request_queue *q; + unsigned long long dev_size; /* * 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. @@ -178,13 +179,12 @@ static struct se_device *fd_create_virtdevice( * one (1) logical sector from underlying struct block_device */ 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); pr_debug("FILEIO: Using size: %llu bytes from struct" " block_device blocks: %llu logical_block_size: %d\n", - fd_dev->fd_dev_size, - div_u64(fd_dev->fd_dev_size, fd_dev->fd_block_size), + dev_size, div_u64(dev_size, fd_dev->fd_block_size), fd_dev->fd_block_size); } else { if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) { @@ -572,16 +572,18 @@ static sector_t fd_get_blocks(struct se_device *dev) struct fd_dev *fd_dev = dev->dev_ptr; struct file *f = fd_dev->fd_file; struct inode *i = f->f_mapping->host; + unsigned long long dev_size; /* * When using a file that references an underlying struct block_device, - * ensure that fd_dev->fd_dev_size is always based on the current inode - * size in order to handle underlying block_device resize operations. + * 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)) - fd_dev->fd_dev_size = (i_size_read(i) - fd_dev->fd_block_size); + dev_size = (i_size_read(i) - fd_dev->fd_block_size); + else + dev_size = fd_dev->fd_dev_size; - return div_u64(fd_dev->fd_dev_size, - dev->se_sub_dev->se_dev_attrib.block_size); + return div_u64(dev_size, dev->se_sub_dev->se_dev_attrib.block_size); } -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html