static int bl_parse_scsi(struct nfs_server *server, struct pnfs_block_dev *d, struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask) { struct pnfs_block_volume *v = &volumes[idx]; struct block_device *bdev; const struct pr_ops *ops; int error; if (!bl_validate_designator(v)) return -EINVAL; bdev = bl_open_dm_mpath_udev_path(v); if (IS_ERR(bdev)) bdev = bl_open_udev_path(v); if (IS_ERR(bdev)) return PTR_ERR(bdev); d->bdev = bdev; d->len = i_size_read(d->bdev->bd_inode); d->map = bl_map_simple; d->pr_key = v->scsi.pr_key; pr_info("pNFS: using block device %s (reservation key 0x%llx)\n", d->bdev->bd_disk->disk_name, d->pr_key); ops = d->bdev->bd_disk->fops->pr_ops; if (!ops) { pr_err("pNFS: block device %s does not support reservations.", d->bdev->bd_disk->disk_name); error = -EINVAL; goto out_blkdev_put; } error = ops->pr_register(d->bdev, 0, d->pr_key, true); if (error) { pr_err("pNFS: failed to register key for block device %s.", d->bdev->bd_disk->disk_name); goto out_blkdev_put; } d->pr_registered = true; return 0; out_blkdev_put: blkdev_put(d->bdev, FMODE_READ | FMODE_WRITE); return error; }
static int bl_parse_scsi(struct nfs_server *server, struct pnfs_block_dev *d, struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask) { struct pnfs_block_volume *v = &volumes[idx]; const struct pr_ops *ops; const char *devname; int error; if (!bl_validate_designator(v)) return -EINVAL; switch (v->scsi.designator_len) { case 8: devname = kasprintf(GFP_KERNEL, "/dev/disk/by-id/wwn-0x%8phN", v->scsi.designator); break; case 12: devname = kasprintf(GFP_KERNEL, "/dev/disk/by-id/wwn-0x%12phN", v->scsi.designator); break; case 16: devname = kasprintf(GFP_KERNEL, "/dev/disk/by-id/wwn-0x%16phN", v->scsi.designator); break; default: return -EINVAL; } d->bdev = blkdev_get_by_path(devname, FMODE_READ, NULL); if (IS_ERR(d->bdev)) { pr_warn("pNFS: failed to open device %s (%ld)\n", devname, PTR_ERR(d->bdev)); kfree(devname); return PTR_ERR(d->bdev); } kfree(devname); d->len = i_size_read(d->bdev->bd_inode); d->map = bl_map_simple; d->pr_key = v->scsi.pr_key; pr_info("pNFS: using block device %s (reservation key 0x%llx)\n", d->bdev->bd_disk->disk_name, d->pr_key); ops = d->bdev->bd_disk->fops->pr_ops; if (!ops) { pr_err("pNFS: block device %s does not support reservations.", d->bdev->bd_disk->disk_name); error = -EINVAL; goto out_blkdev_put; } error = ops->pr_register(d->bdev, 0, d->pr_key, true); if (error) { pr_err("pNFS: failed to register key for block device %s.", d->bdev->bd_disk->disk_name); goto out_blkdev_put; } d->pr_registered = true; return 0; out_blkdev_put: blkdev_put(d->bdev, FMODE_READ); return error; }