Commit eaa0bfbd authored by Alexander Viro's avatar Alexander Viro Committed by James Bottomley

[PATCH] block_device_operations always picked from gendisk

	* do_open() cleaned up
	* we always pick block_device_operations from gendisk->fops now
	* register_blkdev() just stores the name of driver, nothing more
	* ->bd_op and ->bd_queue removed - we have that in gendisk
	* get_blkfops() is gone
parent 0b0f135d
...@@ -40,7 +40,7 @@ struct blk_probe { ...@@ -40,7 +40,7 @@ struct blk_probe {
unsigned long range; unsigned long range;
struct module *owner; struct module *owner;
struct gendisk *(*get)(dev_t dev, int *part, void *data); struct gendisk *(*get)(dev_t dev, int *part, void *data);
void (*lock)(dev_t, void *); int (*lock)(dev_t, void *);
void *data; void *data;
} *probes[MAX_BLKDEV]; } *probes[MAX_BLKDEV];
...@@ -52,7 +52,7 @@ static inline int dev_to_index(dev_t dev) ...@@ -52,7 +52,7 @@ static inline int dev_to_index(dev_t dev)
void blk_register_region(dev_t dev, unsigned long range, struct module *module, void blk_register_region(dev_t dev, unsigned long range, struct module *module,
struct gendisk *(*probe)(dev_t, int *, void *), struct gendisk *(*probe)(dev_t, int *, void *),
void (*lock)(dev_t, void *), void *data) int (*lock)(dev_t, void *), void *data)
{ {
int index = dev_to_index(dev); int index = dev_to_index(dev);
struct blk_probe *p = kmalloc(sizeof(struct blk_probe), GFP_KERNEL); struct blk_probe *p = kmalloc(sizeof(struct blk_probe), GFP_KERNEL);
...@@ -97,10 +97,12 @@ static struct gendisk *exact_match(dev_t dev, int *part, void *data) ...@@ -97,10 +97,12 @@ static struct gendisk *exact_match(dev_t dev, int *part, void *data)
return p; return p;
} }
static void exact_lock(dev_t dev, void *data) static int exact_lock(dev_t dev, void *data)
{ {
struct gendisk *p = data; struct gendisk *p = data;
get_disk(p); if (!get_disk(p))
return -1;
return 0;
} }
/** /**
...@@ -167,8 +169,11 @@ get_gendisk(dev_t dev, int *part) ...@@ -167,8 +169,11 @@ get_gendisk(dev_t dev, int *part)
probe = p->get; probe = p->get;
best = p->range; best = p->range;
*part = dev - p->dev; *part = dev - p->dev;
if (p->lock) if (p->lock && p->lock(dev, data) < 0) {
p->lock(dev, data); if (owner)
__MOD_DEC_USE_COUNT(owner);
continue;
}
read_unlock(&gendisk_lock); read_unlock(&gendisk_lock);
disk = probe(dev, part, data); disk = probe(dev, part, data);
/* Currently ->owner protects _only_ ->probe() itself. */ /* Currently ->owner protects _only_ ->probe() itself. */
...@@ -323,6 +328,12 @@ struct gendisk *alloc_disk(int minors) ...@@ -323,6 +328,12 @@ struct gendisk *alloc_disk(int minors)
struct gendisk *get_disk(struct gendisk *disk) struct gendisk *get_disk(struct gendisk *disk)
{ {
struct module *owner;
if (!disk->fops)
return NULL;
owner = disk->fops->owner;
if (owner && !try_inc_mod_count(owner))
return NULL;
atomic_inc(&disk->disk_dev.refcount); atomic_inc(&disk->disk_dev.refcount);
return disk; return disk;
} }
......
...@@ -122,6 +122,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, ...@@ -122,6 +122,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
unsigned long arg) unsigned long arg)
{ {
struct block_device *bdev = inode->i_bdev; struct block_device *bdev = inode->i_bdev;
struct gendisk *disk = bdev->bd_disk;
struct backing_dev_info *bdi; struct backing_dev_info *bdi;
int holder; int holder;
int ret, n; int ret, n;
...@@ -146,7 +147,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, ...@@ -146,7 +147,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
case BLKSSZGET: /* get block device hardware sector size */ case BLKSSZGET: /* get block device hardware sector size */
return put_int(arg, bdev_hardsect_size(bdev)); return put_int(arg, bdev_hardsect_size(bdev));
case BLKSECTGET: case BLKSECTGET:
return put_ushort(arg, bdev->bd_queue->max_sectors); return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
case BLKRASET: case BLKRASET:
case BLKFRASET: case BLKFRASET:
if(!capable(CAP_SYS_ADMIN)) if(!capable(CAP_SYS_ADMIN))
...@@ -184,8 +185,8 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, ...@@ -184,8 +185,8 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
case BLKFLSBUF: case BLKFLSBUF:
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EACCES; return -EACCES;
if (bdev->bd_op->ioctl) { if (disk->fops->ioctl) {
ret = bdev->bd_op->ioctl(inode, file, cmd, arg); ret = disk->fops->ioctl(inode, file, cmd, arg);
if (ret != -EINVAL) if (ret != -EINVAL)
return ret; return ret;
} }
...@@ -193,8 +194,8 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, ...@@ -193,8 +194,8 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
invalidate_bdev(bdev, 0); invalidate_bdev(bdev, 0);
return 0; return 0;
case BLKROSET: case BLKROSET:
if (bdev->bd_op->ioctl) { if (disk->fops->ioctl) {
ret = bdev->bd_op->ioctl(inode, file, cmd, arg); ret = disk->fops->ioctl(inode, file, cmd, arg);
if (ret != -EINVAL) if (ret != -EINVAL)
return ret; return ret;
} }
...@@ -205,8 +206,8 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, ...@@ -205,8 +206,8 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
set_device_ro(bdev, n); set_device_ro(bdev, n);
return 0; return 0;
default: default:
if (bdev->bd_op->ioctl) { if (disk->fops->ioctl) {
ret = bdev->bd_op->ioctl(inode, file, cmd, arg); ret = disk->fops->ioctl(inode, file, cmd, arg);
if (ret != -EINVAL) if (ret != -EINVAL)
return ret; return ret;
} }
......
...@@ -351,10 +351,9 @@ static int rd_open(struct inode * inode, struct file * filp) ...@@ -351,10 +351,9 @@ static int rd_open(struct inode * inode, struct file * filp)
rd_bdev[unit] = bdev; rd_bdev[unit] = bdev;
bdev->bd_openers++; bdev->bd_openers++;
bdev->bd_block_size = rd_blocksize; bdev->bd_block_size = rd_blocksize;
bdev->bd_inode->i_size = get_capacity(rd_disks[unit])<<9;
inode->i_mapping->a_ops = &ramdisk_aops; inode->i_mapping->a_ops = &ramdisk_aops;
inode->i_mapping->backing_dev_info = &rd_backing_dev_info; inode->i_mapping->backing_dev_info = &rd_backing_dev_info;
get_disk(bdev->bd_disk);
bdev->bd_inode->i_size = get_capacity(bdev->bd_disk) << 9;
} }
return 0; return 0;
......
...@@ -68,6 +68,7 @@ static int raw_open(struct inode *inode, struct file *filp) ...@@ -68,6 +68,7 @@ static int raw_open(struct inode *inode, struct file *filp)
} }
} }
} }
filp->private_data = bdev;
up(&raw_mutex); up(&raw_mutex);
return err; return err;
} }
...@@ -92,22 +93,9 @@ static int ...@@ -92,22 +93,9 @@ static int
raw_ioctl(struct inode *inode, struct file *filp, raw_ioctl(struct inode *inode, struct file *filp,
unsigned int command, unsigned long arg) unsigned int command, unsigned long arg)
{ {
const int minor = minor(inode->i_rdev); struct block_device *bdev = filp->private_data;
int err;
struct block_device *bdev;
err = -ENODEV;
if (minor < 1 && minor > 255)
goto out;
bdev = raw_devices[minor].binding; return blkdev_ioctl(bdev->bd_inode, NULL, command, arg);
err = -EINVAL;
if (bdev == NULL)
goto out;
if (bdev->bd_inode && bdev->bd_op && bdev->bd_op->ioctl)
err = bdev->bd_op->ioctl(bdev->bd_inode, NULL, command, arg);
out:
return err;
} }
/* /*
......
...@@ -973,11 +973,10 @@ int init_irq (ide_hwif_t *hwif) ...@@ -973,11 +973,10 @@ int init_irq (ide_hwif_t *hwif)
EXPORT_SYMBOL(init_irq); EXPORT_SYMBOL(init_irq);
static void ata_lock(dev_t dev, void *data) static int ata_lock(dev_t dev, void *data)
{ {
ide_hwif_t *hwif = data; /* FIXME: we want to pin hwif down */
int unit = MINOR(dev) >> PARTN_BITS; return 0;
get_disk(hwif->drives[unit].disk);
} }
struct gendisk *ata_probe(dev_t dev, int *part, void *data) struct gendisk *ata_probe(dev_t dev, int *part, void *data)
...@@ -985,10 +984,8 @@ struct gendisk *ata_probe(dev_t dev, int *part, void *data) ...@@ -985,10 +984,8 @@ struct gendisk *ata_probe(dev_t dev, int *part, void *data)
ide_hwif_t *hwif = data; ide_hwif_t *hwif = data;
int unit = MINOR(dev) >> PARTN_BITS; int unit = MINOR(dev) >> PARTN_BITS;
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
if (!drive->present) { if (!drive->present)
put_disk(drive->disk);
return NULL; return NULL;
}
if (!drive->driver) { if (!drive->driver) {
if (drive->media == ide_disk) if (drive->media == ide_disk)
(void) request_module("ide-disk"); (void) request_module("ide-disk");
...@@ -1001,11 +998,9 @@ struct gendisk *ata_probe(dev_t dev, int *part, void *data) ...@@ -1001,11 +998,9 @@ struct gendisk *ata_probe(dev_t dev, int *part, void *data)
if (drive->media == ide_floppy) if (drive->media == ide_floppy)
(void) request_module("ide-floppy"); (void) request_module("ide-floppy");
} }
if (!drive->driver) { if (!drive->driver)
put_disk(drive->disk);
return NULL; return NULL;
} return get_disk(drive->disk);
return drive->disk;
} }
static int alloc_disks(ide_hwif_t *hwif) static int alloc_disks(ide_hwif_t *hwif)
......
...@@ -306,8 +306,6 @@ struct block_device *bdget(dev_t dev) ...@@ -306,8 +306,6 @@ struct block_device *bdget(dev_t dev)
atomic_set(&new_bdev->bd_count,1); atomic_set(&new_bdev->bd_count,1);
new_bdev->bd_dev = dev; new_bdev->bd_dev = dev;
new_bdev->bd_op = NULL;
new_bdev->bd_queue = NULL;
new_bdev->bd_contains = NULL; new_bdev->bd_contains = NULL;
new_bdev->bd_inode = inode; new_bdev->bd_inode = inode;
new_bdev->bd_part_count = 0; new_bdev->bd_part_count = 0;
...@@ -434,10 +432,7 @@ void bd_release(struct block_device *bdev) ...@@ -434,10 +432,7 @@ void bd_release(struct block_device *bdev)
spin_unlock(&bdev_lock); spin_unlock(&bdev_lock);
} }
static struct { static const char *blkdevs[MAX_BLKDEV];
const char *name;
struct block_device_operations *bdops;
} blkdevs[MAX_BLKDEV];
int get_blkdev_list(char * p) int get_blkdev_list(char * p)
{ {
...@@ -446,44 +441,20 @@ int get_blkdev_list(char * p) ...@@ -446,44 +441,20 @@ int get_blkdev_list(char * p)
len = sprintf(p, "\nBlock devices:\n"); len = sprintf(p, "\nBlock devices:\n");
for (i = 0; i < MAX_BLKDEV ; i++) { for (i = 0; i < MAX_BLKDEV ; i++) {
if (blkdevs[i].bdops) { if (blkdevs[i])
len += sprintf(p+len, "%3d %s\n", i, blkdevs[i].name); len += sprintf(p+len, "%3d %s\n", i, blkdevs[i]);
}
} }
return len; return len;
} }
/*
Return the function table of a device.
Load the driver if needed.
*/
struct block_device_operations * get_blkfops(unsigned int major)
{
struct block_device_operations *ret = NULL;
/* major 0 is used for non-device mounts */
if (major && major < MAX_BLKDEV) {
#ifdef CONFIG_KMOD
if (!blkdevs[major].bdops) {
char name[20];
sprintf(name, "block-major-%d", major);
request_module(name);
}
#endif
ret = blkdevs[major].bdops;
}
return ret;
}
int register_blkdev(unsigned int major, const char * name, struct block_device_operations *bdops) int register_blkdev(unsigned int major, const char * name, struct block_device_operations *bdops)
{ {
if (devfs_only()) if (devfs_only())
return 0; return 0;
if (major == 0) { if (major == 0) {
for (major = MAX_BLKDEV-1; major > 0; major--) { for (major = MAX_BLKDEV-1; major > 0; major--) {
if (blkdevs[major].bdops == NULL) { if (blkdevs[major] == NULL) {
blkdevs[major].name = name; blkdevs[major] = name;
blkdevs[major].bdops = bdops;
return major; return major;
} }
} }
...@@ -491,10 +462,9 @@ int register_blkdev(unsigned int major, const char * name, struct block_device_o ...@@ -491,10 +462,9 @@ int register_blkdev(unsigned int major, const char * name, struct block_device_o
} }
if (major >= MAX_BLKDEV) if (major >= MAX_BLKDEV)
return -EINVAL; return -EINVAL;
if (blkdevs[major].bdops && blkdevs[major].bdops != bdops) if (blkdevs[major])
return -EBUSY; return -EBUSY;
blkdevs[major].name = name; blkdevs[major] = name;
blkdevs[major].bdops = bdops;
return 0; return 0;
} }
...@@ -504,12 +474,11 @@ int unregister_blkdev(unsigned int major, const char * name) ...@@ -504,12 +474,11 @@ int unregister_blkdev(unsigned int major, const char * name)
return 0; return 0;
if (major >= MAX_BLKDEV) if (major >= MAX_BLKDEV)
return -EINVAL; return -EINVAL;
if (!blkdevs[major].bdops) if (!blkdevs[major])
return -EINVAL; return -EINVAL;
if (strcmp(blkdevs[major].name, name)) if (strcmp(blkdevs[major], name))
return -EINVAL; return -EINVAL;
blkdevs[major].name = NULL; blkdevs[major] = NULL;
blkdevs[major].bdops = NULL;
return 0; return 0;
} }
...@@ -524,7 +493,8 @@ int unregister_blkdev(unsigned int major, const char * name) ...@@ -524,7 +493,8 @@ int unregister_blkdev(unsigned int major, const char * name)
*/ */
int check_disk_change(struct block_device *bdev) int check_disk_change(struct block_device *bdev)
{ {
struct block_device_operations * bdops = bdev->bd_op; struct gendisk *disk = bdev->bd_disk;
struct block_device_operations * bdops = disk->fops;
kdev_t dev = to_kdev_t(bdev->bd_dev); kdev_t dev = to_kdev_t(bdev->bd_dev);
if (!bdops->media_changed) if (!bdops->media_changed)
...@@ -587,117 +557,98 @@ static void bd_set_size(struct block_device *bdev, loff_t size) ...@@ -587,117 +557,98 @@ static void bd_set_size(struct block_device *bdev, loff_t size)
static int do_open(struct block_device *bdev, struct inode *inode, struct file *file) static int do_open(struct block_device *bdev, struct inode *inode, struct file *file)
{ {
int ret = -ENXIO;
kdev_t dev = to_kdev_t(bdev->bd_dev);
struct module *owner = NULL; struct module *owner = NULL;
struct block_device_operations *ops, *old;
struct gendisk *disk; struct gendisk *disk;
int ret = -ENXIO;
int part; int part;
lock_kernel(); lock_kernel();
ops = get_blkfops(major(dev));
if (ops) {
owner = ops->owner;
if (owner)
__MOD_INC_USE_COUNT(owner);
}
disk = get_gendisk(bdev->bd_dev, &part); disk = get_gendisk(bdev->bd_dev, &part);
if (!disk) { if (!disk) {
if (owner)
__MOD_DEC_USE_COUNT(owner);
bdput(bdev); bdput(bdev);
return ret; return ret;
} }
owner = disk->fops->owner;
down(&bdev->bd_sem); down(&bdev->bd_sem);
old = bdev->bd_op; if (!bdev->bd_openers) {
if (!old) { bdev->bd_disk = disk;
if (!ops)
goto out;
bdev->bd_op = ops;
} else {
if (owner)
__MOD_DEC_USE_COUNT(owner);
}
if (!bdev->bd_contains) {
bdev->bd_contains = bdev; bdev->bd_contains = bdev;
if (part) { if (!part) {
struct backing_dev_info *bdi;
if (disk->fops->open) {
ret = disk->fops->open(inode, file);
if (ret)
goto out_first;
}
bdev->bd_offset = 0;
if (!bdev->bd_openers) {
bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
bdi = blk_get_backing_dev_info(bdev);
if (bdi == NULL)
bdi = &default_backing_dev_info;
bdev->bd_inode->i_data.backing_dev_info = bdi;
}
if (bdev->bd_invalidated)
rescan_partitions(disk, bdev);
} else {
struct hd_struct *p;
struct block_device *whole; struct block_device *whole;
whole = bdget(MKDEV(disk->major, disk->first_minor)); whole = bdget(MKDEV(disk->major, disk->first_minor));
ret = -ENOMEM; ret = -ENOMEM;
if (!whole) if (!whole)
goto out1; goto out_first;
ret = blkdev_get(whole, file->f_mode, file->f_flags, BDEV_RAW); ret = blkdev_get(whole, file->f_mode, file->f_flags, BDEV_RAW);
if (ret) if (ret)
goto out1; goto out_first;
bdev->bd_contains = whole; bdev->bd_contains = whole;
} down(&whole->bd_sem);
} whole->bd_part_count++;
if (bdev->bd_contains == bdev) {
if (!bdev->bd_openers) {
bdev->bd_disk = disk;
bdev->bd_queue = disk->queue;
}
if (bdev->bd_op->open) {
ret = bdev->bd_op->open(inode, file);
if (ret)
goto out2;
}
if (!bdev->bd_openers) {
struct backing_dev_info *bdi;
bdev->bd_offset = 0;
bd_set_size(bdev, (loff_t)get_capacity(disk) << 9);
bdi = blk_get_backing_dev_info(bdev);
if (bdi == NULL)
bdi = &default_backing_dev_info;
bdev->bd_inode->i_data.backing_dev_info = bdi;
}
if (bdev->bd_invalidated)
rescan_partitions(disk, bdev);
} else {
down(&bdev->bd_contains->bd_sem);
bdev->bd_contains->bd_part_count++;
if (!bdev->bd_openers) {
struct hd_struct *p;
p = disk->part + part - 1; p = disk->part + part - 1;
bdev->bd_inode->i_data.backing_dev_info = bdev->bd_inode->i_data.backing_dev_info =
bdev->bd_contains->bd_inode->i_data.backing_dev_info; whole->bd_inode->i_data.backing_dev_info;
if (!(disk->flags & GENHD_FL_UP) || !p->nr_sects) { if (!(disk->flags & GENHD_FL_UP) || !p->nr_sects) {
bdev->bd_contains->bd_part_count--; whole->bd_part_count--;
up(&bdev->bd_contains->bd_sem); up(&whole->bd_sem);
ret = -ENXIO; ret = -ENXIO;
goto out2; goto out_first;
} }
bdev->bd_queue = bdev->bd_contains->bd_queue;
bdev->bd_offset = p->start_sect; bdev->bd_offset = p->start_sect;
bd_set_size(bdev, (loff_t) p->nr_sects << 9); bd_set_size(bdev, (loff_t) p->nr_sects << 9);
bdev->bd_disk = disk; up(&whole->bd_sem);
} }
up(&bdev->bd_contains->bd_sem); } else {
}
if (bdev->bd_openers++)
put_disk(disk); put_disk(disk);
if (owner)
__MOD_DEC_USE_COUNT(owner);
if (bdev->bd_contains == bdev) {
if (bdev->bd_disk->fops->open) {
ret = bdev->bd_disk->fops->open(inode, file);
if (ret)
goto out;
}
if (bdev->bd_invalidated)
rescan_partitions(bdev->bd_disk, bdev);
} else {
down(&bdev->bd_contains->bd_sem);
bdev->bd_contains->bd_part_count++;
up(&bdev->bd_contains->bd_sem);
}
}
bdev->bd_openers++;
up(&bdev->bd_sem); up(&bdev->bd_sem);
unlock_kernel(); unlock_kernel();
return 0; return 0;
out2: out_first:
if (!bdev->bd_openers) { bdev->bd_disk = NULL;
bdev->bd_queue = NULL; bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
bdev->bd_disk = NULL; if (bdev != bdev->bd_contains)
bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; blkdev_put(bdev->bd_contains, BDEV_RAW);
if (bdev != bdev->bd_contains) { bdev->bd_contains = NULL;
blkdev_put(bdev->bd_contains, BDEV_RAW);
bdev->bd_contains = NULL;
}
}
out1:
put_disk(disk); put_disk(disk);
if (!old) { if (owner)
bdev->bd_op = NULL; __MOD_DEC_USE_COUNT(owner);
if (owner)
__MOD_DEC_USE_COUNT(owner);
}
out: out:
up(&bdev->bd_sem); up(&bdev->bd_sem);
unlock_kernel(); unlock_kernel();
...@@ -740,12 +691,13 @@ int blkdev_open(struct inode * inode, struct file * filp) ...@@ -740,12 +691,13 @@ int blkdev_open(struct inode * inode, struct file * filp)
bdev = inode->i_bdev; bdev = inode->i_bdev;
return do_open(bdev, inode, filp); return do_open(bdev, inode, filp);
} }
int blkdev_put(struct block_device *bdev, int kind) int blkdev_put(struct block_device *bdev, int kind)
{ {
int ret = 0; int ret = 0;
struct inode *bd_inode = bdev->bd_inode; struct inode *bd_inode = bdev->bd_inode;
struct gendisk *disk = bdev->bd_disk;
down(&bdev->bd_sem); down(&bdev->bd_sem);
lock_kernel(); lock_kernel();
...@@ -758,26 +710,24 @@ int blkdev_put(struct block_device *bdev, int kind) ...@@ -758,26 +710,24 @@ int blkdev_put(struct block_device *bdev, int kind)
if (!--bdev->bd_openers) if (!--bdev->bd_openers)
kill_bdev(bdev); kill_bdev(bdev);
if (bdev->bd_contains == bdev) { if (bdev->bd_contains == bdev) {
if (bdev->bd_op->release) if (disk->fops->release)
ret = bdev->bd_op->release(bd_inode, NULL); ret = disk->fops->release(bd_inode, NULL);
} else { } else {
down(&bdev->bd_contains->bd_sem); down(&bdev->bd_contains->bd_sem);
bdev->bd_contains->bd_part_count--; bdev->bd_contains->bd_part_count--;
up(&bdev->bd_contains->bd_sem); up(&bdev->bd_contains->bd_sem);
} }
if (!bdev->bd_openers) { if (!bdev->bd_openers) {
struct gendisk *disk = bdev->bd_disk; struct module *owner = disk->fops->owner;
if (bdev->bd_op->owner) put_disk(disk);
__MOD_DEC_USE_COUNT(bdev->bd_op->owner); if (owner)
bdev->bd_op = NULL; __MOD_DEC_USE_COUNT(owner);
bdev->bd_queue = NULL;
bdev->bd_disk = NULL; bdev->bd_disk = NULL;
bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
if (bdev != bdev->bd_contains) { if (bdev != bdev->bd_contains) {
blkdev_put(bdev->bd_contains, BDEV_RAW); blkdev_put(bdev->bd_contains, BDEV_RAW);
bdev->bd_contains = NULL;
} }
put_disk(disk); bdev->bd_contains = NULL;
} }
unlock_kernel(); unlock_kernel();
up(&bdev->bd_sem); up(&bdev->bd_sem);
...@@ -836,7 +786,7 @@ int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) ...@@ -836,7 +786,7 @@ int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
const char *__bdevname(kdev_t dev) const char *__bdevname(kdev_t dev)
{ {
static char buffer[32]; static char buffer[32];
const char * name = blkdevs[major(dev)].name; const char * name = blkdevs[major(dev)];
if (!name) if (!name)
name = "unknown-block"; name = "unknown-block";
......
...@@ -1570,13 +1570,8 @@ devfs_handle_t devfs_register (devfs_handle_t dir, const char *name, ...@@ -1570,13 +1570,8 @@ devfs_handle_t devfs_register (devfs_handle_t dir, const char *name,
} }
if (ops == NULL) if (ops == NULL)
{ {
if ( S_ISBLK (mode) ) ops = (void *) get_blkfops (major); PRINTK ("(%s): NULL ops pointer\n", name);
if (ops == NULL) return NULL;
{
PRINTK ("(%s): NULL ops pointer\n", name);
return NULL;
}
PRINTK ("(%s): NULL ops, got %p from major table\n", name, ops);
} }
if ( S_ISDIR (mode) ) if ( S_ISDIR (mode) )
{ {
...@@ -2378,29 +2373,21 @@ static int try_modload (struct devfs_entry *parent, struct fs_info *fs_info, ...@@ -2378,29 +2373,21 @@ static int try_modload (struct devfs_entry *parent, struct fs_info *fs_info,
static int check_disc_changed (struct devfs_entry *de) static int check_disc_changed (struct devfs_entry *de)
{ {
int tmp; int tmp;
int retval = 0; int retval = 0;
kdev_t dev = mk_kdev (de->u.fcb.u.device.major, de->u.fcb.u.device.minor); dev_t dev = MKDEV(de->u.fcb.u.device.major, de->u.fcb.u.device.minor);
struct block_device *bdev; extern int warn_no_part;
struct block_device_operations *bdops;
extern int warn_no_part; if (!S_ISBLK(de->mode))
return 0;
if ( !S_ISBLK (de->mode) ) return 0; /* Ugly hack to disable messages about unable to read partition table */
bdev = bdget (kdev_t_to_nr (dev) ); tmp = warn_no_part;
if (!bdev) return 0; warn_no_part = 0;
bdops = devfs_get_ops (de); retval = __check_disk_change(dev);
if (!bdops) return 0; warn_no_part = tmp;
bdev->bd_op = bdops; return retval;
/* Ugly hack to disable messages about unable to read partition table */
tmp = warn_no_part;
warn_no_part = 0;
retval = full_check_disk_change (bdev);
warn_no_part = tmp;
devfs_put_ops (de);
return retval;
} /* End Function check_disc_changed */ } /* End Function check_disc_changed */
/** /**
* scan_dir_for_removable - Scan a directory for removable media devices and check media. * scan_dir_for_removable - Scan a directory for removable media devices and check media.
* @dir: The directory. * @dir: The directory.
...@@ -2582,12 +2569,8 @@ static struct inode *_devfs_get_vfs_inode (struct super_block *sb, ...@@ -2582,12 +2569,8 @@ static struct inode *_devfs_get_vfs_inode (struct super_block *sb,
{ {
inode->i_rdev = mk_kdev (de->u.fcb.u.device.major, inode->i_rdev = mk_kdev (de->u.fcb.u.device.major,
de->u.fcb.u.device.minor); de->u.fcb.u.device.minor);
if (bd_acquire (inode) == 0) if (bd_acquire (inode) != 0)
{ PRINTK ("(%d): no block device from bdget()\n",(int)inode->i_ino);
if (!inode->i_bdev->bd_op && de->u.fcb.ops)
inode->i_bdev->bd_op = de->u.fcb.ops;
}
else PRINTK ("(%d): no block device from bdget()\n",(int)inode->i_ino);
is_fcb = TRUE; is_fcb = TRUE;
} }
else if ( S_ISFIFO (de->mode) ) inode->i_fop = &def_fifo_fops; else if ( S_ISFIFO (de->mode) ) inode->i_fop = &def_fifo_fops;
...@@ -2706,7 +2689,6 @@ static int devfs_open (struct inode *inode, struct file *file) ...@@ -2706,7 +2689,6 @@ static int devfs_open (struct inode *inode, struct file *file)
if ( S_ISBLK (inode->i_mode) ) if ( S_ISBLK (inode->i_mode) )
{ {
file->f_op = &def_blk_fops; file->f_op = &def_blk_fops;
if (ops) inode->i_bdev->bd_op = ops;
err = def_blk_fops.open (inode, file); /* Module refcount unchanged */ err = def_blk_fops.open (inode, file); /* Module refcount unchanged */
} }
else else
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/blk.h> #include <linux/blk.h>
#include <linux/kmod.h> #include <linux/kmod.h>
...@@ -511,8 +512,8 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) ...@@ -511,8 +512,8 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
bdev->bd_invalidated = 0; bdev->bd_invalidated = 0;
for (p = 1; p < disk->minors; p++) for (p = 1; p < disk->minors; p++)
delete_partition(disk, p); delete_partition(disk, p);
if (bdev->bd_op->revalidate_disk) if (disk->fops->revalidate_disk)
bdev->bd_op->revalidate_disk(disk); disk->fops->revalidate_disk(disk);
if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
return res; return res;
for (p = 1; p < state->limit; p++) { for (p = 1; p < state->limit; p++) {
...@@ -613,9 +614,12 @@ char *partition_name(dev_t dev) ...@@ -613,9 +614,12 @@ char *partition_name(dev_t dev)
*/ */
hd = get_gendisk(dev, &part); hd = get_gendisk(dev, &part);
dname->name = NULL; dname->name = NULL;
if (hd) if (hd) {
dname->name = disk_name(hd, part, dname->namebuf); dname->name = disk_name(hd, part, dname->namebuf);
put_disk(hd); if (hd->fops->owner)
__MOD_DEC_USE_COUNT(hd->fops->owner);
put_disk(hd);
}
if (!dname->name) { if (!dname->name) {
sprintf(dname->namebuf, "[dev %s]", kdevname(to_kdev_t(dev))); sprintf(dname->namebuf, "[dev %s]", kdevname(to_kdev_t(dev)));
dname->name = dname->namebuf; dname->name = dname->namebuf;
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/acct.h> #include <linux/acct.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/quotaops.h> #include <linux/quotaops.h>
...@@ -465,11 +464,8 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type, ...@@ -465,11 +464,8 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
{ {
struct inode *inode; struct inode *inode;
struct block_device *bdev; struct block_device *bdev;
struct block_device_operations *bdops;
devfs_handle_t de;
struct super_block * s; struct super_block * s;
struct nameidata nd; struct nameidata nd;
kdev_t dev;
int error = 0; int error = 0;
mode_t mode = FMODE_READ; /* we always need it ;-) */ mode_t mode = FMODE_READ; /* we always need it ;-) */
...@@ -490,15 +486,10 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type, ...@@ -490,15 +486,10 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
if (error) if (error)
goto out; goto out;
bdev = inode->i_bdev; bdev = inode->i_bdev;
de = devfs_get_handle_from_inode (inode);
bdops = devfs_get_ops (de); /* Increments module use count */
if (bdops) bdev->bd_op = bdops;
/* Done with lookups, semaphore down */ /* Done with lookups, semaphore down */
dev = to_kdev_t(bdev->bd_dev);
if (!(flags & MS_RDONLY)) if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE; mode |= FMODE_WRITE;
error = blkdev_get(bdev, mode, 0, BDEV_FS); error = blkdev_get(bdev, mode, 0, BDEV_FS);
devfs_put_ops (de); /* Decrement module use count now we're safe */
if (error) if (error)
goto out; goto out;
error = -EACCES; error = -EACCES;
......
...@@ -312,7 +312,7 @@ extern void __blk_stop_queue(request_queue_t *q); ...@@ -312,7 +312,7 @@ extern void __blk_stop_queue(request_queue_t *q);
static inline request_queue_t *bdev_get_queue(struct block_device *bdev) static inline request_queue_t *bdev_get_queue(struct block_device *bdev)
{ {
return bdev->bd_queue; return bdev->bd_disk->queue;
} }
/* /*
......
...@@ -348,8 +348,6 @@ struct block_device { ...@@ -348,8 +348,6 @@ struct block_device {
struct inode * bd_inode; struct inode * bd_inode;
dev_t bd_dev; /* not a kdev_t - it's a search key */ dev_t bd_dev; /* not a kdev_t - it's a search key */
int bd_openers; int bd_openers;
struct block_device_operations *bd_op;
struct request_queue *bd_queue;
struct semaphore bd_sem; /* open/close mutex */ struct semaphore bd_sem; /* open/close mutex */
struct list_head bd_inodes; struct list_head bd_inodes;
void * bd_holder; void * bd_holder;
...@@ -1096,7 +1094,6 @@ extern void bd_release(struct block_device *); ...@@ -1096,7 +1094,6 @@ extern void bd_release(struct block_device *);
extern void blk_run_queues(void); extern void blk_run_queues(void);
/* fs/devices.c */ /* fs/devices.c */
extern struct block_device_operations *get_blkfops(unsigned int);
extern int register_chrdev(unsigned int, const char *, struct file_operations *); extern int register_chrdev(unsigned int, const char *, struct file_operations *);
extern int unregister_chrdev(unsigned int, const char *); extern int unregister_chrdev(unsigned int, const char *);
extern int chrdev_open(struct inode *, struct file *); extern int chrdev_open(struct inode *, struct file *);
......
...@@ -282,7 +282,7 @@ extern void put_disk(struct gendisk *disk); ...@@ -282,7 +282,7 @@ extern void put_disk(struct gendisk *disk);
extern void blk_register_region(dev_t dev, unsigned long range, extern void blk_register_region(dev_t dev, unsigned long range,
struct module *module, struct module *module,
struct gendisk *(*probe)(dev_t, int *, void *), struct gendisk *(*probe)(dev_t, int *, void *),
void (*lock)(dev_t, void *), int (*lock)(dev_t, void *),
void *data); void *data);
extern void blk_unregister_region(dev_t dev, unsigned long range); extern void blk_unregister_region(dev_t dev, unsigned long range);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment