diff options
| author | Alexander Viro <viro@math.psu.edu> | 2002-07-20 20:47:53 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-07-20 20:47:53 -0700 |
| commit | 5844ac33e46839babf72edf7e8315b45cb95ebc6 (patch) | |
| tree | 91b38eeb23cbf72668f1b6270b19d83f0de140c6 | |
| parent | a22f8253014bf053a5253ad9388611c368a7e285 (diff) | |
[PATCH] block device size cleanups
for partitioned devices we use ->nr_sect to find the size; blk_size[] is
still used for things like floppy.c, etc.; that will go away later.
There was only one place (do_open()) that needed it - the rest uses
->bd_inode->i_size now. So blkdev_size_in_bytes() is gone - it's
expanded in its only caller. Same place (do_open()) finds the partition
offset and stores it in new field ->bd_offset. As the result, call of
get_gendisk() is gone from the IO path - in blk_partition_remap() we
just add ->bd_offset.
Additionally, we take driver probing (get_blkfops()) outside of ->bd_sem
(again, do_open()) - that will allow to kill ad-hackery in check_partitions()
(opening bdev by hand).
| -rw-r--r-- | drivers/block/ll_rw_blk.c | 8 | ||||
| -rw-r--r-- | fs/block_dev.c | 57 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 14 | ||||
| -rw-r--r-- | include/linux/fs.h | 1 |
4 files changed, 36 insertions, 44 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 48616f94f5ee..8ada278181c8 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1573,16 +1573,10 @@ end_io: static inline void blk_partition_remap(struct bio *bio) { struct block_device *bdev = bio->bi_bdev; - struct gendisk *g; - if (bdev == bdev->bd_contains) return; - g = get_gendisk(to_kdev_t(bdev->bd_dev)); - if (!g) - BUG(); - - bio->bi_sector += g->part[minor(to_kdev_t((bdev->bd_dev)))].start_sect; + bio->bi_sector += bdev->bd_offset; bio->bi_bdev = bdev->bd_contains; /* lots of checks are possible */ } diff --git a/fs/block_dev.c b/fs/block_dev.c index aa496e1bdd29..90c46b454f3c 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -37,14 +37,6 @@ static unsigned long max_block(struct block_device *bdev) return retval; } -static loff_t blkdev_size(kdev_t dev) -{ - loff_t sz = blkdev_size_in_bytes(dev); - if (sz) - return sz; - return ~0ULL; -} - /* Kill _all_ buffers, dirty or not.. */ static void kill_bdev(struct block_device *bdev) { @@ -538,17 +530,23 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file * int ret = -ENXIO; kdev_t dev = to_kdev_t(bdev->bd_dev); struct module *owner = NULL; + struct block_device_operations *ops, *current_ops; - down(&bdev->bd_sem); lock_kernel(); - if (!bdev->bd_op) { - bdev->bd_op = get_blkfops(major(dev)); - if (!bdev->bd_op) - goto out; - owner = bdev->bd_op->owner; + ops = get_blkfops(major(dev)); + if (ops) { + owner = ops->owner; if (owner) __MOD_INC_USE_COUNT(owner); } + + down(&bdev->bd_sem); + if (!bdev->bd_op) + current_ops = ops; + else + current_ops = bdev->bd_op; + if (!current_ops) + goto out; if (!bdev->bd_contains) { unsigned minor = minor(dev); struct gendisk *g = get_gendisk(dev); @@ -569,15 +567,30 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file * } } } - if (bdev->bd_op->open) { - ret = bdev->bd_op->open(inode, file); + if (current_ops->open) { + ret = current_ops->open(inode, file); if (ret) goto out2; } - bdev->bd_inode->i_size = blkdev_size(dev); + if (!bdev->bd_op) + bdev->bd_op = ops; + else if (owner) + __MOD_DEC_USE_COUNT(owner); if (!bdev->bd_openers) { struct blk_dev_struct *p = blk_dev + major(dev); + struct gendisk *g = get_gendisk(dev); unsigned bsize = bdev_hardsect_size(bdev); + + bdev->bd_offset = 0; + if (g) { + bdev->bd_inode->i_size = + (loff_t) g->part[minor(dev)].nr_sects << 9; + bdev->bd_offset = g->part[minor(dev)].start_sect; + } else if (blk_size[major(dev)]) + bdev->bd_inode->i_size = + (loff_t) blk_size[major(dev)][minor(dev)] << 10; + else + bdev->bd_inode->i_size = 0; while (bsize < PAGE_CACHE_SIZE) { if (bdev->bd_inode->i_size & bsize) break; @@ -601,14 +614,12 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file * } } bdev->bd_openers++; - unlock_kernel(); up(&bdev->bd_sem); + unlock_kernel(); return 0; out2: if (!bdev->bd_openers) { - bdev->bd_op = NULL; - bdev->bd_queue = NULL; bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; if (bdev != bdev->bd_contains) { blkdev_put(bdev->bd_contains, BDEV_RAW); @@ -619,8 +630,8 @@ out1: if (owner) __MOD_DEC_USE_COUNT(owner); out: - unlock_kernel(); up(&bdev->bd_sem); + unlock_kernel(); if (ret) bdput(bdev); return ret; @@ -679,9 +690,9 @@ int blkdev_put(struct block_device *bdev, int kind) kill_bdev(bdev); if (bdev->bd_op->release) ret = bdev->bd_op->release(bd_inode, NULL); - if (bdev->bd_op->owner) - __MOD_DEC_USE_COUNT(bdev->bd_op->owner); if (!bdev->bd_openers) { + if (bdev->bd_op->owner) + __MOD_DEC_USE_COUNT(bdev->bd_op->owner); bdev->bd_op = NULL; bdev->bd_queue = NULL; bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 297cb0ba10c1..7460a98bb0b3 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -389,20 +389,6 @@ extern inline unsigned int block_size(struct block_device *bdev) return bdev->bd_block_size; } -static inline loff_t blkdev_size_in_bytes(kdev_t dev) -{ -#if 0 - if (blk_size_in_bytes[major(dev)]) - return blk_size_in_bytes[major(dev)][minor(dev)]; - else -#endif - if (blk_size[major(dev)]) - return (loff_t) blk_size[major(dev)][minor(dev)] - << BLOCK_SIZE_BITS; - else - return 0; -} - typedef struct {struct page *v;} Sector; unsigned char *read_dev_sector(struct block_device *, unsigned long, Sector *); diff --git a/include/linux/fs.h b/include/linux/fs.h index 84413138923e..83f5a21b5d26 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -350,6 +350,7 @@ struct block_device { int bd_holders; struct block_device * bd_contains; unsigned bd_block_size; + unsigned long bd_offset; }; struct inode { |
