diff options
| author | Pavan Sondur <pavan@gluster.com> | 2009-10-16 01:56:06 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2009-10-16 03:12:56 -0700 | 
| commit | bd6a6bc71dfaad3f74aa974f0c26ee4adc4dc05e (patch) | |
| tree | f643c8cf736e2ae96f6df36b12670053df653a22 | |
| parent | 6b3cf8045866726b09576e4d3f0a417257716373 (diff) | |
Changes in posix unlink and rmdir to prevent inode num re-use immediately.
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 112 (parallel deletion of files mounted by different clients on the same back-end hangs and/or does not completely delete)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=112
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 61 | 
1 files changed, 55 insertions, 6 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 1f1a5add2fd..aafa1d4c7ee 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -81,9 +81,10 @@ typedef struct {  int  posix_forget (xlator_t *this, inode_t *inode)  { -	uint64_t tmp_cache = 0; -	if (!inode_ctx_del (inode, this, &tmp_cache)) -		dict_destroy ((dict_t *)(long)tmp_cache); +	uint64_t unlinked_fd = -1; + +	if (!inode_ctx_del (inode, this, &unlinked_fd)) +                close (unlinked_fd);  	return 0;  } @@ -1002,8 +1003,11 @@ posix_unlink (call_frame_t *frame, xlator_t *this,          int32_t                  op_ret    = -1;          int32_t                  op_errno  = 0;          char                    *real_path = NULL; -        int32_t                  fd = -1; +        int32_t                  fd        = -1;          struct posix_private    *priv      = NULL; +        uint64_t                tmp_fd     = -1; +        struct stat             stbuf      = { 0, }; +        int32_t                 ret        = -1;          DECLARE_OLD_FS_ID_VAR; @@ -1026,6 +1030,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this,                                          strerror (op_errno));                                  goto out;                          } +                  }          } @@ -1046,9 +1051,33 @@ posix_unlink (call_frame_t *frame, xlator_t *this,          STACK_UNWIND (frame, op_ret, op_errno);          if (fd != -1) { -                close (fd); -        } +                ret = fstat (fd, &stbuf); +                if (ret == -1) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "fstat on %s failed: %s", +                                real_path, strerror (errno)); +                        goto fail; +                } + +                if (stbuf.st_nlink == 0) { +                        ret =  ftruncate (fd, 0); +                        if (ret == -1) { +                                gf_log (this->name, GF_LOG_ERROR, +                                        "ftruncate failed on fd=%d: %s", +                                        fd, strerror (errno)); +                                goto fail; +                        } +                } + +                if ((inode_ctx_get (loc->inode, this, &tmp_fd)) == 0) +                        close (fd); +                else +                        inode_ctx_put (loc->inode, this, (uint64_t) fd); +        } +fail: +        if (fd != -1) +                close (fd);          return 0;  } @@ -1060,6 +1089,9 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,          int32_t op_errno  = 0;          char *  real_path = 0; +        uint64_t fd       = -1; +        struct posix_private *  priv   = NULL; +          DECLARE_OLD_FS_ID_VAR;          VALIDATE_OR_GOTO (frame, out); @@ -1069,6 +1101,20 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,          SET_FS_ID (frame->root->uid, frame->root->gid);          MAKE_REAL_PATH (real_path, this, loc->path); +        priv = this->private; + +        if (priv->background_unlink) { +                fd = open (real_path, O_RDONLY); +                if (fd == -1){ +                        op_errno = errno; +                        gf_log (this->name, GF_LOG_ERROR, +                                "open() failed on `%s': %s", +                                real_path, strerror (op_errno)); +                        goto out; +                } + +        } +          op_ret = rmdir (real_path);          op_errno = errno; @@ -1088,6 +1134,9 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,          STACK_UNWIND (frame, op_ret, op_errno); +        if (fd != -1) +                inode_ctx_put (loc->inode, this, (uint64_t) fd); +          return 0;  }  | 
