Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-4.4/reservations' of git://git.kernel.dk/linux-block

Pull block reservation support from Jens Axboe:
"This adds support for persistent reservations, both at the core level,
as well as for sd and NVMe"

[ Background from the docs: "Persistent Reservations allow restricting
access to block devices to specific initiators in a shared storage
setup. All implementations are expected to ensure the reservations
survive a power loss and cover all connections in a multi path
environment" ]

* 'for-4.4/reservations' of git://git.kernel.dk/linux-block:
NVMe: Precedence error in nvme_pr_clear()
nvme: add missing endianess annotations in nvme_pr_command
NVMe: Add persistent reservation ops
sd: implement the Persistent Reservation API
block: add an API for Persistent Reservations
block: cleanup blkdev_ioctl

+609 -101
+119
Documentation/block/pr.txt
··· 1 + 2 + Block layer support for Persistent Reservations 3 + =============================================== 4 + 5 + The Linux kernel supports a user space interface for simplified 6 + Persistent Reservations which map to block devices that support 7 + these (like SCSI). Persistent Reservations allow restricting 8 + access to block devices to specific initiators in a shared storage 9 + setup. 10 + 11 + This document gives a general overview of the support ioctl commands. 12 + For a more detailed reference please refer the the SCSI Primary 13 + Commands standard, specifically the section on Reservations and the 14 + "PERSISTENT RESERVE IN" and "PERSISTENT RESERVE OUT" commands. 15 + 16 + All implementations are expected to ensure the reservations survive 17 + a power loss and cover all connections in a multi path environment. 18 + These behaviors are optional in SPC but will be automatically applied 19 + by Linux. 20 + 21 + 22 + The following types of reservations are supported: 23 + -------------------------------------------------- 24 + 25 + - PR_WRITE_EXCLUSIVE 26 + 27 + Only the initiator that owns the reservation can write to the 28 + device. Any initiator can read from the device. 29 + 30 + - PR_EXCLUSIVE_ACCESS 31 + 32 + Only the initiator that owns the reservation can access the 33 + device. 34 + 35 + - PR_WRITE_EXCLUSIVE_REG_ONLY 36 + 37 + Only initiators with a registered key can write to the device, 38 + Any initiator can read from the device. 39 + 40 + - PR_EXCLUSIVE_ACCESS_REG_ONLY 41 + 42 + Only initiators with a registered key can access the device. 43 + 44 + - PR_WRITE_EXCLUSIVE_ALL_REGS 45 + 46 + Only initiators with a registered key can write to the device, 47 + Any initiator can read from the device. 48 + All initiators with a registered key are considered reservation 49 + holders. 50 + Please reference the SPC spec on the meaning of a reservation 51 + holder if you want to use this type. 52 + 53 + - PR_EXCLUSIVE_ACCESS_ALL_REGS 54 + 55 + Only initiators with a registered key can access the device. 56 + All initiators with a registered key are considered reservation 57 + holders. 58 + Please reference the SPC spec on the meaning of a reservation 59 + holder if you want to use this type. 60 + 61 + 62 + The following ioctl are supported: 63 + ---------------------------------- 64 + 65 + 1. IOC_PR_REGISTER 66 + 67 + This ioctl command registers a new reservation if the new_key argument 68 + is non-null. If no existing reservation exists old_key must be zero, 69 + if an existing reservation should be replaced old_key must contain 70 + the old reservation key. 71 + 72 + If the new_key argument is 0 it unregisters the existing reservation passed 73 + in old_key. 74 + 75 + 76 + 2. IOC_PR_RESERVE 77 + 78 + This ioctl command reserves the device and thus restricts access for other 79 + devices based on the type argument. The key argument must be the existing 80 + reservation key for the device as acquired by the IOC_PR_REGISTER, 81 + IOC_PR_REGISTER_IGNORE, IOC_PR_PREEMPT or IOC_PR_PREEMPT_ABORT commands. 82 + 83 + 84 + 3. IOC_PR_RELEASE 85 + 86 + This ioctl command releases the reservation specified by key and flags 87 + and thus removes any access restriction implied by it. 88 + 89 + 90 + 4. IOC_PR_PREEMPT 91 + 92 + This ioctl command releases the existing reservation referred to by 93 + old_key and replaces it with a a new reservation of type for the 94 + reservation key new_key. 95 + 96 + 97 + 5. IOC_PR_PREEMPT_ABORT 98 + 99 + This ioctl command works like IOC_PR_PREEMPT except that it also aborts 100 + any outstanding command sent over a connection identified by old_key. 101 + 102 + 6. IOC_PR_CLEAR 103 + 104 + This ioctl command unregisters both key and any other reservation key 105 + registered with the device and drops any existing reservation. 106 + 107 + 108 + Flags 109 + ----- 110 + 111 + All the ioctls have a flag field. Currently only one flag is supported: 112 + 113 + - PR_FL_IGNORE_KEY 114 + 115 + Ignore the existing reservation key. This is commonly supported for 116 + IOC_PR_REGISTER, and some implementation may support the flag for 117 + IOC_PR_RESERVE. 118 + 119 + For all unknown flags the kernel will return -EOPNOTSUPP.
+231 -101
block/ioctl.c
··· 7 7 #include <linux/backing-dev.h> 8 8 #include <linux/fs.h> 9 9 #include <linux/blktrace_api.h> 10 + #include <linux/pr.h> 10 11 #include <asm/uaccess.h> 11 12 12 13 static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user *arg) ··· 194 193 } 195 194 EXPORT_SYMBOL(blkdev_reread_part); 196 195 197 - static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, 198 - uint64_t len, int secure) 196 + static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode, 197 + unsigned long arg, unsigned long flags) 199 198 { 200 - unsigned long flags = 0; 199 + uint64_t range[2]; 200 + uint64_t start, len; 201 + 202 + if (!(mode & FMODE_WRITE)) 203 + return -EBADF; 204 + 205 + if (copy_from_user(range, (void __user *)arg, sizeof(range))) 206 + return -EFAULT; 207 + 208 + start = range[0]; 209 + len = range[1]; 201 210 202 211 if (start & 511) 203 212 return -EINVAL; ··· 218 207 219 208 if (start + len > (i_size_read(bdev->bd_inode) >> 9)) 220 209 return -EINVAL; 221 - if (secure) 222 - flags |= BLKDEV_DISCARD_SECURE; 223 210 return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags); 224 211 } 225 212 226 - static int blk_ioctl_zeroout(struct block_device *bdev, uint64_t start, 227 - uint64_t len) 213 + static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode, 214 + unsigned long arg) 228 215 { 216 + uint64_t range[2]; 217 + uint64_t start, len; 218 + 219 + if (!(mode & FMODE_WRITE)) 220 + return -EBADF; 221 + 222 + if (copy_from_user(range, (void __user *)arg, sizeof(range))) 223 + return -EFAULT; 224 + 225 + start = range[0]; 226 + len = range[1]; 227 + 229 228 if (start & 511) 230 229 return -EINVAL; 231 230 if (len & 511) ··· 296 275 */ 297 276 EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl); 298 277 278 + static int blkdev_pr_register(struct block_device *bdev, 279 + struct pr_registration __user *arg) 280 + { 281 + const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; 282 + struct pr_registration reg; 283 + 284 + if (!capable(CAP_SYS_ADMIN)) 285 + return -EPERM; 286 + if (!ops || !ops->pr_register) 287 + return -EOPNOTSUPP; 288 + if (copy_from_user(&reg, arg, sizeof(reg))) 289 + return -EFAULT; 290 + 291 + if (reg.flags & ~PR_FL_IGNORE_KEY) 292 + return -EOPNOTSUPP; 293 + return ops->pr_register(bdev, reg.old_key, reg.new_key, reg.flags); 294 + } 295 + 296 + static int blkdev_pr_reserve(struct block_device *bdev, 297 + struct pr_reservation __user *arg) 298 + { 299 + const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; 300 + struct pr_reservation rsv; 301 + 302 + if (!capable(CAP_SYS_ADMIN)) 303 + return -EPERM; 304 + if (!ops || !ops->pr_reserve) 305 + return -EOPNOTSUPP; 306 + if (copy_from_user(&rsv, arg, sizeof(rsv))) 307 + return -EFAULT; 308 + 309 + if (rsv.flags & ~PR_FL_IGNORE_KEY) 310 + return -EOPNOTSUPP; 311 + return ops->pr_reserve(bdev, rsv.key, rsv.type, rsv.flags); 312 + } 313 + 314 + static int blkdev_pr_release(struct block_device *bdev, 315 + struct pr_reservation __user *arg) 316 + { 317 + const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; 318 + struct pr_reservation rsv; 319 + 320 + if (!capable(CAP_SYS_ADMIN)) 321 + return -EPERM; 322 + if (!ops || !ops->pr_release) 323 + return -EOPNOTSUPP; 324 + if (copy_from_user(&rsv, arg, sizeof(rsv))) 325 + return -EFAULT; 326 + 327 + if (rsv.flags) 328 + return -EOPNOTSUPP; 329 + return ops->pr_release(bdev, rsv.key, rsv.type); 330 + } 331 + 332 + static int blkdev_pr_preempt(struct block_device *bdev, 333 + struct pr_preempt __user *arg, bool abort) 334 + { 335 + const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; 336 + struct pr_preempt p; 337 + 338 + if (!capable(CAP_SYS_ADMIN)) 339 + return -EPERM; 340 + if (!ops || !ops->pr_preempt) 341 + return -EOPNOTSUPP; 342 + if (copy_from_user(&p, arg, sizeof(p))) 343 + return -EFAULT; 344 + 345 + if (p.flags) 346 + return -EOPNOTSUPP; 347 + return ops->pr_preempt(bdev, p.old_key, p.new_key, p.type, abort); 348 + } 349 + 350 + static int blkdev_pr_clear(struct block_device *bdev, 351 + struct pr_clear __user *arg) 352 + { 353 + const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; 354 + struct pr_clear c; 355 + 356 + if (!capable(CAP_SYS_ADMIN)) 357 + return -EPERM; 358 + if (!ops || !ops->pr_clear) 359 + return -EOPNOTSUPP; 360 + if (copy_from_user(&c, arg, sizeof(c))) 361 + return -EFAULT; 362 + 363 + if (c.flags) 364 + return -EOPNOTSUPP; 365 + return ops->pr_clear(bdev, c.key); 366 + } 367 + 299 368 /* 300 369 * Is it an unrecognized ioctl? The correct returns are either 301 370 * ENOTTY (final) or ENOIOCTLCMD ("I don't know this one, try a ··· 406 295 ret == -ENOIOCTLCMD; 407 296 } 408 297 298 + static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode, 299 + unsigned cmd, unsigned long arg) 300 + { 301 + int ret; 302 + 303 + if (!capable(CAP_SYS_ADMIN)) 304 + return -EACCES; 305 + 306 + ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); 307 + if (!is_unrecognized_ioctl(ret)) 308 + return ret; 309 + 310 + fsync_bdev(bdev); 311 + invalidate_bdev(bdev); 312 + return 0; 313 + } 314 + 315 + static int blkdev_roset(struct block_device *bdev, fmode_t mode, 316 + unsigned cmd, unsigned long arg) 317 + { 318 + int ret, n; 319 + 320 + ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); 321 + if (!is_unrecognized_ioctl(ret)) 322 + return ret; 323 + if (!capable(CAP_SYS_ADMIN)) 324 + return -EACCES; 325 + if (get_user(n, (int __user *)arg)) 326 + return -EFAULT; 327 + set_device_ro(bdev, n); 328 + return 0; 329 + } 330 + 331 + static int blkdev_getgeo(struct block_device *bdev, 332 + struct hd_geometry __user *argp) 333 + { 334 + struct gendisk *disk = bdev->bd_disk; 335 + struct hd_geometry geo; 336 + int ret; 337 + 338 + if (!argp) 339 + return -EINVAL; 340 + if (!disk->fops->getgeo) 341 + return -ENOTTY; 342 + 343 + /* 344 + * We need to set the startsect first, the driver may 345 + * want to override it. 346 + */ 347 + memset(&geo, 0, sizeof(geo)); 348 + geo.start = get_start_sect(bdev); 349 + ret = disk->fops->getgeo(bdev, &geo); 350 + if (ret) 351 + return ret; 352 + if (copy_to_user(argp, &geo, sizeof(geo))) 353 + return -EFAULT; 354 + return 0; 355 + } 356 + 357 + /* set the logical block size */ 358 + static int blkdev_bszset(struct block_device *bdev, fmode_t mode, 359 + int __user *argp) 360 + { 361 + int ret, n; 362 + 363 + if (!capable(CAP_SYS_ADMIN)) 364 + return -EACCES; 365 + if (!argp) 366 + return -EINVAL; 367 + if (get_user(n, argp)) 368 + return -EFAULT; 369 + 370 + if (!(mode & FMODE_EXCL)) { 371 + bdgrab(bdev); 372 + if (blkdev_get(bdev, mode | FMODE_EXCL, &bdev) < 0) 373 + return -EBUSY; 374 + } 375 + 376 + ret = set_blocksize(bdev, n); 377 + if (!(mode & FMODE_EXCL)) 378 + blkdev_put(bdev, mode | FMODE_EXCL); 379 + return ret; 380 + } 381 + 409 382 /* 410 383 * always keep this in sync with compat_blkdev_ioctl() 411 384 */ 412 385 int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, 413 386 unsigned long arg) 414 387 { 415 - struct gendisk *disk = bdev->bd_disk; 416 388 struct backing_dev_info *bdi; 389 + void __user *argp = (void __user *)arg; 417 390 loff_t size; 418 - int ret, n; 419 391 unsigned int max_sectors; 420 392 421 - switch(cmd) { 393 + switch (cmd) { 422 394 case BLKFLSBUF: 423 - if (!capable(CAP_SYS_ADMIN)) 424 - return -EACCES; 425 - 426 - ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); 427 - if (!is_unrecognized_ioctl(ret)) 428 - return ret; 429 - 430 - fsync_bdev(bdev); 431 - invalidate_bdev(bdev); 432 - return 0; 433 - 395 + return blkdev_flushbuf(bdev, mode, cmd, arg); 434 396 case BLKROSET: 435 - ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); 436 - if (!is_unrecognized_ioctl(ret)) 437 - return ret; 438 - if (!capable(CAP_SYS_ADMIN)) 439 - return -EACCES; 440 - if (get_user(n, (int __user *)(arg))) 441 - return -EFAULT; 442 - set_device_ro(bdev, n); 443 - return 0; 444 - 397 + return blkdev_roset(bdev, mode, cmd, arg); 445 398 case BLKDISCARD: 446 - case BLKSECDISCARD: { 447 - uint64_t range[2]; 448 - 449 - if (!(mode & FMODE_WRITE)) 450 - return -EBADF; 451 - 452 - if (copy_from_user(range, (void __user *)arg, sizeof(range))) 453 - return -EFAULT; 454 - 455 - return blk_ioctl_discard(bdev, range[0], range[1], 456 - cmd == BLKSECDISCARD); 457 - } 458 - case BLKZEROOUT: { 459 - uint64_t range[2]; 460 - 461 - if (!(mode & FMODE_WRITE)) 462 - return -EBADF; 463 - 464 - if (copy_from_user(range, (void __user *)arg, sizeof(range))) 465 - return -EFAULT; 466 - 467 - return blk_ioctl_zeroout(bdev, range[0], range[1]); 468 - } 469 - 470 - case HDIO_GETGEO: { 471 - struct hd_geometry geo; 472 - 473 - if (!arg) 474 - return -EINVAL; 475 - if (!disk->fops->getgeo) 476 - return -ENOTTY; 477 - 478 - /* 479 - * We need to set the startsect first, the driver may 480 - * want to override it. 481 - */ 482 - memset(&geo, 0, sizeof(geo)); 483 - geo.start = get_start_sect(bdev); 484 - ret = disk->fops->getgeo(bdev, &geo); 485 - if (ret) 486 - return ret; 487 - if (copy_to_user((struct hd_geometry __user *)arg, &geo, 488 - sizeof(geo))) 489 - return -EFAULT; 490 - return 0; 491 - } 399 + return blk_ioctl_discard(bdev, mode, arg, 0); 400 + case BLKSECDISCARD: 401 + return blk_ioctl_discard(bdev, mode, arg, 402 + BLKDEV_DISCARD_SECURE); 403 + case BLKZEROOUT: 404 + return blk_ioctl_zeroout(bdev, mode, arg); 405 + case HDIO_GETGEO: 406 + return blkdev_getgeo(bdev, argp); 492 407 case BLKRAGET: 493 408 case BLKFRAGET: 494 409 if (!arg) ··· 551 414 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; 552 415 return 0; 553 416 case BLKBSZSET: 554 - /* set the logical block size */ 555 - if (!capable(CAP_SYS_ADMIN)) 556 - return -EACCES; 557 - if (!arg) 558 - return -EINVAL; 559 - if (get_user(n, (int __user *) arg)) 560 - return -EFAULT; 561 - if (!(mode & FMODE_EXCL)) { 562 - bdgrab(bdev); 563 - if (blkdev_get(bdev, mode | FMODE_EXCL, &bdev) < 0) 564 - return -EBUSY; 565 - } 566 - ret = set_blocksize(bdev, n); 567 - if (!(mode & FMODE_EXCL)) 568 - blkdev_put(bdev, mode | FMODE_EXCL); 569 - return ret; 417 + return blkdev_bszset(bdev, mode, argp); 570 418 case BLKPG: 571 - ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg); 572 - break; 419 + return blkpg_ioctl(bdev, argp); 573 420 case BLKRRPART: 574 - ret = blkdev_reread_part(bdev); 575 - break; 421 + return blkdev_reread_part(bdev); 576 422 case BLKGETSIZE: 577 423 size = i_size_read(bdev->bd_inode); 578 424 if ((size >> 9) > ~0UL) ··· 567 447 case BLKTRACESTOP: 568 448 case BLKTRACESETUP: 569 449 case BLKTRACETEARDOWN: 570 - ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg); 571 - break; 450 + return blk_trace_ioctl(bdev, cmd, argp); 451 + case IOC_PR_REGISTER: 452 + return blkdev_pr_register(bdev, argp); 453 + case IOC_PR_RESERVE: 454 + return blkdev_pr_reserve(bdev, argp); 455 + case IOC_PR_RELEASE: 456 + return blkdev_pr_release(bdev, argp); 457 + case IOC_PR_PREEMPT: 458 + return blkdev_pr_preempt(bdev, argp, false); 459 + case IOC_PR_PREEMPT_ABORT: 460 + return blkdev_pr_preempt(bdev, argp, true); 461 + case IOC_PR_CLEAR: 462 + return blkdev_pr_clear(bdev, argp); 572 463 default: 573 - ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); 464 + return __blkdev_driver_ioctl(bdev, mode, cmd, arg); 574 465 } 575 - return ret; 576 466 } 577 467 EXPORT_SYMBOL_GPL(blkdev_ioctl);
+95
drivers/nvme/host/pci.c
··· 39 39 #include <linux/slab.h> 40 40 #include <linux/t10-pi.h> 41 41 #include <linux/types.h> 42 + #include <linux/pr.h> 42 43 #include <scsi/sg.h> 43 44 #include <asm-generic/io-64-nonatomic-lo-hi.h> 45 + #include <asm/unaligned.h> 44 46 45 47 #include <uapi/linux/nvme_ioctl.h> 46 48 #include "nvme.h" ··· 2066 2064 return 0; 2067 2065 } 2068 2066 2067 + static char nvme_pr_type(enum pr_type type) 2068 + { 2069 + switch (type) { 2070 + case PR_WRITE_EXCLUSIVE: 2071 + return 1; 2072 + case PR_EXCLUSIVE_ACCESS: 2073 + return 2; 2074 + case PR_WRITE_EXCLUSIVE_REG_ONLY: 2075 + return 3; 2076 + case PR_EXCLUSIVE_ACCESS_REG_ONLY: 2077 + return 4; 2078 + case PR_WRITE_EXCLUSIVE_ALL_REGS: 2079 + return 5; 2080 + case PR_EXCLUSIVE_ACCESS_ALL_REGS: 2081 + return 6; 2082 + default: 2083 + return 0; 2084 + } 2085 + }; 2086 + 2087 + static int nvme_pr_command(struct block_device *bdev, u32 cdw10, 2088 + u64 key, u64 sa_key, u8 op) 2089 + { 2090 + struct nvme_ns *ns = bdev->bd_disk->private_data; 2091 + struct nvme_command c; 2092 + u8 data[16] = { 0, }; 2093 + 2094 + put_unaligned_le64(key, &data[0]); 2095 + put_unaligned_le64(sa_key, &data[8]); 2096 + 2097 + memset(&c, 0, sizeof(c)); 2098 + c.common.opcode = op; 2099 + c.common.nsid = cpu_to_le32(ns->ns_id); 2100 + c.common.cdw10[0] = cpu_to_le32(cdw10); 2101 + 2102 + return nvme_submit_sync_cmd(ns->queue, &c, data, 16); 2103 + } 2104 + 2105 + static int nvme_pr_register(struct block_device *bdev, u64 old, 2106 + u64 new, unsigned flags) 2107 + { 2108 + u32 cdw10; 2109 + 2110 + if (flags & ~PR_FL_IGNORE_KEY) 2111 + return -EOPNOTSUPP; 2112 + 2113 + cdw10 = old ? 2 : 0; 2114 + cdw10 |= (flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0; 2115 + cdw10 |= (1 << 30) | (1 << 31); /* PTPL=1 */ 2116 + return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_register); 2117 + } 2118 + 2119 + static int nvme_pr_reserve(struct block_device *bdev, u64 key, 2120 + enum pr_type type, unsigned flags) 2121 + { 2122 + u32 cdw10; 2123 + 2124 + if (flags & ~PR_FL_IGNORE_KEY) 2125 + return -EOPNOTSUPP; 2126 + 2127 + cdw10 = nvme_pr_type(type) << 8; 2128 + cdw10 |= ((flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0); 2129 + return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_acquire); 2130 + } 2131 + 2132 + static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new, 2133 + enum pr_type type, bool abort) 2134 + { 2135 + u32 cdw10 = nvme_pr_type(type) << 8 | abort ? 2 : 1; 2136 + return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_acquire); 2137 + } 2138 + 2139 + static int nvme_pr_clear(struct block_device *bdev, u64 key) 2140 + { 2141 + u32 cdw10 = 1 | (key ? 1 << 3 : 0); 2142 + return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register); 2143 + } 2144 + 2145 + static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type) 2146 + { 2147 + u32 cdw10 = nvme_pr_type(type) << 8 | key ? 1 << 3 : 0; 2148 + return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release); 2149 + } 2150 + 2151 + static const struct pr_ops nvme_pr_ops = { 2152 + .pr_register = nvme_pr_register, 2153 + .pr_reserve = nvme_pr_reserve, 2154 + .pr_release = nvme_pr_release, 2155 + .pr_preempt = nvme_pr_preempt, 2156 + .pr_clear = nvme_pr_clear, 2157 + }; 2158 + 2069 2159 static const struct block_device_operations nvme_fops = { 2070 2160 .owner = THIS_MODULE, 2071 2161 .ioctl = nvme_ioctl, ··· 2166 2072 .release = nvme_release, 2167 2073 .getgeo = nvme_getgeo, 2168 2074 .revalidate_disk= nvme_revalidate_disk, 2075 + .pr_ops = &nvme_pr_ops, 2169 2076 }; 2170 2077 2171 2078 static int nvme_kthread(void *data)
+96
drivers/scsi/sd.c
··· 51 51 #include <linux/async.h> 52 52 #include <linux/slab.h> 53 53 #include <linux/pm_runtime.h> 54 + #include <linux/pr.h> 54 55 #include <asm/uaccess.h> 55 56 #include <asm/unaligned.h> 56 57 ··· 1536 1535 } 1537 1536 #endif 1538 1537 1538 + static char sd_pr_type(enum pr_type type) 1539 + { 1540 + switch (type) { 1541 + case PR_WRITE_EXCLUSIVE: 1542 + return 0x01; 1543 + case PR_EXCLUSIVE_ACCESS: 1544 + return 0x03; 1545 + case PR_WRITE_EXCLUSIVE_REG_ONLY: 1546 + return 0x05; 1547 + case PR_EXCLUSIVE_ACCESS_REG_ONLY: 1548 + return 0x06; 1549 + case PR_WRITE_EXCLUSIVE_ALL_REGS: 1550 + return 0x07; 1551 + case PR_EXCLUSIVE_ACCESS_ALL_REGS: 1552 + return 0x08; 1553 + default: 1554 + return 0; 1555 + } 1556 + }; 1557 + 1558 + static int sd_pr_command(struct block_device *bdev, u8 sa, 1559 + u64 key, u64 sa_key, u8 type, u8 flags) 1560 + { 1561 + struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device; 1562 + struct scsi_sense_hdr sshdr; 1563 + int result; 1564 + u8 cmd[16] = { 0, }; 1565 + u8 data[24] = { 0, }; 1566 + 1567 + cmd[0] = PERSISTENT_RESERVE_OUT; 1568 + cmd[1] = sa; 1569 + cmd[2] = type; 1570 + put_unaligned_be32(sizeof(data), &cmd[5]); 1571 + 1572 + put_unaligned_be64(key, &data[0]); 1573 + put_unaligned_be64(sa_key, &data[8]); 1574 + data[20] = flags; 1575 + 1576 + result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, &data, sizeof(data), 1577 + &sshdr, SD_TIMEOUT, SD_MAX_RETRIES, NULL); 1578 + 1579 + if ((driver_byte(result) & DRIVER_SENSE) && 1580 + (scsi_sense_valid(&sshdr))) { 1581 + sdev_printk(KERN_INFO, sdev, "PR command failed: %d\n", result); 1582 + scsi_print_sense_hdr(sdev, NULL, &sshdr); 1583 + } 1584 + 1585 + return result; 1586 + } 1587 + 1588 + static int sd_pr_register(struct block_device *bdev, u64 old_key, u64 new_key, 1589 + u32 flags) 1590 + { 1591 + if (flags & ~PR_FL_IGNORE_KEY) 1592 + return -EOPNOTSUPP; 1593 + return sd_pr_command(bdev, (flags & PR_FL_IGNORE_KEY) ? 0x06 : 0x00, 1594 + old_key, new_key, 0, 1595 + (1 << 0) /* APTPL */ | 1596 + (1 << 2) /* ALL_TG_PT */); 1597 + } 1598 + 1599 + static int sd_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type, 1600 + u32 flags) 1601 + { 1602 + if (flags) 1603 + return -EOPNOTSUPP; 1604 + return sd_pr_command(bdev, 0x01, key, 0, sd_pr_type(type), 0); 1605 + } 1606 + 1607 + static int sd_pr_release(struct block_device *bdev, u64 key, enum pr_type type) 1608 + { 1609 + return sd_pr_command(bdev, 0x02, key, 0, sd_pr_type(type), 0); 1610 + } 1611 + 1612 + static int sd_pr_preempt(struct block_device *bdev, u64 old_key, u64 new_key, 1613 + enum pr_type type, bool abort) 1614 + { 1615 + return sd_pr_command(bdev, abort ? 0x05 : 0x04, old_key, new_key, 1616 + sd_pr_type(type), 0); 1617 + } 1618 + 1619 + static int sd_pr_clear(struct block_device *bdev, u64 key) 1620 + { 1621 + return sd_pr_command(bdev, 0x03, key, 0, 0, 0); 1622 + } 1623 + 1624 + static const struct pr_ops sd_pr_ops = { 1625 + .pr_register = sd_pr_register, 1626 + .pr_reserve = sd_pr_reserve, 1627 + .pr_release = sd_pr_release, 1628 + .pr_preempt = sd_pr_preempt, 1629 + .pr_clear = sd_pr_clear, 1630 + }; 1631 + 1539 1632 static const struct block_device_operations sd_fops = { 1540 1633 .owner = THIS_MODULE, 1541 1634 .open = sd_open, ··· 1642 1547 .check_events = sd_check_events, 1643 1548 .revalidate_disk = sd_revalidate_disk, 1644 1549 .unlock_native_capacity = sd_unlock_native_capacity, 1550 + .pr_ops = &sd_pr_ops, 1645 1551 }; 1646 1552 1647 1553 /**
+2
include/linux/blkdev.h
··· 35 35 struct bsg_job; 36 36 struct blkcg_gq; 37 37 struct blk_flush_queue; 38 + struct pr_ops; 38 39 39 40 #define BLKDEV_MIN_RQ 4 40 41 #define BLKDEV_MAX_RQ 128 /* Default maximum */ ··· 1630 1629 /* this callback is with swap_lock and sometimes page table lock held */ 1631 1630 void (*swap_slot_free_notify) (struct block_device *, unsigned long); 1632 1631 struct module *owner; 1632 + const struct pr_ops *pr_ops; 1633 1633 }; 1634 1634 1635 1635 extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
+18
include/linux/pr.h
··· 1 + #ifndef LINUX_PR_H 2 + #define LINUX_PR_H 3 + 4 + #include <uapi/linux/pr.h> 5 + 6 + struct pr_ops { 7 + int (*pr_register)(struct block_device *bdev, u64 old_key, u64 new_key, 8 + u32 flags); 9 + int (*pr_reserve)(struct block_device *bdev, u64 key, 10 + enum pr_type type, u32 flags); 11 + int (*pr_release)(struct block_device *bdev, u64 key, 12 + enum pr_type type); 13 + int (*pr_preempt)(struct block_device *bdev, u64 old_key, u64 new_key, 14 + enum pr_type type, bool abort); 15 + int (*pr_clear)(struct block_device *bdev, u64 key); 16 + }; 17 + 18 + #endif /* LINUX_PR_H */
+48
include/uapi/linux/pr.h
··· 1 + #ifndef _UAPI_PR_H 2 + #define _UAPI_PR_H 3 + 4 + enum pr_type { 5 + PR_WRITE_EXCLUSIVE = 1, 6 + PR_EXCLUSIVE_ACCESS = 2, 7 + PR_WRITE_EXCLUSIVE_REG_ONLY = 3, 8 + PR_EXCLUSIVE_ACCESS_REG_ONLY = 4, 9 + PR_WRITE_EXCLUSIVE_ALL_REGS = 5, 10 + PR_EXCLUSIVE_ACCESS_ALL_REGS = 6, 11 + }; 12 + 13 + struct pr_reservation { 14 + __u64 key; 15 + __u32 type; 16 + __u32 flags; 17 + }; 18 + 19 + struct pr_registration { 20 + __u64 old_key; 21 + __u64 new_key; 22 + __u32 flags; 23 + __u32 __pad; 24 + }; 25 + 26 + struct pr_preempt { 27 + __u64 old_key; 28 + __u64 new_key; 29 + __u32 type; 30 + __u32 flags; 31 + }; 32 + 33 + struct pr_clear { 34 + __u64 key; 35 + __u32 flags; 36 + __u32 __pad; 37 + }; 38 + 39 + #define PR_FL_IGNORE_KEY (1 << 0) /* ignore existing key */ 40 + 41 + #define IOC_PR_REGISTER _IOW('p', 200, struct pr_registration) 42 + #define IOC_PR_RESERVE _IOW('p', 201, struct pr_reservation) 43 + #define IOC_PR_RELEASE _IOW('p', 202, struct pr_reservation) 44 + #define IOC_PR_PREEMPT _IOW('p', 203, struct pr_preempt) 45 + #define IOC_PR_PREEMPT_ABORT _IOW('p', 204, struct pr_preempt) 46 + #define IOC_PR_CLEAR _IOW('p', 205, struct pr_clear) 47 + 48 + #endif /* _UAPI_PR_H */