diff options
| author | Shehjar Tikoo <shehjart@gluster.com> | 2010-08-31 06:50:33 +0000 | 
|---|---|---|
| committer | Vijay Bellur <vijay@dev.gluster.com> | 2010-08-31 07:44:50 -0700 | 
| commit | 2dd921a2848365f5fd538dd891b36a9f355ca78c (patch) | |
| tree | 1a48e89c80f1ebbb6095ce829a680b59a5f4217d /xlators/nfs | |
| parent | 4b892368108b9c41449fb1185319cf3acf3c2ea8 (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')
| -rw-r--r-- | xlators/nfs/server/src/nfs3.c | 19 | 
1 files changed, 19 insertions, 0 deletions
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);  | 
