Commit d685cc6d authored by Alex Tomas's avatar Alex Tomas Committed by James Bottomley

[PATCH] Re: hot scsi disk resize

Hi!

Here is new version of the patch. All procfs-related stuff has been removed.
One may rescan device size writing something to /sysfs/.../<scsi device>/rescan:

root@zefir:~# echo 1 >/sysfs/bus/scsi/devices/0\:0\:1\:0/rescan
root@zefir:~# dmesg
scsi0:A:1:0: Tagged Queuing enabled.  Depth 64
scsi: host 0 channel 0 id 1 lun16384 has a LUN larger than allowed by the host adapter
SCSI device sda: 2097152 512-byte hdwr sectors (1074 MB)
SCSI device sda: drive cache: write through
 sda: unknown partition table
Attached scsi disk sda at scsi0, channel 0, id 1, lun 0
SCSI device sda: 125829120 512-byte hdwr sectors (64425 MB)
root@zefir:~#
parent 7fe8f35f
......@@ -549,6 +549,7 @@ struct Scsi_Device_Template
void (*detach)(Scsi_Device *);
int (*init_command)(Scsi_Cmnd *); /* Used by new queueing code.
Selects command for blkdevs */
void (*rescan)(Scsi_Device *);
struct device_driver scsi_driverfs_driver;
};
......
......@@ -1264,6 +1264,21 @@ void scsi_detach_device(struct scsi_device *sdev)
up_read(&scsi_devicelist_mutex);
}
void scsi_rescan_device(struct scsi_device *sdev)
{
struct Scsi_Device_Template *sdt;
down_read(&scsi_devicelist_mutex);
list_for_each_entry(sdt, &scsi_devicelist, list) {
if (!try_module_get(sdt->module))
continue;
if (*sdt->rescan)
(*sdt->rescan)(sdev);
module_put(sdt->module);
}
up_read(&scsi_devicelist_mutex);
}
int scsi_device_get(struct scsi_device *sdev)
{
if (!try_module_get(sdev->host->hostt->module))
......
......@@ -266,6 +266,25 @@ sdev_rd_attr (model, "%.16s\n");
sdev_rd_attr (rev, "%.4s\n");
sdev_rw_attr_bit (online);
static ssize_t
show_rescan_field (struct device *dev, char *buf)
{
return 0;
}
static ssize_t
store_rescan_field (struct device *dev, const char *buf, size_t count)
{
int ret = ENODEV;
struct scsi_device *sdev;
sdev = to_scsi_device(dev);
if (sdev)
ret = scsi_rescan_device(sdev);
return ret;
}
static DEVICE_ATTR(rescan, S_IRUGO | S_IWUSR, show_rescan_field, store_rescan_field)
static struct device_attribute * const sdev_attrs[] = {
&dev_attr_device_blocked,
&dev_attr_queue_depth,
......@@ -276,6 +295,7 @@ static struct device_attribute * const sdev_attrs[] = {
&dev_attr_model,
&dev_attr_rev,
&dev_attr_online,
&dev_attr_rescan,
};
/**
......
......@@ -93,10 +93,12 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt);
static int sd_attach(struct scsi_device *);
static void sd_detach(struct scsi_device *);
static void sd_rescan(struct scsi_device *);
static int sd_init_command(struct scsi_cmnd *);
static int sd_synchronize_cache(struct scsi_disk *, int);
static int sd_notifier(struct notifier_block *, unsigned long, void *);
static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer);
static struct notifier_block sd_notifier_block = {sd_notifier, NULL, 0};
static struct Scsi_Device_Template sd_template = {
......@@ -106,6 +108,7 @@ static struct Scsi_Device_Template sd_template = {
.scsi_type = TYPE_DISK,
.attach = sd_attach,
.detach = sd_detach,
.rescan = sd_rescan,
.init_command = sd_init_command,
.scsi_driverfs_driver = {
.name = "sd",
......@@ -629,6 +632,38 @@ static int sd_media_changed(struct gendisk *disk)
return 1;
}
static void sd_rescan(struct scsi_device * sdp)
{
unsigned char *buffer;
struct scsi_disk *sdkp = sd_find_by_sdev(sdp);
struct gendisk *gd;
struct scsi_request *SRpnt;
if (!sdkp || sdp->online == FALSE || !sdkp->media_present)
return;
gd = sdkp->disk;
SCSI_LOG_HLQUEUE(3, printk("sd_rescan: disk=%s\n", gd->disk_name));
SRpnt = scsi_allocate_request(sdp);
if (!SRpnt) {
printk(KERN_WARNING "(sd_rescan:) Request allocation "
"failure.\n");
return;
}
if (sdkp->device->host->unchecked_isa_dma)
buffer = kmalloc(512, GFP_DMA);
else
buffer = kmalloc(512, GFP_KERNEL);
sd_read_capacity(sdkp, gd->disk_name, SRpnt, buffer);
set_capacity(gd, sdkp->capacity);
scsi_release_request(SRpnt);
kfree(buffer);
}
static int sd_revalidate_disk(struct gendisk *disk)
{
struct scsi_disk *sdkp = scsi_disk(disk);
......
......@@ -573,6 +573,8 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
up(&whole->bd_sem);
}
} else {
if (!part)
bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
put_disk(disk);
module_put(owner);
if (bdev->bd_contains == bdev) {
......
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