From 4e6fb304ce41acbaf7c9ba67c06bf443e65082e8 Mon Sep 17 00:00:00 2001 From: Shehjar Tikoo Date: Fri, 17 Sep 2010 06:32:01 +0000 Subject: nfs3: Unref & unbind dir fd with inode lock on EOF ..so that when EOF is reached on this fd, any further requests on the same inode do not get handled through this fd but result in a new fd being opened. Unbinding results in the fd getting deleted from the inode's fd list. Signed-off-by: Shehjar Tikoo Signed-off-by: Vijay Bellur BUG: 1619 (glusterfs nfs server crashed on dht+replica(2x2)) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1619 --- xlators/nfs/server/src/nfs3.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'xlators/nfs/server/src') diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index 0a55e55c9c8..2d5df536937 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -3885,6 +3885,17 @@ nfs3svc_readdir_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: + + /* On end-of-directory, unref the fd to have it removed from the cache + * and also unbind it from the fd so that any subsequent request on the + * on the directory do not get this fd when fd_lookup is called in + * dir open resume path. + */ + if (is_eof) { + gf_log (GF_NFS3, GF_LOG_TRACE, "EOF REF: %d", cs->fd->refcount); + fd_unref_unbind (cs->fd); + } + if (cs->maxcount == 0) { nfs3_log_readdir_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno, (uintptr_t)cs->fd, @@ -3902,11 +3913,6 @@ nfs3err: cs->maxcount, is_eof); } - if (is_eof) { - gf_log (GF_NFS3, GF_LOG_TRACE, "EOF REF: %d", cs->fd->refcount); - fd_unref (cs->fd); - } - gf_log (GF_NFS3, GF_LOG_TRACE, "CS WIPE REF: %d", cs->fd->refcount); nfs3_call_state_wipe (cs); return 0; @@ -3958,7 +3964,7 @@ err: * so that next time the dir is read, we'll get any changed directory * entries. */ - fd_unref (cs->fd); + fd_unref_unbind (cs->fd); nfs3_call_state_wipe (cs); ret: return 0; -- cgit