4799697 nfs messages could be more useful
6354997 File changes on NFSv4 servers take a long time to be detected
6355634 Client handling of CB_GETATTR fails to set bitmap
--- a/usr/src/uts/common/fs/nfs/nfs4_callback.c Tue Jan 10 08:05:23 2006 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_callback.c Tue Jan 10 08:52:24 2006 -0800
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -93,8 +93,6 @@
nfs_space_limit4 nfs4_deleg_space_phony2 = { NFS_LIMIT_BLOCKS, 0 };
nfs_modified_limit4 nfs4_deleg_space_phonyl = { 8, 512 };
changeid4 nfs4_deleg_change_phony = 0x7eeeeeee76666660LL;
-/* ignore malformed file handle on recall, bug in linux server */
-int nfs4_linux_bug = 1;
int nfs4_use_phony_limit;
int nfs4_use_phony_recall;
int nfs4_phony_recall_v;
@@ -192,7 +190,7 @@
bool_t found = FALSE;
struct nfs4_server *sp;
struct fattr4 *fap;
- char *fdata = NULL;
+ rpc_inline_t *fdata;
long mapcnt;
fattr4_change change;
fattr4_size size;
@@ -317,7 +315,7 @@
fap->attrmask = 0;
/* attrlist4_len starts at 0 and increases as attrs are processed */
- fap->attrlist4 = fdata;
+ fap->attrlist4 = (char *)fdata;
fap->attrlist4_len = 0;
/* don't supply attrs if request was zero */
@@ -359,6 +357,7 @@
*/
IXDR_PUT_U_HYPER(fdata, change);
fap->attrlist4_len += 2 * BYTES_PER_XDR_UNIT;
+ fap->attrmask |= FATTR4_CHANGE_MASK;
}
if (args->attr_request & FATTR4_SIZE_MASK) {
@@ -376,6 +375,7 @@
*/
IXDR_PUT_U_HYPER(fdata, size);
fap->attrlist4_len += 2 * BYTES_PER_XDR_UNIT;
+ fap->attrmask |= FATTR4_SIZE_MASK;
}
}
@@ -457,11 +457,6 @@
} else {
#ifdef DEBUG
CB_WARN("cb_recall: stateid OK, bad fh");
-
- if (nfs4_linux_bug) {
- found = TRUE;
- break;
- }
#endif
}
}
@@ -735,7 +730,7 @@
break;
case CB_COMPOUND:
- xdr_args = xdr_CB_COMPOUND4args;
+ xdr_args = xdr_CB_COMPOUND4args_clnt;
xdr_res = xdr_CB_COMPOUND4res;
proc = cb_compound;
freeproc = cb_compound_free;
--- a/usr/src/uts/common/fs/nfs/nfs4_srv_attr.c Tue Jan 10 08:05:23 2006 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv_attr.c Tue Jan 10 08:52:24 2006 -0800
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -753,19 +753,37 @@
return (error);
}
+/*
+ * Server side compare of a filehandle from the wire to a native
+ * server filehandle.
+ */
+static int
+rfs4fhcmp(nfs_fh4 *wirefh, nfs_fh4 *srvfh)
+{
+ nfs_fh4_fmt_t fh;
+
+ ASSERT(IS_P2ALIGNED(wirefh->nfs_fh4_val, sizeof (uint32_t)));
+
+ bzero(&fh, sizeof (nfs_fh4_fmt_t));
+ if (!xdr_inline_decode_nfs_fh4((uint32_t *)wirefh->nfs_fh4_val, &fh,
+ wirefh->nfs_fh4_len))
+ return (1);
+
+ return (bcmp(srvfh->nfs_fh4_val, &fh, srvfh->nfs_fh4_len));
+}
+
/* ARGSUSED */
static int
rfs4_fattr4_filehandle(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
union nfs4_attr_u *na)
{
- int error = 0;
nfs_fh4 *fh;
switch (cmd) {
case NFS4ATTR_SUPPORTED:
if (sarg->op == NFS4ATTR_SETIT)
- error = EINVAL;
- break; /* this attr is supported */
+ return (EINVAL);
+ return (0); /* this attr is supported */
case NFS4ATTR_GETIT:
/*
* If sarg->cs->fh is all zeros then should makefh a new
@@ -773,42 +791,44 @@
*/
fh = &sarg->cs->fh;
if (sarg->cs->fh.nfs_fh4_len == 0) {
- if (sarg->rdattr_error && (sarg->cs->vp == NULL)) {
- error = -1; /* okay if rdattr_error */
- break;
- }
+ if (sarg->rdattr_error && (sarg->cs->vp == NULL))
+ return (-1); /* okay if rdattr_error */
ASSERT(sarg->cs->vp != NULL);
na->filehandle.nfs_fh4_val =
- kmem_alloc(NFS_FH4_LEN, KM_SLEEP);
- error = makefh4(&na->filehandle, sarg->cs->vp,
- sarg->cs->exi);
- } else {
- na->filehandle.nfs_fh4_val =
- kmem_alloc(fh->nfs_fh4_len, KM_SLEEP);
- nfs_fh4_copy(fh, &na->filehandle);
+ kmem_alloc(NFS_FH4_LEN, KM_SLEEP);
+ return (makefh4(&na->filehandle, sarg->cs->vp,
+ sarg->cs->exi));
}
- break;
+ na->filehandle.nfs_fh4_val =
+ kmem_alloc(fh->nfs_fh4_len, KM_SLEEP);
+ nfs_fh4_copy(fh, &na->filehandle);
+ return (0);
case NFS4ATTR_SETIT:
/*
* read-only attr
*/
- error = EINVAL;
- break;
+ return (EINVAL);
case NFS4ATTR_VERIT:
- if (nfs4cmpfh(&na->filehandle, &sarg->cs->fh))
- error = -1; /* no match */
- break;
+ /*
+ * A verify of a filehandle will have the client sending
+ * the raw format which needs to be compared to the
+ * native format.
+ */
+ if (rfs4fhcmp(&na->filehandle, &sarg->cs->fh) == 1)
+ return (-1); /* no match */
+ return (0);
case NFS4ATTR_FREEIT:
- if (sarg->op == NFS4ATTR_GETIT) {
- if (na->filehandle.nfs_fh4_val) {
- kmem_free(na->filehandle.nfs_fh4_val,
- na->filehandle.nfs_fh4_len);
- bzero(&na->filehandle, sizeof (na->filehandle));
- }
- }
- break;
+ if (sarg->op != NFS4ATTR_GETIT)
+ return (0);
+ if (na->filehandle.nfs_fh4_val == NULL)
+ return (0);
+ kmem_free(na->filehandle.nfs_fh4_val,
+ na->filehandle.nfs_fh4_len);
+ na->filehandle.nfs_fh4_val = NULL;
+ na->filehandle.nfs_fh4_len = 0;
+ return (0);
}
- return (error);
+ return (0);
}
/*
--- a/usr/src/uts/common/fs/nfs/nfs4_srv_deleg.c Tue Jan 10 08:05:23 2006 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv_deleg.c Tue Jan 10 08:52:24 2006 -0800
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -833,7 +833,7 @@
*/
args->callback_ident = cbp->cb_ident;
- stat = clnt_call(ch, CB_COMPOUND, xdr_CB_COMPOUND4args,
+ stat = clnt_call(ch, CB_COMPOUND, xdr_CB_COMPOUND4args_srv,
(caddr_t)args, xdr_CB_COMPOUND4res,
(caddr_t)res, timeout);
--- a/usr/src/uts/common/fs/nfs/nfs4_xdr.c Tue Jan 10 08:05:23 2006 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_xdr.c Tue Jan 10 08:52:24 2006 -0800
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc.
+ * Copyright 2006 Sun Microsystems, Inc.
* All rights reserved. Use is subject to license terms.
*/
@@ -149,6 +149,179 @@
}
/*
+ * XDR_INLINE decode a filehandle.
+ */
+bool_t
+xdr_inline_decode_nfs_fh4(uint32_t *ptr, nfs_fh4_fmt_t *fhp, uint32_t fhsize)
+{
+ uchar_t *bp = (uchar_t *)ptr;
+ uchar_t *cp;
+ uint32_t dsize;
+ uintptr_t resid;
+
+ /*
+ * Check to see if what the client sent us is bigger or smaller
+ * than what we can ever possibly send out. NFS_FHMAXDATA is
+ * unfortunately badly named as it is no longer the max and is
+ * really the min of what is sent over the wire.
+ */
+ if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
+ sizeof (ushort_t) + NFS_FHMAXDATA +
+ sizeof (ushort_t) + NFS_FHMAXDATA)) {
+ return (FALSE);
+ }
+
+ /*
+ * All internal parts of a filehandle are in native byte order.
+ *
+ * Decode what should be fh4_fsid, it is aligned.
+ */
+ fhp->fh4_fsid.val[0] = *(uint32_t *)bp;
+ bp += BYTES_PER_XDR_UNIT;
+ fhp->fh4_fsid.val[1] = *(uint32_t *)bp;
+ bp += BYTES_PER_XDR_UNIT;
+
+ /*
+ * Decode what should be fh4_len. fh4_len is two bytes, so we're
+ * unaligned now.
+ */
+ cp = (uchar_t *)&fhp->fh4_len;
+ *cp++ = *bp++;
+ *cp++ = *bp++;
+ fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
+
+ /*
+ * For backwards compatability, the fid length may be less than
+ * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
+ */
+ dsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
+
+ /*
+ * Make sure the client isn't sending us a bogus length for fh4_data.
+ */
+ if (fhsize < dsize)
+ return (FALSE);
+ bcopy(bp, fhp->fh4_data, dsize);
+ bp += dsize;
+ fhsize -= dsize;
+
+ if (fhsize < sizeof (ushort_t))
+ return (FALSE);
+ cp = (uchar_t *)&fhp->fh4_xlen;
+ *cp++ = *bp++;
+ *cp++ = *bp++;
+ fhsize -= sizeof (ushort_t);
+
+ dsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
+
+ /*
+ * Make sure the client isn't sending us a bogus length for fh4_xdata.
+ */
+ if (fhsize < dsize)
+ return (FALSE);
+ bcopy(bp, fhp->fh4_xdata, dsize);
+ fhsize -= dsize;
+ bp += dsize;
+
+ /*
+ * We realign things on purpose, so skip any padding
+ */
+ resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
+ if (resid != 0) {
+ if (fhsize < (BYTES_PER_XDR_UNIT - resid))
+ return (FALSE);
+ bp += BYTES_PER_XDR_UNIT - resid;
+ fhsize -= BYTES_PER_XDR_UNIT - resid;
+ }
+
+ if (fhsize < BYTES_PER_XDR_UNIT)
+ return (FALSE);
+ fhp->fh4_flag = *(uint32_t *)bp;
+ bp += BYTES_PER_XDR_UNIT;
+ fhsize -= BYTES_PER_XDR_UNIT;
+
+#ifdef VOLATILE_FH_TEST
+ if (fhsize < BYTES_PER_XDR_UNIT)
+ return (FALSE);
+ fhp->fh4_volatile_id = *(uint32_t *)bp;
+ bp += BYTES_PER_XDR_UNIT;
+ fhsize -= BYTES_PER_XDR_UNIT;
+#endif
+ /*
+ * Make sure client didn't send extra bytes
+ */
+ if (fhsize != 0)
+ return (FALSE);
+ return (TRUE);
+}
+
+static bool_t
+xdr_decode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
+{
+ uint32_t fhsize; /* filehandle size */
+ uint32_t bufsize;
+ rpc_inline_t *ptr;
+ uchar_t *buf, *bp;
+
+ ASSERT(xdrs->x_op == XDR_DECODE);
+
+ /*
+ * Retrieve the filehandle length.
+ */
+ if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
+ return (FALSE);
+
+ objp->nfs_fh4_val = NULL;
+ objp->nfs_fh4_len = 0;
+
+ /*
+ * Check to see if what the client sent us is bigger or smaller
+ * than what we can ever possibly send out. NFS_FHMAXDATA is
+ * unfortunately badly named as it is no longer the max and is
+ * really the min of what is sent over the wire.
+ */
+ if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
+ sizeof (ushort_t) + NFS_FHMAXDATA +
+ sizeof (ushort_t) + NFS_FHMAXDATA)) {
+ if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
+ return (FALSE);
+ return (TRUE);
+ }
+
+ /*
+ * bring in fhsize plus any padding
+ */
+ bufsize = RNDUP(fhsize);
+ ptr = XDR_INLINE(xdrs, bufsize);
+ bp = (uchar_t *)ptr;
+ if (ptr == NULL) {
+ bp = buf = kmem_alloc(bufsize, KM_SLEEP);
+ if (!xdr_opaque(xdrs, (char *)bp, bufsize))
+ return (FALSE);
+ }
+
+ objp->nfs_fh4_val = kmem_zalloc(sizeof (nfs_fh4_fmt_t), KM_SLEEP);
+ objp->nfs_fh4_len = sizeof (nfs_fh4_fmt_t);
+
+ if (xdr_inline_decode_nfs_fh4((uint32_t *)bp,
+ (nfs_fh4_fmt_t *)objp->nfs_fh4_val, fhsize) == FALSE) {
+ /*
+ * If in the process of decoding we find the file handle
+ * is not correctly formed, we need to continue decoding
+ * and trigger an NFS layer error. Set the nfs_fh4_len to
+ * zero so it gets caught as a bad length.
+ */
+ kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
+ objp->nfs_fh4_val = NULL;
+ objp->nfs_fh4_len = 0;
+ }
+
+ if (ptr == NULL)
+ kmem_free(buf, bufsize);
+ return (TRUE);
+}
+
+/*
* XDR_INLINE encode a filehandle.
*/
bool_t
@@ -240,162 +413,6 @@
}
static bool_t
-xdr_decode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
-{
- uint32_t fhsize; /* filehandle size */
- uint32_t bufsize;
- uint32_t dsize;
- nfs_fh4_fmt_t *fh_fmtp;
- rpc_inline_t *ptr;
- uintptr_t resid;
- uchar_t *buf, *bp, *cp;
-
- ASSERT(xdrs->x_op == XDR_DECODE);
-
- /*
- * Retrieve the filehandle length.
- */
- if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
- return (FALSE);
-
- objp->nfs_fh4_val = NULL;
- objp->nfs_fh4_len = 0;
-
- /*
- * Check to see if what the client sent us is bigger or smaller
- * than what we can ever possibly send out. NFS_FHMAXDATA is
- * unfortunately badly named as it is no longer the max and is
- * really the min of what is sent over the wire.
- */
- if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
- sizeof (ushort_t) + NFS_FHMAXDATA +
- sizeof (ushort_t) + NFS_FHMAXDATA)) {
- if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
- return (FALSE);
- return (TRUE);
- }
-
- /*
- * bring in fhsize plus any padding
- */
- bufsize = RNDUP(fhsize);
- ptr = XDR_INLINE(xdrs, bufsize);
- if (ptr == NULL) {
- bp = buf = kmem_alloc(bufsize, KM_SLEEP);
- if (!xdr_opaque(xdrs, (char *)bp, bufsize))
- return (FALSE);
- } else {
- bp = (uchar_t *)ptr;
- }
-
- objp->nfs_fh4_val = kmem_zalloc(sizeof (nfs_fh4_fmt_t), KM_SLEEP);
- objp->nfs_fh4_len = sizeof (nfs_fh4_fmt_t);
- fh_fmtp = (nfs_fh4_fmt_t *)objp->nfs_fh4_val;
-
- /*
- * All internal parts of a filehandle are in native byte order.
- *
- * Decode what should be fh4_fsid, it is aligned.
- */
- fh_fmtp->fh4_fsid.val[0] = *(uint32_t *)bp;
- bp += BYTES_PER_XDR_UNIT;
- fh_fmtp->fh4_fsid.val[1] = *(uint32_t *)bp;
- bp += BYTES_PER_XDR_UNIT;
-
- /*
- * Decode what should be fh4_len. fh4_len is two bytes, so we're
- * unaligned now.
- */
- cp = (uchar_t *)&fh_fmtp->fh4_len;
- *cp++ = *bp++;
- *cp++ = *bp++;
- fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
-
- /*
- * For backwards compatability, the fid length may be less than
- * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
- */
- dsize = fh_fmtp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA :
- fh_fmtp->fh4_len;
-
- /*
- * Make sure the client isn't sending us a bogus length for fh4_data.
- */
- if (dsize > fhsize)
- goto badfh;
- bcopy(bp, fh_fmtp->fh4_data, dsize);
- bp += dsize;
- fhsize -= dsize;
-
- if (fhsize < sizeof (ushort_t))
- goto badfh;
- cp = (uchar_t *)&fh_fmtp->fh4_xlen;
- *cp++ = *bp++;
- *cp++ = *bp++;
- fhsize -= sizeof (ushort_t);
-
- dsize = fh_fmtp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA :
- fh_fmtp->fh4_xlen;
- /*
- * Make sure the client isn't sending us a bogus length for fh4_xdata.
- */
- if (dsize > fhsize)
- goto badfh;
- bcopy(bp, fh_fmtp->fh4_xdata, dsize);
- fhsize -= dsize;
- bp += dsize;
-
- /*
- * We realign things on purpose, so skip any padding
- */
- resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
- if (resid != 0) {
- if (fhsize < (BYTES_PER_XDR_UNIT - resid))
- goto badfh;
- bp += BYTES_PER_XDR_UNIT - resid;
- fhsize -= BYTES_PER_XDR_UNIT - resid;
- }
-
- if (fhsize < BYTES_PER_XDR_UNIT)
- goto badfh;
- fh_fmtp->fh4_flag = *(uint32_t *)bp;
- bp += BYTES_PER_XDR_UNIT;
- fhsize -= BYTES_PER_XDR_UNIT;
-
-#ifdef VOLATILE_FH_TEST
- if (fhsize < BYTES_PER_XDR_UNIT)
- goto badfh;
- fh_fmtp->fh4_fh4_volatile_id = *(uint32_t *)bp;
- bp += BYTES_PER_XDR_UNIT;
- fhsize -= BYTES_PER_XDR_UNIT;
-#endif
- /*
- * Make sure client didn't send extra bytes
- */
- if (fhsize != 0)
- goto badfh;
-
- if (ptr == NULL)
- kmem_free(buf, bufsize);
- return (TRUE);
-
-badfh:
- /*
- * If in the process of decoding we find the file handle
- * is not correctly formed, we need to continue decoding
- * and trigger an NFS layer error. Set the nfs_fh4_len to
- * zero so it gets caught as a bad length.
- */
- if (objp->nfs_fh4_val != NULL)
- kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
- objp->nfs_fh4_val = NULL;
- objp->nfs_fh4_len = 0;
- if (ptr == NULL)
- kmem_free(buf, bufsize);
- return (TRUE);
-}
-
-static bool_t
xdr_encode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
{
uint_t otw_len, fsize, xsize; /* otw, file, and export sizes */
@@ -450,20 +467,26 @@
/*
* XDR a NFSv4 filehandle.
+ * Encoding interprets the contents (server).
+ * Decoding the contents are opaque (client).
*/
bool_t
xdr_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
{
- if (xdrs->x_op == XDR_DECODE)
- return (xdr_decode_nfs_fh4(xdrs, objp));
- else if (xdrs->x_op == XDR_ENCODE)
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
return (xdr_encode_nfs_fh4(xdrs, objp));
-
- if (objp->nfs_fh4_val != NULL) {
- kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
- objp->nfs_fh4_val = NULL;
+ case XDR_DECODE:
+ return (xdr_bytes(xdrs, (char **)&objp->nfs_fh4_val,
+ (uint_t *)&objp->nfs_fh4_len, NFS4_FHSIZE));
+ case XDR_FREE:
+ if (objp->nfs_fh4_val != NULL) {
+ kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
+ objp->nfs_fh4_val = NULL;
+ }
+ return (TRUE);
}
- return (TRUE);
+ return (FALSE);
}
/* Called by xdr_array */
@@ -4397,7 +4420,7 @@
if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
return (TRUE);
return (xdr_encode_nfs_fh4(xdrs,
- &objp->nfs_resop4_u.opgetfh.object));
+ &objp->nfs_resop4_u.opgetfh.object));
default:
return (xdr_nfs_resop4(xdrs, objp));
}
@@ -4715,35 +4738,78 @@
objp->array_len, objp->array_len));
}
+/*
+ * NFS server side callback, initiating the callback request so it
+ * is the RPC client. Must convert from server's internal filehandle
+ * format to wire format.
+ */
static bool_t
-xdr_nfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
+xdr_snfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
{
+ CB_GETATTR4args *gargs;
+ CB_RECALL4args *rargs;
+
+ ASSERT(xdrs->x_op == XDR_ENCODE);
+
+ if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->argop))
+ return (FALSE);
+
+ switch (objp->argop) {
+ case OP_CB_GETATTR:
+ gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
+
+ if (!xdr_encode_nfs_fh4(xdrs, &gargs->fh))
+ return (FALSE);
+ return (xdr_bitmap4(xdrs, &gargs->attr_request));
+ case OP_CB_RECALL:
+ rargs = &objp->nfs_cb_argop4_u.opcbrecall;
+
+ if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->stateid.seqid))
+ return (FALSE);
+ if (!xdr_opaque(xdrs, rargs->stateid.other, 12))
+ return (FALSE);
+ if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->truncate))
+ return (FALSE);
+ return (xdr_encode_nfs_fh4(xdrs, &rargs->fh));
+ case OP_CB_ILLEGAL:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * NFS client side callback, receiving the callback request so it
+ * is the RPC server. Must treat the file handles as opaque.
+ */
+static bool_t
+xdr_cnfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
+{
+ CB_GETATTR4args *gargs;
+ CB_RECALL4args *rargs;
+
+ ASSERT(xdrs->x_op != XDR_ENCODE);
+
if (!xdr_u_int(xdrs, &objp->argop))
return (FALSE);
switch (objp->argop) {
case OP_CB_GETATTR:
- if (!xdr_bytes(xdrs,
- (char **)&objp->nfs_cb_argop4_u.opcbgetattr.fh.nfs_fh4_val,
- (uint_t *)&objp->nfs_cb_argop4_u.opcbgetattr.fh.nfs_fh4_len,
- NFS4_FHSIZE))
- return (FALSE);
- return (xdr_bitmap4(xdrs,
- &objp->nfs_cb_argop4_u.opcbgetattr.attr_request));
- case OP_CB_RECALL:
- if (!xdr_u_int(xdrs,
- &objp->nfs_cb_argop4_u.opcbrecall.stateid.seqid))
+ gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
+
+ if (!xdr_bytes(xdrs, (char **)&gargs->fh.nfs_fh4_val,
+ (uint_t *)&gargs->fh.nfs_fh4_len, NFS4_FHSIZE))
return (FALSE);
- if (!xdr_opaque(xdrs,
- objp->nfs_cb_argop4_u.opcbrecall.stateid.other,
- 12))
+ return (xdr_bitmap4(xdrs, &gargs->attr_request));
+ case OP_CB_RECALL:
+ rargs = &objp->nfs_cb_argop4_u.opcbrecall;
+
+ if (!xdr_u_int(xdrs, &rargs->stateid.seqid))
return (FALSE);
- if (!xdr_bool(xdrs,
- &objp->nfs_cb_argop4_u.opcbrecall.truncate))
+ if (!xdr_opaque(xdrs, rargs->stateid.other, 12))
return (FALSE);
- return (xdr_bytes(xdrs,
- (char **)&objp->nfs_cb_argop4_u.opcbrecall.fh.nfs_fh4_val,
- (uint_t *)&objp->nfs_cb_argop4_u.opcbrecall.fh.nfs_fh4_len,
- NFS4_FHSIZE));
+ if (!xdr_bool(xdrs, &rargs->truncate))
+ return (FALSE);
+ return (xdr_bytes(xdrs, (char **)&rargs->fh.nfs_fh4_val,
+ (uint_t *)&rargs->fh.nfs_fh4_len, NFS4_FHSIZE));
case OP_CB_ILLEGAL:
return (TRUE);
}
@@ -4776,8 +4842,11 @@
return (FALSE);
}
+/*
+ * The NFS client side callback, RPC server
+ */
bool_t
-xdr_CB_COMPOUND4args(XDR *xdrs, CB_COMPOUND4args *objp)
+xdr_CB_COMPOUND4args_clnt(XDR *xdrs, CB_COMPOUND4args *objp)
{
if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
(uint_t *)&objp->tag.utf8string_len,
@@ -4789,7 +4858,26 @@
return (FALSE);
return (xdr_array(xdrs, (char **)&objp->array,
(uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
- sizeof (nfs_cb_argop4), (xdrproc_t)xdr_nfs_cb_argop4));
+ sizeof (nfs_cb_argop4), (xdrproc_t)xdr_cnfs_cb_argop4));
+}
+
+/*
+ * The NFS server side callback, RPC client
+ */
+bool_t
+xdr_CB_COMPOUND4args_srv(XDR *xdrs, CB_COMPOUND4args *objp)
+{
+ if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
+ (uint_t *)&objp->tag.utf8string_len,
+ NFS4_MAX_UTF8STRING))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->minorversion))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->callback_ident))
+ return (FALSE);
+ return (xdr_array(xdrs, (char **)&objp->array,
+ (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
+ sizeof (nfs_cb_argop4), (xdrproc_t)xdr_snfs_cb_argop4));
}
bool_t
--- a/usr/src/uts/common/fs/nfs/nfs_server.c Tue Jan 10 08:05:23 2006 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs_server.c Tue Jan 10 08:52:24 2006 -0800
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1426,6 +1426,8 @@
struct netbuf nb;
bool_t logging_enabled = FALSE;
struct exportinfo *nfslog_exi = NULL;
+ char **procnames;
+ char cbuf[INET6_ADDRSTRLEN]; /* to hold both IPv4 and IPv6 addr */
vers = req->rq_vers;
@@ -1447,12 +1449,13 @@
(*(disptable[(int)vers].dis_proccntp))[which].value.ui64++;
disp = &disptable[(int)vers].dis_table[which];
+ procnames = disptable[(int)vers].dis_procnames;
auth_flavor = req->rq_cred.oa_flavor;
+
/*
* Deserialize into the args struct.
*/
-
args = (char *)&args_buf;
#ifdef DEBUG
@@ -1468,8 +1471,11 @@
if (!SVC_GETARGS(xprt, disp->dis_xdrargs, args)) {
svcerr_decode(xprt);
error++;
- cmn_err(CE_NOTE, "%s: bad getargs for %u/%d",
- pgmname, vers + min_vers, which);
+ cmn_err(CE_NOTE,
+ "Failed to decode arguments for %s version %u "
+ "procedure %s client %s%s",
+ pgmname, vers + min_vers, procnames[which],
+ client_name(req), client_addr(req, cbuf));
goto done;
}
}
@@ -1741,7 +1747,7 @@
rfs_dispatch(struct svc_req *req, SVCXPRT *xprt)
{
common_dispatch(req, xprt, NFS_VERSMIN, NFS_VERSMAX,
- "nfs_server", rfs_disptable);
+ "NFS", rfs_disptable);
}
static char *aclcallnames_v2[] = {
@@ -1867,7 +1873,7 @@
acl_dispatch(struct svc_req *req, SVCXPRT *xprt)
{
common_dispatch(req, xprt, NFS_ACL_VERSMIN, NFS_ACL_VERSMAX,
- "acl_server", acl_disptable);
+ "ACL", acl_disptable);
}
int
--- a/usr/src/uts/common/nfs/nfs4.h Tue Jan 10 08:05:23 2006 -0800
+++ b/usr/src/uts/common/nfs/nfs4.h Tue Jan 10 08:52:24 2006 -0800
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1286,6 +1286,8 @@
extern uint_t nfs4_tsize(struct knetconfig *);
extern uint_t rfs4_tsize(struct svc_req *);
+extern bool_t xdr_inline_decode_nfs_fh4(uint32_t *, nfs_fh4_fmt_t *,
+ uint32_t);
extern bool_t xdr_inline_encode_nfs_fh4(uint32_t **, uint32_t *,
nfs_fh4_fmt_t *);
--- a/usr/src/uts/common/nfs/nfs4_kprot.h Tue Jan 10 08:05:23 2006 -0800
+++ b/usr/src/uts/common/nfs/nfs4_kprot.h Tue Jan 10 08:52:24 2006 -0800
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1621,7 +1621,8 @@
extern bool_t xdr_COMPOUND4args_srv(XDR *, COMPOUND4args *);
extern bool_t xdr_COMPOUND4res_clnt(XDR *, COMPOUND4res_clnt *);
extern bool_t xdr_COMPOUND4res_srv(XDR *, COMPOUND4res *);
-extern bool_t xdr_CB_COMPOUND4args(XDR *, CB_COMPOUND4args *);
+extern bool_t xdr_CB_COMPOUND4args_clnt(XDR *, CB_COMPOUND4args *);
+extern bool_t xdr_CB_COMPOUND4args_srv(XDR *, CB_COMPOUND4args *);
extern bool_t xdr_CB_COMPOUND4res(XDR *, CB_COMPOUND4res *);