diff options
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r-- | drivers/block/loop.c | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index d3a25b027ff9..3f09cd8bcc38 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -210,7 +210,7 @@ lo_do_transfer(struct loop_device *lo, int cmd, | |||
210 | * space operations write_begin and write_end. | 210 | * space operations write_begin and write_end. |
211 | */ | 211 | */ |
212 | static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, | 212 | static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, |
213 | int bsize, loff_t pos, struct page *unused) | 213 | loff_t pos, struct page *unused) |
214 | { | 214 | { |
215 | struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ | 215 | struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ |
216 | struct address_space *mapping = file->f_mapping; | 216 | struct address_space *mapping = file->f_mapping; |
@@ -302,7 +302,7 @@ static int __do_lo_send_write(struct file *file, | |||
302 | * filesystems. | 302 | * filesystems. |
303 | */ | 303 | */ |
304 | static int do_lo_send_direct_write(struct loop_device *lo, | 304 | static int do_lo_send_direct_write(struct loop_device *lo, |
305 | struct bio_vec *bvec, int bsize, loff_t pos, struct page *page) | 305 | struct bio_vec *bvec, loff_t pos, struct page *page) |
306 | { | 306 | { |
307 | ssize_t bw = __do_lo_send_write(lo->lo_backing_file, | 307 | ssize_t bw = __do_lo_send_write(lo->lo_backing_file, |
308 | kmap(bvec->bv_page) + bvec->bv_offset, | 308 | kmap(bvec->bv_page) + bvec->bv_offset, |
@@ -326,7 +326,7 @@ static int do_lo_send_direct_write(struct loop_device *lo, | |||
326 | * destination pages of the backing file. | 326 | * destination pages of the backing file. |
327 | */ | 327 | */ |
328 | static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, | 328 | static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, |
329 | int bsize, loff_t pos, struct page *page) | 329 | loff_t pos, struct page *page) |
330 | { | 330 | { |
331 | int ret = lo_do_transfer(lo, WRITE, page, 0, bvec->bv_page, | 331 | int ret = lo_do_transfer(lo, WRITE, page, 0, bvec->bv_page, |
332 | bvec->bv_offset, bvec->bv_len, pos >> 9); | 332 | bvec->bv_offset, bvec->bv_len, pos >> 9); |
@@ -341,10 +341,9 @@ static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, | |||
341 | return ret; | 341 | return ret; |
342 | } | 342 | } |
343 | 343 | ||
344 | static int lo_send(struct loop_device *lo, struct bio *bio, int bsize, | 344 | static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos) |
345 | loff_t pos) | ||
346 | { | 345 | { |
347 | int (*do_lo_send)(struct loop_device *, struct bio_vec *, int, loff_t, | 346 | int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t, |
348 | struct page *page); | 347 | struct page *page); |
349 | struct bio_vec *bvec; | 348 | struct bio_vec *bvec; |
350 | struct page *page = NULL; | 349 | struct page *page = NULL; |
@@ -362,7 +361,7 @@ static int lo_send(struct loop_device *lo, struct bio *bio, int bsize, | |||
362 | } | 361 | } |
363 | } | 362 | } |
364 | bio_for_each_segment(bvec, bio, i) { | 363 | bio_for_each_segment(bvec, bio, i) { |
365 | ret = do_lo_send(lo, bvec, bsize, pos, page); | 364 | ret = do_lo_send(lo, bvec, pos, page); |
366 | if (ret < 0) | 365 | if (ret < 0) |
367 | break; | 366 | break; |
368 | pos += bvec->bv_len; | 367 | pos += bvec->bv_len; |
@@ -478,7 +477,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | |||
478 | 477 | ||
479 | pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; | 478 | pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; |
480 | if (bio_rw(bio) == WRITE) | 479 | if (bio_rw(bio) == WRITE) |
481 | ret = lo_send(lo, bio, lo->lo_blocksize, pos); | 480 | ret = lo_send(lo, bio, pos); |
482 | else | 481 | else |
483 | ret = lo_receive(lo, bio, lo->lo_blocksize, pos); | 482 | ret = lo_receive(lo, bio, lo->lo_blocksize, pos); |
484 | return ret; | 483 | return ret; |
@@ -652,8 +651,8 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p) | |||
652 | * This can only work if the loop device is used read-only, and if the | 651 | * This can only work if the loop device is used read-only, and if the |
653 | * new backing store is the same size and type as the old backing store. | 652 | * new backing store is the same size and type as the old backing store. |
654 | */ | 653 | */ |
655 | static int loop_change_fd(struct loop_device *lo, struct file *lo_file, | 654 | static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, |
656 | struct block_device *bdev, unsigned int arg) | 655 | unsigned int arg) |
657 | { | 656 | { |
658 | struct file *file, *old_file; | 657 | struct file *file, *old_file; |
659 | struct inode *inode; | 658 | struct inode *inode; |
@@ -712,7 +711,7 @@ static inline int is_loop_device(struct file *file) | |||
712 | return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; | 711 | return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; |
713 | } | 712 | } |
714 | 713 | ||
715 | static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | 714 | static int loop_set_fd(struct loop_device *lo, fmode_t mode, |
716 | struct block_device *bdev, unsigned int arg) | 715 | struct block_device *bdev, unsigned int arg) |
717 | { | 716 | { |
718 | struct file *file, *f; | 717 | struct file *file, *f; |
@@ -740,7 +739,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | |||
740 | while (is_loop_device(f)) { | 739 | while (is_loop_device(f)) { |
741 | struct loop_device *l; | 740 | struct loop_device *l; |
742 | 741 | ||
743 | if (f->f_mapping->host->i_rdev == lo_file->f_mapping->host->i_rdev) | 742 | if (f->f_mapping->host->i_bdev == bdev) |
744 | goto out_putf; | 743 | goto out_putf; |
745 | 744 | ||
746 | l = f->f_mapping->host->i_bdev->bd_disk->private_data; | 745 | l = f->f_mapping->host->i_bdev->bd_disk->private_data; |
@@ -786,7 +785,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | |||
786 | goto out_putf; | 785 | goto out_putf; |
787 | } | 786 | } |
788 | 787 | ||
789 | if (!(lo_file->f_mode & FMODE_WRITE)) | 788 | if (!(mode & FMODE_WRITE)) |
790 | lo_flags |= LO_FLAGS_READ_ONLY; | 789 | lo_flags |= LO_FLAGS_READ_ONLY; |
791 | 790 | ||
792 | set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); | 791 | set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); |
@@ -918,9 +917,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
918 | memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); | 917 | memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); |
919 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); | 918 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); |
920 | memset(lo->lo_file_name, 0, LO_NAME_SIZE); | 919 | memset(lo->lo_file_name, 0, LO_NAME_SIZE); |
921 | invalidate_bdev(bdev); | 920 | if (bdev) |
921 | invalidate_bdev(bdev); | ||
922 | set_capacity(lo->lo_disk, 0); | 922 | set_capacity(lo->lo_disk, 0); |
923 | bd_set_size(bdev, 0); | 923 | if (bdev) |
924 | bd_set_size(bdev, 0); | ||
924 | mapping_set_gfp_mask(filp->f_mapping, gfp); | 925 | mapping_set_gfp_mask(filp->f_mapping, gfp); |
925 | lo->lo_state = Lo_unbound; | 926 | lo->lo_state = Lo_unbound; |
926 | fput(filp); | 927 | fput(filp); |
@@ -1137,22 +1138,22 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) { | |||
1137 | return err; | 1138 | return err; |
1138 | } | 1139 | } |
1139 | 1140 | ||
1140 | static int lo_ioctl(struct inode * inode, struct file * file, | 1141 | static int lo_ioctl(struct block_device *bdev, fmode_t mode, |
1141 | unsigned int cmd, unsigned long arg) | 1142 | unsigned int cmd, unsigned long arg) |
1142 | { | 1143 | { |
1143 | struct loop_device *lo = inode->i_bdev->bd_disk->private_data; | 1144 | struct loop_device *lo = bdev->bd_disk->private_data; |
1144 | int err; | 1145 | int err; |
1145 | 1146 | ||
1146 | mutex_lock(&lo->lo_ctl_mutex); | 1147 | mutex_lock(&lo->lo_ctl_mutex); |
1147 | switch (cmd) { | 1148 | switch (cmd) { |
1148 | case LOOP_SET_FD: | 1149 | case LOOP_SET_FD: |
1149 | err = loop_set_fd(lo, file, inode->i_bdev, arg); | 1150 | err = loop_set_fd(lo, mode, bdev, arg); |
1150 | break; | 1151 | break; |
1151 | case LOOP_CHANGE_FD: | 1152 | case LOOP_CHANGE_FD: |
1152 | err = loop_change_fd(lo, file, inode->i_bdev, arg); | 1153 | err = loop_change_fd(lo, bdev, arg); |
1153 | break; | 1154 | break; |
1154 | case LOOP_CLR_FD: | 1155 | case LOOP_CLR_FD: |
1155 | err = loop_clr_fd(lo, inode->i_bdev); | 1156 | err = loop_clr_fd(lo, bdev); |
1156 | break; | 1157 | break; |
1157 | case LOOP_SET_STATUS: | 1158 | case LOOP_SET_STATUS: |
1158 | err = loop_set_status_old(lo, (struct loop_info __user *) arg); | 1159 | err = loop_set_status_old(lo, (struct loop_info __user *) arg); |
@@ -1292,10 +1293,10 @@ loop_get_status_compat(struct loop_device *lo, | |||
1292 | return err; | 1293 | return err; |
1293 | } | 1294 | } |
1294 | 1295 | ||
1295 | static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 1296 | static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, |
1297 | unsigned int cmd, unsigned long arg) | ||
1296 | { | 1298 | { |
1297 | struct inode *inode = file->f_path.dentry->d_inode; | 1299 | struct loop_device *lo = bdev->bd_disk->private_data; |
1298 | struct loop_device *lo = inode->i_bdev->bd_disk->private_data; | ||
1299 | int err; | 1300 | int err; |
1300 | 1301 | ||
1301 | switch(cmd) { | 1302 | switch(cmd) { |
@@ -1317,7 +1318,7 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a | |||
1317 | arg = (unsigned long) compat_ptr(arg); | 1318 | arg = (unsigned long) compat_ptr(arg); |
1318 | case LOOP_SET_FD: | 1319 | case LOOP_SET_FD: |
1319 | case LOOP_CHANGE_FD: | 1320 | case LOOP_CHANGE_FD: |
1320 | err = lo_ioctl(inode, file, cmd, arg); | 1321 | err = lo_ioctl(bdev, mode, cmd, arg); |
1321 | break; | 1322 | break; |
1322 | default: | 1323 | default: |
1323 | err = -ENOIOCTLCMD; | 1324 | err = -ENOIOCTLCMD; |
@@ -1327,9 +1328,9 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a | |||
1327 | } | 1328 | } |
1328 | #endif | 1329 | #endif |
1329 | 1330 | ||
1330 | static int lo_open(struct inode *inode, struct file *file) | 1331 | static int lo_open(struct block_device *bdev, fmode_t mode) |
1331 | { | 1332 | { |
1332 | struct loop_device *lo = inode->i_bdev->bd_disk->private_data; | 1333 | struct loop_device *lo = bdev->bd_disk->private_data; |
1333 | 1334 | ||
1334 | mutex_lock(&lo->lo_ctl_mutex); | 1335 | mutex_lock(&lo->lo_ctl_mutex); |
1335 | lo->lo_refcnt++; | 1336 | lo->lo_refcnt++; |
@@ -1338,15 +1339,15 @@ static int lo_open(struct inode *inode, struct file *file) | |||
1338 | return 0; | 1339 | return 0; |
1339 | } | 1340 | } |
1340 | 1341 | ||
1341 | static int lo_release(struct inode *inode, struct file *file) | 1342 | static int lo_release(struct gendisk *disk, fmode_t mode) |
1342 | { | 1343 | { |
1343 | struct loop_device *lo = inode->i_bdev->bd_disk->private_data; | 1344 | struct loop_device *lo = disk->private_data; |
1344 | 1345 | ||
1345 | mutex_lock(&lo->lo_ctl_mutex); | 1346 | mutex_lock(&lo->lo_ctl_mutex); |
1346 | --lo->lo_refcnt; | 1347 | --lo->lo_refcnt; |
1347 | 1348 | ||
1348 | if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt) | 1349 | if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt) |
1349 | loop_clr_fd(lo, inode->i_bdev); | 1350 | loop_clr_fd(lo, NULL); |
1350 | 1351 | ||
1351 | mutex_unlock(&lo->lo_ctl_mutex); | 1352 | mutex_unlock(&lo->lo_ctl_mutex); |
1352 | 1353 | ||