Commit 8fbd544c authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] bdev: add I_BDEV()

From: viro@parcelfarce.linux.theplanet.co.uk <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.
parent 980f7186
...@@ -683,7 +683,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, ...@@ -683,7 +683,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
lo_flags |= LO_FLAGS_READ_ONLY; lo_flags |= LO_FLAGS_READ_ONLY;
if (S_ISBLK(inode->i_mode)) { if (S_ISBLK(inode->i_mode)) {
lo_device = inode->i_bdev; lo_device = I_BDEV(inode);
if (lo_device == bdev) { if (lo_device == bdev) {
error = -EBUSY; error = -EBUSY;
goto out_putf; goto out_putf;
......
...@@ -25,6 +25,22 @@ ...@@ -25,6 +25,22 @@
#include <linux/namei.h> #include <linux/namei.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
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) static sector_t max_block(struct block_device *bdev)
{ {
...@@ -100,10 +116,10 @@ static int ...@@ -100,10 +116,10 @@ static int
blkdev_get_block(struct inode *inode, sector_t iblock, blkdev_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh, int create) struct buffer_head *bh, int create)
{ {
if (iblock >= max_block(inode->i_bdev)) if (iblock >= max_block(I_BDEV(inode)))
return -EIO; return -EIO;
bh->b_bdev = inode->i_bdev; bh->b_bdev = I_BDEV(inode);
bh->b_blocknr = iblock; bh->b_blocknr = iblock;
set_buffer_mapped(bh); set_buffer_mapped(bh);
return 0; return 0;
...@@ -113,10 +129,10 @@ static int ...@@ -113,10 +129,10 @@ static int
blkdev_get_blocks(struct inode *inode, sector_t iblock, blkdev_get_blocks(struct inode *inode, sector_t iblock,
unsigned long max_blocks, struct buffer_head *bh, int create) 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; return -EIO;
bh->b_bdev = inode->i_bdev; bh->b_bdev = I_BDEV(inode);
bh->b_blocknr = iblock; bh->b_blocknr = iblock;
bh->b_size = max_blocks << inode->i_blkbits; bh->b_size = max_blocks << inode->i_blkbits;
set_buffer_mapped(bh); set_buffer_mapped(bh);
...@@ -130,7 +146,7 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, ...@@ -130,7 +146,7 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host; 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); nr_segs, blkdev_get_blocks, NULL);
} }
...@@ -161,11 +177,10 @@ static int blkdev_commit_write(struct file *file, struct page *page, unsigned fr ...@@ -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) 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 size;
loff_t retval; loff_t retval;
bd_inode = file->f_dentry->d_inode->i_bdev->bd_inode;
down(&bd_inode->i_sem); down(&bd_inode->i_sem);
size = i_size_read(bd_inode); size = i_size_read(bd_inode);
...@@ -188,15 +203,13 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin) ...@@ -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 * Filp is never NULL; the only case when ->fsync() is called with
* since the vma has no handle. * 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) static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
{ {
struct inode * inode = dentry->d_inode; return sync_blockdev(I_BDEV(filp->f_mapping->host));
return sync_blockdev(inode->i_bdev);
} }
/* /*
...@@ -206,16 +219,6 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) ...@@ -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 spinlock_t bdev_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
static kmem_cache_t * bdev_cachep; 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) static struct inode *bdev_alloc_inode(struct super_block *sb)
{ {
struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL); struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL);
...@@ -735,11 +738,12 @@ int blkdev_put(struct block_device *bdev, int kind) ...@@ -735,11 +738,12 @@ int blkdev_put(struct block_device *bdev, int kind)
EXPORT_SYMBOL(blkdev_put); 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) struct block_device *bdev = I_BDEV(filp->f_mapping->host);
bd_release(inode->i_bdev); if (bdev->bd_holder == filp)
return blkdev_put(inode->i_bdev, BDEV_FILE); bd_release(bdev);
return blkdev_put(bdev, BDEV_FILE);
} }
static ssize_t blkdev_file_write(struct file *file, const char __user *buf, 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, ...@@ -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); 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 = { struct address_space_operations def_blk_aops = {
.readpage = blkdev_readpage, .readpage = blkdev_readpage,
...@@ -779,7 +788,7 @@ struct file_operations def_blk_fops = { ...@@ -779,7 +788,7 @@ struct file_operations def_blk_fops = {
.aio_write = blkdev_file_aio_write, .aio_write = blkdev_file_aio_write,
.mmap = generic_file_mmap, .mmap = generic_file_mmap,
.fsync = block_fsync, .fsync = block_fsync,
.ioctl = blkdev_ioctl, .ioctl = block_ioctl,
.readv = generic_file_readv, .readv = generic_file_readv,
.writev = generic_file_writev, .writev = generic_file_writev,
.sendfile = generic_file_sendfile, .sendfile = generic_file_sendfile,
......
...@@ -1937,18 +1937,13 @@ static int journal_init_dev( struct super_block *super, ...@@ -1937,18 +1937,13 @@ static int journal_init_dev( struct super_block *super,
journal -> j_dev_file = filp_open( jdev_name, 0, 0 ); journal -> j_dev_file = filp_open( jdev_name, 0, 0 );
if( !IS_ERR( journal -> j_dev_file ) ) { if( !IS_ERR( journal -> j_dev_file ) ) {
struct inode *jdev_inode; struct inode *jdev_inode = journal->j_dev_file->f_mapping->host;
jdev_inode = journal -> j_dev_file -> f_dentry -> d_inode;
journal -> j_dev_bd = jdev_inode -> i_bdev;
if( !S_ISBLK( jdev_inode -> i_mode ) ) { if( !S_ISBLK( jdev_inode -> i_mode ) ) {
printk( "journal_init_dev: '%s' is not a block device\n", jdev_name ); printk( "journal_init_dev: '%s' is not a block device\n", jdev_name );
result = -ENOTBLK; result = -ENOTBLK;
} else if( jdev_inode -> i_bdev == NULL ) {
printk( "journal_init_dev: bdev uninitialized for '%s'\n", jdev_name );
result = -ENOMEM;
} else { } else {
/* ok */ /* ok */
journal->j_dev_bd = I_BDEV(jdev_inode);
set_blocksize(journal->j_dev_bd, super->s_blocksize); set_blocksize(journal->j_dev_bd, super->s_blocksize);
} }
} else { } else {
......
...@@ -480,6 +480,8 @@ static inline unsigned imajor(struct inode *inode) ...@@ -480,6 +480,8 @@ static inline unsigned imajor(struct inode *inode)
return MAJOR(inode->i_rdev); return MAJOR(inode->i_rdev);
} }
extern struct block_device *I_BDEV(struct inode *inode);
struct fown_struct { struct fown_struct {
rwlock_t lock; /* protects pid, uid, euid fields */ rwlock_t lock; /* protects pid, uid, euid fields */
int pid; /* pid or -pgrp where SIGIO should be sent */ int pid; /* pid or -pgrp where SIGIO should be sent */
...@@ -1128,7 +1130,6 @@ extern struct block_device *bdget(dev_t); ...@@ -1128,7 +1130,6 @@ extern struct block_device *bdget(dev_t);
extern void bd_forget(struct inode *inode); extern void bd_forget(struct inode *inode);
extern void bdput(struct block_device *); extern void bdput(struct block_device *);
extern int blkdev_open(struct inode *, struct file *); 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 block_device *open_by_devnum(dev_t, unsigned, int);
extern struct file_operations def_blk_fops; extern struct file_operations def_blk_fops;
extern struct address_space_operations def_blk_aops; extern struct address_space_operations def_blk_aops;
......
...@@ -1690,7 +1690,7 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i ...@@ -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; *count = inode->i_sb->s_maxbytes - *pos;
} else { } else {
loff_t isize; loff_t isize;
if (bdev_read_only(inode->i_bdev)) if (bdev_read_only(I_BDEV(inode)))
return -EPERM; return -EPERM;
isize = i_size_read(inode); isize = i_size_read(inode);
if (*pos >= isize) { if (*pos >= isize) {
......
...@@ -1100,8 +1100,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile) ...@@ -1100,8 +1100,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile)
swap_list_unlock(); swap_list_unlock();
vfree(swap_map); vfree(swap_map);
if (S_ISBLK(mapping->host->i_mode)) { if (S_ISBLK(mapping->host->i_mode)) {
struct block_device *bdev; struct block_device *bdev = I_BDEV(mapping->host);
bdev = mapping->host->i_bdev;
set_blocksize(bdev, p->old_block_size); set_blocksize(bdev, p->old_block_size);
bd_release(bdev); bd_release(bdev);
} else { } else {
...@@ -1294,14 +1293,14 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) ...@@ -1294,14 +1293,14 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
error = -EINVAL; error = -EINVAL;
if (S_ISBLK(inode->i_mode)) { if (S_ISBLK(inode->i_mode)) {
bdev = inode->i_bdev; bdev = I_BDEV(inode);
error = bd_claim(bdev, sys_swapon); error = bd_claim(bdev, sys_swapon);
if (error < 0) { if (error < 0) {
bdev = NULL; bdev = NULL;
goto bad_swap; goto bad_swap;
} }
p->old_block_size = block_size(bdev); p->old_block_size = block_size(bdev);
error = set_blocksize(inode->i_bdev, PAGE_SIZE); error = set_blocksize(bdev, PAGE_SIZE);
if (error < 0) if (error < 0)
goto bad_swap; goto bad_swap;
p->bdev = bdev; p->bdev = bdev;
......
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