diff options
author | NeilBrown <neilb@cse.unsw.edu.au> | 2005-07-07 17:59:14 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-07 18:24:08 -0700 |
commit | 0fa822e452084032b8495ca0d8e0199329847815 (patch) | |
tree | 5be25dc1f1222d2998a9754e5b5e26d516601b9d | |
parent | 67be431350941765e211eeed237c12def3aaba70 (diff) |
[PATCH] nfsd4: fix release_lockowner
We oops in list_for_each_entry(), because release_stateowner frees something
on the list we're traversing.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/nfsd/nfs4state.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9f9db40b566..e388c9070de 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3084,7 +3084,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner * * of the lockowner state released; so don't release any until all * have been checked. */ status = nfs_ok; - list_for_each_entry(sop, &matches, so_perclient) { + while (!list_empty(&matches)) { + sop = list_entry(matches.next, struct nfs4_stateowner, + so_perclient); + /* unhash_stateowner deletes so_perclient only + * for openowners. */ + list_del(&sop->so_perclient); release_stateowner(sop); } out: |