44 */ 
55#include  <linux/exportfs.h> 
66#include  <linux/iomap.h> 
7+ #include  <linux/genhd.h> 
78#include  <linux/slab.h> 
89#include  <linux/pr.h> 
910
1011#include  <linux/nfsd/debug.h> 
12+ #include  <scsi/scsi_proto.h> 
13+ #include  <scsi/scsi_common.h> 
14+ #include  <scsi/scsi_request.h> 
1115
1216#include  "blocklayoutxdr.h" 
1317#include  "pnfs.h" 
1418#include  "filecache.h" 
15- #include  "vfs.h" 
1619
1720#define  NFSDDBG_FACILITY 	NFSDDBG_PNFS
1821
@@ -208,6 +211,109 @@ const struct nfsd4_layout_ops bl_layout_ops = {
208211#endif  /* CONFIG_NFSD_BLOCKLAYOUT */ 
209212
210213#ifdef  CONFIG_NFSD_SCSILAYOUT 
214+ static  int  nfsd4_scsi_identify_device (struct  block_device  * bdev ,
215+ 		struct  pnfs_block_volume  * b )
216+ {
217+ 	struct  request_queue  * q  =  bdev -> bd_disk -> queue ;
218+ 	struct  request  * rq ;
219+ 	struct  scsi_request  * req ;
220+ 	/* 
221+ 	 * The allocation length (passed in bytes 3 and 4 of the INQUIRY 
222+ 	 * command descriptor block) specifies the number of bytes that have 
223+ 	 * been allocated for the data-in buffer. 
224+ 	 * 252 is the highest one-byte value that is a multiple of 4. 
225+ 	 * 65532 is the highest two-byte value that is a multiple of 4. 
226+ 	 */ 
227+ 	size_t  bufflen  =  252 , maxlen  =  65532 , len , id_len ;
228+ 	u8  * buf , * d , type , assoc ;
229+ 	int  retries  =  1 , error ;
230+ 
231+ 	if  (WARN_ON_ONCE (!blk_queue_scsi_passthrough (q )))
232+ 		return  - EINVAL ;
233+ 
234+ again :
235+ 	buf  =  kzalloc (bufflen , GFP_KERNEL );
236+ 	if  (!buf )
237+ 		return  - ENOMEM ;
238+ 
239+ 	rq  =  blk_get_request (q , REQ_OP_DRV_IN , 0 );
240+ 	if  (IS_ERR (rq )) {
241+ 		error  =  - ENOMEM ;
242+ 		goto out_free_buf ;
243+ 	}
244+ 	req  =  scsi_req (rq );
245+ 
246+ 	error  =  blk_rq_map_kern (q , rq , buf , bufflen , GFP_KERNEL );
247+ 	if  (error )
248+ 		goto out_put_request ;
249+ 
250+ 	req -> cmd [0 ] =  INQUIRY ;
251+ 	req -> cmd [1 ] =  1 ;
252+ 	req -> cmd [2 ] =  0x83 ;
253+ 	req -> cmd [3 ] =  bufflen  >> 8 ;
254+ 	req -> cmd [4 ] =  bufflen  &  0xff ;
255+ 	req -> cmd_len  =  COMMAND_SIZE (INQUIRY );
256+ 
257+ 	blk_execute_rq (NULL , rq , 1 );
258+ 	if  (req -> result ) {
259+ 		pr_err ("pNFS: INQUIRY 0x83 failed with: %x\n" ,
260+ 			req -> result );
261+ 		error  =  - EIO ;
262+ 		goto out_put_request ;
263+ 	}
264+ 
265+ 	len  =  (buf [2 ] << 8 ) +  buf [3 ] +  4 ;
266+ 	if  (len  >  bufflen ) {
267+ 		if  (len  <= maxlen  &&  retries -- ) {
268+ 			blk_put_request (rq );
269+ 			kfree (buf );
270+ 			bufflen  =  len ;
271+ 			goto again ;
272+ 		}
273+ 		pr_err ("pNFS: INQUIRY 0x83 response invalid (len = %zd)\n" ,
274+ 			len );
275+ 		goto out_put_request ;
276+ 	}
277+ 
278+ 	d  =  buf  +  4 ;
279+ 	for  (d  =  buf  +  4 ; d  <  buf  +  len ; d  +=  id_len  +  4 ) {
280+ 		id_len  =  d [3 ];
281+ 		type  =  d [1 ] &  0xf ;
282+ 		assoc  =  (d [1 ] >> 4 ) &  0x3 ;
283+ 
284+ 		/* 
285+ 		 * We only care about a EUI-64 and NAA designator types 
286+ 		 * with LU association. 
287+ 		 */ 
288+ 		if  (assoc  !=  0x00 )
289+ 			continue ;
290+ 		if  (type  !=  0x02  &&  type  !=  0x03 )
291+ 			continue ;
292+ 		if  (id_len  !=  8  &&  id_len  !=  12  &&  id_len  !=  16 )
293+ 			continue ;
294+ 
295+ 		b -> scsi .code_set  =  PS_CODE_SET_BINARY ;
296+ 		b -> scsi .designator_type  =  type  ==  0x02  ?
297+ 			PS_DESIGNATOR_EUI64  : PS_DESIGNATOR_NAA ;
298+ 		b -> scsi .designator_len  =  id_len ;
299+ 		memcpy (b -> scsi .designator , d  +  4 , id_len );
300+ 
301+ 		/* 
302+ 		 * If we found a 8 or 12 byte descriptor continue on to 
303+ 		 * see if a 16 byte one is available.  If we find a 
304+ 		 * 16 byte descriptor we're done. 
305+ 		 */ 
306+ 		if  (id_len  ==  16 )
307+ 			break ;
308+ 	}
309+ 
310+ out_put_request :
311+ 	blk_put_request (rq );
312+ out_free_buf :
313+ 	kfree (buf );
314+ 	return  error ;
315+ }
316+ 
211317#define  NFSD_MDS_PR_KEY 		0x0100000000000000ULL
212318
213319/* 
@@ -219,31 +325,6 @@ static u64 nfsd4_scsi_pr_key(struct nfs4_client *clp)
219325	return  ((u64 )clp -> cl_clientid .cl_boot  << 32 ) | clp -> cl_clientid .cl_id ;
220326}
221327
222- static  const  u8  designator_types [] =  {
223- 	PS_DESIGNATOR_EUI64 ,
224- 	PS_DESIGNATOR_NAA ,
225- };
226- 
227- static  int 
228- nfsd4_block_get_unique_id (struct  gendisk  * disk , struct  pnfs_block_volume  * b )
229- {
230- 	int  ret , i ;
231- 
232- 	for  (i  =  0 ; i  <  ARRAY_SIZE (designator_types ); i ++ ) {
233- 		u8  type  =  designator_types [i ];
234- 
235- 		ret  =  disk -> fops -> get_unique_id (disk , b -> scsi .designator , type );
236- 		if  (ret  >  0 ) {
237- 			b -> scsi .code_set  =  PS_CODE_SET_BINARY ;
238- 			b -> scsi .designator_type  =  type ;
239- 			b -> scsi .designator_len  =  ret ;
240- 			return  0 ;
241- 		}
242- 	}
243- 
244- 	return  - EINVAL ;
245- }
246- 
247328static  int 
248329nfsd4_block_get_device_info_scsi (struct  super_block  * sb ,
249330		struct  nfs4_client  * clp ,
@@ -252,7 +333,7 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb,
252333	struct  pnfs_block_deviceaddr  * dev ;
253334	struct  pnfs_block_volume  * b ;
254335	const  struct  pr_ops  * ops ;
255- 	int  ret ;
336+ 	int  error ;
256337
257338	dev  =  kzalloc (sizeof (struct  pnfs_block_deviceaddr ) + 
258339		      sizeof (struct  pnfs_block_volume ), GFP_KERNEL );
@@ -266,39 +347,33 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb,
266347	b -> type  =  PNFS_BLOCK_VOLUME_SCSI ;
267348	b -> scsi .pr_key  =  nfsd4_scsi_pr_key (clp );
268349
269- 	ret  =  nfsd4_block_get_unique_id (sb -> s_bdev -> bd_disk , b );
270- 	if  (ret   <   0 )
271- 		goto  out_free_dev ;
350+ 	error  =  nfsd4_scsi_identify_device (sb -> s_bdev , b );
351+ 	if  (error )
352+ 		return   error ;
272353
273- 	ret  =  - EINVAL ;
274354	ops  =  sb -> s_bdev -> bd_disk -> fops -> pr_ops ;
275355	if  (!ops ) {
276356		pr_err ("pNFS: device %s does not support PRs.\n" ,
277357			sb -> s_id );
278- 		goto  out_free_dev ;
358+ 		return   - EINVAL ;
279359	}
280360
281- 	ret  =  ops -> pr_register (sb -> s_bdev , 0 , NFSD_MDS_PR_KEY , true);
282- 	if  (ret ) {
361+ 	error  =  ops -> pr_register (sb -> s_bdev , 0 , NFSD_MDS_PR_KEY , true);
362+ 	if  (error ) {
283363		pr_err ("pNFS: failed to register key for device %s.\n" ,
284364			sb -> s_id );
285- 		goto  out_free_dev ;
365+ 		return   - EINVAL ;
286366	}
287367
288- 	ret  =  ops -> pr_reserve (sb -> s_bdev , NFSD_MDS_PR_KEY ,
368+ 	error  =  ops -> pr_reserve (sb -> s_bdev , NFSD_MDS_PR_KEY ,
289369			PR_EXCLUSIVE_ACCESS_REG_ONLY , 0 );
290- 	if  (ret ) {
370+ 	if  (error ) {
291371		pr_err ("pNFS: failed to reserve device %s.\n" ,
292372			sb -> s_id );
293- 		goto  out_free_dev ;
373+ 		return   - EINVAL ;
294374	}
295375
296376	return  0 ;
297- 
298- out_free_dev :
299- 	kfree (dev );
300- 	gdp -> gd_device  =  NULL ;
301- 	return  ret ;
302377}
303378
304379static  __be32 
0 commit comments