44 */
55#include <linux/exportfs.h>
66#include <linux/iomap.h>
7- #include <linux/genhd.h>
87#include <linux/slab.h>
98#include <linux/pr.h>
109
1110#include <linux/nfsd/debug.h>
12- #include <scsi/scsi_proto.h>
13- #include <scsi/scsi_common.h>
14- #include <scsi/scsi_request.h>
1511
1612#include "blocklayoutxdr.h"
1713#include "pnfs.h"
1814#include "filecache.h"
15+ #include "vfs.h"
1916
2017#define NFSDDBG_FACILITY NFSDDBG_PNFS
2118
@@ -211,109 +208,6 @@ const struct nfsd4_layout_ops bl_layout_ops = {
211208#endif /* CONFIG_NFSD_BLOCKLAYOUT */
212209
213210#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-
317211#define NFSD_MDS_PR_KEY 0x0100000000000000ULL
318212
319213/*
@@ -325,6 +219,31 @@ static u64 nfsd4_scsi_pr_key(struct nfs4_client *clp)
325219 return ((u64 )clp -> cl_clientid .cl_boot << 32 ) | clp -> cl_clientid .cl_id ;
326220}
327221
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+
328247static int
329248nfsd4_block_get_device_info_scsi (struct super_block * sb ,
330249 struct nfs4_client * clp ,
@@ -333,7 +252,7 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb,
333252 struct pnfs_block_deviceaddr * dev ;
334253 struct pnfs_block_volume * b ;
335254 const struct pr_ops * ops ;
336- int error ;
255+ int ret ;
337256
338257 dev = kzalloc (sizeof (struct pnfs_block_deviceaddr ) +
339258 sizeof (struct pnfs_block_volume ), GFP_KERNEL );
@@ -347,33 +266,39 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb,
347266 b -> type = PNFS_BLOCK_VOLUME_SCSI ;
348267 b -> scsi .pr_key = nfsd4_scsi_pr_key (clp );
349268
350- error = nfsd4_scsi_identify_device (sb -> s_bdev , b );
351- if (error )
352- return error ;
269+ ret = nfsd4_block_get_unique_id (sb -> s_bdev -> bd_disk , b );
270+ if (ret < 0 )
271+ goto out_free_dev ;
353272
273+ ret = - EINVAL ;
354274 ops = sb -> s_bdev -> bd_disk -> fops -> pr_ops ;
355275 if (!ops ) {
356276 pr_err ("pNFS: device %s does not support PRs.\n" ,
357277 sb -> s_id );
358- return - EINVAL ;
278+ goto out_free_dev ;
359279 }
360280
361- error = ops -> pr_register (sb -> s_bdev , 0 , NFSD_MDS_PR_KEY , true);
362- if (error ) {
281+ ret = ops -> pr_register (sb -> s_bdev , 0 , NFSD_MDS_PR_KEY , true);
282+ if (ret ) {
363283 pr_err ("pNFS: failed to register key for device %s.\n" ,
364284 sb -> s_id );
365- return - EINVAL ;
285+ goto out_free_dev ;
366286 }
367287
368- error = ops -> pr_reserve (sb -> s_bdev , NFSD_MDS_PR_KEY ,
288+ ret = ops -> pr_reserve (sb -> s_bdev , NFSD_MDS_PR_KEY ,
369289 PR_EXCLUSIVE_ACCESS_REG_ONLY , 0 );
370- if (error ) {
290+ if (ret ) {
371291 pr_err ("pNFS: failed to reserve device %s.\n" ,
372292 sb -> s_id );
373- return - EINVAL ;
293+ goto out_free_dev ;
374294 }
375295
376296 return 0 ;
297+
298+ out_free_dev :
299+ kfree (dev );
300+ gdp -> gd_device = NULL ;
301+ return ret ;
377302}
378303
379304static __be32
0 commit comments