Commit 75f1dc0d authored by Tejun Heo's avatar Tejun Heo

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: default avatarTejun Heo <tj@kernel.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: linux-usb@vger.kernel.org
parent 6a027eff
...@@ -543,7 +543,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) ...@@ -543,7 +543,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
ro = curlun->initially_ro; ro = curlun->initially_ro;
if (!ro) { if (!ro) {
filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0); filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
if (-EROFS == PTR_ERR(filp)) if (PTR_ERR(filp) == -EROFS || PTR_ERR(filp) == -EACCES)
ro = 1; ro = 1;
} }
if (ro) if (ro)
...@@ -558,10 +558,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) ...@@ -558,10 +558,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
if (filp->f_path.dentry) if (filp->f_path.dentry)
inode = filp->f_path.dentry->d_inode; inode = filp->f_path.dentry->d_inode;
if (inode && S_ISBLK(inode->i_mode)) { if (!inode || (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) {
if (bdev_read_only(inode->i_bdev))
ro = 1;
} else if (!inode || !S_ISREG(inode->i_mode)) {
LINFO(curlun, "invalid file type: %s\n", filename); LINFO(curlun, "invalid file type: %s\n", filename);
goto out; goto out;
} }
......
...@@ -1149,6 +1149,12 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) ...@@ -1149,6 +1149,12 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
res = __blkdev_get(bdev, mode, 0); res = __blkdev_get(bdev, mode, 0);
/* __blkdev_get() may alter read only status, check it afterwards */
if (!res && (mode & FMODE_WRITE) && bdev_read_only(bdev)) {
__blkdev_put(bdev, mode, 0);
res = -EACCES;
}
if (whole) { if (whole) {
/* finish claiming */ /* finish claiming */
spin_lock(&bdev_lock); spin_lock(&bdev_lock);
...@@ -1453,11 +1459,6 @@ struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *h ...@@ -1453,11 +1459,6 @@ struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *h
if (error) if (error)
return ERR_PTR(error); return ERR_PTR(error);
if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) {
blkdev_put(bdev, mode);
return ERR_PTR(-EACCES);
}
return bdev; return bdev;
} }
......
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