diff options
author | robinson <none@none> | 2006-01-10 08:52:24 -0800 |
---|---|---|
committer | robinson <none@none> | 2006-01-10 08:52:24 -0800 |
commit | eac3aab7aa7e29942e099c28d9dcd8017972926d (patch) | |
tree | 19046f94721e20f8cef8a88123c96b749724f685 /usr/src/uts/common/fs/nfs/nfs4_srv_attr.c | |
parent | d2443e765650e70b88cd0346e67d2aee6dd1ea3a (diff) | |
download | illumos-joyent-eac3aab7aa7e29942e099c28d9dcd8017972926d.tar.gz |
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
Diffstat (limited to 'usr/src/uts/common/fs/nfs/nfs4_srv_attr.c')
-rw-r--r-- | usr/src/uts/common/fs/nfs/nfs4_srv_attr.c | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/usr/src/uts/common/fs/nfs/nfs4_srv_attr.c b/usr/src/uts/common/fs/nfs/nfs4_srv_attr.c index 6169621a73..5e77185200 100644 --- a/usr/src/uts/common/fs/nfs/nfs4_srv_attr.c +++ b/usr/src/uts/common/fs/nfs/nfs4_srv_attr.c @@ -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 @@ rfs4_fattr4_rdattr_error(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 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 @@ rfs4_fattr4_filehandle(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, */ 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); } /* |