@@ -7175,6 +7175,65 @@ static void get_pif_sts(struct nvme_id_ns *ns, struct nvme_nvm_id_ns *nvm_ns,
71757175 * pif = (elbaf & NVME_NVM_ELBAF_QPIF_MASK ) >> 9 ;
71767176}
71777177
7178+ static int get_pi_info (struct nvme_transport_handle * hdl ,
7179+ __u32 nsid , __u8 prinfo , __u64 ilbrt , __u64 lbst ,
7180+ unsigned int * logical_block_size , __u16 * metadata_size )
7181+ {
7182+ _cleanup_free_ struct nvme_nvm_id_ns * nvm_ns = NULL ;
7183+ _cleanup_free_ struct nvme_id_ns * ns = NULL ;
7184+ __u8 sts = 0 , pif = 0 ;
7185+ unsigned int lbs = 0 ;
7186+ __u8 lba_index ;
7187+ int pi_size ;
7188+ __u16 ms ;
7189+ int err ;
7190+
7191+ ns = nvme_alloc (sizeof (* ns ));
7192+ if (!ns )
7193+ return - ENOMEM ;
7194+
7195+ err = nvme_identify_ns (hdl , nsid , ns );
7196+ if (err > 0 ) {
7197+ nvme_show_status (err );
7198+ return err ;
7199+ } else if (err < 0 ) {
7200+ nvme_show_error ("identify namespace: %s" , nvme_strerror (err ));
7201+ return err ;
7202+ }
7203+
7204+ nvme_id_ns_flbas_to_lbaf_inuse (ns -> flbas , & lba_index );
7205+ lbs = 1 << ns -> lbaf [lba_index ].ds ;
7206+ ms = le16_to_cpu (ns -> lbaf [lba_index ].ms );
7207+
7208+ nvm_ns = nvme_alloc (sizeof (* nvm_ns ));
7209+ if (!nvm_ns )
7210+ return - ENOMEM ;
7211+
7212+ err = nvme_identify_csi_ns (hdl , nsid , NVME_CSI_NVM , 0 ,
7213+ nvm_ns );
7214+ if (!err )
7215+ get_pif_sts (ns , nvm_ns , & pif , & sts );
7216+
7217+ pi_size = (pif == NVME_NVM_PIF_16B_GUARD ) ? 8 : 16 ;
7218+ if (NVME_FLBAS_META_EXT (ns -> flbas )) {
7219+ /*
7220+ * No meta data is transferred for PRACT=1 and MD=PI size:
7221+ * 5.2.2.1 Protection Information and Write Commands
7222+ * 5.2.2.2 Protection Information and Read Commands
7223+ */
7224+ if (!((prinfo & 0x8 ) != 0 && ms == pi_size ))
7225+ logical_block_size += ms ;
7226+ }
7227+
7228+ if (invalid_tags (lbst , ilbrt , sts , pif ))
7229+ return - EINVAL ;
7230+
7231+ * logical_block_size = lbs ;
7232+ * metadata_size = ms ;
7233+
7234+ return 0 ;
7235+ }
7236+
71787237static int init_pi_tags (struct nvme_transport_handle * hdl ,
71797238 struct nvme_passthru_cmd * cmd , __u32 nsid , __u64 ilbrt , __u64 lbst ,
71807239 __u16 lbat , __u16 lbatm )
@@ -8073,14 +8132,14 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
80738132 struct timeval start_time , end_time ;
80748133 _cleanup_free_ void * mbuffer = NULL ;
80758134 _cleanup_fd_ int dfd = -1 , mfd = -1 ;
8076- __u8 lba_index , sts = 0 , pif = 0 ;
80778135 __u16 control = 0 , nblocks = 0 ;
80788136 struct nvme_passthru_cmd cmd ;
8079- int flags , pi_size ;
8137+ __u8 sts = 0 , pif = 0 ;
80808138 __u32 dsmgmt = 0 ;
80818139 int mode = 0644 ;
80828140 void * buffer ;
80838141 int err = 0 ;
8142+ int flags ;
80848143 __u16 ms ;
80858144
80868145 const char * start_block_addr = "64-bit addr of first block to access" ;
@@ -8256,45 +8315,12 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
82568315 logical_block_size = cfg .block_size ;
82578316 ms = cfg .metadata_size ;
82588317 } else {
8259- ns = nvme_alloc (sizeof (* ns ));
8260- if (!ns )
8261- return - ENOMEM ;
8262-
8263- err = nvme_identify_ns (hdl , cfg .nsid , ns );
8264- if (err > 0 ) {
8265- nvme_show_status (err );
8266- return err ;
8267- } else if (err < 0 ) {
8268- nvme_show_error ("identify namespace: %s" , nvme_strerror (err ));
8269- return err ;
8270- }
8271-
8272- nvme_id_ns_flbas_to_lbaf_inuse (ns -> flbas , & lba_index );
8273- logical_block_size = 1 << ns -> lbaf [lba_index ].ds ;
8274- ms = le16_to_cpu (ns -> lbaf [lba_index ].ms );
8275-
8276- nvm_ns = nvme_alloc (sizeof (* nvm_ns ));
8277- if (!nvm_ns )
8278- return - ENOMEM ;
8279-
8280- err = nvme_identify_csi_ns (hdl , cfg .nsid , NVME_CSI_NVM , 0 ,
8281- nvm_ns );
8282- if (!err )
8283- get_pif_sts (ns , nvm_ns , & pif , & sts );
8284-
8285- pi_size = (pif == NVME_NVM_PIF_16B_GUARD ) ? 8 : 16 ;
8286- if (NVME_FLBAS_META_EXT (ns -> flbas )) {
8287- /*
8288- * No meta data is transferred for PRACT=1 and MD=PI size:
8289- * 5.2.2.1 Protection Information and Write Commands
8290- * 5.2.2.2 Protection Information and Read Commands
8291- */
8292- if (!((cfg .prinfo & 0x8 ) != 0 && ms == pi_size ))
8293- logical_block_size += ms ;
8318+ err = get_pi_info (hdl , cfg .nsid , cfg .prinfo ,
8319+ cfg .ilbrt , cfg .lbst , & logical_block_size , & ms );
8320+ if (err ) {
8321+ logical_block_size = 0 ;
8322+ ms = 0 ;
82948323 }
8295-
8296- if (invalid_tags (cfg .lbst , cfg .ilbrt , sts , pif ))
8297- return - EINVAL ;
82988324 }
82998325
83008326 buffer_size = ((long long )cfg .block_count + 1 ) * logical_block_size ;
0 commit comments