linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Reread partition table when a partition is added
@ 2004-08-22 22:19 Stefanos Harhalakis
  2004-08-23  9:53 ` Andries Brouwer
  0 siblings, 1 reply; 3+ messages in thread
From: Stefanos Harhalakis @ 2004-08-22 22:19 UTC (permalink / raw)
  To: rmk; +Cc: linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 2641 bytes --]

  This small patch rereads the partition table even if the block device is 
beeing used. It only rereads it when there are no changes at the current 
partitions and there are new partitions added at the end. Any existing 
partition change will/should make it fail.

  Is it OK and/or useful ?

  (I'm quite inexperienced about kernel coding so be gentle :)

Signed-off-by: Stefanos Harhalakis <v13@priest.com>

RCS file: /usr/local/cvsroot/linux-2.6/fs/partitions/check.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 check.c
--- check.c	22 Aug 2004 11:08:27 -0000	1.1.1.1
+++ check.c	22 Aug 2004 22:09:11 -0000
@@ -391,19 +391,44 @@ void register_disk(struct gendisk *disk)
 	blkdev_put(bdev);
 }
 
+/*
+ * Determine the last partition.
+ * Return the partition number or 0 if there is no partition
+ */
+static int get_last_partition(struct gendisk *disk)
+{
+	int	n, ret = 0;
+
+	for (n=0; n < disk->minors ; n++) {
+		if (disk->part[n])
+			ret=n+1;
+	}
+
+	return(ret);
+}
+
 int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
 {
 	struct parsed_partitions *state;
+	struct hd_struct *phd;
 	int p, res;
+	int is_busy = 0, last_partition = 0;
+
+	if (bdev->bd_part_count) {
+		is_busy = 1;
+		last_partition=get_last_partition(disk);
+	}
 
-	if (bdev->bd_part_count)
-		return -EBUSY;
 	res = invalidate_partition(disk, 0);
 	if (res)
 		return res;
 	bdev->bd_invalidated = 0;
-	for (p = 1; p < disk->minors; p++)
-		delete_partition(disk, p);
+
+	if (!is_busy) {
+		for (p = 1; p < disk->minors; p++)
+			delete_partition(disk, p);
+	}
+
 	if (disk->fops->revalidate_disk)
 		disk->fops->revalidate_disk(disk);
 	if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
@@ -411,13 +436,29 @@ int rescan_partitions(struct gendisk *di
 	for (p = 1; p < state->limit; p++) {
 		sector_t size = state->parts[p].size;
 		sector_t from = state->parts[p].from;
+
+		if (is_busy && p<=last_partition) {
+			phd=disk->part[p-1];
+			if (phd != NULL && (phd->start_sect != from ||
+			 	phd->nr_sects != size)) {
+				printk(KERN_INFO
+					"Existing partition was changed. "
+					"Reboot is required.\n");
+				res=-EBUSY;
+				break;
+			}
+		}
+
 		if (!size)
 			continue;
-		add_partition(disk, p, from, size);
+
+		if (!is_busy || p>last_partition) {
+			add_partition(disk, p, from, size);
 #ifdef CONFIG_BLK_DEV_MD
-		if (state->parts[p].flags)
-			md_autodetect_dev(bdev->bd_dev+p);
+			if (state->parts[p].flags)
+				md_autodetect_dev(bdev->bd_dev+p);
 #endif
+		}
 	}
 	kfree(state);
 	return res;

[-- Attachment #1.2: rescan_partitions.patch --]
[-- Type: text/x-diff, Size: 2219 bytes --]

RCS file: /usr/local/cvsroot/linux-2.6/fs/partitions/check.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 check.c
--- check.c	22 Aug 2004 11:08:27 -0000	1.1.1.1
+++ check.c	22 Aug 2004 22:09:11 -0000
@@ -391,19 +391,44 @@ void register_disk(struct gendisk *disk)
 	blkdev_put(bdev);
 }
 
+/*
+ * Determine the last partition.
+ * Return the partition number or 0 if there is no partition
+ */
+static int get_last_partition(struct gendisk *disk)
+{
+	int	n, ret = 0;
+
+	for (n=0; n < disk->minors ; n++) {
+		if (disk->part[n])
+			ret=n+1;
+	}
+
+	return(ret);
+}
+
 int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
 {
 	struct parsed_partitions *state;
+	struct hd_struct *phd;
 	int p, res;
+	int is_busy = 0, last_partition = 0;
+
+	if (bdev->bd_part_count) {
+		is_busy = 1;
+		last_partition=get_last_partition(disk);
+	}
 
-	if (bdev->bd_part_count)
-		return -EBUSY;
 	res = invalidate_partition(disk, 0);
 	if (res)
 		return res;
 	bdev->bd_invalidated = 0;
-	for (p = 1; p < disk->minors; p++)
-		delete_partition(disk, p);
+
+	if (!is_busy) {
+		for (p = 1; p < disk->minors; p++)
+			delete_partition(disk, p);
+	}
+
 	if (disk->fops->revalidate_disk)
 		disk->fops->revalidate_disk(disk);
 	if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
@@ -411,13 +436,29 @@ int rescan_partitions(struct gendisk *di
 	for (p = 1; p < state->limit; p++) {
 		sector_t size = state->parts[p].size;
 		sector_t from = state->parts[p].from;
+
+		if (is_busy && p<=last_partition) {
+			phd=disk->part[p-1];
+			if (phd != NULL && (phd->start_sect != from ||
+			 	phd->nr_sects != size)) {
+				printk(KERN_INFO
+					"Existing partition was changed. "
+					"Reboot is required.\n");
+				res=-EBUSY;
+				break;
+			}
+		}
+
 		if (!size)
 			continue;
-		add_partition(disk, p, from, size);
+
+		if (!is_busy || p>last_partition) {
+			add_partition(disk, p, from, size);
 #ifdef CONFIG_BLK_DEV_MD
-		if (state->parts[p].flags)
-			md_autodetect_dev(bdev->bd_dev+p);
+			if (state->parts[p].flags)
+				md_autodetect_dev(bdev->bd_dev+p);
 #endif
+		}
 	}
 	kfree(state);
 	return res;

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [PATCH] Reread partition table when a partition is added
  2004-08-22 22:19 [PATCH] Reread partition table when a partition is added Stefanos Harhalakis
@ 2004-08-23  9:53 ` Andries Brouwer
  2004-08-23 16:14   ` V13
  0 siblings, 1 reply; 3+ messages in thread
From: Andries Brouwer @ 2004-08-23  9:53 UTC (permalink / raw)
  To: Stefanos Harhalakis; +Cc: rmk, linux-kernel

On Mon, Aug 23, 2004 at 01:19:06AM +0300, Stefanos Harhalakis wrote:

>   This small patch rereads the partition table even if the block device is 
> beeing used. It only rereads it when there are no changes at the current 
> partitions and there are new partitions added at the end. Any existing 
> partition change will/should make it fail.
> 
>   Is it OK and/or useful ?

What you want is possible already today.
For an example, see partx in util-linux.

Andries


[More precisely: rereading the pt consists of (i) reading pt, and
(ii) updating kernel tables. Now (i) can be done from user space,
by fdisk-type programs, and (ii) can be done from user space,
by partx-type programs.]

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

* Re: [PATCH] Reread partition table when a partition is added
  2004-08-23  9:53 ` Andries Brouwer
@ 2004-08-23 16:14   ` V13
  0 siblings, 0 replies; 3+ messages in thread
From: V13 @ 2004-08-23 16:14 UTC (permalink / raw)
  To: Andries Brouwer; +Cc: rmk, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 757 bytes --]

On Monday 23 August 2004 12:53, Andries Brouwer wrote:
> On Mon, Aug 23, 2004 at 01:19:06AM +0300, Stefanos Harhalakis wrote:
> >   This small patch rereads the partition table even if the block device
> > is beeing used. It only rereads it when there are no changes at the
> > current partitions and there are new partitions added at the end. Any
> > existing partition change will/should make it fail.
> >
> >   Is it OK and/or useful ?
>
> What you want is possible already today.
> For an example, see partx in util-linux.

Oh! didn't new about that. Indeed it seems to be the right thing to do (tm) 
regarding partition handling. Util-linux does not build partx by default so I 
didn't notice it at all.

Thanks!

> Andries
<<V13>>

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

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

end of thread, other threads:[~2004-08-23 16:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-22 22:19 [PATCH] Reread partition table when a partition is added Stefanos Harhalakis
2004-08-23  9:53 ` Andries Brouwer
2004-08-23 16:14   ` V13

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).