Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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