diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2010-09-19 01:18:03 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2010-09-19 01:18:03 +0000 |
commit | eebc7df64cafec4f2e406fa12be1388c91175299 (patch) | |
tree | fccf377d47e965d156e669324e6388be12be2263 | |
parent | 05211dfe9fe155103b65707bafb0840d073373c8 (diff) | |
download | FreeBSD-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
-rw-r--r-- | sys/fs/nfsserver/nfs_nfsdstate.c | 11 |
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) |