diff options
author | Neil Brown <neilb@cse.unsw.edu.au> | 2005-01-04 05:50:29 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-04 05:50:29 -0800 |
commit | 8d1e7aae5f7bca81f5ce450a903002c8608af93a (patch) | |
tree | 8390e0f2f012648fd9e87fc0067c71a0ce3d0384 /fs | |
parent | 7d47a605fbb6f650fd1774afd32c95ada4052eae (diff) | |
download | history-8d1e7aae5f7bca81f5ce450a903002c8608af93a.tar.gz |
[PATCH] knfsd: delay nfsd_colse for delegations until reaping
Because nfsd_close() can call locks_remove_flock() which removes leases,
delay nfsd_close() for delegations until the delegation is reaped.
Don't release an nfs4_file struct with delegations.
Signed-off-by: Andy Adamson <andros@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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs4state.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index dbb470b2bba3f9..f416b5ac1dd6fd 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -977,7 +977,7 @@ release_all_files(void) while (!list_empty(&file_hashtbl[i])) { fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash); /* this should never be more than once... */ - if (!list_empty(&fp->fi_perfile)) { + if (!list_empty(&fp->fi_perfile) || !list_empty(&fp->fi_del_perfile)) { printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp); } release_file(fp); @@ -1112,14 +1112,29 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateow __set_bit(open->op_share_deny, &stp->st_deny_bmap); } +/* +* Because nfsd_close() can call locks_remove_flock() which removes leases, +* delay nfsd_close() for delegations from the nfsd_open() clientid +* until the delegation is reaped. +*/ static void -release_stateid(struct nfs4_stateid *stp, int flags) { +release_stateid(struct nfs4_stateid *stp, int flags) +{ + struct nfs4_delegation *dp; + struct nfs4_file *fp = stp->st_file; list_del(&stp->st_hash); list_del_perfile++; list_del(&stp->st_perfile); list_del(&stp->st_perfilestate); if ((stp->st_vfs_set) && (flags & OPEN_STATE)) { + list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) { + if(cmp_clid(&dp->dl_client->cl_clientid, + &stp->st_stateowner->so_client->cl_clientid)) { + dp->dl_stp = stp; + return; + } + } release_stateid_lockowner(stp); nfsd_close(stp->st_vfs_file); vfsclose++; @@ -1168,7 +1183,7 @@ release_state_owner(struct nfs4_stateid *stp, struct nfs4_stateowner **sopp, if (sop->so_confirmed && list_empty(&sop->so_perfilestate)) move_to_close_lru(sop); /* unused nfs4_file's are releseed. XXX slab cache? */ - if (list_empty(&fp->fi_perfile)) { + if (list_empty(&fp->fi_perfile) && list_empty(&fp->fi_del_perfile)) { release_file(fp); } } |