]>
git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - fs/nfs/blocklayout/dev.c
2 * Copyright (c) 2014-2016 Christoph Hellwig.
4 #include <linux/sunrpc/svc.h>
5 #include <linux/blkdev.h>
6 #include <linux/nfs4.h>
7 #include <linux/nfs_fs.h>
8 #include <linux/nfs_xdr.h>
11 #include "blocklayout.h"
13 #define NFSDBG_FACILITY NFSDBG_PNFS_LD
16 bl_free_device(struct pnfs_block_dev
*dev
)
18 if (dev
->nr_children
) {
21 for (i
= 0; i
< dev
->nr_children
; i
++)
22 bl_free_device(&dev
->children
[i
]);
25 if (dev
->pr_registered
) {
26 const struct pr_ops
*ops
=
27 dev
->bdev
->bd_disk
->fops
->pr_ops
;
30 error
= ops
->pr_register(dev
->bdev
, dev
->pr_key
, 0,
33 pr_err("failed to unregister PR key.\n");
37 blkdev_put(dev
->bdev
, FMODE_READ
| FMODE_WRITE
);
42 bl_free_deviceid_node(struct nfs4_deviceid_node
*d
)
44 struct pnfs_block_dev
*dev
=
45 container_of(d
, struct pnfs_block_dev
, node
);
48 kfree_rcu(dev
, node
.rcu
);
52 nfs4_block_decode_volume(struct xdr_stream
*xdr
, struct pnfs_block_volume
*b
)
57 p
= xdr_inline_decode(xdr
, 4);
60 b
->type
= be32_to_cpup(p
++);
63 case PNFS_BLOCK_VOLUME_SIMPLE
:
64 p
= xdr_inline_decode(xdr
, 4);
67 b
->simple
.nr_sigs
= be32_to_cpup(p
++);
68 if (!b
->simple
.nr_sigs
|| b
->simple
.nr_sigs
> PNFS_BLOCK_MAX_UUIDS
) {
69 dprintk("Bad signature count: %d\n", b
->simple
.nr_sigs
);
73 b
->simple
.len
= 4 + 4;
74 for (i
= 0; i
< b
->simple
.nr_sigs
; i
++) {
75 p
= xdr_inline_decode(xdr
, 8 + 4);
78 p
= xdr_decode_hyper(p
, &b
->simple
.sigs
[i
].offset
);
79 b
->simple
.sigs
[i
].sig_len
= be32_to_cpup(p
++);
80 if (b
->simple
.sigs
[i
].sig_len
> PNFS_BLOCK_UUID_LEN
) {
81 pr_info("signature too long: %d\n",
82 b
->simple
.sigs
[i
].sig_len
);
86 p
= xdr_inline_decode(xdr
, b
->simple
.sigs
[i
].sig_len
);
89 memcpy(&b
->simple
.sigs
[i
].sig
, p
,
90 b
->simple
.sigs
[i
].sig_len
);
92 b
->simple
.len
+= 8 + 4 + \
93 (XDR_QUADLEN(b
->simple
.sigs
[i
].sig_len
) << 2);
96 case PNFS_BLOCK_VOLUME_SLICE
:
97 p
= xdr_inline_decode(xdr
, 8 + 8 + 4);
100 p
= xdr_decode_hyper(p
, &b
->slice
.start
);
101 p
= xdr_decode_hyper(p
, &b
->slice
.len
);
102 b
->slice
.volume
= be32_to_cpup(p
++);
104 case PNFS_BLOCK_VOLUME_CONCAT
:
105 p
= xdr_inline_decode(xdr
, 4);
109 b
->concat
.volumes_count
= be32_to_cpup(p
++);
110 if (b
->concat
.volumes_count
> PNFS_BLOCK_MAX_DEVICES
) {
111 dprintk("Too many volumes: %d\n", b
->concat
.volumes_count
);
115 p
= xdr_inline_decode(xdr
, b
->concat
.volumes_count
* 4);
118 for (i
= 0; i
< b
->concat
.volumes_count
; i
++)
119 b
->concat
.volumes
[i
] = be32_to_cpup(p
++);
121 case PNFS_BLOCK_VOLUME_STRIPE
:
122 p
= xdr_inline_decode(xdr
, 8 + 4);
126 p
= xdr_decode_hyper(p
, &b
->stripe
.chunk_size
);
127 b
->stripe
.volumes_count
= be32_to_cpup(p
++);
128 if (b
->stripe
.volumes_count
> PNFS_BLOCK_MAX_DEVICES
) {
129 dprintk("Too many volumes: %d\n", b
->stripe
.volumes_count
);
133 p
= xdr_inline_decode(xdr
, b
->stripe
.volumes_count
* 4);
136 for (i
= 0; i
< b
->stripe
.volumes_count
; i
++)
137 b
->stripe
.volumes
[i
] = be32_to_cpup(p
++);
139 case PNFS_BLOCK_VOLUME_SCSI
:
140 p
= xdr_inline_decode(xdr
, 4 + 4 + 4);
143 b
->scsi
.code_set
= be32_to_cpup(p
++);
144 b
->scsi
.designator_type
= be32_to_cpup(p
++);
145 b
->scsi
.designator_len
= be32_to_cpup(p
++);
146 p
= xdr_inline_decode(xdr
, b
->scsi
.designator_len
);
149 if (b
->scsi
.designator_len
> 256)
151 memcpy(&b
->scsi
.designator
, p
, b
->scsi
.designator_len
);
152 p
= xdr_inline_decode(xdr
, 8);
155 p
= xdr_decode_hyper(p
, &b
->scsi
.pr_key
);
158 dprintk("unknown volume type!\n");
165 static bool bl_map_simple(struct pnfs_block_dev
*dev
, u64 offset
,
166 struct pnfs_block_dev_map
*map
)
168 map
->start
= dev
->start
;
170 map
->disk_offset
= dev
->disk_offset
;
171 map
->bdev
= dev
->bdev
;
175 static bool bl_map_concat(struct pnfs_block_dev
*dev
, u64 offset
,
176 struct pnfs_block_dev_map
*map
)
180 for (i
= 0; i
< dev
->nr_children
; i
++) {
181 struct pnfs_block_dev
*child
= &dev
->children
[i
];
183 if (child
->start
> offset
||
184 child
->start
+ child
->len
<= offset
)
187 child
->map(child
, offset
- child
->start
, map
);
191 dprintk("%s: ran off loop!\n", __func__
);
195 static bool bl_map_stripe(struct pnfs_block_dev
*dev
, u64 offset
,
196 struct pnfs_block_dev_map
*map
)
198 struct pnfs_block_dev
*child
;
203 chunk
= div_u64(offset
, dev
->chunk_size
);
204 div_u64_rem(chunk
, dev
->nr_children
, &chunk_idx
);
206 if (chunk_idx
> dev
->nr_children
) {
207 dprintk("%s: invalid chunk idx %d (%lld/%lld)\n",
208 __func__
, chunk_idx
, offset
, dev
->chunk_size
);
209 /* error, should not happen */
213 /* truncate offset to the beginning of the stripe */
214 offset
= chunk
* dev
->chunk_size
;
216 /* disk offset of the stripe */
217 disk_offset
= div_u64(offset
, dev
->nr_children
);
219 child
= &dev
->children
[chunk_idx
];
220 child
->map(child
, disk_offset
, map
);
222 map
->start
+= offset
;
223 map
->disk_offset
+= disk_offset
;
224 map
->len
= dev
->chunk_size
;
229 bl_parse_deviceid(struct nfs_server
*server
, struct pnfs_block_dev
*d
,
230 struct pnfs_block_volume
*volumes
, int idx
, gfp_t gfp_mask
);
234 bl_parse_simple(struct nfs_server
*server
, struct pnfs_block_dev
*d
,
235 struct pnfs_block_volume
*volumes
, int idx
, gfp_t gfp_mask
)
237 struct pnfs_block_volume
*v
= &volumes
[idx
];
238 struct block_device
*bdev
;
241 dev
= bl_resolve_deviceid(server
, v
, gfp_mask
);
245 bdev
= blkdev_get_by_dev(dev
, FMODE_READ
| FMODE_WRITE
, NULL
);
247 printk(KERN_WARNING
"pNFS: failed to open device %d:%d (%ld)\n",
248 MAJOR(dev
), MINOR(dev
), PTR_ERR(bdev
));
249 return PTR_ERR(bdev
);
254 d
->len
= i_size_read(d
->bdev
->bd_inode
);
255 d
->map
= bl_map_simple
;
257 printk(KERN_INFO
"pNFS: using block device %s\n",
258 d
->bdev
->bd_disk
->disk_name
);
263 bl_validate_designator(struct pnfs_block_volume
*v
)
265 switch (v
->scsi
.designator_type
) {
266 case PS_DESIGNATOR_EUI64
:
267 if (v
->scsi
.code_set
!= PS_CODE_SET_BINARY
)
270 if (v
->scsi
.designator_len
!= 8 &&
271 v
->scsi
.designator_len
!= 10 &&
272 v
->scsi
.designator_len
!= 16)
276 case PS_DESIGNATOR_NAA
:
277 if (v
->scsi
.code_set
!= PS_CODE_SET_BINARY
)
280 if (v
->scsi
.designator_len
!= 8 &&
281 v
->scsi
.designator_len
!= 16)
285 case PS_DESIGNATOR_T10
:
286 case PS_DESIGNATOR_NAME
:
287 pr_err("pNFS: unsupported designator "
288 "(code set %d, type %d, len %d.\n",
290 v
->scsi
.designator_type
,
291 v
->scsi
.designator_len
);
294 pr_err("pNFS: invalid designator "
295 "(code set %d, type %d, len %d.\n",
297 v
->scsi
.designator_type
,
298 v
->scsi
.designator_len
);
304 * Try to open the udev path for the WWN. At least on Debian the udev
305 * by-id path will always point to the dm-multipath device if one exists.
307 static struct block_device
*
308 bl_open_udev_path(struct pnfs_block_volume
*v
)
310 struct block_device
*bdev
;
313 devname
= kasprintf(GFP_KERNEL
, "/dev/disk/by-id/wwn-0x%*phN",
314 v
->scsi
.designator_len
, v
->scsi
.designator
);
316 return ERR_PTR(-ENOMEM
);
318 bdev
= blkdev_get_by_path(devname
, FMODE_READ
| FMODE_WRITE
, NULL
);
320 pr_warn("pNFS: failed to open device %s (%ld)\n",
321 devname
, PTR_ERR(bdev
));
329 * Try to open the RH/Fedora specific dm-mpath udev path for this WWN, as the
330 * wwn- links will only point to the first discovered SCSI device there.
332 static struct block_device
*
333 bl_open_dm_mpath_udev_path(struct pnfs_block_volume
*v
)
335 struct block_device
*bdev
;
338 devname
= kasprintf(GFP_KERNEL
,
339 "/dev/disk/by-id/dm-uuid-mpath-%d%*phN",
340 v
->scsi
.designator_type
,
341 v
->scsi
.designator_len
, v
->scsi
.designator
);
343 return ERR_PTR(-ENOMEM
);
345 bdev
= blkdev_get_by_path(devname
, FMODE_READ
| FMODE_WRITE
, NULL
);
351 bl_parse_scsi(struct nfs_server
*server
, struct pnfs_block_dev
*d
,
352 struct pnfs_block_volume
*volumes
, int idx
, gfp_t gfp_mask
)
354 struct pnfs_block_volume
*v
= &volumes
[idx
];
355 struct block_device
*bdev
;
356 const struct pr_ops
*ops
;
359 if (!bl_validate_designator(v
))
362 bdev
= bl_open_dm_mpath_udev_path(v
);
364 bdev
= bl_open_udev_path(v
);
366 return PTR_ERR(bdev
);
369 d
->len
= i_size_read(d
->bdev
->bd_inode
);
370 d
->map
= bl_map_simple
;
371 d
->pr_key
= v
->scsi
.pr_key
;
373 pr_info("pNFS: using block device %s (reservation key 0x%llx)\n",
374 d
->bdev
->bd_disk
->disk_name
, d
->pr_key
);
376 ops
= d
->bdev
->bd_disk
->fops
->pr_ops
;
378 pr_err("pNFS: block device %s does not support reservations.",
379 d
->bdev
->bd_disk
->disk_name
);
384 error
= ops
->pr_register(d
->bdev
, 0, d
->pr_key
, true);
386 pr_err("pNFS: failed to register key for block device %s.",
387 d
->bdev
->bd_disk
->disk_name
);
391 d
->pr_registered
= true;
395 blkdev_put(d
->bdev
, FMODE_READ
| FMODE_WRITE
);
400 bl_parse_slice(struct nfs_server
*server
, struct pnfs_block_dev
*d
,
401 struct pnfs_block_volume
*volumes
, int idx
, gfp_t gfp_mask
)
403 struct pnfs_block_volume
*v
= &volumes
[idx
];
406 ret
= bl_parse_deviceid(server
, d
, volumes
, v
->slice
.volume
, gfp_mask
);
410 d
->disk_offset
= v
->slice
.start
;
411 d
->len
= v
->slice
.len
;
416 bl_parse_concat(struct nfs_server
*server
, struct pnfs_block_dev
*d
,
417 struct pnfs_block_volume
*volumes
, int idx
, gfp_t gfp_mask
)
419 struct pnfs_block_volume
*v
= &volumes
[idx
];
423 d
->children
= kcalloc(v
->concat
.volumes_count
,
424 sizeof(struct pnfs_block_dev
), GFP_KERNEL
);
428 for (i
= 0; i
< v
->concat
.volumes_count
; i
++) {
429 ret
= bl_parse_deviceid(server
, &d
->children
[i
],
430 volumes
, v
->concat
.volumes
[i
], gfp_mask
);
435 d
->children
[i
].start
+= len
;
436 len
+= d
->children
[i
].len
;
440 d
->map
= bl_map_concat
;
445 bl_parse_stripe(struct nfs_server
*server
, struct pnfs_block_dev
*d
,
446 struct pnfs_block_volume
*volumes
, int idx
, gfp_t gfp_mask
)
448 struct pnfs_block_volume
*v
= &volumes
[idx
];
452 d
->children
= kcalloc(v
->stripe
.volumes_count
,
453 sizeof(struct pnfs_block_dev
), GFP_KERNEL
);
457 for (i
= 0; i
< v
->stripe
.volumes_count
; i
++) {
458 ret
= bl_parse_deviceid(server
, &d
->children
[i
],
459 volumes
, v
->stripe
.volumes
[i
], gfp_mask
);
464 len
+= d
->children
[i
].len
;
468 d
->chunk_size
= v
->stripe
.chunk_size
;
469 d
->map
= bl_map_stripe
;
474 bl_parse_deviceid(struct nfs_server
*server
, struct pnfs_block_dev
*d
,
475 struct pnfs_block_volume
*volumes
, int idx
, gfp_t gfp_mask
)
477 switch (volumes
[idx
].type
) {
478 case PNFS_BLOCK_VOLUME_SIMPLE
:
479 return bl_parse_simple(server
, d
, volumes
, idx
, gfp_mask
);
480 case PNFS_BLOCK_VOLUME_SLICE
:
481 return bl_parse_slice(server
, d
, volumes
, idx
, gfp_mask
);
482 case PNFS_BLOCK_VOLUME_CONCAT
:
483 return bl_parse_concat(server
, d
, volumes
, idx
, gfp_mask
);
484 case PNFS_BLOCK_VOLUME_STRIPE
:
485 return bl_parse_stripe(server
, d
, volumes
, idx
, gfp_mask
);
486 case PNFS_BLOCK_VOLUME_SCSI
:
487 return bl_parse_scsi(server
, d
, volumes
, idx
, gfp_mask
);
489 dprintk("unsupported volume type: %d\n", volumes
[idx
].type
);
494 struct nfs4_deviceid_node
*
495 bl_alloc_deviceid_node(struct nfs_server
*server
, struct pnfs_device
*pdev
,
498 struct nfs4_deviceid_node
*node
= NULL
;
499 struct pnfs_block_volume
*volumes
;
500 struct pnfs_block_dev
*top
;
501 struct xdr_stream xdr
;
503 struct page
*scratch
;
504 int nr_volumes
, ret
, i
;
507 scratch
= alloc_page(gfp_mask
);
511 xdr_init_decode_pages(&xdr
, &buf
, pdev
->pages
, pdev
->pglen
);
512 xdr_set_scratch_buffer(&xdr
, page_address(scratch
), PAGE_SIZE
);
514 p
= xdr_inline_decode(&xdr
, sizeof(__be32
));
516 goto out_free_scratch
;
517 nr_volumes
= be32_to_cpup(p
++);
519 volumes
= kcalloc(nr_volumes
, sizeof(struct pnfs_block_volume
),
522 goto out_free_scratch
;
524 for (i
= 0; i
< nr_volumes
; i
++) {
525 ret
= nfs4_block_decode_volume(&xdr
, &volumes
[i
]);
527 goto out_free_volumes
;
530 top
= kzalloc(sizeof(*top
), gfp_mask
);
532 goto out_free_volumes
;
534 ret
= bl_parse_deviceid(server
, top
, volumes
, nr_volumes
- 1, gfp_mask
);
538 goto out_free_volumes
;
542 nfs4_init_deviceid_node(node
, server
, &pdev
->dev_id
);
547 __free_page(scratch
);