diff options
author | Tejun Heo <tj@kernel.org> | 2010-11-13 05:55:17 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2010-11-13 05:55:17 -0500 |
commit | 75f1dc0d076d1c1168f2115f1941ea627d38bd5a (patch) | |
tree | af12858b842579e8924b30cb636b96fcca6f46b1 | |
parent | 6a027eff62f6ae32d49f2ae5dadd6f4eee1ddae2 (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.c | 7 | ||||
-rw-r--r-- | fs/block_dev.c | 11 |
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 | ||