Commit 5e5ac463 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] loop/shmfs fixes

 - add lo->lo_blocksize
 - kill lo_get_bs() - great name, but...
 - set ->lo_device only if we do have a block device
 - pull determination of ->lo_blocksize into both branches - bdev
   variant gets it from lo_device and file one uses ->i_blocksize.
 - switched the ioctl getting information about underlying object
   to lo->lo_device ? stat.rdev : stat.dev
 - i.e. st_rdev of underlying object if it's a device and st_dev - if it's
   a file.
 - reverted the bogosity in shmem.c
parent 159ecf44
......@@ -338,15 +338,10 @@ lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
return ret;
}
static inline int loop_get_bs(struct loop_device *lo)
{
return block_size(lo->lo_device);
}
static inline unsigned long loop_get_iv(struct loop_device *lo,
unsigned long sector)
{
int bs = loop_get_bs(lo);
int bs = lo->lo_blocksize;
unsigned long offset, IV;
IV = sector / (bs >> 9) + lo->lo_offset / bs;
......@@ -366,9 +361,9 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
do {
if (bio_rw(bio) == WRITE)
ret = lo_send(lo, bio, loop_get_bs(lo), pos);
ret = lo_send(lo, bio, lo->lo_blocksize, pos);
else
ret = lo_receive(lo, bio, loop_get_bs(lo), pos);
ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
} while (++bio->bi_idx < bio->bi_vcnt);
......@@ -650,7 +645,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
{
struct file *file;
struct inode *inode;
struct block_device *lo_device;
struct block_device *lo_device = NULL;
unsigned lo_blocksize;
int lo_flags = 0;
int error;
......@@ -677,6 +673,9 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
error = -EBUSY;
goto out;
}
lo_blocksize = block_size(lo_device);
if (bdev_read_only(lo_device))
lo_flags |= LO_FLAGS_READ_ONLY;
} else if (S_ISREG(inode->i_mode)) {
struct address_space_operations *aops = inode->i_mapping->a_ops;
/*
......@@ -689,7 +688,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
if (!aops->prepare_write || !aops->commit_write)
lo_flags |= LO_FLAGS_READ_ONLY;
lo_device = inode->i_sb->s_bdev;
lo_blocksize = inode->i_blocksize;
lo_flags |= LO_FLAGS_DO_BMAP;
error = 0;
} else
......@@ -697,12 +696,12 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
get_file(file);
if (IS_RDONLY (inode) || bdev_read_only(lo_device)
|| !(lo_file->f_mode & FMODE_WRITE))
if (!(lo_file->f_mode & FMODE_WRITE))
lo_flags |= LO_FLAGS_READ_ONLY;
set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0);
lo->lo_blocksize = lo_blocksize;
lo->lo_device = lo_device;
lo->lo_flags = lo_flags;
lo->lo_backing_file = file;
......@@ -716,7 +715,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
lo->old_gfp_mask = inode->i_mapping->gfp_mask;
inode->i_mapping->gfp_mask = GFP_NOIO;
set_blocksize(bdev, block_size(lo_device));
set_blocksize(bdev, lo_blocksize);
lo->lo_bio = lo->lo_biotail = NULL;
......@@ -899,7 +898,7 @@ static int loop_get_status(struct loop_device *lo, struct loop_info *arg)
info.lo_number = lo->lo_number;
info.lo_device = stat.dev;
info.lo_inode = stat.ino;
info.lo_rdevice = lo->lo_device->bd_dev;
info.lo_rdevice = lo->lo_device ? stat.rdev : stat.dev;
info.lo_offset = lo->lo_offset;
info.lo_flags = lo->lo_flags;
strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE);
......
......@@ -43,6 +43,7 @@ struct loop_device {
struct file * lo_backing_file;
struct block_device *lo_device;
unsigned lo_blocksize;
void *key_data;
char key_reserved[48]; /* for use by the filter modules */
......
......@@ -1694,16 +1694,13 @@ static int shmem_fill_super(struct super_block *sb, void *data, int silent)
sbinfo->max_inodes = inodes;
sbinfo->free_inodes = inodes;
sb->s_maxbytes = SHMEM_MAX_BYTES;
sb->s_bdev = bdget(sb->s_dev);
if (!sb->s_bdev)
goto failed;
if (!sb_set_blocksize(sb, PAGE_CACHE_SIZE))
BUG();
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
sb->s_magic = TMPFS_MAGIC;
sb->s_op = &shmem_ops;
inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
if (!inode)
goto failed_bdput;
goto failed;
inode->i_uid = uid;
inode->i_gid = gid;
root = d_alloc_root(inode);
......@@ -1714,9 +1711,6 @@ static int shmem_fill_super(struct super_block *sb, void *data, int silent)
failed_iput:
iput(inode);
failed_bdput:
bdput(sb->s_bdev);
sb->s_bdev = NULL;
failed:
kfree(sbinfo);
sb->s_fs_info = NULL;
......@@ -1725,8 +1719,6 @@ static int shmem_fill_super(struct super_block *sb, void *data, int silent)
static void shmem_put_super(struct super_block *sb)
{
bdput(sb->s_bdev);
sb->s_bdev = NULL;
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
}
......
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