summaryrefslogtreecommitdiffstats
path: root/xlators/nfs/server/src/nfs3.c
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2010-08-31 06:50:33 +0000
committerVijay Bellur <vijay@dev.gluster.com>2010-08-31 07:44:50 -0700
commit2dd921a2848365f5fd538dd891b36a9f355ca78c (patch)
tree1a48e89c80f1ebbb6095ce829a680b59a5f4217d /xlators/nfs/server/src/nfs3.c
parent4b892368108b9c41449fb1185319cf3acf3c2ea8 (diff)
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 <shehjart@gluster.com> Signed-off-by: Vijay Bellur <vijay@dev.gluster.com> BUG: 1464 (fd leak after rename) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1464
Diffstat (limited to 'xlators/nfs/server/src/nfs3.c')
-rw-r--r--xlators/nfs/server/src/nfs3.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c
index 420baddb6..16a5e6521 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);