提交 f30195c5 编写于 作者: J Jens Axboe

Merge branch 'cleanup-bd_claim' of...

Merge branch 'cleanup-bd_claim' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc into for-2.6.38/core
...@@ -295,11 +295,12 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, ...@@ -295,11 +295,12 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
return -EINVAL; return -EINVAL;
if (get_user(n, (int __user *) arg)) if (get_user(n, (int __user *) arg))
return -EFAULT; return -EFAULT;
if (!(mode & FMODE_EXCL) && bd_claim(bdev, &bdev) < 0) if (!(mode & FMODE_EXCL) &&
blkdev_get(bdev, mode | FMODE_EXCL, &bdev) < 0)
return -EBUSY; return -EBUSY;
ret = set_blocksize(bdev, n); ret = set_blocksize(bdev, n);
if (!(mode & FMODE_EXCL)) if (!(mode & FMODE_EXCL))
bd_release(bdev); blkdev_put(bdev, mode | FMODE_EXCL);
return ret; return ret;
case BLKPG: case BLKPG:
ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg); ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
......
...@@ -911,8 +911,6 @@ struct drbd_md { ...@@ -911,8 +911,6 @@ struct drbd_md {
struct drbd_backing_dev { struct drbd_backing_dev {
struct block_device *backing_bdev; struct block_device *backing_bdev;
struct block_device *md_bdev; struct block_device *md_bdev;
struct file *lo_file;
struct file *md_file;
struct drbd_md md; struct drbd_md md;
struct disk_conf dc; /* The user provided config... */ struct disk_conf dc; /* The user provided config... */
sector_t known_size; /* last known size of that backing device */ sector_t known_size; /* last known size of that backing device */
......
...@@ -3372,11 +3372,8 @@ void drbd_free_bc(struct drbd_backing_dev *ldev) ...@@ -3372,11 +3372,8 @@ void drbd_free_bc(struct drbd_backing_dev *ldev)
if (ldev == NULL) if (ldev == NULL)
return; return;
bd_release(ldev->backing_bdev); blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
bd_release(ldev->md_bdev); blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
fput(ldev->lo_file);
fput(ldev->md_file);
kfree(ldev); kfree(ldev);
} }
......
...@@ -855,7 +855,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp ...@@ -855,7 +855,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
sector_t max_possible_sectors; sector_t max_possible_sectors;
sector_t min_md_device_sectors; sector_t min_md_device_sectors;
struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */ struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */
struct inode *inode, *inode2; struct block_device *bdev;
struct lru_cache *resync_lru = NULL; struct lru_cache *resync_lru = NULL;
union drbd_state ns, os; union drbd_state ns, os;
unsigned int max_seg_s; unsigned int max_seg_s;
...@@ -907,46 +907,40 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp ...@@ -907,46 +907,40 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
} }
} }
nbc->lo_file = filp_open(nbc->dc.backing_dev, O_RDWR, 0); bdev = blkdev_get_by_path(nbc->dc.backing_dev,
if (IS_ERR(nbc->lo_file)) { FMODE_READ | FMODE_WRITE | FMODE_EXCL, mdev);
if (IS_ERR(bdev)) {
dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev, dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev,
PTR_ERR(nbc->lo_file)); PTR_ERR(bdev));
nbc->lo_file = NULL;
retcode = ERR_OPEN_DISK; retcode = ERR_OPEN_DISK;
goto fail; goto fail;
} }
nbc->backing_bdev = bdev;
inode = nbc->lo_file->f_dentry->d_inode; /*
* meta_dev_idx >= 0: external fixed size, possibly multiple
if (!S_ISBLK(inode->i_mode)) { * drbd sharing one meta device. TODO in that case, paranoia
retcode = ERR_DISK_NOT_BDEV; * check that [md_bdev, meta_dev_idx] is not yet used by some
goto fail; * other drbd minor! (if you use drbd.conf + drbdadm, that
} * should check it for you already; but if you don't, or
* someone fooled it, we need to double check here)
nbc->md_file = filp_open(nbc->dc.meta_dev, O_RDWR, 0); */
if (IS_ERR(nbc->md_file)) { bdev = blkdev_get_by_path(nbc->dc.meta_dev,
FMODE_READ | FMODE_WRITE | FMODE_EXCL,
(nbc->dc.meta_dev_idx < 0) ?
(void *)mdev : (void *)drbd_m_holder);
if (IS_ERR(bdev)) {
dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev, dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev,
PTR_ERR(nbc->md_file)); PTR_ERR(bdev));
nbc->md_file = NULL;
retcode = ERR_OPEN_MD_DISK; retcode = ERR_OPEN_MD_DISK;
goto fail; goto fail;
} }
nbc->md_bdev = bdev;
inode2 = nbc->md_file->f_dentry->d_inode; if ((nbc->backing_bdev == nbc->md_bdev) !=
(nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
if (!S_ISBLK(inode2->i_mode)) { nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
retcode = ERR_MD_NOT_BDEV; retcode = ERR_MD_IDX_INVALID;
goto fail;
}
nbc->backing_bdev = inode->i_bdev;
if (bd_claim(nbc->backing_bdev, mdev)) {
printk(KERN_ERR "drbd: bd_claim(%p,%p); failed [%p;%p;%u]\n",
nbc->backing_bdev, mdev,
nbc->backing_bdev->bd_holder,
nbc->backing_bdev->bd_contains->bd_holder,
nbc->backing_bdev->bd_holders);
retcode = ERR_BDCLAIM_DISK;
goto fail; goto fail;
} }
...@@ -955,28 +949,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp ...@@ -955,28 +949,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
offsetof(struct bm_extent, lce)); offsetof(struct bm_extent, lce));
if (!resync_lru) { if (!resync_lru) {
retcode = ERR_NOMEM; retcode = ERR_NOMEM;
goto release_bdev_fail; goto fail;
}
/* meta_dev_idx >= 0: external fixed size,
* possibly multiple drbd sharing one meta device.
* TODO in that case, paranoia check that [md_bdev, meta_dev_idx] is
* not yet used by some other drbd minor!
* (if you use drbd.conf + drbdadm,
* that should check it for you already; but if you don't, or someone
* fooled it, we need to double check here) */
nbc->md_bdev = inode2->i_bdev;
if (bd_claim(nbc->md_bdev, (nbc->dc.meta_dev_idx < 0) ? (void *)mdev
: (void *) drbd_m_holder)) {
retcode = ERR_BDCLAIM_MD_DISK;
goto release_bdev_fail;
}
if ((nbc->backing_bdev == nbc->md_bdev) !=
(nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL ||
nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) {
retcode = ERR_MD_IDX_INVALID;
goto release_bdev2_fail;
} }
/* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */ /* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */
...@@ -987,7 +960,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp ...@@ -987,7 +960,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
(unsigned long long) drbd_get_max_capacity(nbc), (unsigned long long) drbd_get_max_capacity(nbc),
(unsigned long long) nbc->dc.disk_size); (unsigned long long) nbc->dc.disk_size);
retcode = ERR_DISK_TO_SMALL; retcode = ERR_DISK_TO_SMALL;
goto release_bdev2_fail; goto fail;
} }
if (nbc->dc.meta_dev_idx < 0) { if (nbc->dc.meta_dev_idx < 0) {
...@@ -1004,7 +977,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp ...@@ -1004,7 +977,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
dev_warn(DEV, "refusing attach: md-device too small, " dev_warn(DEV, "refusing attach: md-device too small, "
"at least %llu sectors needed for this meta-disk type\n", "at least %llu sectors needed for this meta-disk type\n",
(unsigned long long) min_md_device_sectors); (unsigned long long) min_md_device_sectors);
goto release_bdev2_fail; goto fail;
} }
/* Make sure the new disk is big enough /* Make sure the new disk is big enough
...@@ -1012,7 +985,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp ...@@ -1012,7 +985,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
if (drbd_get_max_capacity(nbc) < if (drbd_get_max_capacity(nbc) <
drbd_get_capacity(mdev->this_bdev)) { drbd_get_capacity(mdev->this_bdev)) {
retcode = ERR_DISK_TO_SMALL; retcode = ERR_DISK_TO_SMALL;
goto release_bdev2_fail; goto fail;
} }
nbc->known_size = drbd_get_capacity(nbc->backing_bdev); nbc->known_size = drbd_get_capacity(nbc->backing_bdev);
...@@ -1035,7 +1008,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp ...@@ -1035,7 +1008,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE); retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE);
drbd_resume_io(mdev); drbd_resume_io(mdev);
if (retcode < SS_SUCCESS) if (retcode < SS_SUCCESS)
goto release_bdev2_fail; goto fail;
if (!get_ldev_if_state(mdev, D_ATTACHING)) if (!get_ldev_if_state(mdev, D_ATTACHING))
goto force_diskless; goto force_diskless;
...@@ -1269,18 +1242,14 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp ...@@ -1269,18 +1242,14 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
force_diskless: force_diskless:
drbd_force_state(mdev, NS(disk, D_FAILED)); drbd_force_state(mdev, NS(disk, D_FAILED));
drbd_md_sync(mdev); drbd_md_sync(mdev);
release_bdev2_fail:
if (nbc)
bd_release(nbc->md_bdev);
release_bdev_fail:
if (nbc)
bd_release(nbc->backing_bdev);
fail: fail:
if (nbc) { if (nbc) {
if (nbc->lo_file) if (nbc->backing_bdev)
fput(nbc->lo_file); blkdev_put(nbc->backing_bdev,
if (nbc->md_file) FMODE_READ | FMODE_WRITE | FMODE_EXCL);
fput(nbc->md_file); if (nbc->md_bdev)
blkdev_put(nbc->md_bdev,
FMODE_READ | FMODE_WRITE | FMODE_EXCL);
kfree(nbc); kfree(nbc);
} }
lc_destroy(resync_lru); lc_destroy(resync_lru);
......
...@@ -2296,15 +2296,12 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) ...@@ -2296,15 +2296,12 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
* so bdget() can't fail. * so bdget() can't fail.
*/ */
bdget(pd->bdev->bd_dev); bdget(pd->bdev->bd_dev);
if ((ret = blkdev_get(pd->bdev, FMODE_READ))) if ((ret = blkdev_get(pd->bdev, FMODE_READ | FMODE_EXCL, pd)))
goto out; goto out;
if ((ret = bd_claim(pd->bdev, pd)))
goto out_putdev;
if ((ret = pkt_get_last_written(pd, &lba))) { if ((ret = pkt_get_last_written(pd, &lba))) {
printk(DRIVER_NAME": pkt_get_last_written failed\n"); printk(DRIVER_NAME": pkt_get_last_written failed\n");
goto out_unclaim; goto out_putdev;
} }
set_capacity(pd->disk, lba << 2); set_capacity(pd->disk, lba << 2);
...@@ -2314,7 +2311,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) ...@@ -2314,7 +2311,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
q = bdev_get_queue(pd->bdev); q = bdev_get_queue(pd->bdev);
if (write) { if (write) {
if ((ret = pkt_open_write(pd))) if ((ret = pkt_open_write(pd)))
goto out_unclaim; goto out_putdev;
/* /*
* Some CDRW drives can not handle writes larger than one packet, * Some CDRW drives can not handle writes larger than one packet,
* even if the size is a multiple of the packet size. * even if the size is a multiple of the packet size.
...@@ -2329,23 +2326,21 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) ...@@ -2329,23 +2326,21 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write)
} }
if ((ret = pkt_set_segment_merging(pd, q))) if ((ret = pkt_set_segment_merging(pd, q)))
goto out_unclaim; goto out_putdev;
if (write) { if (write) {
if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
printk(DRIVER_NAME": not enough memory for buffers\n"); printk(DRIVER_NAME": not enough memory for buffers\n");
ret = -ENOMEM; ret = -ENOMEM;
goto out_unclaim; goto out_putdev;
} }
printk(DRIVER_NAME": %lukB available on disc\n", lba << 1); printk(DRIVER_NAME": %lukB available on disc\n", lba << 1);
} }
return 0; return 0;
out_unclaim:
bd_release(pd->bdev);
out_putdev: out_putdev:
blkdev_put(pd->bdev, FMODE_READ); blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL);
out: out:
return ret; return ret;
} }
...@@ -2362,8 +2357,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush) ...@@ -2362,8 +2357,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
pkt_lock_door(pd, 0); pkt_lock_door(pd, 0);
pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
bd_release(pd->bdev); blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL);
blkdev_put(pd->bdev, FMODE_READ);
pkt_shrink_pktlist(pd); pkt_shrink_pktlist(pd);
} }
...@@ -2733,7 +2727,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) ...@@ -2733,7 +2727,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
bdev = bdget(dev); bdev = bdget(dev);
if (!bdev) if (!bdev)
return -ENOMEM; return -ENOMEM;
ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY); ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY, NULL);
if (ret) if (ret)
return ret; return ret;
......
...@@ -65,15 +65,12 @@ static int raw_open(struct inode *inode, struct file *filp) ...@@ -65,15 +65,12 @@ static int raw_open(struct inode *inode, struct file *filp)
if (!bdev) if (!bdev)
goto out; goto out;
igrab(bdev->bd_inode); igrab(bdev->bd_inode);
err = blkdev_get(bdev, filp->f_mode); err = blkdev_get(bdev, filp->f_mode | FMODE_EXCL, raw_open);
if (err) if (err)
goto out; goto out;
err = bd_claim(bdev, raw_open);
if (err)
goto out1;
err = set_blocksize(bdev, bdev_logical_block_size(bdev)); err = set_blocksize(bdev, bdev_logical_block_size(bdev));
if (err) if (err)
goto out2; goto out1;
filp->f_flags |= O_DIRECT; filp->f_flags |= O_DIRECT;
filp->f_mapping = bdev->bd_inode->i_mapping; filp->f_mapping = bdev->bd_inode->i_mapping;
if (++raw_devices[minor].inuse == 1) if (++raw_devices[minor].inuse == 1)
...@@ -83,10 +80,8 @@ static int raw_open(struct inode *inode, struct file *filp) ...@@ -83,10 +80,8 @@ static int raw_open(struct inode *inode, struct file *filp)
mutex_unlock(&raw_mutex); mutex_unlock(&raw_mutex);
return 0; return 0;
out2:
bd_release(bdev);
out1: out1:
blkdev_put(bdev, filp->f_mode); blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
out: out:
mutex_unlock(&raw_mutex); mutex_unlock(&raw_mutex);
return err; return err;
...@@ -110,8 +105,7 @@ static int raw_release(struct inode *inode, struct file *filp) ...@@ -110,8 +105,7 @@ static int raw_release(struct inode *inode, struct file *filp)
} }
mutex_unlock(&raw_mutex); mutex_unlock(&raw_mutex);
bd_release(bdev); blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
blkdev_put(bdev, filp->f_mode);
return 0; return 0;
} }
......
...@@ -325,15 +325,18 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev, ...@@ -325,15 +325,18 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev,
BUG_ON(d->dm_dev.bdev); BUG_ON(d->dm_dev.bdev);
bdev = open_by_devnum(dev, d->dm_dev.mode); bdev = blkdev_get_by_dev(dev, d->dm_dev.mode | FMODE_EXCL, _claim_ptr);
if (IS_ERR(bdev)) if (IS_ERR(bdev))
return PTR_ERR(bdev); return PTR_ERR(bdev);
r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md));
if (r) r = bd_link_disk_holder(bdev, dm_disk(md));
blkdev_put(bdev, d->dm_dev.mode); if (r) {
else blkdev_put(bdev, d->dm_dev.mode | FMODE_EXCL);
d->dm_dev.bdev = bdev; return r;
return r; }
d->dm_dev.bdev = bdev;
return 0;
} }
/* /*
...@@ -344,8 +347,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) ...@@ -344,8 +347,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
if (!d->dm_dev.bdev) if (!d->dm_dev.bdev)
return; return;
bd_release_from_disk(d->dm_dev.bdev, dm_disk(md)); blkdev_put(d->dm_dev.bdev, d->dm_dev.mode | FMODE_EXCL);
blkdev_put(d->dm_dev.bdev, d->dm_dev.mode);
d->dm_dev.bdev = NULL; d->dm_dev.bdev = NULL;
} }
......
...@@ -1880,7 +1880,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) ...@@ -1880,7 +1880,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
rdev->sysfs_state = sysfs_get_dirent_safe(rdev->kobj.sd, "state"); rdev->sysfs_state = sysfs_get_dirent_safe(rdev->kobj.sd, "state");
list_add_rcu(&rdev->same_set, &mddev->disks); list_add_rcu(&rdev->same_set, &mddev->disks);
bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); bd_link_disk_holder(rdev->bdev, mddev->gendisk);
/* May as well allow recovery to be retried once */ /* May as well allow recovery to be retried once */
mddev->recovery_disabled = 0; mddev->recovery_disabled = 0;
...@@ -1907,7 +1907,6 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) ...@@ -1907,7 +1907,6 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
MD_BUG(); MD_BUG();
return; return;
} }
bd_release_from_disk(rdev->bdev, rdev->mddev->gendisk);
list_del_rcu(&rdev->same_set); list_del_rcu(&rdev->same_set);
printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
rdev->mddev = NULL; rdev->mddev = NULL;
...@@ -1935,19 +1934,13 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared) ...@@ -1935,19 +1934,13 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared)
struct block_device *bdev; struct block_device *bdev;
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
shared ? (mdk_rdev_t *)lock_rdev : rdev);
if (IS_ERR(bdev)) { if (IS_ERR(bdev)) {
printk(KERN_ERR "md: could not open %s.\n", printk(KERN_ERR "md: could not open %s.\n",
__bdevname(dev, b)); __bdevname(dev, b));
return PTR_ERR(bdev); return PTR_ERR(bdev);
} }
err = bd_claim(bdev, shared ? (mdk_rdev_t *)lock_rdev : rdev);
if (err) {
printk(KERN_ERR "md: could not bd_claim %s.\n",
bdevname(bdev, b));
blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
return err;
}
if (!shared) if (!shared)
set_bit(AllReserved, &rdev->flags); set_bit(AllReserved, &rdev->flags);
rdev->bdev = bdev; rdev->bdev = bdev;
...@@ -1960,8 +1953,7 @@ static void unlock_rdev(mdk_rdev_t *rdev) ...@@ -1960,8 +1953,7 @@ static void unlock_rdev(mdk_rdev_t *rdev)
rdev->bdev = NULL; rdev->bdev = NULL;
if (!bdev) if (!bdev)
MD_BUG(); MD_BUG();
bd_release(bdev); blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
} }
void md_autodetect_dev(dev_t dev); void md_autodetect_dev(dev_t dev);
......
...@@ -224,7 +224,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) ...@@ -224,7 +224,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
if (dev->blkdev) { if (dev->blkdev) {
invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
0, -1); 0, -1);
close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE); blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
} }
kfree(dev); kfree(dev);
...@@ -234,6 +234,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) ...@@ -234,6 +234,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
/* FIXME: ensure that mtd->size % erase_size == 0 */ /* FIXME: ensure that mtd->size % erase_size == 0 */
static struct block2mtd_dev *add_device(char *devname, int erase_size) static struct block2mtd_dev *add_device(char *devname, int erase_size)
{ {
const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
struct block_device *bdev; struct block_device *bdev;
struct block2mtd_dev *dev; struct block2mtd_dev *dev;
char *name; char *name;
...@@ -246,7 +247,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) ...@@ -246,7 +247,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
return NULL; return NULL;
/* Get a handle on the device */ /* Get a handle on the device */
bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL); bdev = blkdev_get_by_path(devname, mode, dev);
#ifndef MODULE #ifndef MODULE
if (IS_ERR(bdev)) { if (IS_ERR(bdev)) {
...@@ -254,9 +255,8 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) ...@@ -254,9 +255,8 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
to resolve the device name by other means. */ to resolve the device name by other means. */
dev_t devt = name_to_dev_t(devname); dev_t devt = name_to_dev_t(devname);
if (devt) { if (devt)
bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); bdev = blkdev_get_by_dev(devt, mode, dev);
}
} }
#endif #endif
......
...@@ -103,7 +103,7 @@ int dasd_scan_partitions(struct dasd_block *block) ...@@ -103,7 +103,7 @@ int dasd_scan_partitions(struct dasd_block *block)
struct block_device *bdev; struct block_device *bdev;
bdev = bdget_disk(block->gdp, 0); bdev = bdget_disk(block->gdp, 0);
if (!bdev || blkdev_get(bdev, FMODE_READ) < 0) if (!bdev || blkdev_get(bdev, FMODE_READ, NULL) < 0)
return -ENODEV; return -ENODEV;
/* /*
* See fs/partition/check.c:register_disk,rescan_partitions * See fs/partition/check.c:register_disk,rescan_partitions
......
...@@ -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;
} }
......
此差异已折叠。
...@@ -489,7 +489,7 @@ int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) ...@@ -489,7 +489,7 @@ int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices)
continue; continue;
if (device->bdev) { if (device->bdev) {
close_bdev_exclusive(device->bdev, device->mode); blkdev_put(device->bdev, device->mode);
device->bdev = NULL; device->bdev = NULL;
fs_devices->open_devices--; fs_devices->open_devices--;
} }
...@@ -523,7 +523,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) ...@@ -523,7 +523,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
list_for_each_entry(device, &fs_devices->devices, dev_list) { list_for_each_entry(device, &fs_devices->devices, dev_list) {
if (device->bdev) { if (device->bdev) {
close_bdev_exclusive(device->bdev, device->mode); blkdev_put(device->bdev, device->mode);
fs_devices->open_devices--; fs_devices->open_devices--;
} }
if (device->writeable) { if (device->writeable) {
...@@ -580,13 +580,15 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, ...@@ -580,13 +580,15 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
int seeding = 1; int seeding = 1;
int ret = 0; int ret = 0;
flags |= FMODE_EXCL;
list_for_each_entry(device, head, dev_list) { list_for_each_entry(device, head, dev_list) {
if (device->bdev) if (device->bdev)
continue; continue;
if (!device->name) if (!device->name)
continue; continue;
bdev = open_bdev_exclusive(device->name, flags, holder); bdev = blkdev_get_by_path(device->name, flags, holder);
if (IS_ERR(bdev)) { if (IS_ERR(bdev)) {
printk(KERN_INFO "open %s failed\n", device->name); printk(KERN_INFO "open %s failed\n", device->name);
goto error; goto error;
...@@ -638,7 +640,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, ...@@ -638,7 +640,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
error_brelse: error_brelse:
brelse(bh); brelse(bh);
error_close: error_close:
close_bdev_exclusive(bdev, FMODE_READ); blkdev_put(bdev, flags);
error: error:
continue; continue;
} }
...@@ -684,7 +686,8 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, ...@@ -684,7 +686,8 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
mutex_lock(&uuid_mutex); mutex_lock(&uuid_mutex);
bdev = open_bdev_exclusive(path, flags, holder); flags |= FMODE_EXCL;
bdev = blkdev_get_by_path(path, flags, holder);
if (IS_ERR(bdev)) { if (IS_ERR(bdev)) {
ret = PTR_ERR(bdev); ret = PTR_ERR(bdev);
...@@ -716,7 +719,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, ...@@ -716,7 +719,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
brelse(bh); brelse(bh);
error_close: error_close:
close_bdev_exclusive(bdev, flags); blkdev_put(bdev, flags);
error: error:
mutex_unlock(&uuid_mutex); mutex_unlock(&uuid_mutex);
return ret; return ret;
...@@ -1179,8 +1182,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) ...@@ -1179,8 +1182,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
goto out; goto out;
} }
} else { } else {
bdev = open_bdev_exclusive(device_path, FMODE_READ, bdev = blkdev_get_by_path(device_path, FMODE_READ | FMODE_EXCL,
root->fs_info->bdev_holder); root->fs_info->bdev_holder);
if (IS_ERR(bdev)) { if (IS_ERR(bdev)) {
ret = PTR_ERR(bdev); ret = PTR_ERR(bdev);
goto out; goto out;
...@@ -1244,7 +1247,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) ...@@ -1244,7 +1247,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
root->fs_info->fs_devices->latest_bdev = next_device->bdev; root->fs_info->fs_devices->latest_bdev = next_device->bdev;
if (device->bdev) { if (device->bdev) {
close_bdev_exclusive(device->bdev, device->mode); blkdev_put(device->bdev, device->mode);
device->bdev = NULL; device->bdev = NULL;
device->fs_devices->open_devices--; device->fs_devices->open_devices--;
} }
...@@ -1287,7 +1290,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) ...@@ -1287,7 +1290,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
brelse(bh); brelse(bh);
error_close: error_close:
if (bdev) if (bdev)
close_bdev_exclusive(bdev, FMODE_READ); blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
out: out:
mutex_unlock(&root->fs_info->volume_mutex); mutex_unlock(&root->fs_info->volume_mutex);
mutex_unlock(&uuid_mutex); mutex_unlock(&uuid_mutex);
...@@ -1439,7 +1442,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) ...@@ -1439,7 +1442,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding) if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding)
return -EINVAL; return -EINVAL;
bdev = open_bdev_exclusive(device_path, 0, root->fs_info->bdev_holder); bdev = blkdev_get_by_path(device_path, FMODE_EXCL,
root->fs_info->bdev_holder);
if (IS_ERR(bdev)) if (IS_ERR(bdev))
return PTR_ERR(bdev); return PTR_ERR(bdev);
...@@ -1565,7 +1569,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) ...@@ -1565,7 +1569,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
mutex_unlock(&root->fs_info->volume_mutex); mutex_unlock(&root->fs_info->volume_mutex);
return ret; return ret;
error: error:
close_bdev_exclusive(bdev, 0); blkdev_put(bdev, FMODE_EXCL);
if (seeding_dev) { if (seeding_dev) {
mutex_unlock(&uuid_mutex); mutex_unlock(&uuid_mutex);
up_write(&sb->s_umount); up_write(&sb->s_umount);
......
...@@ -49,7 +49,7 @@ struct btrfs_device { ...@@ -49,7 +49,7 @@ struct btrfs_device {
struct block_device *bdev; struct block_device *bdev;
/* the mode sent to open_bdev_exclusive */ /* the mode sent to blkdev_get */
fmode_t mode; fmode_t mode;
char *name; char *name;
......
...@@ -347,7 +347,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb) ...@@ -347,7 +347,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb)
struct block_device *bdev; struct block_device *bdev;
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb);
if (IS_ERR(bdev)) if (IS_ERR(bdev))
goto fail; goto fail;
return bdev; return bdev;
...@@ -364,8 +364,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb) ...@@ -364,8 +364,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb)
*/ */
static int ext3_blkdev_put(struct block_device *bdev) static int ext3_blkdev_put(struct block_device *bdev)
{ {
bd_release(bdev); return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
} }
static int ext3_blkdev_remove(struct ext3_sb_info *sbi) static int ext3_blkdev_remove(struct ext3_sb_info *sbi)
...@@ -2136,13 +2135,6 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb, ...@@ -2136,13 +2135,6 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb,
if (bdev == NULL) if (bdev == NULL)
return NULL; return NULL;
if (bd_claim(bdev, sb)) {
ext3_msg(sb, KERN_ERR,
"error: failed to claim external journal device");
blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
return NULL;
}
blocksize = sb->s_blocksize; blocksize = sb->s_blocksize;
hblock = bdev_logical_block_size(bdev); hblock = bdev_logical_block_size(bdev);
if (blocksize < hblock) { if (blocksize < hblock) {
......
...@@ -647,7 +647,7 @@ static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb) ...@@ -647,7 +647,7 @@ static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb)
struct block_device *bdev; struct block_device *bdev;
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb);
if (IS_ERR(bdev)) if (IS_ERR(bdev))
goto fail; goto fail;
return bdev; return bdev;
...@@ -663,8 +663,7 @@ static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb) ...@@ -663,8 +663,7 @@ static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb)
*/ */
static int ext4_blkdev_put(struct block_device *bdev) static int ext4_blkdev_put(struct block_device *bdev)
{ {
bd_release(bdev); return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
return blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
} }
static int ext4_blkdev_remove(struct ext4_sb_info *sbi) static int ext4_blkdev_remove(struct ext4_sb_info *sbi)
...@@ -3758,13 +3757,6 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, ...@@ -3758,13 +3757,6 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
if (bdev == NULL) if (bdev == NULL)
return NULL; return NULL;
if (bd_claim(bdev, sb)) {
ext4_msg(sb, KERN_ERR,
"failed to claim external journal device");
blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
return NULL;
}
blocksize = sb->s_blocksize; blocksize = sb->s_blocksize;
hblock = bdev_logical_block_size(bdev); hblock = bdev_logical_block_size(bdev);
if (blocksize < hblock) { if (blocksize < hblock) {
......
...@@ -1268,7 +1268,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, ...@@ -1268,7 +1268,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
{ {
struct block_device *bdev; struct block_device *bdev;
struct super_block *s; struct super_block *s;
fmode_t mode = FMODE_READ; fmode_t mode = FMODE_READ | FMODE_EXCL;
int error; int error;
struct gfs2_args args; struct gfs2_args args;
struct gfs2_sbd *sdp; struct gfs2_sbd *sdp;
...@@ -1276,7 +1276,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, ...@@ -1276,7 +1276,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
if (!(flags & MS_RDONLY)) if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE; mode |= FMODE_WRITE;
bdev = open_bdev_exclusive(dev_name, mode, fs_type); bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(bdev)) if (IS_ERR(bdev))
return ERR_CAST(bdev); return ERR_CAST(bdev);
...@@ -1298,7 +1298,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, ...@@ -1298,7 +1298,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
goto error_bdev; goto error_bdev;
if (s->s_root) if (s->s_root)
close_bdev_exclusive(bdev, mode); blkdev_put(bdev, mode);
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.ar_quota = GFS2_QUOTA_DEFAULT; args.ar_quota = GFS2_QUOTA_DEFAULT;
...@@ -1342,7 +1342,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, ...@@ -1342,7 +1342,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
deactivate_locked_super(s); deactivate_locked_super(s);
return ERR_PTR(error); return ERR_PTR(error);
error_bdev: error_bdev:
close_bdev_exclusive(bdev, mode); blkdev_put(bdev, mode);
return ERR_PTR(error); return ERR_PTR(error);
} }
......
...@@ -1120,16 +1120,13 @@ int lmLogOpen(struct super_block *sb) ...@@ -1120,16 +1120,13 @@ int lmLogOpen(struct super_block *sb)
* file systems to log may have n-to-1 relationship; * file systems to log may have n-to-1 relationship;
*/ */
bdev = open_by_devnum(sbi->logdev, FMODE_READ|FMODE_WRITE); bdev = blkdev_get_by_dev(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
log);
if (IS_ERR(bdev)) { if (IS_ERR(bdev)) {
rc = -PTR_ERR(bdev); rc = -PTR_ERR(bdev);
goto free; goto free;
} }
if ((rc = bd_claim(bdev, log))) {
goto close;
}
log->bdev = bdev; log->bdev = bdev;
memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid)); memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid));
...@@ -1137,7 +1134,7 @@ int lmLogOpen(struct super_block *sb) ...@@ -1137,7 +1134,7 @@ int lmLogOpen(struct super_block *sb)
* initialize log: * initialize log:
*/ */
if ((rc = lmLogInit(log))) if ((rc = lmLogInit(log)))
goto unclaim; goto close;
list_add(&log->journal_list, &jfs_external_logs); list_add(&log->journal_list, &jfs_external_logs);
...@@ -1163,11 +1160,8 @@ int lmLogOpen(struct super_block *sb) ...@@ -1163,11 +1160,8 @@ int lmLogOpen(struct super_block *sb)
list_del(&log->journal_list); list_del(&log->journal_list);
lbmLogShutdown(log); lbmLogShutdown(log);
unclaim:
bd_release(bdev);
close: /* close external log device */ close: /* close external log device */
blkdev_put(bdev, FMODE_READ|FMODE_WRITE); blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
free: /* free log descriptor */ free: /* free log descriptor */
mutex_unlock(&jfs_log_mutex); mutex_unlock(&jfs_log_mutex);
...@@ -1512,8 +1506,7 @@ int lmLogClose(struct super_block *sb) ...@@ -1512,8 +1506,7 @@ int lmLogClose(struct super_block *sb)
bdev = log->bdev; bdev = log->bdev;
rc = lmLogShutdown(log); rc = lmLogShutdown(log);
bd_release(bdev); blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
blkdev_put(bdev, FMODE_READ|FMODE_WRITE);
kfree(log); kfree(log);
......
...@@ -300,7 +300,7 @@ static int bdev_write_sb(struct super_block *sb, struct page *page) ...@@ -300,7 +300,7 @@ static int bdev_write_sb(struct super_block *sb, struct page *page)
static void bdev_put_device(struct logfs_super *s) static void bdev_put_device(struct logfs_super *s)
{ {
close_bdev_exclusive(s->s_bdev, FMODE_READ|FMODE_WRITE); blkdev_put(s->s_bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
} }
static int bdev_can_write_buf(struct super_block *sb, u64 ofs) static int bdev_can_write_buf(struct super_block *sb, u64 ofs)
...@@ -325,13 +325,14 @@ int logfs_get_sb_bdev(struct logfs_super *p, struct file_system_type *type, ...@@ -325,13 +325,14 @@ int logfs_get_sb_bdev(struct logfs_super *p, struct file_system_type *type,
{ {
struct block_device *bdev; struct block_device *bdev;
bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, type); bdev = blkdev_get_by_path(devname, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
type);
if (IS_ERR(bdev)) if (IS_ERR(bdev))
return PTR_ERR(bdev); return PTR_ERR(bdev);
if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
int mtdnr = MINOR(bdev->bd_dev); int mtdnr = MINOR(bdev->bd_dev);
close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
return logfs_get_sb_mtd(p, mtdnr); return logfs_get_sb_mtd(p, mtdnr);
} }
......
...@@ -1147,14 +1147,14 @@ nilfs_mount(struct file_system_type *fs_type, int flags, ...@@ -1147,14 +1147,14 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
{ {
struct nilfs_super_data sd; struct nilfs_super_data sd;
struct super_block *s; struct super_block *s;
fmode_t mode = FMODE_READ; fmode_t mode = FMODE_READ | FMODE_EXCL;
struct dentry *root_dentry; struct dentry *root_dentry;
int err, s_new = false; int err, s_new = false;
if (!(flags & MS_RDONLY)) if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE; mode |= FMODE_WRITE;
sd.bdev = open_bdev_exclusive(dev_name, mode, fs_type); sd.bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(sd.bdev)) if (IS_ERR(sd.bdev))
return ERR_CAST(sd.bdev); return ERR_CAST(sd.bdev);
...@@ -1233,7 +1233,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, ...@@ -1233,7 +1233,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
} }
if (!s_new) if (!s_new)
close_bdev_exclusive(sd.bdev, mode); blkdev_put(sd.bdev, mode);
return root_dentry; return root_dentry;
...@@ -1242,7 +1242,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, ...@@ -1242,7 +1242,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
failed: failed:
if (!s_new) if (!s_new)
close_bdev_exclusive(sd.bdev, mode); blkdev_put(sd.bdev, mode);
return ERR_PTR(err); return ERR_PTR(err);
} }
......
...@@ -1674,7 +1674,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, ...@@ -1674,7 +1674,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
goto out; goto out;
reg->hr_bdev = I_BDEV(filp->f_mapping->host); reg->hr_bdev = I_BDEV(filp->f_mapping->host);
ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ); ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, NULL);
if (ret) { if (ret) {
reg->hr_bdev = NULL; reg->hr_bdev = NULL;
goto out; goto out;
......
...@@ -558,7 +558,7 @@ void register_disk(struct gendisk *disk) ...@@ -558,7 +558,7 @@ void register_disk(struct gendisk *disk)
goto exit; goto exit;
bdev->bd_invalidated = 1; bdev->bd_invalidated = 1;
err = blkdev_get(bdev, FMODE_READ); err = blkdev_get(bdev, FMODE_READ, NULL);
if (err < 0) if (err < 0)
goto exit; goto exit;
blkdev_put(bdev, FMODE_READ); blkdev_put(bdev, FMODE_READ);
......
...@@ -2552,8 +2552,6 @@ static int release_journal_dev(struct super_block *super, ...@@ -2552,8 +2552,6 @@ static int release_journal_dev(struct super_block *super,
result = 0; result = 0;
if (journal->j_dev_bd != NULL) { if (journal->j_dev_bd != NULL) {
if (journal->j_dev_bd->bd_dev != super->s_dev)
bd_release(journal->j_dev_bd);
result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode); result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode);
journal->j_dev_bd = NULL; journal->j_dev_bd = NULL;
} }
...@@ -2571,7 +2569,7 @@ static int journal_init_dev(struct super_block *super, ...@@ -2571,7 +2569,7 @@ static int journal_init_dev(struct super_block *super,
{ {
int result; int result;
dev_t jdev; dev_t jdev;
fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE; fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
result = 0; result = 0;
...@@ -2585,7 +2583,10 @@ static int journal_init_dev(struct super_block *super, ...@@ -2585,7 +2583,10 @@ static int journal_init_dev(struct super_block *super,
/* there is no "jdev" option and journal is on separate device */ /* there is no "jdev" option and journal is on separate device */
if ((!jdev_name || !jdev_name[0])) { if ((!jdev_name || !jdev_name[0])) {
journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode); if (jdev == super->s_dev)
blkdev_mode &= ~FMODE_EXCL;
journal->j_dev_bd = blkdev_get_by_dev(jdev, blkdev_mode,
journal);
journal->j_dev_mode = blkdev_mode; journal->j_dev_mode = blkdev_mode;
if (IS_ERR(journal->j_dev_bd)) { if (IS_ERR(journal->j_dev_bd)) {
result = PTR_ERR(journal->j_dev_bd); result = PTR_ERR(journal->j_dev_bd);
...@@ -2594,22 +2595,14 @@ static int journal_init_dev(struct super_block *super, ...@@ -2594,22 +2595,14 @@ static int journal_init_dev(struct super_block *super,
"cannot init journal device '%s': %i", "cannot init journal device '%s': %i",
__bdevname(jdev, b), result); __bdevname(jdev, b), result);
return result; return result;
} else if (jdev != super->s_dev) { } else if (jdev != super->s_dev)
result = bd_claim(journal->j_dev_bd, journal);
if (result) {
blkdev_put(journal->j_dev_bd, blkdev_mode);
return result;
}
set_blocksize(journal->j_dev_bd, super->s_blocksize); set_blocksize(journal->j_dev_bd, super->s_blocksize);
}
return 0; return 0;
} }
journal->j_dev_mode = blkdev_mode; journal->j_dev_mode = blkdev_mode;
journal->j_dev_bd = open_bdev_exclusive(jdev_name, journal->j_dev_bd = blkdev_get_by_path(jdev_name, blkdev_mode, journal);
blkdev_mode, journal);
if (IS_ERR(journal->j_dev_bd)) { if (IS_ERR(journal->j_dev_bd)) {
result = PTR_ERR(journal->j_dev_bd); result = PTR_ERR(journal->j_dev_bd);
journal->j_dev_bd = NULL; journal->j_dev_bd = NULL;
......
...@@ -766,13 +766,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, ...@@ -766,13 +766,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
{ {
struct block_device *bdev; struct block_device *bdev;
struct super_block *s; struct super_block *s;
fmode_t mode = FMODE_READ; fmode_t mode = FMODE_READ | FMODE_EXCL;
int error = 0; int error = 0;
if (!(flags & MS_RDONLY)) if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE; mode |= FMODE_WRITE;
bdev = open_bdev_exclusive(dev_name, mode, fs_type); bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(bdev)) if (IS_ERR(bdev))
return ERR_CAST(bdev); return ERR_CAST(bdev);
...@@ -801,13 +801,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, ...@@ -801,13 +801,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
/* /*
* s_umount nests inside bd_mutex during * s_umount nests inside bd_mutex during
* __invalidate_device(). close_bdev_exclusive() * __invalidate_device(). blkdev_put() acquires
* acquires bd_mutex and can't be called under * bd_mutex and can't be called under s_umount. Drop
* s_umount. Drop s_umount temporarily. This is safe * s_umount temporarily. This is safe as we're
* as we're holding an active reference. * holding an active reference.
*/ */
up_write(&s->s_umount); up_write(&s->s_umount);
close_bdev_exclusive(bdev, mode); blkdev_put(bdev, mode);
down_write(&s->s_umount); down_write(&s->s_umount);
} else { } else {
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
...@@ -831,7 +831,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, ...@@ -831,7 +831,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
error_s: error_s:
error = PTR_ERR(s); error = PTR_ERR(s);
error_bdev: error_bdev:
close_bdev_exclusive(bdev, mode); blkdev_put(bdev, mode);
error: error:
return ERR_PTR(error); return ERR_PTR(error);
} }
...@@ -862,7 +862,8 @@ void kill_block_super(struct super_block *sb) ...@@ -862,7 +862,8 @@ void kill_block_super(struct super_block *sb)
bdev->bd_super = NULL; bdev->bd_super = NULL;
generic_shutdown_super(sb); generic_shutdown_super(sb);
sync_blockdev(bdev); sync_blockdev(bdev);
close_bdev_exclusive(bdev, mode); WARN_ON_ONCE(!(mode & FMODE_EXCL));
blkdev_put(bdev, mode | FMODE_EXCL);
} }
EXPORT_SYMBOL(kill_block_super); EXPORT_SYMBOL(kill_block_super);
......
...@@ -606,7 +606,8 @@ xfs_blkdev_get( ...@@ -606,7 +606,8 @@ xfs_blkdev_get(
{ {
int error = 0; int error = 0;
*bdevp = open_bdev_exclusive(name, FMODE_READ|FMODE_WRITE, mp); *bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
mp);
if (IS_ERR(*bdevp)) { if (IS_ERR(*bdevp)) {
error = PTR_ERR(*bdevp); error = PTR_ERR(*bdevp);
printk("XFS: Invalid device [%s], error=%d\n", name, error); printk("XFS: Invalid device [%s], error=%d\n", name, error);
...@@ -620,7 +621,7 @@ xfs_blkdev_put( ...@@ -620,7 +621,7 @@ xfs_blkdev_put(
struct block_device *bdev) struct block_device *bdev)
{ {
if (bdev) if (bdev)
close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
} }
/* /*
......
...@@ -663,7 +663,7 @@ struct block_device { ...@@ -663,7 +663,7 @@ struct block_device {
void * bd_holder; void * bd_holder;
int bd_holders; int bd_holders;
#ifdef CONFIG_SYSFS #ifdef CONFIG_SYSFS
struct list_head bd_holder_list; struct gendisk * bd_holder_disk; /* for sysfs slave linkng */
#endif #endif
struct block_device * bd_contains; struct block_device * bd_contains;
unsigned bd_block_size; unsigned bd_block_size;
...@@ -2006,7 +2006,6 @@ extern struct block_device *bdgrab(struct block_device *bdev); ...@@ -2006,7 +2006,6 @@ extern struct block_device *bdgrab(struct block_device *bdev);
extern void bd_set_size(struct block_device *, loff_t size); extern void bd_set_size(struct block_device *, loff_t size);
extern void bd_forget(struct inode *inode); extern void bd_forget(struct inode *inode);
extern void bdput(struct block_device *); extern void bdput(struct block_device *);
extern struct block_device *open_by_devnum(dev_t, fmode_t);
extern void invalidate_bdev(struct block_device *); extern void invalidate_bdev(struct block_device *);
extern int sync_blockdev(struct block_device *bdev); extern int sync_blockdev(struct block_device *bdev);
extern struct super_block *freeze_bdev(struct block_device *); extern struct super_block *freeze_bdev(struct block_device *);
...@@ -2037,16 +2036,20 @@ extern const struct file_operations def_fifo_fops; ...@@ -2037,16 +2036,20 @@ extern const struct file_operations def_fifo_fops;
extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
extern int blkdev_get(struct block_device *, fmode_t); extern int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder);
extern int blkdev_put(struct block_device *, fmode_t); extern struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,
extern int bd_claim(struct block_device *, void *); void *holder);
extern void bd_release(struct block_device *); extern struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode,
void *holder);
extern int blkdev_put(struct block_device *bdev, fmode_t mode);
#ifdef CONFIG_SYSFS #ifdef CONFIG_SYSFS
extern int bd_claim_by_disk(struct block_device *, void *, struct gendisk *); extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk);
extern void bd_release_from_disk(struct block_device *, struct gendisk *);
#else #else
#define bd_claim_by_disk(bdev, holder, disk) bd_claim(bdev, holder) static inline int bd_link_disk_holder(struct block_device *bdev,
#define bd_release_from_disk(bdev, disk) bd_release(bdev) struct gendisk *disk)
{
return 0;
}
#endif #endif
#endif #endif
...@@ -2082,8 +2085,6 @@ static inline void unregister_chrdev(unsigned int major, const char *name) ...@@ -2082,8 +2085,6 @@ static inline void unregister_chrdev(unsigned int major, const char *name)
extern const char *__bdevname(dev_t, char *buffer); extern const char *__bdevname(dev_t, char *buffer);
extern const char *bdevname(struct block_device *bdev, char *buffer); extern const char *bdevname(struct block_device *bdev, char *buffer);
extern struct block_device *lookup_bdev(const char *); extern struct block_device *lookup_bdev(const char *);
extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *);
extern void close_bdev_exclusive(struct block_device *, fmode_t);
extern void blkdev_show(struct seq_file *,off_t); extern void blkdev_show(struct seq_file *,off_t);
#else #else
......
...@@ -223,7 +223,7 @@ static int swsusp_swap_check(void) ...@@ -223,7 +223,7 @@ static int swsusp_swap_check(void)
return res; return res;
root_swap = res; root_swap = res;
res = blkdev_get(hib_resume_bdev, FMODE_WRITE); res = blkdev_get(hib_resume_bdev, FMODE_WRITE, NULL);
if (res) if (res)
return res; return res;
...@@ -907,7 +907,8 @@ int swsusp_check(void) ...@@ -907,7 +907,8 @@ int swsusp_check(void)
{ {
int error; int error;
hib_resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ); hib_resume_bdev = blkdev_get_by_dev(swsusp_resume_device,
FMODE_READ, NULL);
if (!IS_ERR(hib_resume_bdev)) { if (!IS_ERR(hib_resume_bdev)) {
set_blocksize(hib_resume_bdev, PAGE_SIZE); set_blocksize(hib_resume_bdev, PAGE_SIZE);
clear_page(swsusp_header); clear_page(swsusp_header);
......
...@@ -1677,7 +1677,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) ...@@ -1677,7 +1677,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
if (S_ISBLK(inode->i_mode)) { if (S_ISBLK(inode->i_mode)) {
struct block_device *bdev = I_BDEV(inode); struct block_device *bdev = I_BDEV(inode);
set_blocksize(bdev, p->old_block_size); set_blocksize(bdev, p->old_block_size);
bd_release(bdev); blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
} else { } else {
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
inode->i_flags &= ~S_SWAPFILE; inode->i_flags &= ~S_SWAPFILE;
...@@ -1939,7 +1939,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) ...@@ -1939,7 +1939,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
error = -EINVAL; error = -EINVAL;
if (S_ISBLK(inode->i_mode)) { if (S_ISBLK(inode->i_mode)) {
bdev = I_BDEV(inode); bdev = I_BDEV(inode);
error = bd_claim(bdev, sys_swapon); error = blkdev_get(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL,
sys_swapon);
if (error < 0) { if (error < 0) {
bdev = NULL; bdev = NULL;
error = -EINVAL; error = -EINVAL;
...@@ -2136,7 +2137,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) ...@@ -2136,7 +2137,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
bad_swap: bad_swap:
if (bdev) { if (bdev) {
set_blocksize(bdev, p->old_block_size); set_blocksize(bdev, p->old_block_size);
bd_release(bdev); blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
} }
destroy_swap_extents(p); destroy_swap_extents(p);
swap_cgroup_swapoff(type); swap_cgroup_swapoff(type);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册