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) ...@@ -338,15 +338,10 @@ lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
return ret; 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, static inline unsigned long loop_get_iv(struct loop_device *lo,
unsigned long sector) unsigned long sector)
{ {
int bs = loop_get_bs(lo); int bs = lo->lo_blocksize;
unsigned long offset, IV; unsigned long offset, IV;
IV = sector / (bs >> 9) + lo->lo_offset / bs; IV = sector / (bs >> 9) + lo->lo_offset / bs;
...@@ -366,9 +361,9 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) ...@@ -366,9 +361,9 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
do { do {
if (bio_rw(bio) == WRITE) 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 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); } while (++bio->bi_idx < bio->bi_vcnt);
...@@ -650,7 +645,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, ...@@ -650,7 +645,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
{ {
struct file *file; struct file *file;
struct inode *inode; struct inode *inode;
struct block_device *lo_device; struct block_device *lo_device = NULL;
unsigned lo_blocksize;
int lo_flags = 0; int lo_flags = 0;
int error; int error;
...@@ -677,6 +673,9 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, ...@@ -677,6 +673,9 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
error = -EBUSY; error = -EBUSY;
goto out; 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)) { } else if (S_ISREG(inode->i_mode)) {
struct address_space_operations *aops = inode->i_mapping->a_ops; 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, ...@@ -689,7 +688,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
if (!aops->prepare_write || !aops->commit_write) if (!aops->prepare_write || !aops->commit_write)
lo_flags |= LO_FLAGS_READ_ONLY; lo_flags |= LO_FLAGS_READ_ONLY;
lo_device = inode->i_sb->s_bdev; lo_blocksize = inode->i_blocksize;
lo_flags |= LO_FLAGS_DO_BMAP; lo_flags |= LO_FLAGS_DO_BMAP;
error = 0; error = 0;
} else } else
...@@ -697,12 +696,12 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, ...@@ -697,12 +696,12 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
get_file(file); get_file(file);
if (IS_RDONLY (inode) || bdev_read_only(lo_device) if (!(lo_file->f_mode & FMODE_WRITE))
|| !(lo_file->f_mode & FMODE_WRITE))
lo_flags |= LO_FLAGS_READ_ONLY; lo_flags |= LO_FLAGS_READ_ONLY;
set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0);
lo->lo_blocksize = lo_blocksize;
lo->lo_device = lo_device; lo->lo_device = lo_device;
lo->lo_flags = lo_flags; lo->lo_flags = lo_flags;
lo->lo_backing_file = file; lo->lo_backing_file = file;
...@@ -716,7 +715,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_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; lo->old_gfp_mask = inode->i_mapping->gfp_mask;
inode->i_mapping->gfp_mask = GFP_NOIO; 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; lo->lo_bio = lo->lo_biotail = NULL;
...@@ -899,7 +898,7 @@ static int loop_get_status(struct loop_device *lo, struct loop_info *arg) ...@@ -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_number = lo->lo_number;
info.lo_device = stat.dev; info.lo_device = stat.dev;
info.lo_inode = stat.ino; 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_offset = lo->lo_offset;
info.lo_flags = lo->lo_flags; info.lo_flags = lo->lo_flags;
strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE); strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE);
......
...@@ -43,6 +43,7 @@ struct loop_device { ...@@ -43,6 +43,7 @@ struct loop_device {
struct file * lo_backing_file; struct file * lo_backing_file;
struct block_device *lo_device; struct block_device *lo_device;
unsigned lo_blocksize;
void *key_data; void *key_data;
char key_reserved[48]; /* for use by the filter modules */ 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) ...@@ -1694,16 +1694,13 @@ static int shmem_fill_super(struct super_block *sb, void *data, int silent)
sbinfo->max_inodes = inodes; sbinfo->max_inodes = inodes;
sbinfo->free_inodes = inodes; sbinfo->free_inodes = inodes;
sb->s_maxbytes = SHMEM_MAX_BYTES; sb->s_maxbytes = SHMEM_MAX_BYTES;
sb->s_bdev = bdget(sb->s_dev); sb->s_blocksize = PAGE_CACHE_SIZE;
if (!sb->s_bdev) sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
goto failed;
if (!sb_set_blocksize(sb, PAGE_CACHE_SIZE))
BUG();
sb->s_magic = TMPFS_MAGIC; sb->s_magic = TMPFS_MAGIC;
sb->s_op = &shmem_ops; sb->s_op = &shmem_ops;
inode = shmem_get_inode(sb, S_IFDIR | mode, 0); inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
if (!inode) if (!inode)
goto failed_bdput; goto failed;
inode->i_uid = uid; inode->i_uid = uid;
inode->i_gid = gid; inode->i_gid = gid;
root = d_alloc_root(inode); root = d_alloc_root(inode);
...@@ -1714,9 +1711,6 @@ static int shmem_fill_super(struct super_block *sb, void *data, int silent) ...@@ -1714,9 +1711,6 @@ static int shmem_fill_super(struct super_block *sb, void *data, int silent)
failed_iput: failed_iput:
iput(inode); iput(inode);
failed_bdput:
bdput(sb->s_bdev);
sb->s_bdev = NULL;
failed: failed:
kfree(sbinfo); kfree(sbinfo);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
...@@ -1725,8 +1719,6 @@ static int shmem_fill_super(struct super_block *sb, void *data, int silent) ...@@ -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) static void shmem_put_super(struct super_block *sb)
{ {
bdput(sb->s_bdev);
sb->s_bdev = NULL;
kfree(sb->s_fs_info); kfree(sb->s_fs_info);
sb->s_fs_info = NULL; 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