From deddb7cba8ef29f7a1366a064df9ae50ec14f01d Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Sun, 27 Apr 2003 03:47:05 -0700 Subject: [PATCH] simple_fill_super() New libfs.c helper - simple_fill_super(). Abstracted from nfsd/nfsctl.c, couple of filesystems converted to it (nfsctl, binfmt_misc). Function takes an array of triples (name, file_operations, mode), superblock and value for its ->s_magic. It acts as fill_super() - populates superblock or fails. We get a ramfs-style flat tree - root directory and a bunch of files in it. That animal allows to put together a simple filesystem without touching any directory-related stuff - now it's as easy as implementing file_operations for files you want to have and telling what to call them. --- include/linux/fs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index ce89b15c54a1..00ddb3866b15 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1292,6 +1292,8 @@ extern struct dentry *simple_lookup(struct inode *, struct dentry *); extern ssize_t generic_read_dir(struct file *, char *, size_t, loff_t *); extern struct file_operations simple_dir_operations; extern struct inode_operations simple_dir_inode_operations; +struct tree_descr { char *name; struct file_operations *ops; int mode; }; +extern int simple_fill_super(struct super_block *, int, struct tree_descr *); #ifdef CONFIG_BLK_DEV_INITRD extern unsigned int real_root_dev; -- cgit v1.2.3 From 259f529f1f956cf9e87a32bd25d5ee5be4829f2d Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Sun, 27 Apr 2003 03:47:14 -0700 Subject: [PATCH] pin_fs/release_fs A couple of helpers - simple_pin_fs() and simple_release_fs(). My fault - that code should've been put into libfs.c from the very beginning. As it is, it got copied all over the place (binfmt_misc, capifs, usbfs, usbdevfs, rpc_pipefs). Taken to libfs.c and cleaned up. --- drivers/isdn/capi/capifs.c | 34 +++++------------------- drivers/usb/core/inode.c | 64 +++++----------------------------------------- fs/binfmt_misc.c | 44 ++++++++----------------------- fs/libfs.c | 36 ++++++++++++++++++++++++++ include/linux/fs.h | 2 ++ kernel/ksyms.c | 2 ++ net/sunrpc/rpc_pipe.c | 38 ++------------------------- 7 files changed, 65 insertions(+), 155 deletions(-) (limited to 'include/linux') diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c index b4679f0c2d65..8cdf0e65f9c6 100644 --- a/drivers/isdn/capi/capifs.c +++ b/drivers/isdn/capi/capifs.c @@ -153,39 +153,17 @@ static struct file_system_type capifs_fs_type = { .kill_sb = kill_anon_super, }; -static spinlock_t entries_lock = SPIN_LOCK_UNLOCKED; static struct vfsmount *capifs_mnt; -static int entry_count = 0; +static int entry_count; -static struct vfsmount *grab_instance(void) +static int grab_instance(void) { - struct vfsmount *mnt = NULL; - spin_lock(&entries_lock); - if (!capifs_mnt) { - spin_unlock(&entries_lock); - mnt = kern_mount(&capifs_fs_type); - if (IS_ERR(mnt)) - return NULL; - spin_lock(&entries_lock); - if (!capifs_mnt) - capifs_mnt = mnt; - } - mntget(capifs_mnt); - entry_count++; - spin_unlock(&entries_lock); - mntput(mnt); - return capifs_mnt; + return simple_pin_fs("capifs", &capifs_mnt, &entry_count); } static void drop_instance(void) { - struct vfsmount *mnt; - spin_lock(&entries_lock); - mnt = capifs_mnt; - if (!--entry_count) - capifs_mnt = NULL; - spin_unlock(&entries_lock); - mntput(mnt); + return simple_release_fs(&capifs_mnt, &entry_count); } static struct dentry *get_node(int type, int num) @@ -207,7 +185,7 @@ void capifs_new_ncci(char type, unsigned int num, dev_t device) struct dentry *dentry; struct inode *inode; - if (!grab_instance()) + if (grab_instance() < 0) return; sb = capifs_mnt->mnt_sb; inode = new_inode(sb); @@ -232,7 +210,7 @@ void capifs_new_ncci(char type, unsigned int num, dev_t device) void capifs_free_ncci(char type, unsigned int num) { - if (grab_instance()) { + if (grab_instance() == 0) { struct dentry *dentry = get_node(type, num); if (!IS_ERR(dentry)) { struct inode *inode = dentry->d_inode; diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 2dfda57eaebf..53f05b670bb6 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -45,7 +45,6 @@ static struct file_operations default_file_operations; static struct inode_operations usbfs_dir_inode_operations; static struct vfsmount *usbdevfs_mount; static struct vfsmount *usbfs_mount; -static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED; static int usbdevfs_mount_count; /* = 0 */ static int usbfs_mount_count; /* = 0 */ @@ -514,69 +513,20 @@ static struct file_system_type usb_fs_type = { }; /* --------------------------------------------------------------------- */ -static int get_mount (struct file_system_type *fs_type, struct vfsmount **mount, int *mount_count) -{ - struct vfsmount *mnt; - - spin_lock (&mount_lock); - if (*mount) { - mntget(*mount); - ++(*mount_count); - spin_unlock (&mount_lock); - goto go_ahead; - } - - spin_unlock (&mount_lock); - mnt = kern_mount (fs_type); - if (IS_ERR(mnt)) { - err ("could not mount the fs...erroring out!\n"); - return -ENODEV; - } - spin_lock (&mount_lock); - if (!*mount) { - *mount = mnt; - ++(*mount_count); - spin_unlock (&mount_lock); - goto go_ahead; - } - mntget(*mount); - ++(*mount_count); - spin_unlock (&mount_lock); - mntput(mnt); - -go_ahead: - dbg("mount_count = %d", *mount_count); - return 0; -} - -static void put_mount (struct vfsmount **mount, int *mount_count) -{ - struct vfsmount *mnt; - - spin_lock (&mount_lock); - mnt = *mount; - --(*mount_count); - if (!(*mount_count)) - *mount = NULL; - - spin_unlock (&mount_lock); - mntput(mnt); - dbg("mount_count = %d", *mount_count); -} static int create_special_files (void) { struct dentry *parent; - int retval = 0; + int retval; /* create the devices special file */ - retval = get_mount (&usbdevice_fs_type, &usbdevfs_mount, &usbdevfs_mount_count); + retval = simple_pin_fs("usbdevfs", &usbdevfs_mount, &usbdevfs_mount_count); if (retval) { err ("Unable to get usbdevfs mount"); goto exit; } - retval = get_mount (&usb_fs_type, &usbfs_mount, &usbfs_mount_count); + retval = simple_pin_fs("usbfs", &usbfs_mount, &usbfs_mount_count); if (retval) { err ("Unable to get usbfs mount"); goto error_clean_usbdevfs_mount; @@ -611,10 +561,10 @@ error_remove_file: devices_usbfs_dentry = NULL; error_clean_mounts: - put_mount (&usbfs_mount, &usbfs_mount_count); + simple_release_fs(&usbfs_mount, &usbfs_mount_count); error_clean_usbdevfs_mount: - put_mount (&usbdevfs_mount, &usbdevfs_mount_count); + simple_release_fs(&usbdevfs_mount, &usbdevfs_mount_count); exit: return retval; @@ -628,8 +578,8 @@ static void remove_special_files (void) fs_remove_file (devices_usbfs_dentry); devices_usbdevfs_dentry = NULL; devices_usbfs_dentry = NULL; - put_mount (&usbdevfs_mount, &usbdevfs_mount_count); - put_mount (&usbfs_mount, &usbfs_mount_count); + simple_release_fs(&usbdevfs_mount, &usbdevfs_mount_count); + simple_release_fs(&usbfs_mount, &usbfs_mount_count); } void usbfs_update_special (void) diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 45a1ac2f181c..d9e70fb1c0e1 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -53,7 +53,7 @@ typedef struct { static rwlock_t entries_lock __attribute__((unused)) = RW_LOCK_UNLOCKED; static struct vfsmount *bm_mnt; -static int entry_count = 0; +static int entry_count; /* * Check if we support the binfmt @@ -399,19 +399,7 @@ static struct inode *bm_get_inode(struct super_block *sb, int mode) static void bm_clear_inode(struct inode *inode) { - Node *e = inode->u.generic_ip; - - if (e) { - struct vfsmount *mnt; - write_lock(&entries_lock); - list_del(&e->list); - mnt = bm_mnt; - if (!--entry_count) - bm_mnt = NULL; - write_unlock(&entries_lock); - kfree(e); - mntput(mnt); - } + kfree(inode->u.generic_ip); } static void kill_node(Node *e) @@ -430,6 +418,7 @@ static void kill_node(Node *e) dentry->d_inode->i_nlink--; d_drop(dentry); dput(dentry); + simple_release_fs(&bm_mnt, &entry_count); } } @@ -498,8 +487,6 @@ static struct file_operations bm_entry_operations = { .write = bm_entry_write, }; -static struct file_system_type bm_fs_type; - /* /register */ static ssize_t bm_register_write(struct file *file, const char *buffer, @@ -507,7 +494,6 @@ static ssize_t bm_register_write(struct file *file, const char *buffer, { Node *e; struct inode *inode; - struct vfsmount *mnt = NULL; struct dentry *root, *dentry; struct super_block *sb = file->f_vfsmnt->mnt_sb; int err = 0; @@ -534,32 +520,22 @@ static ssize_t bm_register_write(struct file *file, const char *buffer, if (!inode) goto out2; - write_lock(&entries_lock); - if (!bm_mnt) { - write_unlock(&entries_lock); - mnt = kern_mount(&bm_fs_type); - if (IS_ERR(mnt)) { - err = PTR_ERR(mnt); - iput(inode); - inode = NULL; - goto out2; - } - write_lock(&entries_lock); - if (!bm_mnt) - bm_mnt = mnt; + err = simple_pin_fs("binfmt_misc", &bm_mnt, &entry_count); + if (err) { + iput(inode); + inode = NULL; + goto out2; } - mntget(bm_mnt); - entry_count++; e->dentry = dget(dentry); inode->u.generic_ip = e; inode->i_fop = &bm_entry_operations; - d_instantiate(dentry, inode); + write_lock(&entries_lock); + d_instantiate(dentry, inode); list_add(&e->list, &entries); write_unlock(&entries_lock); - mntput(mnt); err = 0; out2: dput(dentry); diff --git a/fs/libfs.c b/fs/libfs.c index 643663858a63..860892e92b54 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -4,8 +4,11 @@ */ #include +#include #include +extern struct vfsmount *do_kern_mount(const char *, int, char *, void *); + int simple_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { @@ -390,3 +393,36 @@ out: dput(root); return -ENOMEM; } + +static spinlock_t pin_fs_lock = SPIN_LOCK_UNLOCKED; + +int simple_pin_fs(char *name, struct vfsmount **mount, int *count) +{ + struct vfsmount *mnt = NULL; + spin_lock(&pin_fs_lock); + if (unlikely(!*mount)) { + spin_unlock(&pin_fs_lock); + mnt = do_kern_mount(name, 0, name, NULL); + if (IS_ERR(mnt)) + return PTR_ERR(mnt); + spin_lock(&pin_fs_lock); + if (!*mount) + *mount = mnt; + } + mntget(*mount); + ++*count; + spin_unlock(&pin_fs_lock); + mntput(mnt); + return 0; +} + +void simple_release_fs(struct vfsmount **mount, int *count) +{ + struct vfsmount *mnt; + spin_lock(&pin_fs_lock); + mnt = *mount; + if (!--*count) + *mount = NULL; + spin_unlock(&pin_fs_lock); + mntput(mnt); +} diff --git a/include/linux/fs.h b/include/linux/fs.h index 00ddb3866b15..9b1e07ff267b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1294,6 +1294,8 @@ extern struct file_operations simple_dir_operations; extern struct inode_operations simple_dir_inode_operations; struct tree_descr { char *name; struct file_operations *ops; int mode; }; extern int simple_fill_super(struct super_block *, int, struct tree_descr *); +extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count); +extern void simple_release_fs(struct vfsmount **mount, int *count); #ifdef CONFIG_BLK_DEV_INITRD extern unsigned int real_root_dev; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 16e30b0f15cf..941b4acb0633 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -314,6 +314,8 @@ EXPORT_SYMBOL(simple_prepare_write); EXPORT_SYMBOL(simple_commit_write); EXPORT_SYMBOL(simple_empty); EXPORT_SYMBOL(simple_fill_super); +EXPORT_SYMBOL(simple_pin_fs); +EXPORT_SYMBOL(simple_release_fs); EXPORT_SYMBOL(fd_install); EXPORT_SYMBOL(put_unused_fd); EXPORT_SYMBOL(get_sb_bdev); diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 0b115e9076e3..879fbc8cdf73 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -29,7 +29,6 @@ #include static struct vfsmount *rpc_mount; -static spinlock_t rpc_mount_lock = SPIN_LOCK_UNLOCKED; static int rpc_mount_count; static struct file_system_type rpc_pipe_fs_type; @@ -379,46 +378,13 @@ static struct rpc_filelist authfiles[] = { static int rpc_get_mount(void) { - struct vfsmount * mnt = NULL; - - spin_lock(&rpc_mount_lock); - if (rpc_mount) - goto out_get; - spin_unlock(&rpc_mount_lock); - mnt = kern_mount(&rpc_pipe_fs_type); - if (IS_ERR(mnt)) - return -ENODEV; - spin_lock(&rpc_mount_lock); - if (!rpc_mount) { - rpc_mount = mnt; - mnt = NULL; - goto out_dontget; - } -out_get: - mntget(rpc_mount); -out_dontget: - ++rpc_mount_count; - spin_unlock(&rpc_mount_lock); - if (mnt) - mntput(mnt); - return 0; + return simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count); } static void rpc_put_mount(void) { - struct vfsmount *mnt; - - spin_lock(&rpc_mount_lock); - mnt = rpc_mount; - --rpc_mount_count; - if (rpc_mount_count == 0) - rpc_mount = NULL; - else - mnt = NULL; - spin_unlock(&rpc_mount_lock); - if (mnt) - mntput(mnt); + simple_release_fs(&rpc_mount, &rpc_mount_count); } static int -- cgit v1.2.3 From 80e96b51bbd4cd4a10402fe4a274bfb105057e06 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Sun, 27 Apr 2003 03:47:21 -0700 Subject: [PATCH] open_by_devnum() New helper - open_by_devnum(). Opens block_device by device number; for use in situations when we really have nothing better than dev_t (i.e. had received it from stupid userland API). --- drivers/md/dm-table.c | 21 ++++++++------------- drivers/md/md.c | 9 +++------ drivers/mtd/devices/blkmtd.c | 5 ++--- fs/block_dev.c | 17 +++++++++++++++++ fs/ext3/super.c | 12 ++++-------- fs/jfs/jfs_logmgr.c | 11 ++++------- fs/reiserfs/journal.c | 21 ++++++++------------- include/linux/fs.h | 1 + kernel/ksyms.c | 1 + kernel/suspend.c | 15 +++++++-------- 10 files changed, 55 insertions(+), 58 deletions(-) (limited to 'include/linux') diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 1dabc5dde4ce..f624018db4a7 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -345,26 +345,21 @@ static struct dm_dev *find_device(struct list_head *l, dev_t dev) static int open_dev(struct dm_dev *d, dev_t dev) { static char *_claim_ptr = "I belong to device-mapper"; + struct block_device *bdev; int r; if (d->bdev) BUG(); - d->bdev = bdget(dev); - if (!d->bdev) - return -ENOMEM; - - r = blkdev_get(d->bdev, d->mode, 0, BDEV_RAW); + bdev = open_by_devnum(dev, d->mode, BDEV_RAW); + if (IS_ERR(bdev)) + return PTR_ERR(bdev); + r = bd_claim(bdev, _claim_ptr); if (r) - return r; - - r = bd_claim(d->bdev, _claim_ptr); - if (r) { - blkdev_put(d->bdev, BDEV_RAW); - d->bdev = NULL; - } - + blkdev_put(bdev, BDEV_RAW); + else + d->bdev = bdev; return r; } diff --git a/drivers/md/md.c b/drivers/md/md.c index a1629dbda097..c4dfcf47de3b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1046,12 +1046,9 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev) int err = 0; struct block_device *bdev; - bdev = bdget(dev); - if (!bdev) - return -ENOMEM; - err = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_RAW); - if (err) - return err; + bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE, BDEV_RAW); + if (IS_ERR(bdev)) + return PTR_ERR(bdev); err = bd_claim(bdev, rdev); if (err) { blkdev_put(bdev, BDEV_RAW); diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c index bb458defa98a..be43a9b3956d 100644 --- a/drivers/mtd/devices/blkmtd.c +++ b/drivers/mtd/devices/blkmtd.c @@ -1128,9 +1128,8 @@ static int __init init_blkmtd(void) return 1; } /* get the block device */ - bdev = bdget(rdev); - err = blkdev_get(bdev, mode, 0, BDEV_RAW); - if (err) + bdev = open_by_devnum(rdev, FMODE_READ, BDEV_RAW); + if (IS_ERR(bdev)) return 1; DEBUG(1, "blkmtd: devname = %s\n", bdevname(bdev, b)); diff --git a/fs/block_dev.c b/fs/block_dev.c index 595d89d64e7e..edd8effee850 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -436,6 +436,23 @@ void bd_release(struct block_device *bdev) spin_unlock(&bdev_lock); } +/* + * Tries to open block device by device number. Use it ONLY if you + * really do not have anything better - i.e. when you are behind a + * truly sucky interface and all you are given is a device number. _Never_ + * to be used for internal purposes. If you ever need it - reconsider + * your API. + */ +struct block_device *open_by_devnum(dev_t dev, unsigned mode, int kind) +{ + struct block_device *bdev = bdget(dev); + int err = -ENOMEM; + int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY; + if (bdev) + err = blkdev_get(bdev, mode, flags, kind); + return err ? ERR_PTR(err) : bdev; +} + /* * This routine checks whether a removable media has been changed, * and invalidates all buffer-cache-entries in that case. This diff --git a/fs/ext3/super.c b/fs/ext3/super.c index da7f57d10e87..a4b37b8d9772 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -384,20 +384,16 @@ void ext3_update_dynamic_rev(struct super_block *sb) static struct block_device *ext3_blkdev_get(dev_t dev) { struct block_device *bdev; - int err = -ENODEV; char b[BDEVNAME_SIZE]; - bdev = bdget(dev); - if (bdev == NULL) - goto fail; - err = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_FS); - if (err < 0) + bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE, BDEV_FS); + if (IS_ERR(bdev)) goto fail; return bdev; fail: - printk(KERN_ERR "EXT3: failed to open journal device %s: %d\n", - __bdevname(dev, b), err); + printk(KERN_ERR "EXT3: failed to open journal device %s: %ld\n", + __bdevname(dev, b), PTR_ERR(bdev)); return NULL; } diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 2d18d1d64875..bd3ca7cf8f3d 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1105,13 +1105,10 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr) */ externalLog: - if (!(bdev = bdget(JFS_SBI(sb)->logdev))) { - rc = ENODEV; - goto free; - } - - if ((rc = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_FS))) { - rc = -rc; + bdev = open_by_devnum(JFS_SBI(sb)->logdev, + FMODE_READ|FMODE_WRITE, BDEV_FS); + if (IS_ERR(bdev)) { + rc = -PTR_ERR(bdev); goto free; } diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 986a877f0bf4..2c6b2708515c 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -1911,21 +1911,16 @@ static int journal_init_dev( struct super_block *super, /* there is no "jdev" option and journal is on separate device */ if( ( !jdev_name || !jdev_name[ 0 ] ) ) { - journal -> j_dev_bd = bdget(jdev); - if( journal -> j_dev_bd ) - result = blkdev_get( journal -> j_dev_bd, - blkdev_mode, 0, - BDEV_FS ); - else - result = -ENOMEM; - if( result != 0 ) + journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode, BDEV_FS); + if (IS_ERR(journal->j_dev_bd)) { + result = PTR_ERR(journal->j_dev_bd); + journal->j_dev_bd = NULL; printk( "sh-458: journal_init_dev: cannot init journal device\n '%s': %i", - bdevname(journal->j_dev_bd, b), result ); - - else if (jdev != super->s_dev) { + __bdevname(jdev, b), result ); + return result; + } else if (jdev != super->s_dev) set_blocksize(journal->j_dev_bd, super->s_blocksize); - } - return result; + return 0; } journal -> j_dev_file = filp_open( jdev_name, 0, 0 ); diff --git a/include/linux/fs.h b/include/linux/fs.h index 9b1e07ff267b..26aa1bd539f1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1041,6 +1041,7 @@ extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); extern int blkdev_open(struct inode *, struct file *); extern int blkdev_close(struct inode *, struct file *); +extern struct block_device *open_by_devnum(dev_t, unsigned, int); extern struct file_operations def_blk_fops; extern struct address_space_operations def_blk_aops; extern struct file_operations def_chr_fops; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 941b4acb0633..c55d5a57ea85 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -209,6 +209,7 @@ EXPORT_SYMBOL(bd_claim); EXPORT_SYMBOL(bd_release); EXPORT_SYMBOL(open_bdev_excl); EXPORT_SYMBOL(close_bdev_excl); +EXPORT_SYMBOL(open_by_devnum); EXPORT_SYMBOL(__brelse); EXPORT_SYMBOL(__bforget); EXPORT_SYMBOL(ll_rw_block); diff --git a/kernel/suspend.c b/kernel/suspend.c index f8b76113ecd2..5008bbe76555 100644 --- a/kernel/suspend.c +++ b/kernel/suspend.c @@ -1161,15 +1161,14 @@ static int read_suspend_image(const char * specialfile, int noresume) struct block_device *bdev; printk("Resuming from device %s\n", __bdevname(resume_device, b)); - bdev = bdget(resume_device); - if (!bdev) { - printk("No such block device ?!\n"); - BUG(); + bdev = open_by_devnum(resume_device, FMODE_READ, BDEV_RAW); + if (IS_ERR(bdev)) { + error = PTR_ERR(bdev); + } else { + set_blocksize(bdev, PAGE_SIZE); + error = __read_suspend_image(bdev, cur, noresume); + blkdev_put(bdev, BDEV_RAW); } - blkdev_get(bdev, FMODE_READ, O_RDONLY, BDEV_RAW); - set_blocksize(bdev, PAGE_SIZE); - error = __read_suspend_image(bdev, cur, noresume); - blkdev_put(bdev, BDEV_RAW); } else error = -ENOMEM; if (scratch_page) -- cgit v1.2.3 From 07affbb1eadddfbab8e2270ee17965419887d8a2 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Sun, 27 Apr 2003 03:47:38 -0700 Subject: [PATCH] bdget_disk() New helper - bdget_disk(gendisk, partition) invalidate_device() replaced with invalidate_partition(disk, part) --- drivers/block/floppy.c | 2 +- drivers/block/floppy98.c | 2 +- drivers/block/genhd.c | 11 +++++++++++ drivers/block/ioctl.c | 2 +- drivers/md/dm-ioctl.c | 4 ++-- drivers/md/md.c | 2 +- fs/block_dev.c | 2 +- fs/inode.c | 10 ---------- fs/partitions/check.c | 15 +++++---------- include/linux/fs.h | 2 +- include/linux/genhd.h | 5 +++++ kernel/ksyms.c | 1 - 12 files changed, 29 insertions(+), 29 deletions(-) (limited to 'include/linux') diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index e85256befeec..ee016885325c 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -3885,7 +3885,7 @@ static int floppy_read_block_0(struct gendisk *disk) struct block_device *bdev; int ret; - bdev = bdget(MKDEV(disk->major, disk->first_minor)); + bdev = bdget_disk(disk, 0); if (!bdev) { printk("No block device for %s\n", disk->disk_name); BUG(); diff --git a/drivers/block/floppy98.c b/drivers/block/floppy98.c index a01a515f0618..226b0cee8a20 100644 --- a/drivers/block/floppy98.c +++ b/drivers/block/floppy98.c @@ -3995,7 +3995,7 @@ static int floppy_read_block_0(struct gendisk *disk) struct block_device *bdev; int ret; - bdev = bdget(MKDEV(disk->major, disk->first_minor)); + bdev = bdget_disk(disk, 0); if (!bdev) { printk("No block device for %s\n", disk->disk_name); BUG(); diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index 34d9d4dd91fc..fe922bcc5805 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -721,6 +721,17 @@ int bdev_read_only(struct block_device *bdev) return disk->policy; } +int invalidate_partition(struct gendisk *disk, int index) +{ + int res = 0; + struct block_device *bdev = bdget_disk(disk, index); + if (bdev) + res = __invalidate_device(bdev, 1); + bdput(bdev); + return res; +} + EXPORT_SYMBOL(bdev_read_only); EXPORT_SYMBOL(set_device_ro); EXPORT_SYMBOL(set_disk_ro); +EXPORT_SYMBOL(invalidate_partition); diff --git a/drivers/block/ioctl.c b/drivers/block/ioctl.c index 3dbd0824319b..04aae2485102 100644 --- a/drivers/block/ioctl.c +++ b/drivers/block/ioctl.c @@ -62,7 +62,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg *arg) if (disk->part[part - 1]->nr_sects == 0) return -ENXIO; /* partition in use? Incomplete check for now. */ - bdevp = bdget(MKDEV(disk->major, disk->first_minor) + part); + bdevp = bdget_disk(disk, part); if (!bdevp) return -ENOMEM; if (bd_claim(bdevp, &holder) < 0) { diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 96cabf795823..cb667cdf69d1 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -450,11 +450,11 @@ static int __info(struct mapped_device *md, struct dm_ioctl *param) if (dm_suspended(md)) param->flags |= DM_SUSPEND_FLAG; - param->dev = MKDEV(disk->major, disk->first_minor); - bdev = bdget(param->dev); + bdev = bdget_disk(disk, 0); if (!bdev) return -ENXIO; + param->dev = bdev->bd_dev; param->open_count = bdev->bd_openers; bdput(bdev); diff --git a/drivers/md/md.c b/drivers/md/md.c index c4dfcf47de3b..272bef26e781 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1684,7 +1684,7 @@ static int do_md_stop(mddev_t * mddev, int ro) del_timer_sync(&mddev->safemode_timer); - invalidate_device(mk_kdev(disk->major, disk->first_minor), 1); + invalidate_partition(disk, 0); if (ro) { err = -ENXIO; diff --git a/fs/block_dev.c b/fs/block_dev.c index edd8effee850..7b53dd72cb26 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -535,7 +535,7 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file * } else { struct hd_struct *p; struct block_device *whole; - whole = bdget(MKDEV(disk->major, disk->first_minor)); + whole = bdget_disk(disk, 0); ret = -ENOMEM; if (!whole) goto out_first; diff --git a/fs/inode.c b/fs/inode.c index 6e9b869fe9d2..9440ffe76b08 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -365,16 +365,6 @@ int __invalidate_device(struct block_device *bdev, int do_sync) return res; } -int invalidate_device(kdev_t dev, int do_sync) -{ - int res = 0; - struct block_device *bdev = bdget(kdev_t_to_nr(dev)); - if (bdev) - res = __invalidate_device(bdev, do_sync); - bdput(bdev); - return res; -} - static int can_unuse(struct inode *inode) { if (inode->i_state) diff --git a/fs/partitions/check.c b/fs/partitions/check.c index f185f0284dc3..a8530c42211f 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -311,7 +311,7 @@ void register_disk(struct gendisk *disk) if (!get_capacity(disk)) return; - bdev = bdget(MKDEV(disk->major, disk->first_minor)); + bdev = bdget_disk(disk, 0); if (blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW) < 0) return; state = check_partition(disk, bdev); @@ -336,13 +336,12 @@ void register_disk(struct gendisk *disk) int rescan_partitions(struct gendisk *disk, struct block_device *bdev) { - kdev_t dev = to_kdev_t(bdev->bd_dev); struct parsed_partitions *state; int p, res; if (bdev->bd_part_count) return -EBUSY; - res = invalidate_device(dev, 1); + res = invalidate_partition(disk, 0); if (res) return res; bdev->bd_invalidated = 0; @@ -391,18 +390,14 @@ fail: void del_gendisk(struct gendisk *disk) { - int max_p = disk->minors; - kdev_t devp; int p; /* invalidate stuff */ - for (p = max_p - 1; p > 0; p--) { - devp = mk_kdev(disk->major,disk->first_minor + p); - invalidate_device(devp, 1); + for (p = disk->minors - 1; p > 0; p--) { + invalidate_partition(disk, p); delete_partition(disk, p); } - devp = mk_kdev(disk->major,disk->first_minor); - invalidate_device(devp, 1); + invalidate_partition(disk, 0); disk->capacity = 0; disk->flags &= ~GENHD_FL_UP; unlink_gendisk(disk); diff --git a/include/linux/fs.h b/include/linux/fs.h index 26aa1bd539f1..572b92e6f443 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1105,7 +1105,7 @@ extern int fs_may_remount_ro(struct super_block *); extern int check_disk_change(struct block_device *); extern int invalidate_inodes(struct super_block *); extern int __invalidate_device(struct block_device *, int); -extern int invalidate_device(kdev_t, int); +extern int invalidate_partition(struct gendisk *, int); unsigned long invalidate_mapping_pages(struct address_space *mapping, pgoff_t start, pgoff_t end); unsigned long invalidate_inode_pages(struct address_space *mapping); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 096643e667ae..35e93e35455d 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -367,6 +367,11 @@ extern void blk_register_region(dev_t dev, unsigned long range, void *data); extern void blk_unregister_region(dev_t dev, unsigned long range); +static inline struct block_device *bdget_disk(struct gendisk *disk, int index) +{ + return bdget(MKDEV(disk->major, disk->first_minor) + index); +} + #endif #endif diff --git a/kernel/ksyms.c b/kernel/ksyms.c index c55d5a57ea85..8c8cff48895d 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -188,7 +188,6 @@ EXPORT_SYMBOL(files_lock); EXPORT_SYMBOL(check_disk_change); EXPORT_SYMBOL(invalidate_bdev); EXPORT_SYMBOL(invalidate_inodes); -EXPORT_SYMBOL(invalidate_device); EXPORT_SYMBOL(__invalidate_device); EXPORT_SYMBOL(invalidate_inode_pages); EXPORT_SYMBOL_GPL(invalidate_inode_pages2); -- cgit v1.2.3