3939#include <linux/slab.h>
4040#include <linux/t10-pi.h>
4141#include <linux/types.h>
42+ #include <linux/pr.h>
4243#include <scsi/sg.h>
4344#include <asm-generic/io-64-nonatomic-lo-hi.h>
45+ #include <asm/unaligned.h>
4446
4547#include <uapi/linux/nvme_ioctl.h>
4648#include "nvme.h"
@@ -2060,6 +2062,98 @@ static int nvme_revalidate_disk(struct gendisk *disk)
20602062 return 0 ;
20612063}
20622064
2065+ static char nvme_pr_type (enum pr_type type )
2066+ {
2067+ switch (type ) {
2068+ case PR_WRITE_EXCLUSIVE :
2069+ return 1 ;
2070+ case PR_EXCLUSIVE_ACCESS :
2071+ return 2 ;
2072+ case PR_WRITE_EXCLUSIVE_REG_ONLY :
2073+ return 3 ;
2074+ case PR_EXCLUSIVE_ACCESS_REG_ONLY :
2075+ return 4 ;
2076+ case PR_WRITE_EXCLUSIVE_ALL_REGS :
2077+ return 5 ;
2078+ case PR_EXCLUSIVE_ACCESS_ALL_REGS :
2079+ return 6 ;
2080+ default :
2081+ return 0 ;
2082+ }
2083+ };
2084+
2085+ static int nvme_pr_command (struct block_device * bdev , u32 cdw10 ,
2086+ u64 key , u64 sa_key , u8 op )
2087+ {
2088+ struct nvme_ns * ns = bdev -> bd_disk -> private_data ;
2089+ struct nvme_command c ;
2090+ u8 data [16 ] = { 0 , };
2091+
2092+ put_unaligned_le64 (key , & data [0 ]);
2093+ put_unaligned_le64 (sa_key , & data [8 ]);
2094+
2095+ memset (& c , 0 , sizeof (c ));
2096+ c .common .opcode = op ;
2097+ c .common .nsid = ns -> ns_id ;
2098+ c .common .cdw10 [0 ] = cdw10 ;
2099+
2100+ return nvme_submit_sync_cmd (ns -> queue , & c , data , 16 );
2101+ }
2102+
2103+ static int nvme_pr_register (struct block_device * bdev , u64 old ,
2104+ u64 new , unsigned flags )
2105+ {
2106+ u32 cdw10 ;
2107+
2108+ if (flags & ~PR_FL_IGNORE_KEY )
2109+ return - EOPNOTSUPP ;
2110+
2111+ cdw10 = old ? 2 : 0 ;
2112+ cdw10 |= (flags & PR_FL_IGNORE_KEY ) ? 1 << 3 : 0 ;
2113+ cdw10 |= (1 << 30 ) | (1 << 31 ); /* PTPL=1 */
2114+ return nvme_pr_command (bdev , cdw10 , old , new , nvme_cmd_resv_register );
2115+ }
2116+
2117+ static int nvme_pr_reserve (struct block_device * bdev , u64 key ,
2118+ enum pr_type type , unsigned flags )
2119+ {
2120+ u32 cdw10 ;
2121+
2122+ if (flags & ~PR_FL_IGNORE_KEY )
2123+ return - EOPNOTSUPP ;
2124+
2125+ cdw10 = nvme_pr_type (type ) << 8 ;
2126+ cdw10 |= ((flags & PR_FL_IGNORE_KEY ) ? 1 << 3 : 0 );
2127+ return nvme_pr_command (bdev , cdw10 , key , 0 , nvme_cmd_resv_acquire );
2128+ }
2129+
2130+ static int nvme_pr_preempt (struct block_device * bdev , u64 old , u64 new ,
2131+ enum pr_type type , bool abort )
2132+ {
2133+ u32 cdw10 = nvme_pr_type (type ) << 8 | abort ? 2 : 1 ;
2134+ return nvme_pr_command (bdev , cdw10 , old , new , nvme_cmd_resv_acquire );
2135+ }
2136+
2137+ static int nvme_pr_clear (struct block_device * bdev , u64 key )
2138+ {
2139+ u32 cdw10 = 1 | key ? 1 << 3 : 0 ;
2140+ return nvme_pr_command (bdev , cdw10 , key , 0 , nvme_cmd_resv_register );
2141+ }
2142+
2143+ static int nvme_pr_release (struct block_device * bdev , u64 key , enum pr_type type )
2144+ {
2145+ u32 cdw10 = nvme_pr_type (type ) << 8 | key ? 1 << 3 : 0 ;
2146+ return nvme_pr_command (bdev , cdw10 , key , 0 , nvme_cmd_resv_release );
2147+ }
2148+
2149+ static const struct pr_ops nvme_pr_ops = {
2150+ .pr_register = nvme_pr_register ,
2151+ .pr_reserve = nvme_pr_reserve ,
2152+ .pr_release = nvme_pr_release ,
2153+ .pr_preempt = nvme_pr_preempt ,
2154+ .pr_clear = nvme_pr_clear ,
2155+ };
2156+
20632157static const struct block_device_operations nvme_fops = {
20642158 .owner = THIS_MODULE ,
20652159 .ioctl = nvme_ioctl ,
@@ -2068,6 +2162,7 @@ static const struct block_device_operations nvme_fops = {
20682162 .release = nvme_release ,
20692163 .getgeo = nvme_getgeo ,
20702164 .revalidate_disk = nvme_revalidate_disk ,
2165+ .pr_ops = & nvme_pr_ops ,
20712166};
20722167
20732168static int nvme_kthread (void * data )
0 commit comments