aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/fs/nfs/nfs_commonport.c2
-rw-r--r--sys/fs/nfs/nfsclstate.h1
-rw-r--r--sys/fs/nfsclient/nfs_clport.c2
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c8
-rw-r--r--sys/fs/nfsclient/nfs_clstate.c9
5 files changed, 19 insertions, 3 deletions
diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
index a65ebde881cb..2849163837df 100644
--- a/sys/fs/nfs/nfs_commonport.c
+++ b/sys/fs/nfs/nfs_commonport.c
@@ -225,6 +225,8 @@ void
newnfs_copycred(struct nfscred *nfscr, struct ucred *cr)
{
+ KASSERT(nfscr->nfsc_ngroups >= 0,
+ ("newnfs_copycred: negative nfsc_ngroups"));
cr->cr_uid = nfscr->nfsc_uid;
crsetgroups(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups);
}
diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h
index 10747af5a643..edd479cf2cee 100644
--- a/sys/fs/nfs/nfsclstate.h
+++ b/sys/fs/nfs/nfsclstate.h
@@ -140,6 +140,7 @@ struct nfsclopen {
#define NFSCLOPEN_OK 0
#define NFSCLOPEN_DOOPEN 1
#define NFSCLOPEN_DOOPENDOWNGRADE 2
+#define NFSCLOPEN_SETCRED 3
struct nfscllockowner {
LIST_ENTRY(nfscllockowner) nfsl_list;
diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index e81c3bf805b8..f39666db68ec 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -978,6 +978,8 @@ newnfs_copyincred(struct ucred *cr, struct nfscred *nfscr)
{
int i;
+ KASSERT(cr->cr_ngroups >= 0,
+ ("newnfs_copyincred: negative cr_ngroups"));
nfscr->nfsc_uid = cr->cr_uid;
nfscr->nfsc_ngroups = MIN(cr->cr_ngroups, NFS_MAXGRPS + 1);
for (i = 0; i < nfscr->nfsc_ngroups; i++)
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 95943a9660bb..a7015f5226b5 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -278,7 +278,13 @@ else printf(" fhl=0\n");
error = EIO;
}
newnfs_copyincred(cred, &op->nfso_cred);
- }
+ } else if (ret == NFSCLOPEN_SETCRED)
+ /*
+ * This is a new local open on a delegation. It needs
+ * to have credentials so that an open can be done
+ * against the server during recovery.
+ */
+ newnfs_copyincred(cred, &op->nfso_cred);
/*
* nfso_opencnt is the count of how many VOP_OPEN()s have
diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index 568c5de640af..08150a7228e7 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -274,8 +274,13 @@ nfscl_open(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t amode, int usedeleg,
*owpp = owp;
if (opp != NULL)
*opp = op;
- if (retp != NULL)
- *retp = NFSCLOPEN_OK;
+ if (retp != NULL) {
+ if (nfhp != NULL && dp != NULL && nop == NULL)
+ /* new local open on delegation */
+ *retp = NFSCLOPEN_SETCRED;
+ else
+ *retp = NFSCLOPEN_OK;
+ }
/*
* Now, check the mode on the open and return the appropriate