From 8fbd544cbca5c62947daa5b270a4d083b9c93289 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 18 Jan 2004 18:07:17 -0800 Subject: [PATCH] [PATCH] bdev: add I_BDEV() From: viro@parcelfarce.linux.theplanet.co.uk For bdevfs inodes (ones created along with struct block_device by fs/block_dev.c) we have inode->i_bdev equal to &BDEV_I(inode)->bdev (i.e. it's at the constant offset from inode). New helper added for such inodes (I_BDEV(inode)). A bunch of places (mostly in block_dev.c) switched to use of that helper. A bunch of places that used file->f_dentry->d_inode->i_bdev->bd_inode switched to file->f_mapping->host - those expressions are equal whenever the former is valid. --- drivers/block/loop.c | 2 +- fs/block_dev.c | 63 ++++++++++++++++++++++++------------------- fs/reiserfs/journal.c | 9 ++----- include/linux/fs.h | 3 ++- mm/filemap.c | 2 +- mm/swapfile.c | 7 +++-- 6 files changed, 45 insertions(+), 41 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 5565110f85619..87f8c2527ca8f 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -683,7 +683,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, lo_flags |= LO_FLAGS_READ_ONLY; if (S_ISBLK(inode->i_mode)) { - lo_device = inode->i_bdev; + lo_device = I_BDEV(inode); if (lo_device == bdev) { error = -EBUSY; goto out_putf; diff --git a/fs/block_dev.c b/fs/block_dev.c index 3bfe77ec0864a..c2649835bac09 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -25,6 +25,22 @@ #include #include +struct bdev_inode { + struct block_device bdev; + struct inode vfs_inode; +}; + +static inline struct bdev_inode *BDEV_I(struct inode *inode) +{ + return container_of(inode, struct bdev_inode, vfs_inode); +} + +inline struct block_device *I_BDEV(struct inode *inode) +{ + return &BDEV_I(inode)->bdev; +} + +EXPORT_SYMBOL(I_BDEV); static sector_t max_block(struct block_device *bdev) { @@ -100,10 +116,10 @@ static int blkdev_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh, int create) { - if (iblock >= max_block(inode->i_bdev)) + if (iblock >= max_block(I_BDEV(inode))) return -EIO; - bh->b_bdev = inode->i_bdev; + bh->b_bdev = I_BDEV(inode); bh->b_blocknr = iblock; set_buffer_mapped(bh); return 0; @@ -113,10 +129,10 @@ static int blkdev_get_blocks(struct inode *inode, sector_t iblock, unsigned long max_blocks, struct buffer_head *bh, int create) { - if ((iblock + max_blocks) > max_block(inode->i_bdev)) + if ((iblock + max_blocks) > max_block(I_BDEV(inode))) return -EIO; - bh->b_bdev = inode->i_bdev; + bh->b_bdev = I_BDEV(inode); bh->b_blocknr = iblock; bh->b_size = max_blocks << inode->i_blkbits; set_buffer_mapped(bh); @@ -130,7 +146,7 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; - return blockdev_direct_IO(rw, iocb, inode, inode->i_bdev, iov, offset, + return blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset, nr_segs, blkdev_get_blocks, NULL); } @@ -161,11 +177,10 @@ static int blkdev_commit_write(struct file *file, struct page *page, unsigned fr */ static loff_t block_llseek(struct file *file, loff_t offset, int origin) { - struct inode *bd_inode; + struct inode *bd_inode = file->f_mapping->host; loff_t size; loff_t retval; - bd_inode = file->f_dentry->d_inode->i_bdev->bd_inode; down(&bd_inode->i_sem); size = i_size_read(bd_inode); @@ -188,15 +203,13 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin) } /* - * Filp may be NULL when we are called by an msync of a vma - * since the vma has no handle. + * Filp is never NULL; the only case when ->fsync() is called with + * NULL first argument is nfsd_sync_dir() and that's not a directory. */ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) { - struct inode * inode = dentry->d_inode; - - return sync_blockdev(inode->i_bdev); + return sync_blockdev(I_BDEV(filp->f_mapping->host)); } /* @@ -206,16 +219,6 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) static spinlock_t bdev_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; static kmem_cache_t * bdev_cachep; -struct bdev_inode { - struct block_device bdev; - struct inode vfs_inode; -}; - -static inline struct bdev_inode *BDEV_I(struct inode *inode) -{ - return container_of(inode, struct bdev_inode, vfs_inode); -} - static struct inode *bdev_alloc_inode(struct super_block *sb) { struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL); @@ -735,11 +738,12 @@ int blkdev_put(struct block_device *bdev, int kind) EXPORT_SYMBOL(blkdev_put); -int blkdev_close(struct inode * inode, struct file * filp) +static int blkdev_close(struct inode * inode, struct file * filp) { - if (inode->i_bdev->bd_holder == filp) - bd_release(inode->i_bdev); - return blkdev_put(inode->i_bdev, BDEV_FILE); + struct block_device *bdev = I_BDEV(filp->f_mapping->host); + if (bdev->bd_holder == filp) + bd_release(bdev); + return blkdev_put(bdev, BDEV_FILE); } static ssize_t blkdev_file_write(struct file *file, const char __user *buf, @@ -758,6 +762,11 @@ static ssize_t blkdev_file_aio_write(struct kiocb *iocb, const char __user *buf, return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); } +static int block_ioctl(struct inode *inode, struct file *file, unsigned cmd, + unsigned long arg) +{ + return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); +} struct address_space_operations def_blk_aops = { .readpage = blkdev_readpage, @@ -779,7 +788,7 @@ struct file_operations def_blk_fops = { .aio_write = blkdev_file_aio_write, .mmap = generic_file_mmap, .fsync = block_fsync, - .ioctl = blkdev_ioctl, + .ioctl = block_ioctl, .readv = generic_file_readv, .writev = generic_file_writev, .sendfile = generic_file_sendfile, diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index db1dfe91c2a4b..c86cd729e3a23 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -1937,18 +1937,13 @@ static int journal_init_dev( struct super_block *super, journal -> j_dev_file = filp_open( jdev_name, 0, 0 ); if( !IS_ERR( journal -> j_dev_file ) ) { - struct inode *jdev_inode; - - jdev_inode = journal -> j_dev_file -> f_dentry -> d_inode; - journal -> j_dev_bd = jdev_inode -> i_bdev; + struct inode *jdev_inode = journal->j_dev_file->f_mapping->host; if( !S_ISBLK( jdev_inode -> i_mode ) ) { printk( "journal_init_dev: '%s' is not a block device\n", jdev_name ); result = -ENOTBLK; - } else if( jdev_inode -> i_bdev == NULL ) { - printk( "journal_init_dev: bdev uninitialized for '%s'\n", jdev_name ); - result = -ENOMEM; } else { /* ok */ + journal->j_dev_bd = I_BDEV(jdev_inode); set_blocksize(journal->j_dev_bd, super->s_blocksize); } } else { diff --git a/include/linux/fs.h b/include/linux/fs.h index 2880d702043ed..8863f93617ba7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -480,6 +480,8 @@ static inline unsigned imajor(struct inode *inode) return MAJOR(inode->i_rdev); } +extern struct block_device *I_BDEV(struct inode *inode); + struct fown_struct { rwlock_t lock; /* protects pid, uid, euid fields */ int pid; /* pid or -pgrp where SIGIO should be sent */ @@ -1128,7 +1130,6 @@ extern struct block_device *bdget(dev_t); 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; diff --git a/mm/filemap.c b/mm/filemap.c index d9368c9368de4..b4d34de279a88 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1690,7 +1690,7 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i *count = inode->i_sb->s_maxbytes - *pos; } else { loff_t isize; - if (bdev_read_only(inode->i_bdev)) + if (bdev_read_only(I_BDEV(inode))) return -EPERM; isize = i_size_read(inode); if (*pos >= isize) { diff --git a/mm/swapfile.c b/mm/swapfile.c index 46d1e0f9d26ad..112117a5d66c8 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -1100,8 +1100,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile) swap_list_unlock(); vfree(swap_map); if (S_ISBLK(mapping->host->i_mode)) { - struct block_device *bdev; - bdev = mapping->host->i_bdev; + struct block_device *bdev = I_BDEV(mapping->host); set_blocksize(bdev, p->old_block_size); bd_release(bdev); } else { @@ -1294,14 +1293,14 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) error = -EINVAL; if (S_ISBLK(inode->i_mode)) { - bdev = inode->i_bdev; + bdev = I_BDEV(inode); error = bd_claim(bdev, sys_swapon); if (error < 0) { bdev = NULL; goto bad_swap; } p->old_block_size = block_size(bdev); - error = set_blocksize(inode->i_bdev, PAGE_SIZE); + error = set_blocksize(bdev, PAGE_SIZE); if (error < 0) goto bad_swap; p->bdev = bdev; -- 2.53.0