From: Gleb C. <lna...@ya...> - 2024-04-25 13:10:56
|
Commit: 12f9b6e GitHub URL: https://github.com/SCST-project/scst/commit/12f9b6e681049a10203080dcc437a34153c590dd Author: Gleb Chesnokov Date: 2024-04-25T16:10:21+03:00 Log Message: ----------- scst_lib, scst_vdisk: Port to Linux kernel v6.9 Support for the following block layer changes in the Linux kernel v6.9: - f3a608827d1f ("bdev: open block device as files") - b1211a25c4fe ("bdev: make bdev_{release, open_by_dev}() private to block layer") Modified Paths: -------------- .gitignore | 1 + scst/include/scst.h | 10 ++ scst/src/dev_handlers/scst_vdisk.c | 98 +++++++-------- scst/src/scst_lib.c | 62 ++++++++- 4 files changed, 113 insertions(+), 58 deletions(-) =================================================================== diff --git a/.gitignore b/.gitignore index bcb84e6..9565728 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ *.orig *.sdtinfo.c *.sdtstub.S +*.out *~ .cache.mk .cache/ diff --git a/scst/include/scst.h b/scst/include/scst.h index 2e5aa57..301d106 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -5675,6 +5675,16 @@ int scst_scsi_exec_async(struct scst_cmd *cmd, void *data, int scst_get_file_mode(const char *path); bool scst_parent_dir_exists(const char *path); +struct scst_bdev_descriptor { + struct block_device *bdev; + void *priv; +}; + +int scst_open_bdev_by_path(const char *path, blk_mode_t mode, void *holder, + const struct blk_holder_ops *hops, + struct scst_bdev_descriptor *bdev_desc); +void scst_release_bdev(struct scst_bdev_descriptor *bdev_desc); + struct scst_data_descriptor { uint64_t sdd_lba; uint64_t sdd_blocks; diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index d8265cf..4f65d1a 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -190,7 +190,7 @@ struct scst_vdisk_dev { struct file *fd; struct file *dif_fd; - struct bdev_handle *bdev_handle; + struct scst_bdev_descriptor bdev_desc; struct bio_set *vdisk_bioset; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) struct bio_set vdisk_bioset_struct; @@ -494,7 +494,8 @@ out: static void vdisk_blockio_check_flush_support(struct scst_vdisk_dev *virt_dev) { - struct bdev_handle *bdev_handle; + struct scst_bdev_descriptor bdev_desc; + int rc; TRACE_ENTRY(); @@ -502,26 +503,26 @@ static void vdisk_blockio_check_flush_support(struct scst_vdisk_dev *virt_dev) virt_dev->wt_flag || !virt_dev->dev_active) goto out; - bdev_handle = bdev_open_by_path(virt_dev->filename, BLK_OPEN_READ, NULL, NULL); - if (IS_ERR(bdev_handle)) { - if (PTR_ERR(bdev_handle) == -EMEDIUMTYPE) + rc = scst_open_bdev_by_path(virt_dev->filename, BLK_OPEN_READ, NULL, NULL, &bdev_desc); + if (rc) { + if (rc == -EMEDIUMTYPE) TRACE(TRACE_MINOR, "Unable to open %s with EMEDIUMTYPE, DRBD passive?", virt_dev->filename); else - PRINT_ERROR("bdev_open_by_path(%s) failed: %ld", - virt_dev->filename, PTR_ERR(bdev_handle)); + PRINT_ERROR("bdev_open_by_path(%s) failed: %d", + virt_dev->filename, rc); goto out; } - if (vdisk_blockio_flush(bdev_handle->bdev, GFP_KERNEL, false, NULL, false) != 0) { + if (vdisk_blockio_flush(bdev_desc.bdev, GFP_KERNEL, false, NULL, false) != 0) { PRINT_WARNING( "Device %s doesn't support barriers, switching to NV_CACHE mode. Read README for more details.", virt_dev->filename); virt_dev->nv_cache = 1; } - bdev_release(bdev_handle); + scst_release_bdev(&bdev_desc); out: TRACE_EXIT(); @@ -536,7 +537,7 @@ static bool vdisk_supports_active(const struct scst_vdisk_dev *virt_dev) static void vdisk_check_tp_support(struct scst_vdisk_dev *virt_dev) { - struct bdev_handle *bdev_handle = NULL; + struct scst_bdev_descriptor bdev_desc; struct file *fd = NULL; bool fd_open = false; int res; @@ -549,8 +550,8 @@ static void vdisk_check_tp_support(struct scst_vdisk_dev *virt_dev) goto check; if (virt_dev->blockio) { - bdev_handle = bdev_open_by_path(virt_dev->filename, BLK_OPEN_READ, NULL, NULL); - res = PTR_ERR_OR_ZERO(bdev_handle); + res = scst_open_bdev_by_path(virt_dev->filename, BLK_OPEN_READ, NULL, NULL, + &bdev_desc); } else { fd = filp_open(virt_dev->filename, O_LARGEFILE, 0600); res = PTR_ERR_OR_ZERO(fd); @@ -573,10 +574,10 @@ static void vdisk_check_tp_support(struct scst_vdisk_dev *virt_dev) (!defined(RHEL_RELEASE_CODE) || \ RHEL_RELEASE_CODE -0 < RHEL_RELEASE_VERSION(9, 1)) virt_dev->dev_thin_provisioned = - blk_queue_discard(bdev_get_queue(bdev_handle->bdev)); + blk_queue_discard(bdev_get_queue(bdev_desc.bdev)); #else virt_dev->dev_thin_provisioned = - !!bdev_max_discard_sectors(bdev_handle->bdev); + !!bdev_max_discard_sectors(bdev_desc.bdev); #endif } else { virt_dev->dev_thin_provisioned = (fd->f_op->fallocate != NULL); @@ -613,7 +614,7 @@ check: struct request_queue *q; sBUG_ON(!fd_open); - q = bdev_get_queue(bdev_handle->bdev); + q = bdev_get_queue(bdev_desc.bdev); virt_dev->unmap_opt_gran = q->limits.discard_granularity >> block_shift; virt_dev->unmap_align = q->limits.discard_alignment >> block_shift; if (virt_dev->unmap_opt_gran == virt_dev->unmap_align) @@ -645,7 +646,7 @@ check: if (fd_open) { if (virt_dev->blockio) - bdev_release(bdev_handle); + scst_release_bdev(&bdev_desc); else filp_close(fd, NULL); } @@ -962,21 +963,19 @@ out: #if defined(CONFIG_BLK_DEV_INTEGRITY) static int vdisk_init_block_integrity(struct scst_vdisk_dev *virt_dev) { - int res; struct scst_device *dev = virt_dev->dev; - struct bdev_handle *bdev_handle; + struct scst_bdev_descriptor bdev_desc; struct blk_integrity *bi; const char *bi_profile_name; + int res; TRACE_ENTRY(); - bdev_handle = bdev_open_by_path(virt_dev->filename, BLK_OPEN_READ, NULL, NULL); - if (IS_ERR(bdev_handle)) { - res = PTR_ERR(bdev_handle); + res = scst_open_bdev_by_path(virt_dev->filename, BLK_OPEN_READ, NULL, NULL, &bdev_desc); + if (res) goto out; - } - bi = bdev_get_integrity(bdev_handle->bdev); + bi = bdev_get_integrity(bdev_desc.bdev); if (bi == NULL) { TRACE_DBG("Block integrity not supported"); goto out_no_bi; @@ -1048,7 +1047,7 @@ out_no_bi: res = 0; out_close: - bdev_release(bdev_handle); + scst_release_bdev(&bdev_desc); out: TRACE_EXIT_RES(res); @@ -1297,7 +1296,7 @@ static void vdisk_detach(struct scst_device *dev) static bool vdisk_is_open(const struct scst_vdisk_dev *virt_dev) { - return virt_dev->fd || virt_dev->bdev_handle; + return virt_dev->fd || virt_dev->bdev_desc.bdev; } static int vdisk_open_fd(struct scst_vdisk_dev *virt_dev, bool read_only) @@ -1317,16 +1316,14 @@ static int vdisk_open_fd(struct scst_vdisk_dev *virt_dev, bool read_only) if (!read_only) bdev_mode |= BLK_OPEN_WRITE; - virt_dev->bdev_handle = bdev_open_by_path(virt_dev->filename, bdev_mode, virt_dev, - NULL); - res = PTR_ERR_OR_ZERO(virt_dev->bdev_handle); + res = scst_open_bdev_by_path(virt_dev->filename, bdev_mode, virt_dev, NULL, + &virt_dev->bdev_desc); } else { - virt_dev->fd = vdev_open_fd(virt_dev, virt_dev->filename, - read_only); + virt_dev->fd = vdev_open_fd(virt_dev, virt_dev->filename, read_only); res = PTR_ERR_OR_ZERO(virt_dev->fd); } if (res) { - virt_dev->bdev_handle = NULL; + scst_release_bdev(&virt_dev->bdev_desc); virt_dev->fd = NULL; goto out; } @@ -1336,7 +1333,7 @@ static int vdisk_open_fd(struct scst_vdisk_dev *virt_dev, bool read_only) * characteristics. */ if (virt_dev->blockio && !virt_dev->opt_trans_len_set) - virt_dev->opt_trans_len = bdev_io_opt(virt_dev->bdev_handle->bdev) ? : + virt_dev->opt_trans_len = bdev_io_opt(virt_dev->bdev_desc.bdev) ? : virt_dev->opt_trans_len; if (virt_dev->dif_filename != NULL) { @@ -1350,15 +1347,14 @@ static int vdisk_open_fd(struct scst_vdisk_dev *virt_dev, bool read_only) } TRACE_DBG("virt_dev %s: fd %p %p open (dif_fd %p)", virt_dev->name, - virt_dev->fd, virt_dev->bdev_handle, virt_dev->dif_fd); + virt_dev->fd, virt_dev->bdev_desc.bdev, virt_dev->dif_fd); out: return res; out_close_fd: if (virt_dev->blockio) { - bdev_release(virt_dev->bdev_handle); - virt_dev->bdev_handle = NULL; + scst_release_bdev(&virt_dev->bdev_desc); } else { filp_close(virt_dev->fd, NULL); virt_dev->fd = NULL; @@ -1369,11 +1365,10 @@ out_close_fd: static void vdisk_close_fd(struct scst_vdisk_dev *virt_dev) { TRACE_DBG("virt_dev %s: closing fd %p %p (dif_fd %p)", virt_dev->name, - virt_dev->fd, virt_dev->bdev_handle, virt_dev->dif_fd); + virt_dev->fd, virt_dev->bdev_desc.bdev, virt_dev->dif_fd); - if (virt_dev->bdev_handle) { - bdev_release(virt_dev->bdev_handle); - virt_dev->bdev_handle = NULL; + if (virt_dev->bdev_desc.bdev) { + scst_release_bdev(&virt_dev->bdev_desc); } else if (virt_dev->fd) { filp_close(virt_dev->fd, NULL); virt_dev->fd = NULL; @@ -1459,7 +1454,7 @@ static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev) } } else { virt_dev->fd = NULL; - virt_dev->bdev_handle = NULL; + scst_release_bdev(&virt_dev->bdev_desc); virt_dev->dif_fd = NULL; } @@ -1545,8 +1540,7 @@ static int vdisk_fsync_blockio(loff_t loff, goto out; } - res = vdisk_blockio_flush(virt_dev->bdev_handle->bdev, gfp_flags, true, - cmd, async); + res = vdisk_blockio_flush(virt_dev->bdev_desc.bdev, gfp_flags, true, cmd, async); out: TRACE_EXIT_RES(res); @@ -1857,7 +1851,7 @@ static int vdisk_unmap_range(struct scst_cmd *cmd, (unsigned long long)start_lba, blocks); if (virt_dev->blockio) { - struct block_device *bdev = virt_dev->bdev_handle->bdev; + struct block_device *bdev = virt_dev->bdev_desc.bdev; sector_t start_sector = start_lba << (cmd->dev->block_shift - 9); sector_t nr_sects = blocks << (cmd->dev->block_shift - 9); gfp_t gfp = cmd->cmd_gfp_mask; @@ -2871,7 +2865,7 @@ static ssize_t blockio_read_sync(struct scst_vdisk_dev *virt_dev, void *buf, struct bio_priv_sync s = { COMPLETION_INITIALIZER_ONSTACK(s.c), 0, }; - struct block_device *bdev = virt_dev->bdev_handle->bdev; + struct block_device *bdev = virt_dev->bdev_desc.bdev; const bool is_vmalloc = is_vmalloc_addr(buf); struct bio *bio; void *p; @@ -3407,7 +3401,7 @@ static enum scst_exec_res blockio_exec(struct scst_cmd *cmd) if (unlikely(!vdisk_parse_offset(&p, cmd))) goto err; - if (unlikely(virt_dev->bdev_handle == NULL)) { + if (unlikely(virt_dev->bdev_desc.bdev == NULL)) { if (!vdisk_no_fd_allowed_commands(cmd)) { /* * We should not get here, unless the user space @@ -4996,8 +4990,8 @@ static enum compl_status_e vdisk_exec_read_capacity16(struct vdisk_cmd_params *p /* LOGICAL BLOCKS PER PHYSICAL BLOCK EXPONENT */ if (virt_dev->lb_per_pb_exp) { - struct request_queue *q = virt_dev->bdev_handle ? - bdev_get_queue(virt_dev->bdev_handle->bdev) : NULL; + struct request_queue *q = virt_dev->bdev_desc.bdev ? + bdev_get_queue(virt_dev->bdev_desc.bdev) : NULL; uint32_t physical_blocksize = q ? queue_physical_block_size(q) : 4096; buffer[13] = max(ilog2(physical_blocksize) - ilog2(blocksize), 0); } @@ -5926,7 +5920,7 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) struct scst_device *dev = cmd->dev; struct scst_vdisk_dev *virt_dev = dev->dh_priv; int block_shift = dev->block_shift; - struct block_device *bdev = virt_dev->bdev_handle->bdev; + struct block_device *bdev = virt_dev->bdev_desc.bdev; struct bio_set *bs = virt_dev->vdisk_bioset; struct request_queue *q = bdev_get_queue(bdev); int length, max_nr_vecs = 0, offset; @@ -6597,7 +6591,7 @@ static int vdisk_resync_size(struct scst_vdisk_dev *virt_dev) sBUG_ON(virt_dev->nullio); sBUG_ON(!virt_dev->filename); - if ((!virt_dev->fd && !virt_dev->bdev_handle) || !virt_dev->dev_active) { + if ((!virt_dev->fd && !virt_dev->bdev_desc.bdev) || !virt_dev->dev_active) { res = -EMEDIUMTYPE; goto out; } @@ -7645,7 +7639,7 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev, char *buffer) err = 0; virt_dev->filename = NULL; virt_dev->fd = NULL; - virt_dev->bdev_handle = NULL; + scst_release_bdev(&virt_dev->bdev_desc); } virt_dev->file_size = err; @@ -7705,8 +7699,8 @@ static ssize_t vdisk_sysfs_sync_store(struct kobject *kobj, if (virt_dev->nullio) res = 0; else if (virt_dev->blockio) - res = vdisk_blockio_flush(virt_dev->bdev_handle->bdev, GFP_KERNEL, false, - NULL, false); + res = vdisk_blockio_flush(virt_dev->bdev_desc.bdev, GFP_KERNEL, false, NULL, + false); else res = __vdisk_fsync_fileio(0, i_size_read(file_inode(virt_dev->fd)), dev, NULL, virt_dev->fd); diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index c514795..bbb4c61 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -5937,6 +5937,53 @@ static void scst_complete_request_sense(struct scst_cmd *req_cmd) return; } +int scst_open_bdev_by_path(const char *path, blk_mode_t mode, void *holder, + const struct blk_holder_ops *hops, + struct scst_bdev_descriptor *bdev_desc) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 9, 0) + struct bdev_handle *bdev_handle; + + bdev_handle = bdev_open_by_path(path, mode, holder, hops); + if (IS_ERR(bdev_handle)) + return PTR_ERR(bdev_handle); + + bdev_desc->bdev = bdev_handle->bdev; + bdev_desc->priv = bdev_handle; +#else + struct file *bdev_file; + + bdev_file = bdev_file_open_by_path(path, mode, holder, hops); + if (IS_ERR(bdev_file)) + return PTR_ERR(bdev_file); + + bdev_desc->bdev = file_bdev(bdev_file); + bdev_desc->priv = bdev_file; +#endif + + return 0; +} +EXPORT_SYMBOL(scst_open_bdev_by_path); + +void scst_release_bdev(struct scst_bdev_descriptor *bdev_desc) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 9, 0) + struct bdev_handle *bdev_handle = bdev_desc->priv; + + if (bdev_handle) + bdev_release(bdev_handle); +#else + struct file *bdev_file = bdev_desc->priv; + + if (bdev_file) + fput(bdev_file); +#endif + + bdev_desc->bdev = NULL; + bdev_desc->priv = NULL; +} +EXPORT_SYMBOL(scst_release_bdev); + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) static int scst_cmp_fs_ds(void) { @@ -5980,14 +6027,17 @@ EXPORT_SYMBOL(scst_file_size); */ loff_t scst_bdev_size(const char *path) { - struct bdev_handle *bdev_handle; + struct scst_bdev_descriptor bdev_desc; loff_t res; + int rc; - bdev_handle = bdev_open_by_path(path, BLK_OPEN_READ, NULL, NULL); - if (IS_ERR(bdev_handle)) - return PTR_ERR(bdev_handle); - res = i_size_read(bdev_handle->bdev->bd_inode); - bdev_release(bdev_handle); + rc = scst_open_bdev_by_path(path, BLK_OPEN_READ, NULL, NULL, &bdev_desc); + if (rc) + return rc; + + res = i_size_read(bdev_desc.bdev->bd_inode); + + scst_release_bdev(&bdev_desc); return res; } EXPORT_SYMBOL(scst_bdev_size); |