summaryrefslogtreecommitdiffstats
path: root/fs/partitions/ibm.c
diff options
context:
space:
mode:
authorHorst Hummel <horst.hummel@de.ibm.com>2006-03-08 06:55:39 +0100
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-08 23:14:01 +0100
commit90f0094dc607abe384a412bfb7199fb667ab0735 (patch)
tree2cd4c048a95d49a532bd237388f2b50ceb55ceb6 /fs/partitions/ibm.c
parent[PATCH] s390: iucv message limit for smsg (diff)
downloadlinux-90f0094dc607abe384a412bfb7199fb667ab0735.tar.xz
linux-90f0094dc607abe384a412bfb7199fb667ab0735.zip
[PATCH] s390: dasd partition detection
DASD allows to open a device as soon as gendisk is registered, which means the device is a fake device (capacity=0) and we do know nothing about blocksize and partitions at that point of time. In case the device is opened by someone, the bdev and inode creation is done with the fake device info and the following partition detection code is just using the wrong data. To avoid this modify the DASD state machine to make sure that the open is rejected until the device analysis is either finished or an unformatted device was detected. Signed-off-by: Horst Hummel <horst.hummel@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/partitions/ibm.c')
-rw-r--r--fs/partitions/ibm.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index 78010ad60e47..1e4a93835fed 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -52,6 +52,7 @@ int
ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
{
int blocksize, offset, size;
+ loff_t i_size;
dasd_information_t *info;
struct hd_geometry *geo;
char type[5] = {0,};
@@ -63,6 +64,13 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
unsigned char *data;
Sector sect;
+ blocksize = bdev_hardsect_size(bdev);
+ if (blocksize <= 0)
+ return 0;
+ i_size = i_size_read(bdev->bd_inode);
+ if (i_size == 0)
+ return 0;
+
if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL)
goto out_noinfo;
if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
@@ -73,9 +81,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0)
goto out_noioctl;
-
- if ((blocksize = bdev_hardsect_size(bdev)) <= 0)
- goto out_badsect;
/*
* Get volume label, extract name and type.
@@ -111,7 +116,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
} else {
printk("CMS1/%8s:", name);
offset = (info->label_block + 1);
- size = bdev->bd_inode->i_size >> 9;
+ size = i_size >> 9;
}
put_partition(state, 1, offset*(blocksize >> 9),
size-offset*(blocksize >> 9));
@@ -168,7 +173,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
else
printk("(nonl)/%8s:", name);
offset = (info->label_block + 1);
- size = (bdev->bd_inode->i_size >> 9);
+ size = i_size >> 9;
put_partition(state, 1, offset*(blocksize >> 9),
size-offset*(blocksize >> 9));
}
@@ -180,7 +185,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
return 1;
out_readerr:
-out_badsect:
out_noioctl:
kfree(label);
out_nolab: