All of lore.kernel.org
 help / color / mirror / Atom feed
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) {


             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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.