From: Alex Tomas <bzzz@tmi.comex.ru>
To: linux-scsi@vger.kernel.org
Cc: James Bottomley <James.Bottomley@steeleye.com>,
Jens Axboe <axboe@suse.de>, Alex Tomas <bzzz@tmi.comex.ru>
Subject: hot scsi disk resize
Date: 03 Mar 2003 20:21:24 +0300 [thread overview]
Message-ID: <m3bs0s9xij.fsf@lexa.home.net> (raw)
Hello!
Here is patch to implement hot scsi resize function.
Modern storage boxes support virtualization feature and
may change logical volume size online. I think it would
be great if linux supports such abilities. Look at
this example:
root@zefir:# dmesg | tail
scsi0:A:1:0: Tagged Queuing enabled. Depth 32
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
root@zefir:# mount -treiserfs /dev/sda /mnt
root@zefir:# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/hda1 ext3 1.9G 1.8G 138M 93% /
/dev/sda reiserfs 1.0G 33M 991M 4% /mnt
root@zefir:# echo 'scsi rescan 0 0 1 0' >/proc/scsi/scsi
root@zefir:# dmesg|tail -n1
SCSI device sda: 20971520 512-byte hdwr sectors (10737 MB)
root@zefir:# resize_reiserfs /dev/sda
<-------------resize_reiserfs, 2002------------->
reiserfsprogs 3.6.4
root@zefir:# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/hda1 ext3 1.9G 1.8G 138M 93% /
/dev/sda reiserfs 10G 33M 9.9G 1% /mnt
I think it's really useful for for high-availability systems.
MS Windows has supported online disk resize since 2000. I Would
be happy to hear any comments and suggestions.
diff -uNr linux/drivers/scsi/hosts.h edited/drivers/scsi/hosts.h
--- linux/drivers/scsi/hosts.h Thu Feb 20 13:18:16 2003
+++ edited/drivers/scsi/hosts.h Mon Mar 3 18:48:16 2003
@@ -558,6 +558,7 @@
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;
};
diff -uNr linux/drivers/scsi/scsi.c edited/drivers/scsi/scsi.c
--- linux/drivers/scsi/scsi.c Thu Feb 20 13:18:17 2003
+++ edited/drivers/scsi/scsi.c Mon Mar 3 18:48:16 2003
@@ -1510,6 +1510,21 @@
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))
diff -uNr linux/drivers/scsi/scsi_proc.c edited/drivers/scsi/scsi_proc.c
--- linux/drivers/scsi/scsi_proc.c Thu Feb 20 13:18:17 2003
+++ edited/drivers/scsi/scsi_proc.c Mon Mar 3 18:48:16 2003
@@ -551,6 +551,18 @@
lun = simple_strtoul(p + 1, &p, 0);
err = scsi_remove_single_device(host, channel, id, lun);
+ if (err >= 0)
+ err = length;
+ } else if (!strncmp("rescan", buffer + 5, 6)) {
+ p = buffer + 12;
+
+ host = simple_strtoul(p, &p, 0);
+ channel = simple_strtoul(p + 1, &p, 0);
+ id = simple_strtoul(p + 1, &p, 0);
+ lun = simple_strtoul(p + 1, &p, 0);
+ err = scsi_rescan_single_device(host, channel, id, lun);
+ if (err >= 0)
+ err = length;
}
out:
diff -uNr linux/drivers/scsi/scsi_scan.c edited/drivers/scsi/scsi_scan.c
--- linux/drivers/scsi/scsi_scan.c Thu Feb 20 13:18:17 2003
+++ edited/drivers/scsi/scsi_scan.c Mon Mar 3 18:48:16 2003
@@ -1796,6 +1796,24 @@
return error;
}
+int scsi_rescan_single_device(uint host, uint channel, uint id, uint lun)
+{
+ struct scsi_device *sdev;
+ struct Scsi_Host *shost;
+
+ shost = scsi_host_hn_get(host);
+ if (!shost)
+ return -ENODEV;
+ sdev = scsi_find_device(shost, channel, id, lun);
+ if (!sdev)
+ goto out;
+
+ scsi_rescan_device(sdev);
+out:
+ scsi_host_put(shost);
+ return 0;
+}
+
/**
* scsi_scan_target - scan a target id, possibly including all LUNs on the
* target.
diff -uNr linux/drivers/scsi/sd.c edited/drivers/scsi/sd.c
--- linux/drivers/scsi/sd.c Mon Jan 20 02:23:42 2003
+++ edited/drivers/scsi/sd.c Mon Mar 3 19:19:25 2003
@@ -93,10 +93,12 @@
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 @@
.scsi_type = TYPE_DISK,
.attach = sd_attach,
.detach = sd_detach,
+ .rescan = sd_rescan,
.init_command = sd_init_command,
.scsi_driverfs_driver = {
.name = "sd",
@@ -627,6 +630,38 @@
not_present:
set_media_not_present(sdkp);
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)
diff -uNr linux/fs/block_dev.c edited/fs/block_dev.c
--- linux/fs/block_dev.c Mon Jan 20 02:23:49 2003
+++ edited/fs/block_dev.c Mon Mar 3 18:49:47 2003
@@ -623,6 +623,8 @@
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) {
next reply other threads:[~2003-03-03 17:21 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-03-03 17:21 Alex Tomas [this message]
2003-03-03 18:15 ` hot scsi disk resize Christoph Hellwig
2003-03-04 5:37 ` Alex Tomas
2003-03-04 7:00 ` alexey
2003-03-17 16:21 ` James Bottomley
2003-03-17 16:30 ` Christoph Hellwig
2003-03-04 9:31 ` Fabien Salvi
2003-03-04 9:42 ` alexey
2003-03-05 10:18 ` Fabien Salvi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3bs0s9xij.fsf@lexa.home.net \
--to=bzzz@tmi.comex.ru \
--cc=James.Bottomley@steeleye.com \
--cc=axboe@suse.de \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox