From 2dd921a2848365f5fd538dd891b36a9f355ca78c Mon Sep 17 00:00:00 2001 From: Shehjar Tikoo Date: Tue, 31 Aug 2010 06:50:33 +0000 Subject: nfs3: Close dst cached fd & unref inode on rename If the src file is over-writing an existing file and if the destination file is open, then close the cached fd on the destination file and unref the inode for it. Signed-off-by: Shehjar Tikoo Signed-off-by: Vijay Bellur BUG: 1464 (fd leak after rename) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1464 --- xlators/nfs/server/src/nfs3.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'xlators/nfs') diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index 420baddb67d..16a5e65218f 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -3260,6 +3260,7 @@ nfs3svc_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int ret = -EFAULT; nfsstat3 stat = NFS3ERR_SERVERFAULT; nfs3_call_state_t *cs = NULL; + fd_t *openfd = NULL; cs = frame->local; if (op_ret == -1) { @@ -3268,6 +3269,24 @@ nfs3svc_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } stat = NFS3_OK; + /* Close any cached fds so that when any currently active writes to the + * dst finish, the file is finally removed. + * + * This logic works because we know resolvedloc contains dst, which is + * resolved after src + */ + openfd = fd_lookup (cs->resolvedloc.inode, 0); + if (openfd) { + fd_unref (openfd); + nfs3_fdcache_remove (cs->nfs3state, openfd); + } + + /* This is the unref equivalent of the ref done when the inode was + * created on a lookup or a create request. + * The inode is finally unrefed in call state wipe. + */ + inode_unref (cs->resolvedloc.inode); + nfs3err: nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RENAME", stat, -ret); -- cgit