public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* hot scsi disk resize
@ 2003-03-03 17:21 Alex Tomas
  2003-03-03 18:15 ` Christoph Hellwig
  2003-03-04  9:31 ` Fabien Salvi
  0 siblings, 2 replies; 9+ messages in thread
From: Alex Tomas @ 2003-03-03 17:21 UTC (permalink / raw)
  To: linux-scsi; +Cc: James Bottomley, Jens Axboe, Alex Tomas


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) {


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2003-03-17 16:30 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-03-03 17:21 hot scsi disk resize Alex Tomas
2003-03-03 18:15 ` 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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox