dev.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2014-2016 Christoph Hellwig.
  4. */
  5. #include <linux/sunrpc/svc.h>
  6. #include <linux/blkdev.h>
  7. #include <linux/nfs4.h>
  8. #include <linux/nfs_fs.h>
  9. #include <linux/nfs_xdr.h>
  10. #include <linux/pr.h>
  11. #include "blocklayout.h"
  12. #include "../nfs4trace.h"
  13. #define NFSDBG_FACILITY NFSDBG_PNFS_LD
  14. static void bl_unregister_scsi(struct pnfs_block_dev *dev)
  15. {
  16. struct block_device *bdev = file_bdev(dev->bdev_file);
  17. const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
  18. int status;
  19. status = ops->pr_register(bdev, dev->pr_key, 0, false);
  20. if (status)
  21. trace_bl_pr_key_unreg_err(bdev, dev->pr_key, status);
  22. else
  23. trace_bl_pr_key_unreg(bdev, dev->pr_key);
  24. }
  25. static bool bl_register_scsi(struct pnfs_block_dev *dev)
  26. {
  27. struct block_device *bdev = file_bdev(dev->bdev_file);
  28. const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
  29. int status;
  30. if (test_and_set_bit(PNFS_BDEV_REGISTERED, &dev->flags))
  31. return true;
  32. status = ops->pr_register(bdev, 0, dev->pr_key, true);
  33. if (status) {
  34. trace_bl_pr_key_reg_err(bdev, dev->pr_key, status);
  35. return false;
  36. }
  37. trace_bl_pr_key_reg(bdev, dev->pr_key);
  38. return true;
  39. }
  40. static void bl_unregister_dev(struct pnfs_block_dev *dev)
  41. {
  42. u32 i;
  43. if (dev->nr_children) {
  44. for (i = 0; i < dev->nr_children; i++)
  45. bl_unregister_dev(&dev->children[i]);
  46. return;
  47. }
  48. if (dev->type == PNFS_BLOCK_VOLUME_SCSI &&
  49. test_and_clear_bit(PNFS_BDEV_REGISTERED, &dev->flags))
  50. bl_unregister_scsi(dev);
  51. }
  52. bool bl_register_dev(struct pnfs_block_dev *dev)
  53. {
  54. u32 i;
  55. if (dev->nr_children) {
  56. for (i = 0; i < dev->nr_children; i++) {
  57. if (!bl_register_dev(&dev->children[i])) {
  58. while (i > 0)
  59. bl_unregister_dev(&dev->children[--i]);
  60. return false;
  61. }
  62. }
  63. return true;
  64. }
  65. if (dev->type == PNFS_BLOCK_VOLUME_SCSI)
  66. return bl_register_scsi(dev);
  67. return true;
  68. }
  69. static void
  70. bl_free_device(struct pnfs_block_dev *dev)
  71. {
  72. bl_unregister_dev(dev);
  73. if (dev->nr_children) {
  74. int i;
  75. for (i = 0; i < dev->nr_children; i++)
  76. bl_free_device(&dev->children[i]);
  77. kfree(dev->children);
  78. } else {
  79. if (dev->bdev_file)
  80. fput(dev->bdev_file);
  81. }
  82. }
  83. void
  84. bl_free_deviceid_node(struct nfs4_deviceid_node *d)
  85. {
  86. struct pnfs_block_dev *dev =
  87. container_of(d, struct pnfs_block_dev, node);
  88. bl_free_device(dev);
  89. kfree_rcu(dev, node.rcu);
  90. }
  91. static int
  92. nfs4_block_decode_volume(struct xdr_stream *xdr, struct pnfs_block_volume *b)
  93. {
  94. __be32 *p;
  95. int i;
  96. p = xdr_inline_decode(xdr, 4);
  97. if (!p)
  98. return -EIO;
  99. b->type = be32_to_cpup(p++);
  100. switch (b->type) {
  101. case PNFS_BLOCK_VOLUME_SIMPLE:
  102. p = xdr_inline_decode(xdr, 4);
  103. if (!p)
  104. return -EIO;
  105. b->simple.nr_sigs = be32_to_cpup(p++);
  106. if (!b->simple.nr_sigs || b->simple.nr_sigs > PNFS_BLOCK_MAX_UUIDS) {
  107. dprintk("Bad signature count: %d\n", b->simple.nr_sigs);
  108. return -EIO;
  109. }
  110. b->simple.len = 4 + 4;
  111. for (i = 0; i < b->simple.nr_sigs; i++) {
  112. p = xdr_inline_decode(xdr, 8 + 4);
  113. if (!p)
  114. return -EIO;
  115. p = xdr_decode_hyper(p, &b->simple.sigs[i].offset);
  116. b->simple.sigs[i].sig_len = be32_to_cpup(p++);
  117. if (b->simple.sigs[i].sig_len > PNFS_BLOCK_UUID_LEN) {
  118. pr_info("signature too long: %d\n",
  119. b->simple.sigs[i].sig_len);
  120. return -EIO;
  121. }
  122. p = xdr_inline_decode(xdr, b->simple.sigs[i].sig_len);
  123. if (!p)
  124. return -EIO;
  125. memcpy(&b->simple.sigs[i].sig, p,
  126. b->simple.sigs[i].sig_len);
  127. b->simple.len += 8 + 4 + \
  128. (XDR_QUADLEN(b->simple.sigs[i].sig_len) << 2);
  129. }
  130. break;
  131. case PNFS_BLOCK_VOLUME_SLICE:
  132. p = xdr_inline_decode(xdr, 8 + 8 + 4);
  133. if (!p)
  134. return -EIO;
  135. p = xdr_decode_hyper(p, &b->slice.start);
  136. p = xdr_decode_hyper(p, &b->slice.len);
  137. b->slice.volume = be32_to_cpup(p++);
  138. break;
  139. case PNFS_BLOCK_VOLUME_CONCAT:
  140. p = xdr_inline_decode(xdr, 4);
  141. if (!p)
  142. return -EIO;
  143. b->concat.volumes_count = be32_to_cpup(p++);
  144. if (b->concat.volumes_count > PNFS_BLOCK_MAX_DEVICES) {
  145. dprintk("Too many volumes: %d\n", b->concat.volumes_count);
  146. return -EIO;
  147. }
  148. p = xdr_inline_decode(xdr, b->concat.volumes_count * 4);
  149. if (!p)
  150. return -EIO;
  151. for (i = 0; i < b->concat.volumes_count; i++)
  152. b->concat.volumes[i] = be32_to_cpup(p++);
  153. break;
  154. case PNFS_BLOCK_VOLUME_STRIPE:
  155. p = xdr_inline_decode(xdr, 8 + 4);
  156. if (!p)
  157. return -EIO;
  158. p = xdr_decode_hyper(p, &b->stripe.chunk_size);
  159. b->stripe.volumes_count = be32_to_cpup(p++);
  160. if (b->stripe.volumes_count > PNFS_BLOCK_MAX_DEVICES) {
  161. dprintk("Too many volumes: %d\n", b->stripe.volumes_count);
  162. return -EIO;
  163. }
  164. p = xdr_inline_decode(xdr, b->stripe.volumes_count * 4);
  165. if (!p)
  166. return -EIO;
  167. for (i = 0; i < b->stripe.volumes_count; i++)
  168. b->stripe.volumes[i] = be32_to_cpup(p++);
  169. break;
  170. case PNFS_BLOCK_VOLUME_SCSI:
  171. p = xdr_inline_decode(xdr, 4 + 4 + 4);
  172. if (!p)
  173. return -EIO;
  174. b->scsi.code_set = be32_to_cpup(p++);
  175. b->scsi.designator_type = be32_to_cpup(p++);
  176. b->scsi.designator_len = be32_to_cpup(p++);
  177. p = xdr_inline_decode(xdr, b->scsi.designator_len);
  178. if (!p)
  179. return -EIO;
  180. if (b->scsi.designator_len > 256)
  181. return -EIO;
  182. memcpy(&b->scsi.designator, p, b->scsi.designator_len);
  183. p = xdr_inline_decode(xdr, 8);
  184. if (!p)
  185. return -EIO;
  186. p = xdr_decode_hyper(p, &b->scsi.pr_key);
  187. break;
  188. default:
  189. dprintk("unknown volume type!\n");
  190. return -EIO;
  191. }
  192. return 0;
  193. }
  194. static bool bl_map_simple(struct pnfs_block_dev *dev, u64 offset,
  195. struct pnfs_block_dev_map *map)
  196. {
  197. map->start = dev->start;
  198. map->len = dev->len;
  199. map->disk_offset = dev->disk_offset;
  200. map->bdev = file_bdev(dev->bdev_file);
  201. return true;
  202. }
  203. static bool bl_map_concat(struct pnfs_block_dev *dev, u64 offset,
  204. struct pnfs_block_dev_map *map)
  205. {
  206. int i;
  207. for (i = 0; i < dev->nr_children; i++) {
  208. struct pnfs_block_dev *child = &dev->children[i];
  209. if (child->start > offset ||
  210. child->start + child->len <= offset)
  211. continue;
  212. child->map(child, offset - child->start, map);
  213. return true;
  214. }
  215. dprintk("%s: ran off loop!\n", __func__);
  216. return false;
  217. }
  218. static bool bl_map_stripe(struct pnfs_block_dev *dev, u64 offset,
  219. struct pnfs_block_dev_map *map)
  220. {
  221. struct pnfs_block_dev *child;
  222. u64 chunk;
  223. u32 chunk_idx;
  224. u64 disk_chunk;
  225. u64 disk_offset;
  226. chunk = div_u64(offset, dev->chunk_size);
  227. disk_chunk = div_u64_rem(chunk, dev->nr_children, &chunk_idx);
  228. if (chunk_idx >= dev->nr_children) {
  229. dprintk("%s: invalid chunk idx %d (%lld/%lld)\n",
  230. __func__, chunk_idx, offset, dev->chunk_size);
  231. /* error, should not happen */
  232. return false;
  233. }
  234. /* truncate offset to the beginning of the stripe */
  235. offset = chunk * dev->chunk_size;
  236. /* disk offset of the stripe */
  237. disk_offset = disk_chunk * dev->chunk_size;
  238. child = &dev->children[chunk_idx];
  239. child->map(child, disk_offset, map);
  240. map->start += offset;
  241. map->disk_offset += disk_offset;
  242. map->len = dev->chunk_size;
  243. return true;
  244. }
  245. static int
  246. bl_parse_deviceid(struct nfs_server *server, struct pnfs_block_dev *d,
  247. struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask);
  248. static int
  249. bl_parse_simple(struct nfs_server *server, struct pnfs_block_dev *d,
  250. struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask)
  251. {
  252. struct pnfs_block_volume *v = &volumes[idx];
  253. struct file *bdev_file;
  254. dev_t dev;
  255. dev = bl_resolve_deviceid(server, v, gfp_mask);
  256. if (!dev)
  257. return -EIO;
  258. bdev_file = bdev_file_open_by_dev(dev, BLK_OPEN_READ | BLK_OPEN_WRITE,
  259. NULL, NULL);
  260. if (IS_ERR(bdev_file)) {
  261. printk(KERN_WARNING "pNFS: failed to open device %d:%d (%ld)\n",
  262. MAJOR(dev), MINOR(dev), PTR_ERR(bdev_file));
  263. return PTR_ERR(bdev_file);
  264. }
  265. d->bdev_file = bdev_file;
  266. d->len = bdev_nr_bytes(file_bdev(bdev_file));
  267. d->map = bl_map_simple;
  268. printk(KERN_INFO "pNFS: using block device %s\n",
  269. file_bdev(bdev_file)->bd_disk->disk_name);
  270. return 0;
  271. }
  272. static bool
  273. bl_validate_designator(struct pnfs_block_volume *v)
  274. {
  275. switch (v->scsi.designator_type) {
  276. case PS_DESIGNATOR_EUI64:
  277. if (v->scsi.code_set != PS_CODE_SET_BINARY)
  278. return false;
  279. if (v->scsi.designator_len != 8 &&
  280. v->scsi.designator_len != 10 &&
  281. v->scsi.designator_len != 16)
  282. return false;
  283. return true;
  284. case PS_DESIGNATOR_NAA:
  285. if (v->scsi.code_set != PS_CODE_SET_BINARY)
  286. return false;
  287. if (v->scsi.designator_len != 8 &&
  288. v->scsi.designator_len != 16)
  289. return false;
  290. return true;
  291. case PS_DESIGNATOR_T10:
  292. case PS_DESIGNATOR_NAME:
  293. pr_err("pNFS: unsupported designator "
  294. "(code set %d, type %d, len %d.\n",
  295. v->scsi.code_set,
  296. v->scsi.designator_type,
  297. v->scsi.designator_len);
  298. return false;
  299. default:
  300. pr_err("pNFS: invalid designator "
  301. "(code set %d, type %d, len %d.\n",
  302. v->scsi.code_set,
  303. v->scsi.designator_type,
  304. v->scsi.designator_len);
  305. return false;
  306. }
  307. }
  308. static struct file *
  309. bl_open_path(struct pnfs_block_volume *v, const char *prefix)
  310. {
  311. struct file *bdev_file;
  312. const char *devname;
  313. devname = kasprintf(GFP_KERNEL, "/dev/disk/by-id/%s%*phN",
  314. prefix, v->scsi.designator_len, v->scsi.designator);
  315. if (!devname)
  316. return ERR_PTR(-ENOMEM);
  317. bdev_file = bdev_file_open_by_path(devname, BLK_OPEN_READ | BLK_OPEN_WRITE,
  318. NULL, NULL);
  319. if (IS_ERR(bdev_file)) {
  320. dprintk("failed to open device %s (%ld)\n",
  321. devname, PTR_ERR(bdev_file));
  322. }
  323. kfree(devname);
  324. return bdev_file;
  325. }
  326. static int
  327. bl_parse_scsi(struct nfs_server *server, struct pnfs_block_dev *d,
  328. struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask)
  329. {
  330. struct pnfs_block_volume *v = &volumes[idx];
  331. struct block_device *bdev;
  332. const struct pr_ops *ops;
  333. struct file *bdev_file;
  334. int error;
  335. if (!bl_validate_designator(v))
  336. return -EINVAL;
  337. /*
  338. * Try to open the RH/Fedora specific dm-mpath udev path first, as the
  339. * wwn- links will only point to the first discovered SCSI device there.
  340. * On other distributions like Debian, the default SCSI by-id path will
  341. * point to the dm-multipath device if one exists.
  342. */
  343. bdev_file = bl_open_path(v, "dm-uuid-mpath-0x");
  344. if (IS_ERR(bdev_file))
  345. bdev_file = bl_open_path(v, "wwn-0x");
  346. if (IS_ERR(bdev_file))
  347. bdev_file = bl_open_path(v, "nvme-eui.");
  348. if (IS_ERR(bdev_file)) {
  349. pr_warn("pNFS: no device found for volume %*phN\n",
  350. v->scsi.designator_len, v->scsi.designator);
  351. return PTR_ERR(bdev_file);
  352. }
  353. d->bdev_file = bdev_file;
  354. bdev = file_bdev(bdev_file);
  355. d->len = bdev_nr_bytes(bdev);
  356. d->map = bl_map_simple;
  357. d->pr_key = v->scsi.pr_key;
  358. if (d->len == 0)
  359. return -ENODEV;
  360. ops = bdev->bd_disk->fops->pr_ops;
  361. if (!ops) {
  362. pr_err("pNFS: block device %s does not support reservations.",
  363. bdev->bd_disk->disk_name);
  364. error = -EINVAL;
  365. goto out_blkdev_put;
  366. }
  367. return 0;
  368. out_blkdev_put:
  369. fput(d->bdev_file);
  370. return error;
  371. }
  372. static int
  373. bl_parse_slice(struct nfs_server *server, struct pnfs_block_dev *d,
  374. struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask)
  375. {
  376. struct pnfs_block_volume *v = &volumes[idx];
  377. int ret;
  378. ret = bl_parse_deviceid(server, d, volumes, v->slice.volume, gfp_mask);
  379. if (ret)
  380. return ret;
  381. d->disk_offset = v->slice.start;
  382. d->len = v->slice.len;
  383. return 0;
  384. }
  385. static int
  386. bl_parse_concat(struct nfs_server *server, struct pnfs_block_dev *d,
  387. struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask)
  388. {
  389. struct pnfs_block_volume *v = &volumes[idx];
  390. u64 len = 0;
  391. int ret, i;
  392. d->children = kcalloc(v->concat.volumes_count,
  393. sizeof(struct pnfs_block_dev), gfp_mask);
  394. if (!d->children)
  395. return -ENOMEM;
  396. for (i = 0; i < v->concat.volumes_count; i++) {
  397. ret = bl_parse_deviceid(server, &d->children[i],
  398. volumes, v->concat.volumes[i], gfp_mask);
  399. if (ret)
  400. return ret;
  401. d->nr_children++;
  402. d->children[i].start += len;
  403. len += d->children[i].len;
  404. }
  405. d->len = len;
  406. d->map = bl_map_concat;
  407. return 0;
  408. }
  409. static int
  410. bl_parse_stripe(struct nfs_server *server, struct pnfs_block_dev *d,
  411. struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask)
  412. {
  413. struct pnfs_block_volume *v = &volumes[idx];
  414. u64 len = 0;
  415. int ret, i;
  416. d->children = kcalloc(v->stripe.volumes_count,
  417. sizeof(struct pnfs_block_dev), gfp_mask);
  418. if (!d->children)
  419. return -ENOMEM;
  420. for (i = 0; i < v->stripe.volumes_count; i++) {
  421. ret = bl_parse_deviceid(server, &d->children[i],
  422. volumes, v->stripe.volumes[i], gfp_mask);
  423. if (ret)
  424. return ret;
  425. d->nr_children++;
  426. len += d->children[i].len;
  427. }
  428. d->len = len;
  429. d->chunk_size = v->stripe.chunk_size;
  430. d->map = bl_map_stripe;
  431. return 0;
  432. }
  433. static int
  434. bl_parse_deviceid(struct nfs_server *server, struct pnfs_block_dev *d,
  435. struct pnfs_block_volume *volumes, int idx, gfp_t gfp_mask)
  436. {
  437. d->type = volumes[idx].type;
  438. switch (d->type) {
  439. case PNFS_BLOCK_VOLUME_SIMPLE:
  440. return bl_parse_simple(server, d, volumes, idx, gfp_mask);
  441. case PNFS_BLOCK_VOLUME_SLICE:
  442. return bl_parse_slice(server, d, volumes, idx, gfp_mask);
  443. case PNFS_BLOCK_VOLUME_CONCAT:
  444. return bl_parse_concat(server, d, volumes, idx, gfp_mask);
  445. case PNFS_BLOCK_VOLUME_STRIPE:
  446. return bl_parse_stripe(server, d, volumes, idx, gfp_mask);
  447. case PNFS_BLOCK_VOLUME_SCSI:
  448. return bl_parse_scsi(server, d, volumes, idx, gfp_mask);
  449. default:
  450. dprintk("unsupported volume type: %d\n", d->type);
  451. return -EIO;
  452. }
  453. }
  454. struct nfs4_deviceid_node *
  455. bl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
  456. gfp_t gfp_mask)
  457. {
  458. struct nfs4_deviceid_node *node = NULL;
  459. struct pnfs_block_volume *volumes;
  460. struct pnfs_block_dev *top;
  461. struct xdr_stream xdr;
  462. struct xdr_buf buf;
  463. struct page *scratch;
  464. int nr_volumes, ret, i;
  465. __be32 *p;
  466. scratch = alloc_page(gfp_mask);
  467. if (!scratch)
  468. goto out;
  469. xdr_init_decode_pages(&xdr, &buf, pdev->pages, pdev->pglen);
  470. xdr_set_scratch_page(&xdr, scratch);
  471. p = xdr_inline_decode(&xdr, sizeof(__be32));
  472. if (!p)
  473. goto out_free_scratch;
  474. nr_volumes = be32_to_cpup(p++);
  475. volumes = kcalloc(nr_volumes, sizeof(struct pnfs_block_volume),
  476. gfp_mask);
  477. if (!volumes)
  478. goto out_free_scratch;
  479. for (i = 0; i < nr_volumes; i++) {
  480. ret = nfs4_block_decode_volume(&xdr, &volumes[i]);
  481. if (ret < 0)
  482. goto out_free_volumes;
  483. }
  484. top = kzalloc(sizeof(*top), gfp_mask);
  485. if (!top)
  486. goto out_free_volumes;
  487. ret = bl_parse_deviceid(server, top, volumes, nr_volumes - 1, gfp_mask);
  488. node = &top->node;
  489. nfs4_init_deviceid_node(node, server, &pdev->dev_id);
  490. if (ret)
  491. nfs4_mark_deviceid_unavailable(node);
  492. out_free_volumes:
  493. kfree(volumes);
  494. out_free_scratch:
  495. __free_page(scratch);
  496. out:
  497. return node;
  498. }