This patch applies one of the two fixes suggested by
zack.kirsch at isilon.com for a race between nfsrv_freeopen() and nfsrv_getlockfile() in the experimental NFS server that he found during testing. Although nfsrv_freeopen() holds a sleep lock on the lock file structure when called with cansleep != 0, nfsrv_getlockfile() could still search the list, once it acquired the NFSLOCKSTATE() mutex. I believe that acquiring the mutex in nfsrv_freeopen() fixes the race. MFC after: 2 weeks
This commit is contained in:
parent
1569ab8c49
commit
2c6d0e01f8
@ -1085,8 +1085,11 @@ nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep, NFSPROC_T *p)
|
||||
* associated with the open.
|
||||
* If there are locks associated with the open, the
|
||||
* nfslockfile structure can be freed via nfsrv_freelockowner().
|
||||
* (That is why the call must be here instead of after the loop.)
|
||||
* Acquire the state mutex to avoid races with calls to
|
||||
* nfsrv_getlockfile().
|
||||
*/
|
||||
if (cansleep != 0)
|
||||
NFSLOCKSTATE();
|
||||
if (lfp != NULL && LIST_EMPTY(&lfp->lf_open) &&
|
||||
LIST_EMPTY(&lfp->lf_deleg) && LIST_EMPTY(&lfp->lf_lock) &&
|
||||
LIST_EMPTY(&lfp->lf_locallock) && LIST_EMPTY(&lfp->lf_rollback) &&
|
||||
@ -1096,6 +1099,8 @@ nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep, NFSPROC_T *p)
|
||||
ret = 1;
|
||||
} else
|
||||
ret = 0;
|
||||
if (cansleep != 0)
|
||||
NFSUNLOCKSTATE();
|
||||
FREE((caddr_t)stp, M_NFSDSTATE);
|
||||
newnfsstats.srvopens--;
|
||||
nfsrv_openpluslock--;
|
||||
|
Loading…
Reference in New Issue
Block a user