summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 02ceaaa..e28bc23 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -2498,6 +2498,8 @@ nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp,
struct nfsclient *clp;
int error = 0, haslock = 0, ret, delegate = 1, writedeleg = 1;
int readonly = 0, cbret = 1, getfhret = 0;
+ int gotstate = 0, len = 0;
+ u_char *clidp = NULL;
if ((new_stp->ls_flags & NFSLCK_SHAREBITS) == NFSLCK_READACCESS)
readonly = 1;
@@ -2516,6 +2518,7 @@ nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp,
goto out;
}
+ clidp = malloc(NFSV4_OPAQUELIMIT, M_TEMP, M_WAITOK);
tryagain:
MALLOC(new_lfp, struct nfslockfile *, sizeof (struct nfslockfile),
M_NFSDLOCKFILE, M_WAITOK);
@@ -3178,6 +3181,16 @@ tryagain:
nfsrv_openpluslock++;
nfsrv_delegatecnt++;
}
+ /*
+ * Since NFSv4.1 never does an OpenConfirm, the first
+ * open state will be acquired here.
+ */
+ if (!(clp->lc_flags & LCL_STAMPEDSTABLE)) {
+ clp->lc_flags |= LCL_STAMPEDSTABLE;
+ len = clp->lc_idlen;
+ NFSBCOPY(clp->lc_id, clidp, len);
+ gotstate = 1;
+ }
} else {
*rflagsp |= NFSV4OPEN_RESULTCONFIRM;
new_stp->ls_flags = NFSLCK_NEEDSCONFIRM;
@@ -3214,7 +3227,17 @@ tryagain:
if (new_deleg)
FREE((caddr_t)new_deleg, M_NFSDSTATE);
+ /*
+ * If the NFSv4.1 client just acquired its first open, write a timestamp
+ * to the stable storage file.
+ */
+ if (gotstate != 0) {
+ nfsrv_writestable(clidp, len, NFSNST_NEWSTATE, p);
+ nfsrv_backupstable();
+ }
+
out:
+ free(clidp, M_TEMP);
NFSEXITCODE2(error, nd);
return (error);
}
@@ -3231,7 +3254,7 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
struct nfslockfile *lfp;
u_int32_t bits;
int error = 0, gotstate = 0, len = 0;
- u_char client[NFSV4_OPAQUELIMIT];
+ u_char *clidp = NULL;
/*
* Check for restart conditions (client and server).
@@ -3241,6 +3264,7 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
if (error)
goto out;
+ clidp = malloc(NFSV4_OPAQUELIMIT, M_TEMP, M_WAITOK);
NFSLOCKSTATE();
/*
* Get the open structure via clientid and stateid.
@@ -3319,7 +3343,7 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
if (!(clp->lc_flags & LCL_STAMPEDSTABLE)) {
clp->lc_flags |= LCL_STAMPEDSTABLE;
len = clp->lc_idlen;
- NFSBCOPY(clp->lc_id, client, len);
+ NFSBCOPY(clp->lc_id, clidp, len);
gotstate = 1;
}
NFSUNLOCKSTATE();
@@ -3366,11 +3390,12 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
* to the stable storage file.
*/
if (gotstate != 0) {
- nfsrv_writestable(client, len, NFSNST_NEWSTATE, p);
+ nfsrv_writestable(clidp, len, NFSNST_NEWSTATE, p);
nfsrv_backupstable();
}
out:
+ free(clidp, M_TEMP);
NFSEXITCODE2(error, nd);
return (error);
}
OpenPOWER on IntegriCloud