aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-11-13 05:55:17 -0500
committerTejun Heo <tj@kernel.org>2010-11-13 05:55:17 -0500
commit75f1dc0d076d1c1168f2115f1941ea627d38bd5a (patch)
treeaf12858b842579e8924b30cb636b96fcca6f46b1
parent6a027eff62f6ae32d49f2ae5dadd6f4eee1ddae2 (diff)
block: check bdev_read_only() from blkdev_get()
bdev read-only status can be queried using bdev_read_only() and may change while the device is being opened. Enforce it by checking it from blkdev_get() after open succeeds. This makes bdev_read_only() check in open_bdev_exclusive() and fsg_lun_open() unnecessary. Drop them. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: linux-usb@vger.kernel.org
-rw-r--r--drivers/usb/gadget/storage_common.c7
-rw-r--r--fs/block_dev.c11
2 files changed, 8 insertions, 10 deletions
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 3b513bafaf2a..b015561fd602 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -543,7 +543,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
543 ro = curlun->initially_ro; 543 ro = curlun->initially_ro;
544 if (!ro) { 544 if (!ro) {
545 filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0); 545 filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
546 if (-EROFS == PTR_ERR(filp)) 546 if (PTR_ERR(filp) == -EROFS || PTR_ERR(filp) == -EACCES)
547 ro = 1; 547 ro = 1;
548 } 548 }
549 if (ro) 549 if (ro)
@@ -558,10 +558,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
558 558
559 if (filp->f_path.dentry) 559 if (filp->f_path.dentry)
560 inode = filp->f_path.dentry->d_inode; 560 inode = filp->f_path.dentry->d_inode;
561 if (inode && S_ISBLK(inode->i_mode)) { 561 if (!inode || (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) {
562 if (bdev_read_only(inode->i_bdev))
563 ro = 1;
564 } else if (!inode || !S_ISREG(inode->i_mode)) {
565 LINFO(curlun, "invalid file type: %s\n", filename); 562 LINFO(curlun, "invalid file type: %s\n", filename);
566 goto out; 563 goto out;
567 } 564 }
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 269bfbbd10fc..606a5259f87f 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1149,6 +1149,12 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
1149 1149
1150 res = __blkdev_get(bdev, mode, 0); 1150 res = __blkdev_get(bdev, mode, 0);
1151 1151
1152 /* __blkdev_get() may alter read only status, check it afterwards */
1153 if (!res && (mode & FMODE_WRITE) && bdev_read_only(bdev)) {
1154 __blkdev_put(bdev, mode, 0);
1155 res = -EACCES;
1156 }
1157
1152 if (whole) { 1158 if (whole) {
1153 /* finish claiming */ 1159 /* finish claiming */
1154 spin_lock(&bdev_lock); 1160 spin_lock(&bdev_lock);
@@ -1453,11 +1459,6 @@ struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *h
1453 if (error) 1459 if (error)
1454 return ERR_PTR(error); 1460 return ERR_PTR(error);
1455 1461
1456 if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) {
1457 blkdev_put(bdev, mode);
1458 return ERR_PTR(-EACCES);
1459 }
1460
1461 return bdev; 1462 return bdev;
1462} 1463}
1463 1464