public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Partitioning problems in 2.4.11
@ 2001-10-11 20:00 Alexander Viro
  2001-10-11 22:31 ` Christian Ullrich
  2001-10-11 22:42 ` Alexander Viro
  0 siblings, 2 replies; 16+ messages in thread
From: Alexander Viro @ 2001-10-11 20:00 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Christian Ullrich, Vincent Sweeney, arvest, linux-kernel

	OK, folks.  Right now we have at least 3 cases that look like
breakage in check_partition().  All of them had appeared between 2.4.10
and 2.4.11.

a) does 2.4.10-ac12 work for you?  It had got essentially the same
partition-related code that we have in 2.4.11.  I suspect that causes
of breakage are different, so the answer may not be the same for everybody
affected.

b) there are two bugs - one common for -ac and 2.4.11, another - 2.4.11-only.
I really doubt that the first one had been triggered in any of these cases.
The second might be.

c) in one case we have something very nasty - perfectly sane partition tables
as read by dd(1) and read on the right sector returning crap.  And that read
had been traced down to setting the right ->b_blocknr with right ->i_blkbits
and ->i_size.

d) patch below closes two known holes.  It's known to be not enough in
one case (see above) and unlikely to help in another (sda9).  However,
let's get these holes out of the way first.

e) extra eyes on max_block() might be a good idea.  It looks like we
don't get it right.  I don't see immediate problems (after fixing the
->i_blkbits hole), but...

diff -urN S11/fs/block_dev.c S11-part/fs/block_dev.c
--- S11/fs/block_dev.c	Thu Oct 11 11:29:27 2001
+++ S11-part/fs/block_dev.c	Thu Oct 11 15:50:52 2001
@@ -24,29 +24,6 @@
 
 #define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
 
-static inline unsigned int blksize_bits(unsigned int size)
-{
-	unsigned int bits = 8;
-	do {
-		bits++;
-		size >>= 1;
-	} while (size > 256);
-	return bits;
-}
-
-static inline unsigned int block_size(kdev_t dev)
-{
-	int retval = BLOCK_SIZE;
-	int major = MAJOR(dev);
-
-	if (blksize_size[major]) {
-		int minor = MINOR(dev);
-		if (blksize_size[major][minor])
-			retval = blksize_size[major][minor];
-	}
-	return retval;
-}
-
 static unsigned long max_block(kdev_t dev)
 {
 	unsigned int retval = ~0U;
diff -urN S11/fs/partitions/check.c S11-part/fs/partitions/check.c
--- S11/fs/partitions/check.c	Tue Oct  9 21:47:27 2001
+++ S11-part/fs/partitions/check.c	Thu Oct 11 15:50:11 2001
@@ -247,6 +247,7 @@
 		printk(KERN_INFO " %s:", disk_name(hd, MINOR(dev), buf));
 	bdev = bdget(kdev_t_to_nr(dev));
 	bdev->bd_inode->i_size = (loff_t)hd->part[MINOR(dev)].nr_sects << 9;
+	bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
 	for (i = 0; check_part[i]; i++) {
 		int res;
 		res = check_part[i](hd, bdev, first_sector, first_part_minor);
diff -urN S11/fs/partitions/msdos.c S11-part/fs/partitions/msdos.c
--- S11/fs/partitions/msdos.c	Tue Oct  9 21:47:27 2001
+++ S11-part/fs/partitions/msdos.c	Thu Oct 11 13:28:27 2001
@@ -103,21 +103,20 @@
  */
 
 static void extended_partition(struct gendisk *hd, struct block_device *bdev,
-				int minor, int *current_minor)
+			int minor, unsigned long first_size, int *current_minor)
 {
 	struct partition *p;
 	Sector sect;
 	unsigned char *data;
-	unsigned long first_sector, first_size, this_sector, this_size;
+	unsigned long first_sector, this_sector, this_size;
 	int mask = (1 << hd->minor_shift) - 1;
 	int sector_size = get_hardsect_size(to_kdev_t(bdev->bd_dev)) / 512;
 	int loopct = 0;		/* number of links followed
 				   without finding a data partition */
 	int i;
 
-	first_sector = hd->part[minor].start_sect;
-	first_size = hd->part[minor].nr_sects;
-	this_sector = first_sector;
+	this_sector = first_sector = hd->part[minor].start_sect;
+	this_size = first_size;
 
 	while (1) {
 		if (++loopct > 100)
@@ -133,8 +132,6 @@
 
 		p = (struct partition *) (data + 0x1be);
 
-		this_size = hd->part[minor].nr_sects;
-
 		/*
 		 * Usually, the first entry is the real data partition,
 		 * the 2nd entry is the next extended partition, or empty,
@@ -196,6 +193,7 @@
 			goto done;	 /* nothing left to do */
 
 		this_sector = first_sector + START_SECT(p) * sector_size;
+		this_size = NR_SECTS(p) * sector_size;
 		minor = *current_minor;
 		put_dev_sector(sect);
 	}
@@ -586,12 +584,13 @@
 		}
 #endif
 		if (is_extended_partition(p)) {
+			unsigned long size = hd->part[minor].nr_sects;
 			printk(" <");
 			/* prevent someone doing mkfs or mkswap on an
 			   extended partition, but leave room for LILO */
-			if (hd->part[minor].nr_sects > 2)
+			if (size > 2)
 				hd->part[minor].nr_sects = 2;
-			extended_partition(hd, bdev, minor, &current_minor);
+			extended_partition(hd, bdev, minor, size, &current_minor);
 			printk(" >");
 		}
 	}
diff -urN S11/include/linux/blkdev.h S11-part/include/linux/blkdev.h
--- S11/include/linux/blkdev.h	Tue Oct  9 21:47:28 2001
+++ S11-part/include/linux/blkdev.h	Thu Oct 11 11:30:01 2001
@@ -203,4 +203,27 @@
 #define blk_finished_io(nsects)	do { } while (0)
 #define blk_started_io(nsects)	do { } while (0)
 
+static inline unsigned int blksize_bits(unsigned int size)
+{
+	unsigned int bits = 8;
+	do {
+		bits++;
+		size >>= 1;
+	} while (size > 256);
+	return bits;
+}
+
+static inline unsigned int block_size(kdev_t dev)
+{
+	int retval = BLOCK_SIZE;
+	int major = MAJOR(dev);
+
+	if (blksize_size[major]) {
+		int minor = MINOR(dev);
+		if (blksize_size[major][minor])
+			retval = blksize_size[major][minor];
+	}
+	return retval;
+}
+
 #endif


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

end of thread, other threads:[~2001-10-12 10:21 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-10-11 20:00 Partitioning problems in 2.4.11 Alexander Viro
2001-10-11 22:31 ` Christian Ullrich
2001-10-11 22:59   ` Alexander Viro
2001-10-11 23:03     ` Christian Ullrich
2001-10-11 23:10       ` Jeff Garzik
2001-10-11 23:22         ` Alexander Viro
2001-10-11 23:28           ` David S. Miller
2001-10-11 23:27         ` David S. Miller
2001-10-11 23:34     ` Stephan von Krawczynski
2001-10-11 23:43       ` Alexander Viro
2001-10-11 22:42 ` Alexander Viro
2001-10-11 23:08   ` Christian Ullrich
2001-10-11 23:19     ` Alexander Viro
2001-10-11 23:55     ` [PATCH] " Alexander Viro
2001-10-12 10:19     ` Vincent Sweeney
2001-10-11 23:30   ` Alexander Viro

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