]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] loop/shmfs fixes
authorAlexander Viro <viro@math.psu.edu>
Tue, 29 Oct 2002 11:33:07 +0000 (03:33 -0800)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Tue, 29 Oct 2002 11:33:07 +0000 (03:33 -0800)
 - 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

drivers/block/loop.c
include/linux/loop.h
mm/shmem.c

index 33623103f8ba2d594d6af67e91898e3ce493a61d..c5a437f0f823bd275d1bf1d181780d9f481577f2 100644 (file)
@@ -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);
index 116980ee5daae12192f8dceb2466dc40c4976d61..fe28a0ee8f34919778f53b13e854369c8d5d9df4 100644 (file)
@@ -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 */
 
index f25d24f71a6949732e012d9e6975f5b40dac6fc6..77c30daf60ec6c610e4933cd393ed983ffa04391 100644 (file)
@@ -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 @@ failed:
 
 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;
 }