diff options
author | Vikas Gorur <vikas@gluster.com> | 2010-02-01 07:31:40 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2010-02-02 04:51:52 -0800 |
commit | 4f736b6eb9d761287b6bf4ecfc19974a43a8644f (patch) | |
tree | 0b9a0cfb08e5cf0c0e2d37bd17a1fa28a551c3ca | |
parent | 8bcc534da4b2b29709a80327687085876b02ff5a (diff) |
cluster/dht: Remove linkfile before unlinking the datafile.
dht_unlink: If a linkfile exists, remove it first before attempting
to remove the datafile. This eliminates the case where dht would
end up with the linkfile intact and the datafile gone, and the user
not being able to remove the linkfile.
Thanks to He Xiaobin <allreol@gmail.com> for debugging this
issue.
Signed-off-by: Vikas Gorur <vikas@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 188 ([ glusterfs 2.0.6rc2 ] - "Directory not empty" on rm -rf)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=188
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 80 |
1 files changed, 63 insertions, 17 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 9c5b9006b..ac6173800 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -1189,12 +1189,46 @@ dht_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct stat *postparent) { dht_local_t *local = NULL; - int this_call_cnt = 0; + call_frame_t *prev = NULL; + + local = frame->local; + prev = cookie; + + LOCK (&frame->lock); + { + if (op_ret == -1) { + local->op_ret = -1; + local->op_errno = op_errno; + gf_log (this->name, GF_LOG_DEBUG, + "subvolume %s returned -1 (%s)", + prev->this->name, strerror (op_errno)); + goto unlock; + } + + local->op_ret = 0; + } +unlock: + UNLOCK (&frame->lock); + + DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno, + preparent, postparent); + + return 0; +} + + +int +dht_unlink_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, struct stat *preparent, + struct stat *postparent) +{ + dht_local_t *local = NULL; call_frame_t *prev = NULL; + xlator_t *cached_subvol = NULL; local = frame->local; - prev = cookie; + prev = cookie; LOCK (&frame->lock); { @@ -1211,12 +1245,28 @@ dht_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unlock: UNLOCK (&frame->lock); - this_call_cnt = dht_frame_return (frame); - if (is_last_call (this_call_cnt)) - DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno, - NULL, NULL); + if (op_ret == -1) + goto err; + + cached_subvol = dht_subvol_get_cached (this, local->loc.inode); + if (!cached_subvol) { + gf_log (this->name, GF_LOG_DEBUG, + "no cached subvolume for path=%s", + local->loc.path); + local->op_errno = EINVAL; + goto err; + } + + STACK_WIND (frame, dht_unlink_cbk, + cached_subvol, cached_subvol->fops->unlink, + &local->loc); return 0; + +err: + DHT_STACK_UNWIND (unlink, frame, -1, local->op_errno, + NULL, NULL); + return 0; } @@ -2599,22 +2649,18 @@ dht_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) goto err; } - local->call_cnt = 1; - if (hashed_subvol != cached_subvol) - local->call_cnt++; - - STACK_WIND (frame, dht_unlink_cbk, - cached_subvol, cached_subvol->fops->unlink, loc); - - if (hashed_subvol != cached_subvol) - STACK_WIND (frame, dht_unlink_cbk, + if (hashed_subvol != cached_subvol) { + STACK_WIND (frame, dht_unlink_linkfile_cbk, hashed_subvol, hashed_subvol->fops->unlink, loc); + } else { + STACK_WIND (frame, dht_unlink_cbk, + cached_subvol, cached_subvol->fops->unlink, loc); + } return 0; - err: op_errno = (op_errno == -1) ? errno : op_errno; - DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL); + DHT_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL); return 0; } |