summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2010-09-19 01:18:03 +0000
committerrmacklem <rmacklem@FreeBSD.org>2010-09-19 01:18:03 +0000
commiteebc7df64cafec4f2e406fa12be1388c91175299 (patch)
treefccf377d47e965d156e669324e6388be12be2263 /sys/fs
parent05211dfe9fe155103b65707bafb0840d073373c8 (diff)
downloadFreeBSD-src-eebc7df64cafec4f2e406fa12be1388c91175299.zip
FreeBSD-src-eebc7df64cafec4f2e406fa12be1388c91175299.tar.gz
Fix nfsrv_freeallnfslocks() in the experimental NFSv4 server so that
it frees local locks correctly upon close. In order for nfsrv_localunlock() to work correctly, the lock can no longer be in the lockowner's stateid list. As such, nfsrv_freenfslock() has to be called before nfsrv_localunlock(), to get rid of the lock structure on the lockowner's stateid list. This only affected operation when local locks (vfs.newnfs.enable_locallocks=1) are enabled, which is not the default at this time. MFC after: 1 week
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index df9f054..86b866e 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -1137,6 +1137,7 @@ nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep,
struct nfslockfile *lfp = NULL;
int gottvp = 0;
vnode_t tvp = NULL;
+ uint64_t first, end;
lop = LIST_FIRST(&stp->ls_lock);
while (lop != LIST_END(&stp->ls_lock)) {
@@ -1167,14 +1168,16 @@ nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep,
if (tvp != NULL) {
if (cansleep == 0)
panic("allnfs2");
- nfsrv_localunlock(tvp, lfp, lop->lo_first,
- lop->lo_end, p);
+ first = lop->lo_first;
+ end = lop->lo_end;
+ nfsrv_freenfslock(lop);
+ nfsrv_localunlock(tvp, lfp, first, end, p);
LIST_FOREACH_SAFE(rlp, &lfp->lf_rollback, rlck_list,
nrlp)
free(rlp, M_NFSDROLLBACK);
LIST_INIT(&lfp->lf_rollback);
- }
- nfsrv_freenfslock(lop);
+ } else
+ nfsrv_freenfslock(lop);
lop = nlop;
}
if (vp == NULL && tvp != NULL)
OpenPOWER on IntegriCloud