mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'vfs-6.9.super' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull block handle updates from Christian Brauner:
"Last cycle we changed opening of block devices, and opening a block
device would return a bdev_handle. This allowed us to implement
support for restricting and forbidding writes to mounted block
devices. It was accompanied by converting and adding helpers to
operate on bdev_handles instead of plain block devices.
That was already a good step forward but ultimately it isn't necessary
to have special purpose helpers for opening block devices internally
that return a bdev_handle.
Fundamentally, opening a block device internally should just be
equivalent to opening files. So now all internal opens of block
devices return files just as a userspace open would. Instead of
introducing a separate indirection into bdev_open_by_*() via struct
bdev_handle bdev_file_open_by_*() is made to just return a struct
file. Opening and closing a block device just becomes equivalent to
opening and closing a file.
This all works well because internally we already have a pseudo fs for
block devices and so opening block devices is simple. There's a few
places where we needed to be careful such as during boot when the
kernel is supposed to mount the rootfs directly without init doing it.
Here we need to take care to ensure that we flush out any asynchronous
file close. That's what we already do for opening, unpacking, and
closing the initramfs. So nothing new here.
The equivalence of opening and closing block devices to regular files
is a win in and of itself. But it also has various other advantages.
We can remove struct bdev_handle completely. Various low-level helpers
are now private to the block layer. Other helpers were simply
removable completely.
A follow-up series that is already reviewed build on this and makes it
possible to remove bdev->bd_inode and allows various clean ups of the
buffer head code as well. All places where we stashed a bdev_handle
now just stash a file and use simple accessors to get to the actual
block device which was already the case for bdev_handle"
* tag 'vfs-6.9.super' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (35 commits)
block: remove bdev_handle completely
block: don't rely on BLK_OPEN_RESTRICT_WRITES when yielding write access
bdev: remove bdev pointer from struct bdev_handle
bdev: make struct bdev_handle private to the block layer
bdev: make bdev_{release, open_by_dev}() private to block layer
bdev: remove bdev_open_by_path()
reiserfs: port block device access to file
ocfs2: port block device access to file
nfs: port block device access to files
jfs: port block device access to file
f2fs: port block device access to files
ext4: port block device access to file
erofs: port device access to file
btrfs: port device access to file
bcachefs: port block device access to file
target: port block device access to file
s390: port block device access to file
nvme: port block device access to file
block2mtd: port device access to files
bcache: port block device access to files
...
This commit is contained in:
252
block/bdev.c
252
block/bdev.c
@@ -49,6 +49,12 @@ struct block_device *I_BDEV(struct inode *inode)
|
||||
}
|
||||
EXPORT_SYMBOL(I_BDEV);
|
||||
|
||||
struct block_device *file_bdev(struct file *bdev_file)
|
||||
{
|
||||
return I_BDEV(bdev_file->f_mapping->host);
|
||||
}
|
||||
EXPORT_SYMBOL(file_bdev);
|
||||
|
||||
static void bdev_write_inode(struct block_device *bdev)
|
||||
{
|
||||
struct inode *inode = bdev->bd_inode;
|
||||
@@ -368,12 +374,12 @@ static struct file_system_type bd_type = {
|
||||
};
|
||||
|
||||
struct super_block *blockdev_superblock __ro_after_init;
|
||||
struct vfsmount *blockdev_mnt __ro_after_init;
|
||||
EXPORT_SYMBOL_GPL(blockdev_superblock);
|
||||
|
||||
void __init bdev_cache_init(void)
|
||||
{
|
||||
int err;
|
||||
static struct vfsmount *bd_mnt __ro_after_init;
|
||||
|
||||
bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode),
|
||||
0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
|
||||
@@ -382,10 +388,10 @@ void __init bdev_cache_init(void)
|
||||
err = register_filesystem(&bd_type);
|
||||
if (err)
|
||||
panic("Cannot register bdev pseudo-fs");
|
||||
bd_mnt = kern_mount(&bd_type);
|
||||
if (IS_ERR(bd_mnt))
|
||||
blockdev_mnt = kern_mount(&bd_type);
|
||||
if (IS_ERR(blockdev_mnt))
|
||||
panic("Cannot create bdev pseudo-fs");
|
||||
blockdev_superblock = bd_mnt->mnt_sb; /* For writeback */
|
||||
blockdev_superblock = blockdev_mnt->mnt_sb; /* For writeback */
|
||||
}
|
||||
|
||||
struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
|
||||
@@ -696,6 +702,31 @@ out_blkdev_put:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bdev_permission(dev_t dev, blk_mode_t mode, void *holder)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = devcgroup_check_permission(DEVCG_DEV_BLOCK,
|
||||
MAJOR(dev), MINOR(dev),
|
||||
((mode & BLK_OPEN_READ) ? DEVCG_ACC_READ : 0) |
|
||||
((mode & BLK_OPEN_WRITE) ? DEVCG_ACC_WRITE : 0));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Blocking writes requires exclusive opener */
|
||||
if (mode & BLK_OPEN_RESTRICT_WRITES && !holder)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* We're using error pointers to indicate to ->release() when we
|
||||
* failed to open that block device. Also this doesn't make sense.
|
||||
*/
|
||||
if (WARN_ON_ONCE(IS_ERR(holder)))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void blkdev_put_part(struct block_device *part)
|
||||
{
|
||||
struct block_device *whole = bdev_whole(part);
|
||||
@@ -775,83 +806,55 @@ static void bdev_claim_write_access(struct block_device *bdev, blk_mode_t mode)
|
||||
bdev->bd_writers++;
|
||||
}
|
||||
|
||||
static void bdev_yield_write_access(struct block_device *bdev, blk_mode_t mode)
|
||||
static void bdev_yield_write_access(struct file *bdev_file)
|
||||
{
|
||||
struct block_device *bdev;
|
||||
|
||||
if (bdev_allow_write_mounted)
|
||||
return;
|
||||
|
||||
bdev = file_bdev(bdev_file);
|
||||
/* Yield exclusive or shared write access. */
|
||||
if (mode & BLK_OPEN_RESTRICT_WRITES)
|
||||
bdev_unblock_writes(bdev);
|
||||
else if (mode & BLK_OPEN_WRITE)
|
||||
bdev->bd_writers--;
|
||||
if (bdev_file->f_mode & FMODE_WRITE) {
|
||||
if (bdev_writes_blocked(bdev))
|
||||
bdev_unblock_writes(bdev);
|
||||
else
|
||||
bdev->bd_writers--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* bdev_open_by_dev - open a block device by device number
|
||||
* @dev: device number of block device to open
|
||||
* bdev_open - open a block device
|
||||
* @bdev: block device to open
|
||||
* @mode: open mode (BLK_OPEN_*)
|
||||
* @holder: exclusive holder identifier
|
||||
* @hops: holder operations
|
||||
* @bdev_file: file for the block device
|
||||
*
|
||||
* Open the block device described by device number @dev. If @holder is not
|
||||
* %NULL, the block device is opened with exclusive access. Exclusive opens may
|
||||
* nest for the same @holder.
|
||||
*
|
||||
* Use this interface ONLY if you really do not have anything better - i.e. when
|
||||
* you are behind a truly sucky interface and all you are given is a device
|
||||
* number. Everything else should use bdev_open_by_path().
|
||||
* Open the block device. If @holder is not %NULL, the block device is opened
|
||||
* with exclusive access. Exclusive opens may nest for the same @holder.
|
||||
*
|
||||
* CONTEXT:
|
||||
* Might sleep.
|
||||
*
|
||||
* RETURNS:
|
||||
* Handle with a reference to the block_device on success, ERR_PTR(-errno) on
|
||||
* failure.
|
||||
* zero on success, -errno on failure.
|
||||
*/
|
||||
struct bdev_handle *bdev_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,
|
||||
const struct blk_holder_ops *hops)
|
||||
int bdev_open(struct block_device *bdev, blk_mode_t mode, void *holder,
|
||||
const struct blk_holder_ops *hops, struct file *bdev_file)
|
||||
{
|
||||
struct bdev_handle *handle = kmalloc(sizeof(struct bdev_handle),
|
||||
GFP_KERNEL);
|
||||
struct block_device *bdev;
|
||||
bool unblock_events = true;
|
||||
struct gendisk *disk;
|
||||
struct gendisk *disk = bdev->bd_disk;
|
||||
int ret;
|
||||
|
||||
if (!handle)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = devcgroup_check_permission(DEVCG_DEV_BLOCK,
|
||||
MAJOR(dev), MINOR(dev),
|
||||
((mode & BLK_OPEN_READ) ? DEVCG_ACC_READ : 0) |
|
||||
((mode & BLK_OPEN_WRITE) ? DEVCG_ACC_WRITE : 0));
|
||||
if (ret)
|
||||
goto free_handle;
|
||||
|
||||
/* Blocking writes requires exclusive opener */
|
||||
if (mode & BLK_OPEN_RESTRICT_WRITES && !holder) {
|
||||
ret = -EINVAL;
|
||||
goto free_handle;
|
||||
}
|
||||
|
||||
bdev = blkdev_get_no_open(dev);
|
||||
if (!bdev) {
|
||||
ret = -ENXIO;
|
||||
goto free_handle;
|
||||
}
|
||||
disk = bdev->bd_disk;
|
||||
|
||||
if (holder) {
|
||||
mode |= BLK_OPEN_EXCL;
|
||||
ret = bd_prepare_to_claim(bdev, holder, hops);
|
||||
if (ret)
|
||||
goto put_blkdev;
|
||||
return ret;
|
||||
} else {
|
||||
if (WARN_ON_ONCE(mode & BLK_OPEN_EXCL)) {
|
||||
ret = -EIO;
|
||||
goto put_blkdev;
|
||||
}
|
||||
if (WARN_ON_ONCE(mode & BLK_OPEN_EXCL))
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
disk_block_events(disk);
|
||||
@@ -892,10 +895,16 @@ struct bdev_handle *bdev_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,
|
||||
|
||||
if (unblock_events)
|
||||
disk_unblock_events(disk);
|
||||
handle->bdev = bdev;
|
||||
handle->holder = holder;
|
||||
handle->mode = mode;
|
||||
return handle;
|
||||
|
||||
bdev_file->f_flags |= O_LARGEFILE;
|
||||
bdev_file->f_mode |= FMODE_BUF_RASYNC | FMODE_CAN_ODIRECT;
|
||||
if (bdev_nowait(bdev))
|
||||
bdev_file->f_mode |= FMODE_NOWAIT;
|
||||
bdev_file->f_mapping = bdev->bd_inode->i_mapping;
|
||||
bdev_file->f_wb_err = filemap_sample_wb_err(bdev_file->f_mapping);
|
||||
bdev_file->private_data = holder;
|
||||
|
||||
return 0;
|
||||
put_module:
|
||||
module_put(disk->fops->owner);
|
||||
abort_claiming:
|
||||
@@ -903,36 +912,80 @@ abort_claiming:
|
||||
bd_abort_claiming(bdev, holder);
|
||||
mutex_unlock(&disk->open_mutex);
|
||||
disk_unblock_events(disk);
|
||||
put_blkdev:
|
||||
blkdev_put_no_open(bdev);
|
||||
free_handle:
|
||||
kfree(handle);
|
||||
return ERR_PTR(ret);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(bdev_open_by_dev);
|
||||
|
||||
/**
|
||||
* bdev_open_by_path - open a block device by name
|
||||
* @path: path to the block device to open
|
||||
* @mode: open mode (BLK_OPEN_*)
|
||||
* @holder: exclusive holder identifier
|
||||
* @hops: holder operations
|
||||
/*
|
||||
* If BLK_OPEN_WRITE_IOCTL is set then this is a historical quirk
|
||||
* associated with the floppy driver where it has allowed ioctls if the
|
||||
* file was opened for writing, but does not allow reads or writes.
|
||||
* Make sure that this quirk is reflected in @f_flags.
|
||||
*
|
||||
* Open the block device described by the device file at @path. If @holder is
|
||||
* not %NULL, the block device is opened with exclusive access. Exclusive opens
|
||||
* may nest for the same @holder.
|
||||
*
|
||||
* CONTEXT:
|
||||
* Might sleep.
|
||||
*
|
||||
* RETURNS:
|
||||
* Handle with a reference to the block_device on success, ERR_PTR(-errno) on
|
||||
* failure.
|
||||
* It can also happen if a block device is opened as O_RDWR | O_WRONLY.
|
||||
*/
|
||||
struct bdev_handle *bdev_open_by_path(const char *path, blk_mode_t mode,
|
||||
void *holder, const struct blk_holder_ops *hops)
|
||||
static unsigned blk_to_file_flags(blk_mode_t mode)
|
||||
{
|
||||
struct bdev_handle *handle;
|
||||
unsigned int flags = 0;
|
||||
|
||||
if ((mode & (BLK_OPEN_READ | BLK_OPEN_WRITE)) ==
|
||||
(BLK_OPEN_READ | BLK_OPEN_WRITE))
|
||||
flags |= O_RDWR;
|
||||
else if (mode & BLK_OPEN_WRITE_IOCTL)
|
||||
flags |= O_RDWR | O_WRONLY;
|
||||
else if (mode & BLK_OPEN_WRITE)
|
||||
flags |= O_WRONLY;
|
||||
else if (mode & BLK_OPEN_READ)
|
||||
flags |= O_RDONLY; /* homeopathic, because O_RDONLY is 0 */
|
||||
else
|
||||
WARN_ON_ONCE(true);
|
||||
|
||||
if (mode & BLK_OPEN_NDELAY)
|
||||
flags |= O_NDELAY;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
struct file *bdev_file_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,
|
||||
const struct blk_holder_ops *hops)
|
||||
{
|
||||
struct file *bdev_file;
|
||||
struct block_device *bdev;
|
||||
unsigned int flags;
|
||||
int ret;
|
||||
|
||||
ret = bdev_permission(dev, mode, holder);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
bdev = blkdev_get_no_open(dev);
|
||||
if (!bdev)
|
||||
return ERR_PTR(-ENXIO);
|
||||
|
||||
flags = blk_to_file_flags(mode);
|
||||
bdev_file = alloc_file_pseudo_noaccount(bdev->bd_inode,
|
||||
blockdev_mnt, "", flags | O_LARGEFILE, &def_blk_fops);
|
||||
if (IS_ERR(bdev_file)) {
|
||||
blkdev_put_no_open(bdev);
|
||||
return bdev_file;
|
||||
}
|
||||
ihold(bdev->bd_inode);
|
||||
|
||||
ret = bdev_open(bdev, mode, holder, hops, bdev_file);
|
||||
if (ret) {
|
||||
/* We failed to open the block device. Let ->release() know. */
|
||||
bdev_file->private_data = ERR_PTR(ret);
|
||||
fput(bdev_file);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
return bdev_file;
|
||||
}
|
||||
EXPORT_SYMBOL(bdev_file_open_by_dev);
|
||||
|
||||
struct file *bdev_file_open_by_path(const char *path, blk_mode_t mode,
|
||||
void *holder,
|
||||
const struct blk_holder_ops *hops)
|
||||
{
|
||||
struct file *file;
|
||||
dev_t dev;
|
||||
int error;
|
||||
|
||||
@@ -940,22 +993,28 @@ struct bdev_handle *bdev_open_by_path(const char *path, blk_mode_t mode,
|
||||
if (error)
|
||||
return ERR_PTR(error);
|
||||
|
||||
handle = bdev_open_by_dev(dev, mode, holder, hops);
|
||||
if (!IS_ERR(handle) && (mode & BLK_OPEN_WRITE) &&
|
||||
bdev_read_only(handle->bdev)) {
|
||||
bdev_release(handle);
|
||||
return ERR_PTR(-EACCES);
|
||||
file = bdev_file_open_by_dev(dev, mode, holder, hops);
|
||||
if (!IS_ERR(file) && (mode & BLK_OPEN_WRITE)) {
|
||||
if (bdev_read_only(file_bdev(file))) {
|
||||
fput(file);
|
||||
file = ERR_PTR(-EACCES);
|
||||
}
|
||||
}
|
||||
|
||||
return handle;
|
||||
return file;
|
||||
}
|
||||
EXPORT_SYMBOL(bdev_open_by_path);
|
||||
EXPORT_SYMBOL(bdev_file_open_by_path);
|
||||
|
||||
void bdev_release(struct bdev_handle *handle)
|
||||
void bdev_release(struct file *bdev_file)
|
||||
{
|
||||
struct block_device *bdev = handle->bdev;
|
||||
struct block_device *bdev = file_bdev(bdev_file);
|
||||
void *holder = bdev_file->private_data;
|
||||
struct gendisk *disk = bdev->bd_disk;
|
||||
|
||||
/* We failed to open that block device. */
|
||||
if (IS_ERR(holder))
|
||||
goto put_no_open;
|
||||
|
||||
/*
|
||||
* Sync early if it looks like we're the last one. If someone else
|
||||
* opens the block device between now and the decrement of bd_openers
|
||||
@@ -967,10 +1026,10 @@ void bdev_release(struct bdev_handle *handle)
|
||||
sync_blockdev(bdev);
|
||||
|
||||
mutex_lock(&disk->open_mutex);
|
||||
bdev_yield_write_access(bdev, handle->mode);
|
||||
bdev_yield_write_access(bdev_file);
|
||||
|
||||
if (handle->holder)
|
||||
bd_end_claim(bdev, handle->holder);
|
||||
if (holder)
|
||||
bd_end_claim(bdev, holder);
|
||||
|
||||
/*
|
||||
* Trigger event checking and tell drivers to flush MEDIA_CHANGE
|
||||
@@ -986,10 +1045,9 @@ void bdev_release(struct bdev_handle *handle)
|
||||
mutex_unlock(&disk->open_mutex);
|
||||
|
||||
module_put(disk->fops->owner);
|
||||
put_no_open:
|
||||
blkdev_put_no_open(bdev);
|
||||
kfree(handle);
|
||||
}
|
||||
EXPORT_SYMBOL(bdev_release);
|
||||
|
||||
/**
|
||||
* lookup_bdev() - Look up a struct block_device by name.
|
||||
|
||||
@@ -516,4 +516,8 @@ static inline int req_ref_read(struct request *req)
|
||||
return atomic_read(&req->ref);
|
||||
}
|
||||
|
||||
void bdev_release(struct file *bdev_file);
|
||||
int bdev_open(struct block_device *bdev, blk_mode_t mode, void *holder,
|
||||
const struct blk_holder_ops *hops, struct file *bdev_file);
|
||||
int bdev_permission(dev_t dev, blk_mode_t mode, void *holder);
|
||||
#endif /* BLK_INTERNAL_H */
|
||||
|
||||
46
block/fops.c
46
block/fops.c
@@ -572,18 +572,17 @@ static int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
|
||||
blk_mode_t file_to_blk_mode(struct file *file)
|
||||
{
|
||||
blk_mode_t mode = 0;
|
||||
struct bdev_handle *handle = file->private_data;
|
||||
|
||||
if (file->f_mode & FMODE_READ)
|
||||
mode |= BLK_OPEN_READ;
|
||||
if (file->f_mode & FMODE_WRITE)
|
||||
mode |= BLK_OPEN_WRITE;
|
||||
/*
|
||||
* do_dentry_open() clears O_EXCL from f_flags, use handle->mode to
|
||||
* determine whether the open was exclusive for already open files.
|
||||
* do_dentry_open() clears O_EXCL from f_flags, use file->private_data
|
||||
* to determine whether the open was exclusive for already open files.
|
||||
*/
|
||||
if (handle)
|
||||
mode |= handle->mode & BLK_OPEN_EXCL;
|
||||
if (file->private_data)
|
||||
mode |= BLK_OPEN_EXCL;
|
||||
else if (file->f_flags & O_EXCL)
|
||||
mode |= BLK_OPEN_EXCL;
|
||||
if (file->f_flags & O_NDELAY)
|
||||
@@ -602,36 +601,31 @@ blk_mode_t file_to_blk_mode(struct file *file)
|
||||
|
||||
static int blkdev_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct bdev_handle *handle;
|
||||
struct block_device *bdev;
|
||||
blk_mode_t mode;
|
||||
|
||||
/*
|
||||
* Preserve backwards compatibility and allow large file access
|
||||
* even if userspace doesn't ask for it explicitly. Some mkfs
|
||||
* binary needs it. We might want to drop this workaround
|
||||
* during an unstable branch.
|
||||
*/
|
||||
filp->f_flags |= O_LARGEFILE;
|
||||
filp->f_mode |= FMODE_BUF_RASYNC | FMODE_CAN_ODIRECT;
|
||||
int ret;
|
||||
|
||||
mode = file_to_blk_mode(filp);
|
||||
handle = bdev_open_by_dev(inode->i_rdev, mode,
|
||||
mode & BLK_OPEN_EXCL ? filp : NULL, NULL);
|
||||
if (IS_ERR(handle))
|
||||
return PTR_ERR(handle);
|
||||
/* Use the file as the holder. */
|
||||
if (mode & BLK_OPEN_EXCL)
|
||||
filp->private_data = filp;
|
||||
ret = bdev_permission(inode->i_rdev, mode, filp->private_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (bdev_nowait(handle->bdev))
|
||||
filp->f_mode |= FMODE_NOWAIT;
|
||||
bdev = blkdev_get_no_open(inode->i_rdev);
|
||||
if (!bdev)
|
||||
return -ENXIO;
|
||||
|
||||
filp->f_mapping = handle->bdev->bd_inode->i_mapping;
|
||||
filp->f_wb_err = filemap_sample_wb_err(filp->f_mapping);
|
||||
filp->private_data = handle;
|
||||
return 0;
|
||||
ret = bdev_open(bdev, mode, filp->private_data, NULL, filp);
|
||||
if (ret)
|
||||
blkdev_put_no_open(bdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int blkdev_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
bdev_release(filp->private_data);
|
||||
bdev_release(filp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -342,7 +342,7 @@ EXPORT_SYMBOL_GPL(disk_uevent);
|
||||
|
||||
int disk_scan_partitions(struct gendisk *disk, blk_mode_t mode)
|
||||
{
|
||||
struct bdev_handle *handle;
|
||||
struct file *file;
|
||||
int ret = 0;
|
||||
|
||||
if (disk->flags & (GENHD_FL_NO_PART | GENHD_FL_HIDDEN))
|
||||
@@ -366,12 +366,12 @@ int disk_scan_partitions(struct gendisk *disk, blk_mode_t mode)
|
||||
}
|
||||
|
||||
set_bit(GD_NEED_PART_SCAN, &disk->state);
|
||||
handle = bdev_open_by_dev(disk_devt(disk), mode & ~BLK_OPEN_EXCL, NULL,
|
||||
NULL);
|
||||
if (IS_ERR(handle))
|
||||
ret = PTR_ERR(handle);
|
||||
file = bdev_file_open_by_dev(disk_devt(disk), mode & ~BLK_OPEN_EXCL,
|
||||
NULL, NULL);
|
||||
if (IS_ERR(file))
|
||||
ret = PTR_ERR(file);
|
||||
else
|
||||
bdev_release(handle);
|
||||
fput(file);
|
||||
|
||||
/*
|
||||
* If blkdev_get_by_dev() failed early, GD_NEED_PART_SCAN is still set,
|
||||
|
||||
@@ -469,7 +469,7 @@ static int blkdev_bszset(struct block_device *bdev, blk_mode_t mode,
|
||||
int __user *argp)
|
||||
{
|
||||
int ret, n;
|
||||
struct bdev_handle *handle;
|
||||
struct file *file;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EACCES;
|
||||
@@ -481,12 +481,11 @@ static int blkdev_bszset(struct block_device *bdev, blk_mode_t mode,
|
||||
if (mode & BLK_OPEN_EXCL)
|
||||
return set_blocksize(bdev, n);
|
||||
|
||||
handle = bdev_open_by_dev(bdev->bd_dev, mode, &bdev, NULL);
|
||||
if (IS_ERR(handle))
|
||||
file = bdev_file_open_by_dev(bdev->bd_dev, mode, &bdev, NULL);
|
||||
if (IS_ERR(file))
|
||||
return -EBUSY;
|
||||
ret = set_blocksize(bdev, n);
|
||||
bdev_release(handle);
|
||||
|
||||
fput(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -524,9 +524,9 @@ struct drbd_md {
|
||||
|
||||
struct drbd_backing_dev {
|
||||
struct block_device *backing_bdev;
|
||||
struct bdev_handle *backing_bdev_handle;
|
||||
struct file *backing_bdev_file;
|
||||
struct block_device *md_bdev;
|
||||
struct bdev_handle *md_bdev_handle;
|
||||
struct file *f_md_bdev;
|
||||
struct drbd_md md;
|
||||
struct disk_conf *disk_conf; /* RCU, for updates: resource->conf_update */
|
||||
sector_t known_size; /* last known size of that backing device */
|
||||
|
||||
@@ -1635,45 +1635,45 @@ success:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct bdev_handle *open_backing_dev(struct drbd_device *device,
|
||||
static struct file *open_backing_dev(struct drbd_device *device,
|
||||
const char *bdev_path, void *claim_ptr, bool do_bd_link)
|
||||
{
|
||||
struct bdev_handle *handle;
|
||||
struct file *file;
|
||||
int err = 0;
|
||||
|
||||
handle = bdev_open_by_path(bdev_path, BLK_OPEN_READ | BLK_OPEN_WRITE,
|
||||
claim_ptr, NULL);
|
||||
if (IS_ERR(handle)) {
|
||||
file = bdev_file_open_by_path(bdev_path, BLK_OPEN_READ | BLK_OPEN_WRITE,
|
||||
claim_ptr, NULL);
|
||||
if (IS_ERR(file)) {
|
||||
drbd_err(device, "open(\"%s\") failed with %ld\n",
|
||||
bdev_path, PTR_ERR(handle));
|
||||
return handle;
|
||||
bdev_path, PTR_ERR(file));
|
||||
return file;
|
||||
}
|
||||
|
||||
if (!do_bd_link)
|
||||
return handle;
|
||||
return file;
|
||||
|
||||
err = bd_link_disk_holder(handle->bdev, device->vdisk);
|
||||
err = bd_link_disk_holder(file_bdev(file), device->vdisk);
|
||||
if (err) {
|
||||
bdev_release(handle);
|
||||
fput(file);
|
||||
drbd_err(device, "bd_link_disk_holder(\"%s\", ...) failed with %d\n",
|
||||
bdev_path, err);
|
||||
handle = ERR_PTR(err);
|
||||
file = ERR_PTR(err);
|
||||
}
|
||||
return handle;
|
||||
return file;
|
||||
}
|
||||
|
||||
static int open_backing_devices(struct drbd_device *device,
|
||||
struct disk_conf *new_disk_conf,
|
||||
struct drbd_backing_dev *nbc)
|
||||
{
|
||||
struct bdev_handle *handle;
|
||||
struct file *file;
|
||||
|
||||
handle = open_backing_dev(device, new_disk_conf->backing_dev, device,
|
||||
file = open_backing_dev(device, new_disk_conf->backing_dev, device,
|
||||
true);
|
||||
if (IS_ERR(handle))
|
||||
if (IS_ERR(file))
|
||||
return ERR_OPEN_DISK;
|
||||
nbc->backing_bdev = handle->bdev;
|
||||
nbc->backing_bdev_handle = handle;
|
||||
nbc->backing_bdev = file_bdev(file);
|
||||
nbc->backing_bdev_file = file;
|
||||
|
||||
/*
|
||||
* meta_dev_idx >= 0: external fixed size, possibly multiple
|
||||
@@ -1683,7 +1683,7 @@ static int open_backing_devices(struct drbd_device *device,
|
||||
* should check it for you already; but if you don't, or
|
||||
* someone fooled it, we need to double check here)
|
||||
*/
|
||||
handle = open_backing_dev(device, new_disk_conf->meta_dev,
|
||||
file = open_backing_dev(device, new_disk_conf->meta_dev,
|
||||
/* claim ptr: device, if claimed exclusively; shared drbd_m_holder,
|
||||
* if potentially shared with other drbd minors */
|
||||
(new_disk_conf->meta_dev_idx < 0) ? (void*)device : (void*)drbd_m_holder,
|
||||
@@ -1691,21 +1691,21 @@ static int open_backing_devices(struct drbd_device *device,
|
||||
* as would happen with internal metadata. */
|
||||
(new_disk_conf->meta_dev_idx != DRBD_MD_INDEX_FLEX_INT &&
|
||||
new_disk_conf->meta_dev_idx != DRBD_MD_INDEX_INTERNAL));
|
||||
if (IS_ERR(handle))
|
||||
if (IS_ERR(file))
|
||||
return ERR_OPEN_MD_DISK;
|
||||
nbc->md_bdev = handle->bdev;
|
||||
nbc->md_bdev_handle = handle;
|
||||
nbc->md_bdev = file_bdev(file);
|
||||
nbc->f_md_bdev = file;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
static void close_backing_dev(struct drbd_device *device,
|
||||
struct bdev_handle *handle, bool do_bd_unlink)
|
||||
struct file *bdev_file, bool do_bd_unlink)
|
||||
{
|
||||
if (!handle)
|
||||
if (!bdev_file)
|
||||
return;
|
||||
if (do_bd_unlink)
|
||||
bd_unlink_disk_holder(handle->bdev, device->vdisk);
|
||||
bdev_release(handle);
|
||||
bd_unlink_disk_holder(file_bdev(bdev_file), device->vdisk);
|
||||
fput(bdev_file);
|
||||
}
|
||||
|
||||
void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *ldev)
|
||||
@@ -1713,9 +1713,9 @@ void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *
|
||||
if (ldev == NULL)
|
||||
return;
|
||||
|
||||
close_backing_dev(device, ldev->md_bdev_handle,
|
||||
close_backing_dev(device, ldev->f_md_bdev,
|
||||
ldev->md_bdev != ldev->backing_bdev);
|
||||
close_backing_dev(device, ldev->backing_bdev_handle, true);
|
||||
close_backing_dev(device, ldev->backing_bdev_file, true);
|
||||
|
||||
kfree(ldev->disk_conf);
|
||||
kfree(ldev);
|
||||
@@ -2131,9 +2131,9 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
|
||||
fail:
|
||||
conn_reconfig_done(connection);
|
||||
if (nbc) {
|
||||
close_backing_dev(device, nbc->md_bdev_handle,
|
||||
close_backing_dev(device, nbc->f_md_bdev,
|
||||
nbc->md_bdev != nbc->backing_bdev);
|
||||
close_backing_dev(device, nbc->backing_bdev_handle, true);
|
||||
close_backing_dev(device, nbc->backing_bdev_file, true);
|
||||
kfree(nbc);
|
||||
}
|
||||
kfree(new_disk_conf);
|
||||
|
||||
@@ -340,8 +340,8 @@ static ssize_t device_map_show(const struct class *c, const struct class_attribu
|
||||
n += sysfs_emit_at(data, n, "%s %u:%u %u:%u\n",
|
||||
pd->disk->disk_name,
|
||||
MAJOR(pd->pkt_dev), MINOR(pd->pkt_dev),
|
||||
MAJOR(pd->bdev_handle->bdev->bd_dev),
|
||||
MINOR(pd->bdev_handle->bdev->bd_dev));
|
||||
MAJOR(file_bdev(pd->bdev_file)->bd_dev),
|
||||
MINOR(file_bdev(pd->bdev_file)->bd_dev));
|
||||
}
|
||||
mutex_unlock(&ctl_mutex);
|
||||
return n;
|
||||
@@ -438,7 +438,7 @@ static int pkt_seq_show(struct seq_file *m, void *p)
|
||||
int states[PACKET_NUM_STATES];
|
||||
|
||||
seq_printf(m, "Writer %s mapped to %pg:\n", pd->disk->disk_name,
|
||||
pd->bdev_handle->bdev);
|
||||
file_bdev(pd->bdev_file));
|
||||
|
||||
seq_printf(m, "\nSettings:\n");
|
||||
seq_printf(m, "\tpacket size:\t\t%dkB\n", pd->settings.size / 2);
|
||||
@@ -715,7 +715,7 @@ static void pkt_rbtree_insert(struct pktcdvd_device *pd, struct pkt_rb_node *nod
|
||||
*/
|
||||
static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *cgc)
|
||||
{
|
||||
struct request_queue *q = bdev_get_queue(pd->bdev_handle->bdev);
|
||||
struct request_queue *q = bdev_get_queue(file_bdev(pd->bdev_file));
|
||||
struct scsi_cmnd *scmd;
|
||||
struct request *rq;
|
||||
int ret = 0;
|
||||
@@ -1048,7 +1048,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
|
||||
continue;
|
||||
|
||||
bio = pkt->r_bios[f];
|
||||
bio_init(bio, pd->bdev_handle->bdev, bio->bi_inline_vecs, 1,
|
||||
bio_init(bio, file_bdev(pd->bdev_file), bio->bi_inline_vecs, 1,
|
||||
REQ_OP_READ);
|
||||
bio->bi_iter.bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
|
||||
bio->bi_end_io = pkt_end_io_read;
|
||||
@@ -1264,7 +1264,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
|
||||
struct device *ddev = disk_to_dev(pd->disk);
|
||||
int f;
|
||||
|
||||
bio_init(pkt->w_bio, pd->bdev_handle->bdev, pkt->w_bio->bi_inline_vecs,
|
||||
bio_init(pkt->w_bio, file_bdev(pd->bdev_file), pkt->w_bio->bi_inline_vecs,
|
||||
pkt->frames, REQ_OP_WRITE);
|
||||
pkt->w_bio->bi_iter.bi_sector = pkt->sector;
|
||||
pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
|
||||
@@ -2162,20 +2162,20 @@ static int pkt_open_dev(struct pktcdvd_device *pd, bool write)
|
||||
int ret;
|
||||
long lba;
|
||||
struct request_queue *q;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
|
||||
/*
|
||||
* We need to re-open the cdrom device without O_NONBLOCK to be able
|
||||
* to read/write from/to it. It is already opened in O_NONBLOCK mode
|
||||
* so open should not fail.
|
||||
*/
|
||||
bdev_handle = bdev_open_by_dev(pd->bdev_handle->bdev->bd_dev,
|
||||
bdev_file = bdev_file_open_by_dev(file_bdev(pd->bdev_file)->bd_dev,
|
||||
BLK_OPEN_READ, pd, NULL);
|
||||
if (IS_ERR(bdev_handle)) {
|
||||
ret = PTR_ERR(bdev_handle);
|
||||
if (IS_ERR(bdev_file)) {
|
||||
ret = PTR_ERR(bdev_file);
|
||||
goto out;
|
||||
}
|
||||
pd->open_bdev_handle = bdev_handle;
|
||||
pd->f_open_bdev = bdev_file;
|
||||
|
||||
ret = pkt_get_last_written(pd, &lba);
|
||||
if (ret) {
|
||||
@@ -2184,9 +2184,9 @@ static int pkt_open_dev(struct pktcdvd_device *pd, bool write)
|
||||
}
|
||||
|
||||
set_capacity(pd->disk, lba << 2);
|
||||
set_capacity_and_notify(pd->bdev_handle->bdev->bd_disk, lba << 2);
|
||||
set_capacity_and_notify(file_bdev(pd->bdev_file)->bd_disk, lba << 2);
|
||||
|
||||
q = bdev_get_queue(pd->bdev_handle->bdev);
|
||||
q = bdev_get_queue(file_bdev(pd->bdev_file));
|
||||
if (write) {
|
||||
ret = pkt_open_write(pd);
|
||||
if (ret)
|
||||
@@ -2218,7 +2218,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, bool write)
|
||||
return 0;
|
||||
|
||||
out_putdev:
|
||||
bdev_release(bdev_handle);
|
||||
fput(bdev_file);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@@ -2237,8 +2237,8 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
|
||||
pkt_lock_door(pd, 0);
|
||||
|
||||
pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
|
||||
bdev_release(pd->open_bdev_handle);
|
||||
pd->open_bdev_handle = NULL;
|
||||
fput(pd->f_open_bdev);
|
||||
pd->f_open_bdev = NULL;
|
||||
|
||||
pkt_shrink_pktlist(pd);
|
||||
}
|
||||
@@ -2326,7 +2326,7 @@ static void pkt_end_io_read_cloned(struct bio *bio)
|
||||
|
||||
static void pkt_make_request_read(struct pktcdvd_device *pd, struct bio *bio)
|
||||
{
|
||||
struct bio *cloned_bio = bio_alloc_clone(pd->bdev_handle->bdev, bio,
|
||||
struct bio *cloned_bio = bio_alloc_clone(file_bdev(pd->bdev_file), bio,
|
||||
GFP_NOIO, &pkt_bio_set);
|
||||
struct packet_stacked_data *psd = mempool_alloc(&psd_pool, GFP_NOIO);
|
||||
|
||||
@@ -2497,7 +2497,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
|
||||
{
|
||||
struct device *ddev = disk_to_dev(pd->disk);
|
||||
int i;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
struct scsi_device *sdev;
|
||||
|
||||
if (pd->pkt_dev == dev) {
|
||||
@@ -2508,9 +2508,9 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
|
||||
struct pktcdvd_device *pd2 = pkt_devs[i];
|
||||
if (!pd2)
|
||||
continue;
|
||||
if (pd2->bdev_handle->bdev->bd_dev == dev) {
|
||||
if (file_bdev(pd2->bdev_file)->bd_dev == dev) {
|
||||
dev_err(ddev, "%pg already setup\n",
|
||||
pd2->bdev_handle->bdev);
|
||||
file_bdev(pd2->bdev_file));
|
||||
return -EBUSY;
|
||||
}
|
||||
if (pd2->pkt_dev == dev) {
|
||||
@@ -2519,13 +2519,13 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
|
||||
}
|
||||
}
|
||||
|
||||
bdev_handle = bdev_open_by_dev(dev, BLK_OPEN_READ | BLK_OPEN_NDELAY,
|
||||
bdev_file = bdev_file_open_by_dev(dev, BLK_OPEN_READ | BLK_OPEN_NDELAY,
|
||||
NULL, NULL);
|
||||
if (IS_ERR(bdev_handle))
|
||||
return PTR_ERR(bdev_handle);
|
||||
sdev = scsi_device_from_queue(bdev_handle->bdev->bd_disk->queue);
|
||||
if (IS_ERR(bdev_file))
|
||||
return PTR_ERR(bdev_file);
|
||||
sdev = scsi_device_from_queue(file_bdev(bdev_file)->bd_disk->queue);
|
||||
if (!sdev) {
|
||||
bdev_release(bdev_handle);
|
||||
fput(bdev_file);
|
||||
return -EINVAL;
|
||||
}
|
||||
put_device(&sdev->sdev_gendev);
|
||||
@@ -2533,8 +2533,8 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
|
||||
/* This is safe, since we have a reference from open(). */
|
||||
__module_get(THIS_MODULE);
|
||||
|
||||
pd->bdev_handle = bdev_handle;
|
||||
set_blocksize(bdev_handle->bdev, CD_FRAMESIZE);
|
||||
pd->bdev_file = bdev_file;
|
||||
set_blocksize(file_bdev(bdev_file), CD_FRAMESIZE);
|
||||
|
||||
pkt_init_queue(pd);
|
||||
|
||||
@@ -2546,11 +2546,11 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
|
||||
}
|
||||
|
||||
proc_create_single_data(pd->disk->disk_name, 0, pkt_proc, pkt_seq_show, pd);
|
||||
dev_notice(ddev, "writer mapped to %pg\n", bdev_handle->bdev);
|
||||
dev_notice(ddev, "writer mapped to %pg\n", file_bdev(bdev_file));
|
||||
return 0;
|
||||
|
||||
out_mem:
|
||||
bdev_release(bdev_handle);
|
||||
fput(bdev_file);
|
||||
/* This is safe: open() is still holding a reference. */
|
||||
module_put(THIS_MODULE);
|
||||
return -ENOMEM;
|
||||
@@ -2605,9 +2605,9 @@ static unsigned int pkt_check_events(struct gendisk *disk,
|
||||
|
||||
if (!pd)
|
||||
return 0;
|
||||
if (!pd->bdev_handle)
|
||||
if (!pd->bdev_file)
|
||||
return 0;
|
||||
attached_disk = pd->bdev_handle->bdev->bd_disk;
|
||||
attached_disk = file_bdev(pd->bdev_file)->bd_disk;
|
||||
if (!attached_disk || !attached_disk->fops->check_events)
|
||||
return 0;
|
||||
return attached_disk->fops->check_events(attached_disk, clearing);
|
||||
@@ -2692,7 +2692,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
|
||||
goto out_mem2;
|
||||
|
||||
/* inherit events of the host device */
|
||||
disk->events = pd->bdev_handle->bdev->bd_disk->events;
|
||||
disk->events = file_bdev(pd->bdev_file)->bd_disk->events;
|
||||
|
||||
ret = add_disk(disk);
|
||||
if (ret)
|
||||
@@ -2757,7 +2757,7 @@ static int pkt_remove_dev(dev_t pkt_dev)
|
||||
pkt_debugfs_dev_remove(pd);
|
||||
pkt_sysfs_dev_remove(pd);
|
||||
|
||||
bdev_release(pd->bdev_handle);
|
||||
fput(pd->bdev_file);
|
||||
|
||||
remove_proc_entry(pd->disk->disk_name, pkt_proc);
|
||||
dev_notice(ddev, "writer unmapped\n");
|
||||
@@ -2784,7 +2784,7 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
|
||||
|
||||
pd = pkt_find_dev_from_minor(ctrl_cmd->dev_index);
|
||||
if (pd) {
|
||||
ctrl_cmd->dev = new_encode_dev(pd->bdev_handle->bdev->bd_dev);
|
||||
ctrl_cmd->dev = new_encode_dev(file_bdev(pd->bdev_file)->bd_dev);
|
||||
ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev);
|
||||
} else {
|
||||
ctrl_cmd->dev = 0;
|
||||
|
||||
@@ -145,7 +145,7 @@ static int process_rdma(struct rnbd_srv_session *srv_sess,
|
||||
priv->sess_dev = sess_dev;
|
||||
priv->id = id;
|
||||
|
||||
bio = bio_alloc(sess_dev->bdev_handle->bdev, 1,
|
||||
bio = bio_alloc(file_bdev(sess_dev->bdev_file), 1,
|
||||
rnbd_to_bio_flags(le32_to_cpu(msg->rw)), GFP_KERNEL);
|
||||
if (bio_add_page(bio, virt_to_page(data), datalen,
|
||||
offset_in_page(data)) != datalen) {
|
||||
@@ -219,7 +219,7 @@ void rnbd_destroy_sess_dev(struct rnbd_srv_sess_dev *sess_dev, bool keep_id)
|
||||
rnbd_put_sess_dev(sess_dev);
|
||||
wait_for_completion(&dc); /* wait for inflights to drop to zero */
|
||||
|
||||
bdev_release(sess_dev->bdev_handle);
|
||||
fput(sess_dev->bdev_file);
|
||||
mutex_lock(&sess_dev->dev->lock);
|
||||
list_del(&sess_dev->dev_list);
|
||||
if (!sess_dev->readonly)
|
||||
@@ -534,7 +534,7 @@ rnbd_srv_get_or_create_srv_dev(struct block_device *bdev,
|
||||
static void rnbd_srv_fill_msg_open_rsp(struct rnbd_msg_open_rsp *rsp,
|
||||
struct rnbd_srv_sess_dev *sess_dev)
|
||||
{
|
||||
struct block_device *bdev = sess_dev->bdev_handle->bdev;
|
||||
struct block_device *bdev = file_bdev(sess_dev->bdev_file);
|
||||
|
||||
rsp->hdr.type = cpu_to_le16(RNBD_MSG_OPEN_RSP);
|
||||
rsp->device_id = cpu_to_le32(sess_dev->device_id);
|
||||
@@ -560,7 +560,7 @@ static void rnbd_srv_fill_msg_open_rsp(struct rnbd_msg_open_rsp *rsp,
|
||||
static struct rnbd_srv_sess_dev *
|
||||
rnbd_srv_create_set_sess_dev(struct rnbd_srv_session *srv_sess,
|
||||
const struct rnbd_msg_open *open_msg,
|
||||
struct bdev_handle *handle, bool readonly,
|
||||
struct file *bdev_file, bool readonly,
|
||||
struct rnbd_srv_dev *srv_dev)
|
||||
{
|
||||
struct rnbd_srv_sess_dev *sdev = rnbd_sess_dev_alloc(srv_sess);
|
||||
@@ -572,7 +572,7 @@ rnbd_srv_create_set_sess_dev(struct rnbd_srv_session *srv_sess,
|
||||
|
||||
strscpy(sdev->pathname, open_msg->dev_name, sizeof(sdev->pathname));
|
||||
|
||||
sdev->bdev_handle = handle;
|
||||
sdev->bdev_file = bdev_file;
|
||||
sdev->sess = srv_sess;
|
||||
sdev->dev = srv_dev;
|
||||
sdev->readonly = readonly;
|
||||
@@ -678,7 +678,7 @@ static int process_msg_open(struct rnbd_srv_session *srv_sess,
|
||||
struct rnbd_srv_dev *srv_dev;
|
||||
struct rnbd_srv_sess_dev *srv_sess_dev;
|
||||
const struct rnbd_msg_open *open_msg = msg;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
blk_mode_t open_flags = BLK_OPEN_READ;
|
||||
char *full_path;
|
||||
struct rnbd_msg_open_rsp *rsp = data;
|
||||
@@ -716,15 +716,15 @@ static int process_msg_open(struct rnbd_srv_session *srv_sess,
|
||||
goto reject;
|
||||
}
|
||||
|
||||
bdev_handle = bdev_open_by_path(full_path, open_flags, NULL, NULL);
|
||||
if (IS_ERR(bdev_handle)) {
|
||||
ret = PTR_ERR(bdev_handle);
|
||||
bdev_file = bdev_file_open_by_path(full_path, open_flags, NULL, NULL);
|
||||
if (IS_ERR(bdev_file)) {
|
||||
ret = PTR_ERR(bdev_file);
|
||||
pr_err("Opening device '%s' on session %s failed, failed to open the block device, err: %pe\n",
|
||||
full_path, srv_sess->sessname, bdev_handle);
|
||||
full_path, srv_sess->sessname, bdev_file);
|
||||
goto free_path;
|
||||
}
|
||||
|
||||
srv_dev = rnbd_srv_get_or_create_srv_dev(bdev_handle->bdev, srv_sess,
|
||||
srv_dev = rnbd_srv_get_or_create_srv_dev(file_bdev(bdev_file), srv_sess,
|
||||
open_msg->access_mode);
|
||||
if (IS_ERR(srv_dev)) {
|
||||
pr_err("Opening device '%s' on session %s failed, creating srv_dev failed, err: %pe\n",
|
||||
@@ -734,7 +734,7 @@ static int process_msg_open(struct rnbd_srv_session *srv_sess,
|
||||
}
|
||||
|
||||
srv_sess_dev = rnbd_srv_create_set_sess_dev(srv_sess, open_msg,
|
||||
bdev_handle,
|
||||
bdev_file,
|
||||
open_msg->access_mode == RNBD_ACCESS_RO,
|
||||
srv_dev);
|
||||
if (IS_ERR(srv_sess_dev)) {
|
||||
@@ -750,7 +750,7 @@ static int process_msg_open(struct rnbd_srv_session *srv_sess,
|
||||
*/
|
||||
mutex_lock(&srv_dev->lock);
|
||||
if (!srv_dev->dev_kobj.state_in_sysfs) {
|
||||
ret = rnbd_srv_create_dev_sysfs(srv_dev, bdev_handle->bdev);
|
||||
ret = rnbd_srv_create_dev_sysfs(srv_dev, file_bdev(bdev_file));
|
||||
if (ret) {
|
||||
mutex_unlock(&srv_dev->lock);
|
||||
rnbd_srv_err(srv_sess_dev,
|
||||
@@ -793,7 +793,7 @@ srv_dev_put:
|
||||
}
|
||||
rnbd_put_srv_dev(srv_dev);
|
||||
blkdev_put:
|
||||
bdev_release(bdev_handle);
|
||||
fput(bdev_file);
|
||||
free_path:
|
||||
kfree(full_path);
|
||||
reject:
|
||||
|
||||
@@ -46,7 +46,7 @@ struct rnbd_srv_dev {
|
||||
struct rnbd_srv_sess_dev {
|
||||
/* Entry inside rnbd_srv_dev struct */
|
||||
struct list_head dev_list;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
struct rnbd_srv_session *sess;
|
||||
struct rnbd_srv_dev *dev;
|
||||
struct kobject kobj;
|
||||
|
||||
@@ -465,7 +465,7 @@ static int xen_vbd_translate(struct phys_req *req, struct xen_blkif *blkif,
|
||||
}
|
||||
|
||||
req->dev = vbd->pdevice;
|
||||
req->bdev = vbd->bdev_handle->bdev;
|
||||
req->bdev = file_bdev(vbd->bdev_file);
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
@@ -969,7 +969,7 @@ static int dispatch_discard_io(struct xen_blkif_ring *ring,
|
||||
int err = 0;
|
||||
int status = BLKIF_RSP_OKAY;
|
||||
struct xen_blkif *blkif = ring->blkif;
|
||||
struct block_device *bdev = blkif->vbd.bdev_handle->bdev;
|
||||
struct block_device *bdev = file_bdev(blkif->vbd.bdev_file);
|
||||
struct phys_req preq;
|
||||
|
||||
xen_blkif_get(blkif);
|
||||
|
||||
@@ -221,7 +221,7 @@ struct xen_vbd {
|
||||
unsigned char type;
|
||||
/* phys device that this vbd maps to. */
|
||||
u32 pdevice;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
/* Cached size parameter. */
|
||||
sector_t size;
|
||||
unsigned int flush_support:1;
|
||||
@@ -360,7 +360,7 @@ struct pending_req {
|
||||
};
|
||||
|
||||
|
||||
#define vbd_sz(_v) bdev_nr_sectors((_v)->bdev_handle->bdev)
|
||||
#define vbd_sz(_v) bdev_nr_sectors(file_bdev((_v)->bdev_file))
|
||||
|
||||
#define xen_blkif_get(_b) (atomic_inc(&(_b)->refcnt))
|
||||
#define xen_blkif_put(_b) \
|
||||
|
||||
@@ -81,7 +81,7 @@ static void xen_update_blkif_status(struct xen_blkif *blkif)
|
||||
int i;
|
||||
|
||||
/* Not ready to connect? */
|
||||
if (!blkif->rings || !blkif->rings[0].irq || !blkif->vbd.bdev_handle)
|
||||
if (!blkif->rings || !blkif->rings[0].irq || !blkif->vbd.bdev_file)
|
||||
return;
|
||||
|
||||
/* Already connected? */
|
||||
@@ -99,13 +99,12 @@ static void xen_update_blkif_status(struct xen_blkif *blkif)
|
||||
return;
|
||||
}
|
||||
|
||||
err = sync_blockdev(blkif->vbd.bdev_handle->bdev);
|
||||
err = sync_blockdev(file_bdev(blkif->vbd.bdev_file));
|
||||
if (err) {
|
||||
xenbus_dev_error(blkif->be->dev, err, "block flush");
|
||||
return;
|
||||
}
|
||||
invalidate_inode_pages2(
|
||||
blkif->vbd.bdev_handle->bdev->bd_inode->i_mapping);
|
||||
invalidate_inode_pages2(blkif->vbd.bdev_file->f_mapping);
|
||||
|
||||
for (i = 0; i < blkif->nr_rings; i++) {
|
||||
ring = &blkif->rings[i];
|
||||
@@ -473,9 +472,9 @@ static void xenvbd_sysfs_delif(struct xenbus_device *dev)
|
||||
|
||||
static void xen_vbd_free(struct xen_vbd *vbd)
|
||||
{
|
||||
if (vbd->bdev_handle)
|
||||
bdev_release(vbd->bdev_handle);
|
||||
vbd->bdev_handle = NULL;
|
||||
if (vbd->bdev_file)
|
||||
fput(vbd->bdev_file);
|
||||
vbd->bdev_file = NULL;
|
||||
}
|
||||
|
||||
static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
|
||||
@@ -483,7 +482,7 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
|
||||
int cdrom)
|
||||
{
|
||||
struct xen_vbd *vbd;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
|
||||
vbd = &blkif->vbd;
|
||||
vbd->handle = handle;
|
||||
@@ -492,17 +491,17 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
|
||||
|
||||
vbd->pdevice = MKDEV(major, minor);
|
||||
|
||||
bdev_handle = bdev_open_by_dev(vbd->pdevice, vbd->readonly ?
|
||||
bdev_file = bdev_file_open_by_dev(vbd->pdevice, vbd->readonly ?
|
||||
BLK_OPEN_READ : BLK_OPEN_WRITE, NULL, NULL);
|
||||
|
||||
if (IS_ERR(bdev_handle)) {
|
||||
if (IS_ERR(bdev_file)) {
|
||||
pr_warn("xen_vbd_create: device %08x could not be opened\n",
|
||||
vbd->pdevice);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
vbd->bdev_handle = bdev_handle;
|
||||
if (vbd->bdev_handle->bdev->bd_disk == NULL) {
|
||||
vbd->bdev_file = bdev_file;
|
||||
if (file_bdev(vbd->bdev_file)->bd_disk == NULL) {
|
||||
pr_warn("xen_vbd_create: device %08x doesn't exist\n",
|
||||
vbd->pdevice);
|
||||
xen_vbd_free(vbd);
|
||||
@@ -510,14 +509,14 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
|
||||
}
|
||||
vbd->size = vbd_sz(vbd);
|
||||
|
||||
if (cdrom || disk_to_cdi(vbd->bdev_handle->bdev->bd_disk))
|
||||
if (cdrom || disk_to_cdi(file_bdev(vbd->bdev_file)->bd_disk))
|
||||
vbd->type |= VDISK_CDROM;
|
||||
if (vbd->bdev_handle->bdev->bd_disk->flags & GENHD_FL_REMOVABLE)
|
||||
if (file_bdev(vbd->bdev_file)->bd_disk->flags & GENHD_FL_REMOVABLE)
|
||||
vbd->type |= VDISK_REMOVABLE;
|
||||
|
||||
if (bdev_write_cache(bdev_handle->bdev))
|
||||
if (bdev_write_cache(file_bdev(bdev_file)))
|
||||
vbd->flush_support = true;
|
||||
if (bdev_max_secure_erase_sectors(bdev_handle->bdev))
|
||||
if (bdev_max_secure_erase_sectors(file_bdev(bdev_file)))
|
||||
vbd->discard_secure = true;
|
||||
|
||||
pr_debug("Successful creation of handle=%04x (dom=%u)\n",
|
||||
@@ -570,7 +569,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info
|
||||
struct xen_blkif *blkif = be->blkif;
|
||||
int err;
|
||||
int state = 0;
|
||||
struct block_device *bdev = be->blkif->vbd.bdev_handle->bdev;
|
||||
struct block_device *bdev = file_bdev(be->blkif->vbd.bdev_file);
|
||||
|
||||
if (!xenbus_read_unsigned(dev->nodename, "discard-enable", 1))
|
||||
return;
|
||||
@@ -932,7 +931,7 @@ again:
|
||||
}
|
||||
err = xenbus_printf(xbt, dev->nodename, "sector-size", "%lu",
|
||||
(unsigned long)bdev_logical_block_size(
|
||||
be->blkif->vbd.bdev_handle->bdev));
|
||||
file_bdev(be->blkif->vbd.bdev_file)));
|
||||
if (err) {
|
||||
xenbus_dev_fatal(dev, err, "writing %s/sector-size",
|
||||
dev->nodename);
|
||||
@@ -940,7 +939,7 @@ again:
|
||||
}
|
||||
err = xenbus_printf(xbt, dev->nodename, "physical-sector-size", "%u",
|
||||
bdev_physical_block_size(
|
||||
be->blkif->vbd.bdev_handle->bdev));
|
||||
file_bdev(be->blkif->vbd.bdev_file)));
|
||||
if (err)
|
||||
xenbus_dev_error(dev, err, "writing %s/physical-sector-size",
|
||||
dev->nodename);
|
||||
|
||||
@@ -426,11 +426,11 @@ static void reset_bdev(struct zram *zram)
|
||||
if (!zram->backing_dev)
|
||||
return;
|
||||
|
||||
bdev_release(zram->bdev_handle);
|
||||
fput(zram->bdev_file);
|
||||
/* hope filp_close flush all of IO */
|
||||
filp_close(zram->backing_dev, NULL);
|
||||
zram->backing_dev = NULL;
|
||||
zram->bdev_handle = NULL;
|
||||
zram->bdev_file = NULL;
|
||||
zram->disk->fops = &zram_devops;
|
||||
kvfree(zram->bitmap);
|
||||
zram->bitmap = NULL;
|
||||
@@ -476,7 +476,7 @@ static ssize_t backing_dev_store(struct device *dev,
|
||||
struct address_space *mapping;
|
||||
unsigned int bitmap_sz;
|
||||
unsigned long nr_pages, *bitmap = NULL;
|
||||
struct bdev_handle *bdev_handle = NULL;
|
||||
struct file *bdev_file = NULL;
|
||||
int err;
|
||||
struct zram *zram = dev_to_zram(dev);
|
||||
|
||||
@@ -513,11 +513,11 @@ static ssize_t backing_dev_store(struct device *dev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
bdev_handle = bdev_open_by_dev(inode->i_rdev,
|
||||
bdev_file = bdev_file_open_by_dev(inode->i_rdev,
|
||||
BLK_OPEN_READ | BLK_OPEN_WRITE, zram, NULL);
|
||||
if (IS_ERR(bdev_handle)) {
|
||||
err = PTR_ERR(bdev_handle);
|
||||
bdev_handle = NULL;
|
||||
if (IS_ERR(bdev_file)) {
|
||||
err = PTR_ERR(bdev_file);
|
||||
bdev_file = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -531,7 +531,7 @@ static ssize_t backing_dev_store(struct device *dev,
|
||||
|
||||
reset_bdev(zram);
|
||||
|
||||
zram->bdev_handle = bdev_handle;
|
||||
zram->bdev_file = bdev_file;
|
||||
zram->backing_dev = backing_dev;
|
||||
zram->bitmap = bitmap;
|
||||
zram->nr_pages = nr_pages;
|
||||
@@ -544,8 +544,8 @@ static ssize_t backing_dev_store(struct device *dev,
|
||||
out:
|
||||
kvfree(bitmap);
|
||||
|
||||
if (bdev_handle)
|
||||
bdev_release(bdev_handle);
|
||||
if (bdev_file)
|
||||
fput(bdev_file);
|
||||
|
||||
if (backing_dev)
|
||||
filp_close(backing_dev, NULL);
|
||||
@@ -587,7 +587,7 @@ static void read_from_bdev_async(struct zram *zram, struct page *page,
|
||||
{
|
||||
struct bio *bio;
|
||||
|
||||
bio = bio_alloc(zram->bdev_handle->bdev, 1, parent->bi_opf, GFP_NOIO);
|
||||
bio = bio_alloc(file_bdev(zram->bdev_file), 1, parent->bi_opf, GFP_NOIO);
|
||||
bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9);
|
||||
__bio_add_page(bio, page, PAGE_SIZE, 0);
|
||||
bio_chain(bio, parent);
|
||||
@@ -703,7 +703,7 @@ static ssize_t writeback_store(struct device *dev,
|
||||
continue;
|
||||
}
|
||||
|
||||
bio_init(&bio, zram->bdev_handle->bdev, &bio_vec, 1,
|
||||
bio_init(&bio, file_bdev(zram->bdev_file), &bio_vec, 1,
|
||||
REQ_OP_WRITE | REQ_SYNC);
|
||||
bio.bi_iter.bi_sector = blk_idx * (PAGE_SIZE >> 9);
|
||||
__bio_add_page(&bio, page, PAGE_SIZE, 0);
|
||||
@@ -785,7 +785,7 @@ static void zram_sync_read(struct work_struct *work)
|
||||
struct bio_vec bv;
|
||||
struct bio bio;
|
||||
|
||||
bio_init(&bio, zw->zram->bdev_handle->bdev, &bv, 1, REQ_OP_READ);
|
||||
bio_init(&bio, file_bdev(zw->zram->bdev_file), &bv, 1, REQ_OP_READ);
|
||||
bio.bi_iter.bi_sector = zw->entry * (PAGE_SIZE >> 9);
|
||||
__bio_add_page(&bio, zw->page, PAGE_SIZE, 0);
|
||||
zw->error = submit_bio_wait(&bio);
|
||||
|
||||
@@ -132,7 +132,7 @@ struct zram {
|
||||
spinlock_t wb_limit_lock;
|
||||
bool wb_limit_enable;
|
||||
u64 bd_wb_limit;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
unsigned long *bitmap;
|
||||
unsigned long nr_pages;
|
||||
#endif
|
||||
|
||||
@@ -300,7 +300,7 @@ struct cached_dev {
|
||||
struct list_head list;
|
||||
struct bcache_device disk;
|
||||
struct block_device *bdev;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
|
||||
struct cache_sb sb;
|
||||
struct cache_sb_disk *sb_disk;
|
||||
@@ -423,7 +423,7 @@ struct cache {
|
||||
|
||||
struct kobject kobj;
|
||||
struct block_device *bdev;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
|
||||
struct task_struct *alloc_thread;
|
||||
|
||||
|
||||
@@ -1369,8 +1369,8 @@ static CLOSURE_CALLBACK(cached_dev_free)
|
||||
if (dc->sb_disk)
|
||||
put_page(virt_to_page(dc->sb_disk));
|
||||
|
||||
if (dc->bdev_handle)
|
||||
bdev_release(dc->bdev_handle);
|
||||
if (dc->bdev_file)
|
||||
fput(dc->bdev_file);
|
||||
|
||||
wake_up(&unregister_wait);
|
||||
|
||||
@@ -1445,7 +1445,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size)
|
||||
/* Cached device - bcache superblock */
|
||||
|
||||
static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
|
||||
struct bdev_handle *bdev_handle,
|
||||
struct file *bdev_file,
|
||||
struct cached_dev *dc)
|
||||
{
|
||||
const char *err = "cannot allocate memory";
|
||||
@@ -1453,8 +1453,8 @@ static int register_bdev(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
|
||||
int ret = -ENOMEM;
|
||||
|
||||
memcpy(&dc->sb, sb, sizeof(struct cache_sb));
|
||||
dc->bdev_handle = bdev_handle;
|
||||
dc->bdev = bdev_handle->bdev;
|
||||
dc->bdev_file = bdev_file;
|
||||
dc->bdev = file_bdev(bdev_file);
|
||||
dc->sb_disk = sb_disk;
|
||||
|
||||
if (cached_dev_init(dc, sb->block_size << 9))
|
||||
@@ -2218,8 +2218,8 @@ void bch_cache_release(struct kobject *kobj)
|
||||
if (ca->sb_disk)
|
||||
put_page(virt_to_page(ca->sb_disk));
|
||||
|
||||
if (ca->bdev_handle)
|
||||
bdev_release(ca->bdev_handle);
|
||||
if (ca->bdev_file)
|
||||
fput(ca->bdev_file);
|
||||
|
||||
kfree(ca);
|
||||
module_put(THIS_MODULE);
|
||||
@@ -2339,18 +2339,18 @@ err_free:
|
||||
}
|
||||
|
||||
static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
|
||||
struct bdev_handle *bdev_handle,
|
||||
struct file *bdev_file,
|
||||
struct cache *ca)
|
||||
{
|
||||
const char *err = NULL; /* must be set for any error case */
|
||||
int ret = 0;
|
||||
|
||||
memcpy(&ca->sb, sb, sizeof(struct cache_sb));
|
||||
ca->bdev_handle = bdev_handle;
|
||||
ca->bdev = bdev_handle->bdev;
|
||||
ca->bdev_file = bdev_file;
|
||||
ca->bdev = file_bdev(bdev_file);
|
||||
ca->sb_disk = sb_disk;
|
||||
|
||||
if (bdev_max_discard_sectors((bdev_handle->bdev)))
|
||||
if (bdev_max_discard_sectors(file_bdev(bdev_file)))
|
||||
ca->discard = CACHE_DISCARD(&ca->sb);
|
||||
|
||||
ret = cache_alloc(ca);
|
||||
@@ -2361,20 +2361,20 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
|
||||
err = "cache_alloc(): cache device is too small";
|
||||
else
|
||||
err = "cache_alloc(): unknown error";
|
||||
pr_notice("error %pg: %s\n", bdev_handle->bdev, err);
|
||||
pr_notice("error %pg: %s\n", file_bdev(bdev_file), err);
|
||||
/*
|
||||
* If we failed here, it means ca->kobj is not initialized yet,
|
||||
* kobject_put() won't be called and there is no chance to
|
||||
* call bdev_release() to bdev in bch_cache_release(). So
|
||||
* we explicitly call bdev_release() here.
|
||||
* call fput() to bdev in bch_cache_release(). So
|
||||
* we explicitly call fput() on the block device here.
|
||||
*/
|
||||
bdev_release(bdev_handle);
|
||||
fput(bdev_file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (kobject_add(&ca->kobj, bdev_kobj(bdev_handle->bdev), "bcache")) {
|
||||
if (kobject_add(&ca->kobj, bdev_kobj(file_bdev(bdev_file)), "bcache")) {
|
||||
pr_notice("error %pg: error calling kobject_add\n",
|
||||
bdev_handle->bdev);
|
||||
file_bdev(bdev_file));
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -2388,7 +2388,7 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
|
||||
goto out;
|
||||
}
|
||||
|
||||
pr_info("registered cache device %pg\n", ca->bdev_handle->bdev);
|
||||
pr_info("registered cache device %pg\n", file_bdev(ca->bdev_file));
|
||||
|
||||
out:
|
||||
kobject_put(&ca->kobj);
|
||||
@@ -2446,7 +2446,7 @@ struct async_reg_args {
|
||||
char *path;
|
||||
struct cache_sb *sb;
|
||||
struct cache_sb_disk *sb_disk;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
void *holder;
|
||||
};
|
||||
|
||||
@@ -2457,7 +2457,7 @@ static void register_bdev_worker(struct work_struct *work)
|
||||
container_of(work, struct async_reg_args, reg_work.work);
|
||||
|
||||
mutex_lock(&bch_register_lock);
|
||||
if (register_bdev(args->sb, args->sb_disk, args->bdev_handle,
|
||||
if (register_bdev(args->sb, args->sb_disk, args->bdev_file,
|
||||
args->holder) < 0)
|
||||
fail = true;
|
||||
mutex_unlock(&bch_register_lock);
|
||||
@@ -2478,7 +2478,7 @@ static void register_cache_worker(struct work_struct *work)
|
||||
container_of(work, struct async_reg_args, reg_work.work);
|
||||
|
||||
/* blkdev_put() will be called in bch_cache_release() */
|
||||
if (register_cache(args->sb, args->sb_disk, args->bdev_handle,
|
||||
if (register_cache(args->sb, args->sb_disk, args->bdev_file,
|
||||
args->holder))
|
||||
fail = true;
|
||||
|
||||
@@ -2516,7 +2516,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
|
||||
char *path = NULL;
|
||||
struct cache_sb *sb;
|
||||
struct cache_sb_disk *sb_disk;
|
||||
struct bdev_handle *bdev_handle, *bdev_handle2;
|
||||
struct file *bdev_file, *bdev_file2;
|
||||
void *holder = NULL;
|
||||
ssize_t ret;
|
||||
bool async_registration = false;
|
||||
@@ -2549,15 +2549,15 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
|
||||
|
||||
ret = -EINVAL;
|
||||
err = "failed to open device";
|
||||
bdev_handle = bdev_open_by_path(strim(path), BLK_OPEN_READ, NULL, NULL);
|
||||
if (IS_ERR(bdev_handle))
|
||||
bdev_file = bdev_file_open_by_path(strim(path), BLK_OPEN_READ, NULL, NULL);
|
||||
if (IS_ERR(bdev_file))
|
||||
goto out_free_sb;
|
||||
|
||||
err = "failed to set blocksize";
|
||||
if (set_blocksize(bdev_handle->bdev, 4096))
|
||||
if (set_blocksize(file_bdev(bdev_file), 4096))
|
||||
goto out_blkdev_put;
|
||||
|
||||
err = read_super(sb, bdev_handle->bdev, &sb_disk);
|
||||
err = read_super(sb, file_bdev(bdev_file), &sb_disk);
|
||||
if (err)
|
||||
goto out_blkdev_put;
|
||||
|
||||
@@ -2569,13 +2569,13 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
|
||||
}
|
||||
|
||||
/* Now reopen in exclusive mode with proper holder */
|
||||
bdev_handle2 = bdev_open_by_dev(bdev_handle->bdev->bd_dev,
|
||||
bdev_file2 = bdev_file_open_by_dev(file_bdev(bdev_file)->bd_dev,
|
||||
BLK_OPEN_READ | BLK_OPEN_WRITE, holder, NULL);
|
||||
bdev_release(bdev_handle);
|
||||
bdev_handle = bdev_handle2;
|
||||
if (IS_ERR(bdev_handle)) {
|
||||
ret = PTR_ERR(bdev_handle);
|
||||
bdev_handle = NULL;
|
||||
fput(bdev_file);
|
||||
bdev_file = bdev_file2;
|
||||
if (IS_ERR(bdev_file)) {
|
||||
ret = PTR_ERR(bdev_file);
|
||||
bdev_file = NULL;
|
||||
if (ret == -EBUSY) {
|
||||
dev_t dev;
|
||||
|
||||
@@ -2610,7 +2610,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
|
||||
args->path = path;
|
||||
args->sb = sb;
|
||||
args->sb_disk = sb_disk;
|
||||
args->bdev_handle = bdev_handle;
|
||||
args->bdev_file = bdev_file;
|
||||
args->holder = holder;
|
||||
register_device_async(args);
|
||||
/* No wait and returns to user space */
|
||||
@@ -2619,14 +2619,14 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
|
||||
|
||||
if (SB_IS_BDEV(sb)) {
|
||||
mutex_lock(&bch_register_lock);
|
||||
ret = register_bdev(sb, sb_disk, bdev_handle, holder);
|
||||
ret = register_bdev(sb, sb_disk, bdev_file, holder);
|
||||
mutex_unlock(&bch_register_lock);
|
||||
/* blkdev_put() will be called in cached_dev_free() */
|
||||
if (ret < 0)
|
||||
goto out_free_sb;
|
||||
} else {
|
||||
/* blkdev_put() will be called in bch_cache_release() */
|
||||
ret = register_cache(sb, sb_disk, bdev_handle, holder);
|
||||
ret = register_cache(sb, sb_disk, bdev_file, holder);
|
||||
if (ret)
|
||||
goto out_free_sb;
|
||||
}
|
||||
@@ -2642,8 +2642,8 @@ out_free_holder:
|
||||
out_put_sb_page:
|
||||
put_page(virt_to_page(sb_disk));
|
||||
out_blkdev_put:
|
||||
if (bdev_handle)
|
||||
bdev_release(bdev_handle);
|
||||
if (bdev_file)
|
||||
fput(bdev_file);
|
||||
out_free_sb:
|
||||
kfree(sb);
|
||||
out_free_path:
|
||||
|
||||
@@ -726,7 +726,8 @@ static struct table_device *open_table_device(struct mapped_device *md,
|
||||
dev_t dev, blk_mode_t mode)
|
||||
{
|
||||
struct table_device *td;
|
||||
struct bdev_handle *bdev_handle;
|
||||
struct file *bdev_file;
|
||||
struct block_device *bdev;
|
||||
u64 part_off;
|
||||
int r;
|
||||
|
||||
@@ -735,34 +736,36 @@ static struct table_device *open_table_device(struct mapped_device *md,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
refcount_set(&td->count, 1);
|
||||
|
||||
bdev_handle = bdev_open_by_dev(dev, mode, _dm_claim_ptr, NULL);
|
||||
if (IS_ERR(bdev_handle)) {
|
||||
r = PTR_ERR(bdev_handle);
|
||||
bdev_file = bdev_file_open_by_dev(dev, mode, _dm_claim_ptr, NULL);
|
||||
if (IS_ERR(bdev_file)) {
|
||||
r = PTR_ERR(bdev_file);
|
||||
goto out_free_td;
|
||||
}
|
||||
|
||||
bdev = file_bdev(bdev_file);
|
||||
|
||||
/*
|
||||
* We can be called before the dm disk is added. In that case we can't
|
||||
* register the holder relation here. It will be done once add_disk was
|
||||
* called.
|
||||
*/
|
||||
if (md->disk->slave_dir) {
|
||||
r = bd_link_disk_holder(bdev_handle->bdev, md->disk);
|
||||
r = bd_link_disk_holder(bdev, md->disk);
|
||||
if (r)
|
||||
goto out_blkdev_put;
|
||||
}
|
||||
|
||||
td->dm_dev.mode = mode;
|
||||
td->dm_dev.bdev = bdev_handle->bdev;
|
||||
td->dm_dev.bdev_handle = bdev_handle;
|
||||
td->dm_dev.dax_dev = fs_dax_get_by_bdev(bdev_handle->bdev, &part_off,
|
||||
td->dm_dev.bdev = bdev;
|
||||
td->dm_dev.bdev_file = bdev_file;
|
||||
td->dm_dev.dax_dev = fs_dax_get_by_bdev(bdev, &part_off,
|
||||
NULL, NULL);
|
||||
format_dev_t(td->dm_dev.name, dev);
|
||||
list_add(&td->list, &md->table_devices);
|
||||
return td;
|
||||
|
||||
out_blkdev_put:
|
||||
bdev_release(bdev_handle);
|
||||
fput(bdev_file);
|
||||
out_free_td:
|
||||
kfree(td);
|
||||
return ERR_PTR(r);
|
||||
@@ -775,7 +778,7 @@ static void close_table_device(struct table_device *td, struct mapped_device *md
|
||||
{
|
||||
if (md->disk->slave_dir)
|
||||
bd_unlink_disk_holder(td->dm_dev.bdev, md->disk);
|
||||
bdev_release(td->dm_dev.bdev_handle);
|
||||
fput(td->dm_dev.bdev_file);
|
||||
put_dax(td->dm_dev.dax_dev);
|
||||
list_del(&td->list);
|
||||
kfree(td);
|
||||
|
||||
@@ -2582,7 +2582,7 @@ static void export_rdev(struct md_rdev *rdev, struct mddev *mddev)
|
||||
if (test_bit(AutoDetected, &rdev->flags))
|
||||
md_autodetect_dev(rdev->bdev->bd_dev);
|
||||
#endif
|
||||
bdev_release(rdev->bdev_handle);
|
||||
fput(rdev->bdev_file);
|
||||
rdev->bdev = NULL;
|
||||
kobject_put(&rdev->kobj);
|
||||
}
|
||||
@@ -3777,16 +3777,16 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe
|
||||
if (err)
|
||||
goto out_clear_rdev;
|
||||
|
||||
rdev->bdev_handle = bdev_open_by_dev(newdev,
|
||||
rdev->bdev_file = bdev_file_open_by_dev(newdev,
|
||||
BLK_OPEN_READ | BLK_OPEN_WRITE,
|
||||
super_format == -2 ? &claim_rdev : rdev, NULL);
|
||||
if (IS_ERR(rdev->bdev_handle)) {
|
||||
if (IS_ERR(rdev->bdev_file)) {
|
||||
pr_warn("md: could not open device unknown-block(%u,%u).\n",
|
||||
MAJOR(newdev), MINOR(newdev));
|
||||
err = PTR_ERR(rdev->bdev_handle);
|
||||
err = PTR_ERR(rdev->bdev_file);
|
||||
goto out_clear_rdev;
|
||||
}
|
||||
rdev->bdev = rdev->bdev_handle->bdev;
|
||||
rdev->bdev = file_bdev(rdev->bdev_file);
|
||||
|
||||
kobject_init(&rdev->kobj, &rdev_ktype);
|
||||
|
||||
@@ -3817,7 +3817,7 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe
|
||||
return rdev;
|
||||
|
||||
out_blkdev_put:
|
||||
bdev_release(rdev->bdev_handle);
|
||||
fput(rdev->bdev_file);
|
||||
out_clear_rdev:
|
||||
md_rdev_clear(rdev);
|
||||
out_free_rdev:
|
||||
|
||||
@@ -59,7 +59,7 @@ struct md_rdev {
|
||||
*/
|
||||
struct block_device *meta_bdev;
|
||||
struct block_device *bdev; /* block device handle */
|
||||
struct bdev_handle *bdev_handle; /* Handle from open for bdev */
|
||||
struct file *bdev_file; /* Handle from open for bdev */
|
||||
|
||||
struct page *sb_page, *bb_page;
|
||||
int sb_loaded;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user