svn commit: r368410 - head/stand/libsa/zfs
Toomas Soome
tsoome at FreeBSD.org
Mon Dec 7 11:25:18 UTC 2020
Author: tsoome
Date: Mon Dec 7 11:25:18 2020
New Revision: 368410
URL: https://svnweb.freebsd.org/changeset/base/368410
Log:
loader: xdr_array is missing count
The integer arrays are encoded in nvlist as counted array <count, i0, i1...>,
loader xdr_array() is missing the count. This will affect the pool import when
there are hole devices in pool.
Also fix the new data add and print functions.
Modified:
head/stand/libsa/zfs/nvlist.c
Modified: head/stand/libsa/zfs/nvlist.c
==============================================================================
--- head/stand/libsa/zfs/nvlist.c Mon Dec 7 11:18:51 2020 (r368409)
+++ head/stand/libsa/zfs/nvlist.c Mon Dec 7 11:25:18 2020 (r368410)
@@ -63,7 +63,7 @@ static int
_getint(struct xdr *xdr, int *ip)
{
*ip = be32dec(xdr->xdr_idx);
- return (sizeof (int));
+ return (sizeof(int));
}
static int
@@ -72,14 +72,14 @@ _putint(struct xdr *xdr, int i)
int *ip = (int *)xdr->xdr_idx;
*ip = htobe32(i);
- return (sizeof (int));
+ return (sizeof(int));
}
static int
_getuint(struct xdr *xdr, unsigned *ip)
{
*ip = be32dec(xdr->xdr_idx);
- return (sizeof (unsigned));
+ return (sizeof(unsigned));
}
static int
@@ -88,9 +88,41 @@ _putuint(struct xdr *xdr, unsigned i)
unsigned *up = (unsigned *)xdr->xdr_idx;
*up = htobe32(i);
- return (sizeof (int));
+ return (sizeof(int));
}
+static int
+_getint_mem(struct xdr *xdr, int *ip)
+{
+ *ip = *(int *)xdr->xdr_idx;
+ return (sizeof(int));
+}
+
+static int
+_putint_mem(struct xdr *xdr, int i)
+{
+ int *ip = (int *)xdr->xdr_idx;
+
+ *ip = i;
+ return (sizeof(int));
+}
+
+static int
+_getuint_mem(struct xdr *xdr, unsigned *ip)
+{
+ *ip = *(unsigned *)xdr->xdr_idx;
+ return (sizeof(unsigned));
+}
+
+static int
+_putuint_mem(struct xdr *xdr, unsigned i)
+{
+ unsigned *up = (unsigned *)xdr->xdr_idx;
+
+ *up = i;
+ return (sizeof(int));
+}
+
/*
* XDR data translations.
*/
@@ -131,7 +163,7 @@ xdr_int(xdr_t *xdr, int *ip)
bool rv = false;
int *i = (int *)xdr->xdr_idx;
- if (xdr->xdr_idx + sizeof (int) > xdr->xdr_buf + xdr->xdr_buf_size)
+ if (xdr->xdr_idx + sizeof(int) > xdr->xdr_buf + xdr->xdr_buf_size)
return (rv);
switch (xdr->xdr_op) {
@@ -160,7 +192,7 @@ xdr_u_int(xdr_t *xdr, unsigned *ip)
bool rv = false;
unsigned *u = (unsigned *)xdr->xdr_idx;
- if (xdr->xdr_idx + sizeof (unsigned) > xdr->xdr_buf + xdr->xdr_buf_size)
+ if (xdr->xdr_idx + sizeof(unsigned) > xdr->xdr_buf + xdr->xdr_buf_size)
return (rv);
switch (xdr->xdr_op) {
@@ -183,28 +215,29 @@ xdr_u_int(xdr_t *xdr, unsigned *ip)
static bool
xdr_int64(xdr_t *xdr, int64_t *lp)
{
- int hi;
- unsigned lo;
bool rv = false;
- if (xdr->xdr_idx + sizeof (int64_t) > xdr->xdr_buf + xdr->xdr_buf_size)
+ if (xdr->xdr_idx + sizeof(int64_t) > xdr->xdr_buf + xdr->xdr_buf_size)
return (rv);
switch (xdr->xdr_op) {
case XDR_OP_ENCODE:
/* Encode value *lp, store to buf */
- hi = *lp >> 32;
- lo = *lp & UINT32_MAX;
- xdr->xdr_idx += xdr->xdr_putint(xdr, hi);
- xdr->xdr_idx += xdr->xdr_putint(xdr, lo);
+ if (xdr->xdr_putint == _putint)
+ *(int64_t *)xdr->xdr_idx = htobe64(*lp);
+ else
+ *(int64_t *)xdr->xdr_idx = *lp;
+ xdr->xdr_idx += sizeof(int64_t);
rv = true;
break;
case XDR_OP_DECODE:
/* Decode buf, return value to *ip */
- xdr->xdr_idx += xdr->xdr_getint(xdr, &hi);
- xdr->xdr_idx += xdr->xdr_getuint(xdr, &lo);
- *lp = (((int64_t)hi) << 32) | lo;
+ if (xdr->xdr_getint == _getint)
+ *lp = be64toh(*(int64_t *)xdr->xdr_idx);
+ else
+ *lp = *(int64_t *)xdr->xdr_idx;
+ xdr->xdr_idx += sizeof(int64_t);
rv = true;
}
return (rv);
@@ -213,27 +246,29 @@ xdr_int64(xdr_t *xdr, int64_t *lp)
static bool
xdr_uint64(xdr_t *xdr, uint64_t *lp)
{
- unsigned hi, lo;
bool rv = false;
- if (xdr->xdr_idx + sizeof (uint64_t) > xdr->xdr_buf + xdr->xdr_buf_size)
+ if (xdr->xdr_idx + sizeof(uint64_t) > xdr->xdr_buf + xdr->xdr_buf_size)
return (rv);
switch (xdr->xdr_op) {
case XDR_OP_ENCODE:
/* Encode value *ip, store to buf */
- hi = *lp >> 32;
- lo = *lp & UINT32_MAX;
- xdr->xdr_idx += xdr->xdr_putint(xdr, hi);
- xdr->xdr_idx += xdr->xdr_putint(xdr, lo);
+ if (xdr->xdr_putint == _putint)
+ *(uint64_t *)xdr->xdr_idx = htobe64(*lp);
+ else
+ *(uint64_t *)xdr->xdr_idx = *lp;
+ xdr->xdr_idx += sizeof(uint64_t);
rv = true;
break;
case XDR_OP_DECODE:
/* Decode buf, return value to *ip */
- xdr->xdr_idx += xdr->xdr_getuint(xdr, &hi);
- xdr->xdr_idx += xdr->xdr_getuint(xdr, &lo);
- *lp = (((uint64_t)hi) << 32) | lo;
+ if (xdr->xdr_getuint == _getuint)
+ *lp = be64toh(*(uint64_t *)xdr->xdr_idx);
+ else
+ *lp = *(uint64_t *)xdr->xdr_idx;
+ xdr->xdr_idx += sizeof(uint64_t);
rv = true;
}
return (rv);
@@ -262,7 +297,7 @@ xdr_string(xdr_t *xdr, nv_string_t *s)
switch (xdr->xdr_op) {
case XDR_OP_ENCODE:
size = s->nv_size;
- if (xdr->xdr_idx + sizeof (unsigned) + NV_ALIGN4(size) >
+ if (xdr->xdr_idx + sizeof(unsigned) + NV_ALIGN4(size) >
xdr->xdr_buf + xdr->xdr_buf_size)
break;
xdr->xdr_idx += xdr->xdr_putuint(xdr, s->nv_size);
@@ -271,7 +306,7 @@ xdr_string(xdr_t *xdr, nv_string_t *s)
break;
case XDR_OP_DECODE:
- if (xdr->xdr_idx + sizeof (unsigned) >
+ if (xdr->xdr_idx + sizeof(unsigned) >
xdr->xdr_buf + xdr->xdr_buf_size)
break;
size = xdr->xdr_getuint(xdr, &s->nv_size);
@@ -289,7 +324,11 @@ static bool
xdr_array(xdr_t *xdr, const unsigned nelem, const xdrproc_t elproc)
{
bool rv = true;
+ unsigned c = nelem;
+ if (!xdr_u_int(xdr, &c))
+ return (false);
+
for (unsigned i = 0; i < nelem; i++) {
if (!elproc(xdr, xdr->xdr_idx))
return (false);
@@ -334,14 +373,14 @@ nvlist_create(int flag)
nvlist_t *nvl;
nvs_data_t *nvs;
- nvl = calloc(1, sizeof (*nvl));
+ nvl = calloc(1, sizeof(*nvl));
if (nvl == NULL)
return (nvl);
nvl->nv_header.nvh_encoding = NV_ENCODE_XDR;
nvl->nv_header.nvh_endian = _BYTE_ORDER == _LITTLE_ENDIAN;
- nvl->nv_asize = nvl->nv_size = sizeof (*nvs);
+ nvl->nv_asize = nvl->nv_size = sizeof(*nvs);
nvs = calloc(1, nvl->nv_asize);
if (nvs == NULL) {
free(nvl);
@@ -378,7 +417,7 @@ nvlist_xdr_nvp(xdr_t *xdr, nvlist_t *nvl)
switch (type) {
case DATA_TYPE_NVLIST:
case DATA_TYPE_NVLIST_ARRAY:
- bzero(&nvlist, sizeof (nvlist));
+ bzero(&nvlist, sizeof(nvlist));
nvlist.nv_data = xdr->xdr_idx;
nvlist.nv_idx = nvlist.nv_data;
@@ -514,7 +553,7 @@ nvlist_xdr_nvlist(xdr_t *xdr, nvlist_t *nvl)
if (!xdr_u_int(xdr, &nvph->decoded_size))
return (EINVAL);
} else {
- xdr->xdr_idx += 2 * sizeof (unsigned);
+ xdr->xdr_idx += 2 * sizeof(unsigned);
}
rv = 0;
@@ -531,7 +570,7 @@ nvlist_xdr_nvlist(xdr_t *xdr, nvlist_t *nvl)
if (!xdr_u_int(xdr, &nvph->decoded_size))
return (EINVAL);
} else {
- xdr->xdr_idx += 2 * sizeof (unsigned);
+ xdr->xdr_idx += 2 * sizeof(unsigned);
}
}
return (rv);
@@ -546,7 +585,7 @@ nvlist_size_xdr(xdr_t *xdr, size_t *size)
uint8_t *pair;
unsigned encoded_size, decoded_size;
- xdr->xdr_idx += 2 * sizeof (unsigned);
+ xdr->xdr_idx += 2 * sizeof(unsigned);
pair = xdr->xdr_idx;
if (!xdr_u_int(xdr, &encoded_size) || !xdr_u_int(xdr, &decoded_size))
@@ -578,7 +617,7 @@ nvlist_next_nvpair(nvlist_t *nvl, nvp_header_t *nvh)
xdr.xdr_idx = nvl->nv_data;
xdr.xdr_buf_size = nvl->nv_size;
- xdr.xdr_idx += 2 * sizeof (unsigned);
+ xdr.xdr_idx += 2 * sizeof(unsigned);
/* Skip tp current pair */
if (nvh != NULL) {
@@ -590,12 +629,12 @@ nvlist_next_nvpair(nvlist_t *nvl, nvp_header_t *nvh)
return (NULL);
encoded_size = *(unsigned *)xdr.xdr_idx;
- xdr.xdr_idx += sizeof (unsigned);
+ xdr.xdr_idx += sizeof(unsigned);
if (xdr.xdr_idx > xdr.xdr_buf + xdr.xdr_buf_size)
return (NULL);
decoded_size = *(unsigned *)xdr.xdr_idx;
- xdr.xdr_idx += sizeof (unsigned);
+ xdr.xdr_idx += sizeof(unsigned);
if (xdr.xdr_idx > xdr.xdr_buf + xdr.xdr_buf_size)
return (NULL);
@@ -610,11 +649,11 @@ nvlist_next_nvpair(nvlist_t *nvl, nvp_header_t *nvh)
return (NULL);
encoded_size = *(unsigned *)xdr.xdr_idx;
- xdr.xdr_idx += sizeof (unsigned);
+ xdr.xdr_idx += sizeof(unsigned);
if (xdr.xdr_idx > xdr.xdr_buf + xdr.xdr_buf_size)
return (NULL);
decoded_size = *(unsigned *)xdr.xdr_idx;
- xdr.xdr_idx += sizeof (unsigned);
+ xdr.xdr_idx += sizeof(unsigned);
if (xdr.xdr_idx > xdr.xdr_buf + xdr.xdr_buf_size)
return (NULL);
@@ -634,29 +673,29 @@ nvlist_size_native(xdr_t *xdr, size_t *size)
uint8_t *pair;
unsigned encoded_size, decoded_size;
- xdr->xdr_idx += 2 * sizeof (unsigned);
+ xdr->xdr_idx += 2 * sizeof(unsigned);
pair = xdr->xdr_idx;
if (xdr->xdr_idx > xdr->xdr_buf + xdr->xdr_buf_size)
return (false);
encoded_size = *(unsigned *)xdr->xdr_idx;
- xdr->xdr_idx += sizeof (unsigned);
+ xdr->xdr_idx += sizeof(unsigned);
if (xdr->xdr_idx > xdr->xdr_buf + xdr->xdr_buf_size)
return (false);
decoded_size = *(unsigned *)xdr->xdr_idx;
- xdr->xdr_idx += sizeof (unsigned);
+ xdr->xdr_idx += sizeof(unsigned);
while (encoded_size && decoded_size) {
xdr->xdr_idx = pair + encoded_size;
pair = xdr->xdr_idx;
if (xdr->xdr_idx > xdr->xdr_buf + xdr->xdr_buf_size)
return (false);
encoded_size = *(unsigned *)xdr->xdr_idx;
- xdr->xdr_idx += sizeof (unsigned);
+ xdr->xdr_idx += sizeof(unsigned);
if (xdr->xdr_idx > xdr->xdr_buf + xdr->xdr_buf_size)
return (false);
decoded_size = *(unsigned *)xdr->xdr_idx;
- xdr->xdr_idx += sizeof (unsigned);
+ xdr->xdr_idx += sizeof(unsigned);
}
*size = xdr->xdr_idx - xdr->xdr_buf;
@@ -711,7 +750,7 @@ nvlist_import(const char *stream, size_t size)
be32toh(*(uint32_t *)(stream + 8)) != NV_UNIQUE_NAME)
return (NULL);
- nvl = malloc(sizeof (*nvl));
+ nvl = malloc(sizeof(*nvl));
if (nvl == NULL)
return (nvl);
@@ -810,7 +849,7 @@ clone_nvlist(const nvlist_t *nvl, const uint8_t *ptr,
{
nvlist_t *nv;
- nv = calloc(1, sizeof (*nv));
+ nv = calloc(1, sizeof(*nv));
if (nv == NULL)
return (ENOMEM);
@@ -843,7 +882,7 @@ nvlist_next(const uint8_t *ptr)
while (nvp->encoded_size != 0 && nvp->decoded_size != 0) {
nvp = (nvp_header_t *)((uint8_t *)nvp + nvp->encoded_size);
}
- return ((uint8_t *)nvp + sizeof (*nvp));
+ return ((uint8_t *)nvp + sizeof(*nvp));
}
/*
@@ -868,7 +907,7 @@ nvlist_find(const nvlist_t *nvl, const char *name, dat
nvp = &data->nvl_pair; /* first pair in nvlist */
while (nvp->encoded_size != 0 && nvp->decoded_size != 0) {
- nvp_name = (nv_string_t *)((uint8_t *)nvp + sizeof (*nvp));
+ nvp_name = (nv_string_t *)((uint8_t *)nvp + sizeof(*nvp));
if (nvl->nv_data + nvl->nv_size <
nvp_name->nv_data + nvp_name->nv_size)
return (EIO);
@@ -885,7 +924,7 @@ nvlist_find(const nvlist_t *nvl, const char *name, dat
switch (nvp_data->nv_type) {
case DATA_TYPE_UINT64:
bcopy(nvp_data->nv_data, valuep,
- sizeof (uint64_t));
+ sizeof(uint64_t));
return (0);
case DATA_TYPE_STRING:
nvp_name = (nv_string_t *)nvp_data->nv_data;
@@ -906,7 +945,7 @@ nvlist_find(const nvlist_t *nvl, const char *name, dat
case DATA_TYPE_NVLIST_ARRAY:
nvlist = calloc(nvp_data->nv_nelem,
- sizeof (nvlist_t *));
+ sizeof(nvlist_t *));
if (nvlist == NULL)
return (ENOMEM);
ptr = &nvp_data->nv_data[0];
@@ -957,14 +996,14 @@ get_value_size(data_type_t type, const void *data, uin
case DATA_TYPE_INT32:
case DATA_TYPE_UINT32:
/* Our smallest data unit is 32-bit */
- value_sz = sizeof (uint32_t);
+ value_sz = sizeof(uint32_t);
break;
case DATA_TYPE_HRTIME:
case DATA_TYPE_INT64:
- value_sz = sizeof (int64_t);
+ value_sz = sizeof(int64_t);
break;
case DATA_TYPE_UINT64:
- value_sz = sizeof (uint64_t);
+ value_sz = sizeof(uint64_t);
break;
case DATA_TYPE_STRING:
if (data == NULL)
@@ -973,7 +1012,7 @@ get_value_size(data_type_t type, const void *data, uin
value_sz = strlen(data) + 1;
break;
case DATA_TYPE_BYTE_ARRAY:
- value_sz = nelem * sizeof (uint8_t);
+ value_sz = nelem * sizeof(uint8_t);
break;
case DATA_TYPE_BOOLEAN_ARRAY:
case DATA_TYPE_INT8_ARRAY:
@@ -982,16 +1021,16 @@ get_value_size(data_type_t type, const void *data, uin
case DATA_TYPE_UINT16_ARRAY:
case DATA_TYPE_INT32_ARRAY:
case DATA_TYPE_UINT32_ARRAY:
- value_sz = (uint64_t)nelem * sizeof (uint32_t);
+ value_sz = (uint64_t)nelem * sizeof(uint32_t);
break;
case DATA_TYPE_INT64_ARRAY:
- value_sz = (uint64_t)nelem * sizeof (int64_t);
+ value_sz = (uint64_t)nelem * sizeof(int64_t);
break;
case DATA_TYPE_UINT64_ARRAY:
- value_sz = (uint64_t)nelem * sizeof (uint64_t);
+ value_sz = (uint64_t)nelem * sizeof(uint64_t);
break;
case DATA_TYPE_STRING_ARRAY:
- value_sz = (uint64_t)nelem * sizeof (uint64_t);
+ value_sz = (uint64_t)nelem * sizeof(uint64_t);
if (data != NULL) {
char *const *strs = data;
@@ -1011,7 +1050,7 @@ get_value_size(data_type_t type, const void *data, uin
value_sz = NV_ALIGN(6 * 4); /* sizeof nvlist_t */
break;
case DATA_TYPE_NVLIST_ARRAY:
- value_sz = (uint64_t)nelem * sizeof (uint64_t) +
+ value_sz = (uint64_t)nelem * sizeof(uint64_t) +
(uint64_t)nelem * NV_ALIGN(6 * 4); /* sizeof nvlist_t */
break;
default:
@@ -1041,12 +1080,12 @@ get_nvp_data_size(data_type_t type, const void *data,
case DATA_TYPE_INT32:
case DATA_TYPE_UINT32:
/* Our smallest data unit is 32-bit */
- value_sz = sizeof (uint32_t);
+ value_sz = sizeof(uint32_t);
break;
case DATA_TYPE_HRTIME:
case DATA_TYPE_INT64:
case DATA_TYPE_UINT64:
- value_sz = sizeof (uint64_t);
+ value_sz = sizeof(uint64_t);
break;
case DATA_TYPE_STRING:
value_sz = 4 + NV_ALIGN4(strlen(data));
@@ -1061,11 +1100,11 @@ get_nvp_data_size(data_type_t type, const void *data,
case DATA_TYPE_UINT16_ARRAY:
case DATA_TYPE_INT32_ARRAY:
case DATA_TYPE_UINT32_ARRAY:
- value_sz = 4 + (uint64_t)nelem * sizeof (uint32_t);
+ value_sz = 4 + (uint64_t)nelem * sizeof(uint32_t);
break;
case DATA_TYPE_INT64_ARRAY:
case DATA_TYPE_UINT64_ARRAY:
- value_sz = 4 + (uint64_t)nelem * sizeof (uint64_t);
+ value_sz = 4 + (uint64_t)nelem * sizeof(uint64_t);
break;
case DATA_TYPE_STRING_ARRAY:
if (data != NULL) {
@@ -1120,7 +1159,14 @@ nvlist_add_common(nvlist_t *nvl, const char *name, dat
uint8_t *ptr;
size_t namelen;
int decoded_size, encoded_size;
- xdr_t xdr;
+ xdr_t xdr = {
+ .xdr_op = XDR_OP_ENCODE,
+ .xdr_putint = _putint_mem,
+ .xdr_putuint = _putuint_mem,
+ .xdr_buf = nvl->nv_data,
+ .xdr_idx = nvl->nv_data,
+ .xdr_buf_size = nvl->nv_size
+ };
nvs = (nvs_data_t *)nvl->nv_data;
if (nvs->nvl_nvflag & NV_UNIQUE_NAME)
@@ -1146,7 +1192,7 @@ nvlist_add_common(nvlist_t *nvl, const char *name, dat
*
* The decoded size is calculated as:
* Note: namelen is with terminating 0.
- * NV_ALIGN(sizeof (nvpair_t) (4 * 4) + namelen + 1) +
+ * NV_ALIGN(sizeof(nvpair_t) (4 * 4) + namelen + 1) +
* NV_ALIGN(data_len)
*/
@@ -1160,88 +1206,133 @@ nvlist_add_common(nvlist_t *nvl, const char *name, dat
nvl->nv_data = ptr;
nvl->nv_asize += head.encoded_size;
}
- nvl->nv_idx = nvl->nv_data + nvl->nv_size - sizeof (*hp);
+ nvl->nv_idx = nvl->nv_data + nvl->nv_size - sizeof(*hp);
bzero(nvl->nv_idx, head.encoded_size + 8);
hp = (nvp_header_t *)nvl->nv_idx;
*hp = head;
- nvl->nv_idx += sizeof (*hp);
- *(unsigned *)nvl->nv_idx = namelen;
- nvl->nv_idx += sizeof (unsigned);
- strlcpy((char *)nvl->nv_idx, name, namelen + 1);
- nvl->nv_idx += NV_ALIGN4(namelen);
- *(unsigned *)nvl->nv_idx = type;
- nvl->nv_idx += sizeof (unsigned);
- *(unsigned *)nvl->nv_idx = nelem;
- nvl->nv_idx += sizeof (unsigned);
+ nvl->nv_idx += sizeof(*hp);
+ xdr.xdr_buf = nvl->nv_data;
+ xdr.xdr_idx = nvl->nv_idx;
+
+ xdr.xdr_idx += xdr.xdr_putuint(&xdr, namelen);
+ strlcpy((char *)xdr.xdr_idx, name, namelen + 1);
+ xdr.xdr_idx += NV_ALIGN4(namelen);
+ xdr.xdr_idx += xdr.xdr_putuint(&xdr, type);
+ xdr.xdr_idx += xdr.xdr_putuint(&xdr, nelem);
+
switch (type) {
case DATA_TYPE_BOOLEAN:
break;
+
case DATA_TYPE_BYTE_ARRAY:
- *(unsigned *)nvl->nv_idx = encoded_size;
- nvl->nv_idx += sizeof (unsigned);
- bcopy(data, nvl->nv_idx, nelem);
- nvl->nv_idx += encoded_size;
+ xdr.xdr_idx += xdr.xdr_putuint(&xdr, encoded_size);
+ bcopy(data, xdr.xdr_idx, nelem);
+ xdr.xdr_idx += NV_ALIGN4(encoded_size);
break;
+
case DATA_TYPE_STRING:
encoded_size = strlen(data);
- *(unsigned *)nvl->nv_idx = encoded_size;
- nvl->nv_idx += sizeof (unsigned);
- strlcpy((char *)nvl->nv_idx, data, encoded_size + 1);
- nvl->nv_idx += NV_ALIGN4(encoded_size);
+ xdr.xdr_idx += xdr.xdr_putuint(&xdr, encoded_size);
+ strlcpy((char *)xdr.xdr_idx, data, encoded_size + 1);
+ xdr.xdr_idx += NV_ALIGN4(encoded_size);
break;
+
case DATA_TYPE_STRING_ARRAY:
for (uint32_t i = 0; i < nelem; i++) {
encoded_size = strlen(((char **)data)[i]);
- *(unsigned *)nvl->nv_idx = encoded_size;
- nvl->nv_idx += sizeof (unsigned);
- strlcpy((char *)nvl->nv_idx, ((char **)data)[i],
+ xdr.xdr_idx += xdr.xdr_putuint(&xdr, encoded_size);
+ strlcpy((char *)xdr.xdr_idx, ((char **)data)[i],
encoded_size + 1);
- nvl->nv_idx += NV_ALIGN4(encoded_size);
+ xdr.xdr_idx += NV_ALIGN4(encoded_size);
}
break;
+
case DATA_TYPE_BYTE:
case DATA_TYPE_INT8:
case DATA_TYPE_UINT8:
+ xdr_char(&xdr, (char *)data);
+ break;
+
case DATA_TYPE_INT8_ARRAY:
case DATA_TYPE_UINT8_ARRAY:
- for (uint32_t i = 0; i < nelem; i++) {
- *(unsigned *)nvl->nv_idx = ((uint8_t *)data)[i];
- nvl->nv_idx += sizeof (unsigned);
- }
+ xdr_array(&xdr, nelem, (xdrproc_t)xdr_char);
break;
+
case DATA_TYPE_INT16:
+ xdr_short(&xdr, (short *)data);
+ break;
+
case DATA_TYPE_UINT16:
+ xdr_u_short(&xdr, (unsigned short *)data);
+ break;
+
case DATA_TYPE_INT16_ARRAY:
+ xdr_array(&xdr, nelem, (xdrproc_t)xdr_short);
+ break;
+
case DATA_TYPE_UINT16_ARRAY:
- for (uint32_t i = 0; i < nelem; i++) {
- *(unsigned *)nvl->nv_idx = ((uint16_t *)data)[i];
- nvl->nv_idx += sizeof (unsigned);
- }
+ xdr_array(&xdr, nelem, (xdrproc_t)xdr_u_short);
break;
+
+ case DATA_TYPE_BOOLEAN_VALUE:
+ case DATA_TYPE_INT32:
+ xdr_int(&xdr, (int *)data);
+ break;
+
+ case DATA_TYPE_UINT32:
+ xdr_u_int(&xdr, (unsigned int *)data);
+ break;
+
+ case DATA_TYPE_BOOLEAN_ARRAY:
+ case DATA_TYPE_INT32_ARRAY:
+ xdr_array(&xdr, nelem, (xdrproc_t)xdr_int);
+ break;
+
+ case DATA_TYPE_UINT32_ARRAY:
+ xdr_array(&xdr, nelem, (xdrproc_t)xdr_u_int);
+ break;
+
+ case DATA_TYPE_INT64:
+ xdr_int64(&xdr, (int64_t *)data);
+ break;
+
+ case DATA_TYPE_UINT64:
+ xdr_uint64(&xdr, (uint64_t *)data);
+ break;
+
+ case DATA_TYPE_INT64_ARRAY:
+ xdr_array(&xdr, nelem, (xdrproc_t)xdr_int64);
+ break;
+
+ case DATA_TYPE_UINT64_ARRAY:
+ xdr_array(&xdr, nelem, (xdrproc_t)xdr_uint64);
+ break;
+
case DATA_TYPE_NVLIST:
- bcopy(((nvlist_t *)data)->nv_data, nvl->nv_idx, encoded_size);
+ bcopy(((nvlist_t *)data)->nv_data, xdr.xdr_idx, encoded_size);
break;
+
case DATA_TYPE_NVLIST_ARRAY: {
- uint8_t *buf = nvl->nv_idx;
size_t size;
- xdr_t xdr;
+ xdr_t xdr_nv;
for (uint32_t i = 0; i < nelem; i++) {
- xdr.xdr_idx = ((nvlist_t **)data)[i]->nv_data;
- xdr.xdr_buf = xdr.xdr_idx;
- xdr.xdr_buf_size = ((nvlist_t **)data)[i]->nv_size;
+ xdr_nv.xdr_idx = ((nvlist_t **)data)[i]->nv_data;
+ xdr_nv.xdr_buf = xdr_nv.xdr_idx;
+ xdr_nv.xdr_buf_size = ((nvlist_t **)data)[i]->nv_size;
- if (!nvlist_size_native(&xdr, &size))
+ if (!nvlist_size_native(&xdr_nv, &size))
return (EINVAL);
- bcopy(((nvlist_t **)data)[i]->nv_data, buf, size);
- buf += size;
+ bcopy(((nvlist_t **)data)[i]->nv_data, xdr.xdr_idx,
+ size);
+ xdr.xdr_idx += size;
}
break;
}
default:
- bcopy(data, nvl->nv_idx, encoded_size);
+ bcopy(data, xdr.xdr_idx, encoded_size);
}
nvl->nv_size += head.encoded_size;
@@ -1465,11 +1556,17 @@ nvpair_print(nvp_header_t *nvp, unsigned int indent)
nv_string_t *nvp_name;
nv_pair_data_t *nvp_data;
nvlist_t nvlist;
- xdr_t xdr;
- unsigned i, j, u;
- uint64_t u64;
+ unsigned i, j;
+ xdr_t xdr = {
+ .xdr_op = XDR_OP_DECODE,
+ .xdr_getint = _getint_mem,
+ .xdr_getuint = _getuint_mem,
+ .xdr_buf = (const uint8_t *)nvp,
+ .xdr_idx = NULL,
+ .xdr_buf_size = nvp->encoded_size
+ };
- nvp_name = (nv_string_t *)((uintptr_t)nvp + sizeof (*nvp));
+ nvp_name = (nv_string_t *)((uintptr_t)nvp + sizeof(*nvp));
nvp_data = (nv_pair_data_t *)
NV_ALIGN4((uintptr_t)&nvp_name->nv_data[0] + nvp_name->nv_size);
@@ -1479,32 +1576,60 @@ nvpair_print(nvp_header_t *nvp, unsigned int indent)
printf("%s [%d] %.*s", typenames[nvp_data->nv_type],
nvp_data->nv_nelem, nvp_name->nv_size, nvp_name->nv_data);
+ xdr.xdr_idx = nvp_data->nv_data;
switch (nvp_data->nv_type) {
case DATA_TYPE_BYTE:
case DATA_TYPE_INT8:
- case DATA_TYPE_UINT8:
- bcopy(nvp_data->nv_data, &u, sizeof (u));
- printf(" = 0x%x\n", (unsigned char)u);
+ case DATA_TYPE_UINT8: {
+ char c;
+
+ if (xdr_char(&xdr, &c))
+ printf(" = 0x%x\n", c);
break;
+ }
case DATA_TYPE_INT16:
- case DATA_TYPE_UINT16:
- bcopy(nvp_data->nv_data, &u, sizeof (u));
- printf(" = 0x%hx\n", (unsigned short)u);
+ case DATA_TYPE_UINT16: {
+ unsigned short u;
+
+ if (xdr_u_short(&xdr, &u))
+ printf(" = 0x%hx\n", u);
break;
+ }
case DATA_TYPE_BOOLEAN_VALUE:
case DATA_TYPE_INT32:
- case DATA_TYPE_UINT32:
- bcopy(nvp_data->nv_data, &u, sizeof (u));
- printf(" = 0x%x\n", u);
+ case DATA_TYPE_UINT32: {
+ unsigned u;
+
+ if (xdr_u_int(&xdr, &u))
+ printf(" = 0x%x\n", u);
break;
+ }
case DATA_TYPE_INT64:
- case DATA_TYPE_UINT64:
- bcopy(nvp_data->nv_data, &u64, sizeof (u64));
- printf(" = 0x%jx\n", (uintmax_t)u64);
+ case DATA_TYPE_UINT64: {
+ uint64_t u;
+
+ if (xdr_uint64(&xdr, &u))
+ printf(" = 0x%jx\n", (uintmax_t)u);
break;
+ }
+
+ case DATA_TYPE_INT64_ARRAY:
+ case DATA_TYPE_UINT64_ARRAY: {
+ uint64_t *u;
+
+ if (xdr_array(&xdr, nvp_data->nv_nelem,
+ (xdrproc_t)xdr_uint64)) {
+ u = (uint64_t *)(nvp_data->nv_data + sizeof(unsigned));
+ for (i = 0; i < nvp_data->nv_nelem; i++)
+ printf(" [%u] = 0x%jx", i, (uintmax_t)u[i]);
+ printf("\n");
+ }
+
+ break;
+ }
case DATA_TYPE_STRING:
case DATA_TYPE_STRING_ARRAY:
More information about the svn-src-head
mailing list