7f4c2a
From a288ff3ea3b792dcafaa4ffa247d3c6032d68f10 Mon Sep 17 00:00:00 2001
7f4c2a
From: Sakshi <sabansal@redhat.com>
7f4c2a
Date: Thu, 16 Jul 2015 14:31:03 +0530
7f4c2a
Subject: [PATCH 311/320] dht : lock on subvols to prevent lookup vs rmdir race
7f4c2a
7f4c2a
There is a possibility that while an rmdir is completed on
7f4c2a
some non-hashed subvol and proceeding to others. A lookup
7f4c2a
selfheal can recreate the same directory on those subvols
7f4c2a
for which the rmdir had succeeded. The fix is to take a
7f4c2a
blocking inodelk on the subvols before starting rmdir.
7f4c2a
Since selfheal requires lock on all subvols, if an rmdir
7f4c2a
is in progess acquiring locks will fail and vice versa.
7f4c2a
7f4c2a
Change-Id: I841a44758c3b88f5e04d1cb73ad36e0cac9fdabb
7f4c2a
BUG: 1115367
7f4c2a
Signed-off-by: Sakshi <sabansal@redhat.com>
7f4c2a
Reviewed-on: http://review.gluster.org/11725
7f4c2a
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
7f4c2a
Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
7f4c2a
Reviewed-on: https://code.engineering.redhat.com/gerrit/56595
7f4c2a
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
7f4c2a
Tested-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
7f4c2a
---
7f4c2a
 xlators/cluster/dht/src/dht-common.c   |  180 +++++++++++++++++++++++++++----
7f4c2a
 xlators/cluster/dht/src/dht-common.h   |   14 ++-
7f4c2a
 xlators/cluster/dht/src/dht-helper.c   |   38 ++++++-
7f4c2a
 xlators/cluster/dht/src/dht-rename.c   |    2 +-
7f4c2a
 xlators/cluster/dht/src/dht-selfheal.c |  181 +++++++++++++++++++++++---------
7f4c2a
 5 files changed, 331 insertions(+), 84 deletions(-)
7f4c2a
7f4c2a
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
7f4c2a
index 5c1a693..f819aa6 100644
7f4c2a
--- a/xlators/cluster/dht/src/dht-common.c
7f4c2a
+++ b/xlators/cluster/dht/src/dht-common.c
7f4c2a
@@ -40,6 +40,10 @@ dht_setxattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame);
7f4c2a
 int run_defrag = 0;
7f4c2a
 
7f4c2a
 int
7f4c2a
+dht_rmdir_unlock (call_frame_t *frame, xlator_t *this);
7f4c2a
+
7f4c2a
+
7f4c2a
+int
7f4c2a
 dht_aggregate_quota_xattr (dict_t *dst, char *key, data_t *value)
7f4c2a
 {
7f4c2a
         int              ret            = -1;
7f4c2a
@@ -4514,7 +4518,6 @@ dht_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
7f4c2a
                  * corresponding hashed subvolume will take care of the
7f4c2a
                  * directory entry.
7f4c2a
                  */
7f4c2a
-
7f4c2a
                         if (readdir_optimize) {
7f4c2a
                                 if (prev->this == local->first_up_subvol)
7f4c2a
                                         goto list;
7f4c2a
@@ -4999,7 +5002,7 @@ out:
7f4c2a
         if (local && local->lock.locks) {
7f4c2a
                 /* store op_errno for failure case*/
7f4c2a
                 local->op_errno = op_errno;
7f4c2a
-                local->refresh_layout_unlock (frame, this, op_ret);
7f4c2a
+                local->refresh_layout_unlock (frame, this, op_ret, 0);
7f4c2a
 
7f4c2a
                 if (op_ret == 0) {
7f4c2a
                         DHT_STACK_UNWIND (mknod, frame, op_ret, op_errno,
7f4c2a
@@ -5044,7 +5047,7 @@ dht_mknod_linkfile_create_cbk (call_frame_t *frame, void *cookie,
7f4c2a
         return 0;
7f4c2a
 err:
7f4c2a
         if (local->lock.locks)
7f4c2a
-                local->refresh_layout_unlock (frame, this, -1);
7f4c2a
+                local->refresh_layout_unlock (frame, this, -1, 0);
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
@@ -5149,7 +5152,7 @@ dht_mknod_do (call_frame_t *frame)
7f4c2a
                                          local->umask, local->params);
7f4c2a
         return 0;
7f4c2a
 err:
7f4c2a
-        local->refresh_layout_unlock (frame, this, -1);
7f4c2a
+        local->refresh_layout_unlock (frame, this, -1, 0);
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
@@ -5164,7 +5167,7 @@ dht_mknod_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
 }
7f4c2a
 
7f4c2a
 int32_t
7f4c2a
-dht_mknod_finish (call_frame_t *frame, xlator_t *this, int op_ret)
7f4c2a
+dht_mknod_finish (call_frame_t *frame, xlator_t *this, int op_ret, int invoke_cbk)
7f4c2a
 {
7f4c2a
         dht_local_t  *local      = NULL, *lock_local = NULL;
7f4c2a
         call_frame_t *lock_frame = NULL;
7f4c2a
@@ -5239,7 +5242,7 @@ dht_mknod_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
 err:
7f4c2a
-        dht_mknod_finish (frame, this, -1);
7f4c2a
+        dht_mknod_finish (frame, this, -1, 0);
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
 
7f4c2a
@@ -5270,7 +5273,7 @@ dht_mknod_lock (call_frame_t *frame, xlator_t *subvol)
7f4c2a
         local->lock.lk_count = count;
7f4c2a
 
7f4c2a
         ret = dht_blocking_inodelk (frame, lk_array, count,
7f4c2a
-                                    dht_mknod_lock_cbk);
7f4c2a
+                                    IGNORE_ENOENT_ESTALE, dht_mknod_lock_cbk);
7f4c2a
 
7f4c2a
         if (ret < 0) {
7f4c2a
                 local->lock.locks = NULL;
7f4c2a
@@ -5797,7 +5800,7 @@ out:
7f4c2a
         if (local && local->lock.locks) {
7f4c2a
                 /* store op_errno for failure case*/
7f4c2a
                 local->op_errno = op_errno;
7f4c2a
-                local->refresh_layout_unlock (frame, this, op_ret);
7f4c2a
+                local->refresh_layout_unlock (frame, this, op_ret, 0);
7f4c2a
 
7f4c2a
                 if (op_ret == 0) {
7f4c2a
                         DHT_STACK_UNWIND (create, frame, op_ret, op_errno, fd,
7f4c2a
@@ -5838,7 +5841,7 @@ dht_create_linkfile_create_cbk (call_frame_t *frame, void *cookie,
7f4c2a
         return 0;
7f4c2a
 err:
7f4c2a
         if (local->lock.locks)
7f4c2a
-                local->refresh_layout_unlock (frame, this, -1);
7f4c2a
+                local->refresh_layout_unlock (frame, this, -1, 0);
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
@@ -6002,7 +6005,7 @@ dht_create_do (call_frame_t *frame)
7f4c2a
                                          local->umask, local->fd, local->params);
7f4c2a
         return 0;
7f4c2a
 err:
7f4c2a
-        local->refresh_layout_unlock (frame, this, -1);
7f4c2a
+        local->refresh_layout_unlock (frame, this, -1, 0);
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
@@ -6016,7 +6019,7 @@ dht_create_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
 }
7f4c2a
 
7f4c2a
 int32_t
7f4c2a
-dht_create_finish (call_frame_t *frame, xlator_t *this, int op_ret)
7f4c2a
+dht_create_finish (call_frame_t *frame, xlator_t *this, int op_ret, int invoke_cbk)
7f4c2a
 {
7f4c2a
         dht_local_t  *local      = NULL, *lock_local = NULL;
7f4c2a
         call_frame_t *lock_frame = NULL;
7f4c2a
@@ -6091,7 +6094,7 @@ dht_create_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
 err:
7f4c2a
-        dht_create_finish (frame, this, -1);
7f4c2a
+        dht_create_finish (frame, this, -1, 0);
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
 
7f4c2a
@@ -6122,7 +6125,7 @@ dht_create_lock (call_frame_t *frame, xlator_t *subvol)
7f4c2a
         local->lock.lk_count = count;
7f4c2a
 
7f4c2a
         ret = dht_blocking_inodelk (frame, lk_array, count,
7f4c2a
-                                    dht_create_lock_cbk);
7f4c2a
+                                    IGNORE_ENOENT_ESTALE, dht_create_lock_cbk);
7f4c2a
 
7f4c2a
         if (ret < 0) {
7f4c2a
                 local->lock.locks = NULL;
7f4c2a
@@ -6582,6 +6585,7 @@ unlock:
7f4c2a
         this_call_cnt = dht_frame_return (frame);
7f4c2a
         if (is_last_call (this_call_cnt)) {
7f4c2a
                if (local->need_selfheal) {
7f4c2a
+                        dht_rmdir_unlock (frame, this);
7f4c2a
                         local->layout =
7f4c2a
                                 dht_layout_get (this, local->loc.inode);
7f4c2a
 
7f4c2a
@@ -6605,6 +6609,7 @@ unlock:
7f4c2a
                                                            1);
7f4c2a
                         }
7f4c2a
 
7f4c2a
+                        dht_rmdir_unlock (frame, this);
7f4c2a
                         DHT_STACK_UNWIND (rmdir, frame, local->op_ret,
7f4c2a
                                           local->op_errno, &local->preparent,
7f4c2a
                                           &local->postparent, NULL);
7f4c2a
@@ -6673,6 +6678,7 @@ unlock:
7f4c2a
 
7f4c2a
         if (done) {
7f4c2a
                 if (local->need_selfheal && local->fop_succeeded) {
7f4c2a
+                        dht_rmdir_unlock (frame, this);
7f4c2a
                         local->layout =
7f4c2a
                                 dht_layout_get (this, local->loc.inode);
7f4c2a
 
7f4c2a
@@ -6707,6 +6713,7 @@ unlock:
7f4c2a
 
7f4c2a
                         }
7f4c2a
 
7f4c2a
+                        dht_rmdir_unlock (frame, this);
7f4c2a
                         DHT_STACK_UNWIND (rmdir, frame, local->op_ret,
7f4c2a
                                           local->op_errno, &local->preparent,
7f4c2a
                                           &local->postparent, NULL);
7f4c2a
@@ -6718,11 +6725,110 @@ unlock:
7f4c2a
 
7f4c2a
 
7f4c2a
 int
7f4c2a
+dht_rmdir_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
+                      int32_t op_ret, int32_t op_errno, dict_t *xdata)
7f4c2a
+{
7f4c2a
+        DHT_STACK_DESTROY (frame);
7f4c2a
+        return 0;
7f4c2a
+}
7f4c2a
+
7f4c2a
+
7f4c2a
+int
7f4c2a
+dht_rmdir_unlock (call_frame_t *frame, xlator_t *this)
7f4c2a
+{
7f4c2a
+        dht_local_t  *local      = NULL, *lock_local = NULL;
7f4c2a
+        call_frame_t *lock_frame = NULL;
7f4c2a
+        int           lock_count = 0;
7f4c2a
+
7f4c2a
+        local = frame->local;
7f4c2a
+        lock_count = dht_lock_count (local->lock.locks, local->lock.lk_count);
7f4c2a
+
7f4c2a
+        if (lock_count == 0)
7f4c2a
+                goto done;
7f4c2a
+
7f4c2a
+        lock_frame = copy_frame (frame);
7f4c2a
+        if (lock_frame == NULL)
7f4c2a
+                goto done;
7f4c2a
+
7f4c2a
+        lock_local = dht_local_init (lock_frame, &local->loc, NULL,
7f4c2a
+                                     lock_frame->root->op);
7f4c2a
+        if (lock_local == NULL)
7f4c2a
+                goto done;
7f4c2a
+
7f4c2a
+        lock_local->lock.locks = local->lock.locks;
7f4c2a
+        lock_local->lock.lk_count = local->lock.lk_count;
7f4c2a
+
7f4c2a
+        local->lock.locks = NULL;
7f4c2a
+        local->lock.lk_count = 0;
7f4c2a
+        dht_unlock_inodelk (lock_frame, lock_local->lock.locks,
7f4c2a
+                            lock_local->lock.lk_count,
7f4c2a
+                            dht_rmdir_unlock_cbk);
7f4c2a
+        lock_frame = NULL;
7f4c2a
+
7f4c2a
+done:
7f4c2a
+        if (lock_frame != NULL) {
7f4c2a
+                DHT_STACK_DESTROY (lock_frame);
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        return 0;
7f4c2a
+}
7f4c2a
+
7f4c2a
+
7f4c2a
+int
7f4c2a
+dht_rmdir_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
+                    int32_t op_ret, int32_t op_errno, dict_t *xdata)
7f4c2a
+{
7f4c2a
+        dht_local_t  *local = NULL;
7f4c2a
+        dht_conf_t   *conf  = NULL;
7f4c2a
+        int           i     = 0;
7f4c2a
+
7f4c2a
+        VALIDATE_OR_GOTO (this->private, err);
7f4c2a
+
7f4c2a
+        conf = this->private;
7f4c2a
+        local = frame->local;
7f4c2a
+
7f4c2a
+        if (op_ret < 0) {
7f4c2a
+                gf_msg (this->name, GF_LOG_WARNING, op_errno,
7f4c2a
+                        DHT_MSG_INODE_LK_ERROR,
7f4c2a
+                        "acquiring inodelk failed rmdir for %s)",
7f4c2a
+                        local->loc.path);
7f4c2a
+
7f4c2a
+                local->op_ret = -1;
7f4c2a
+                local->op_errno = (op_errno == EAGAIN) ? EBUSY : op_errno;
7f4c2a
+                goto err;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        for (i = 0; i < conf->subvolume_cnt; i++) {
7f4c2a
+                if (local->hashed_subvol &&
7f4c2a
+                    (local->hashed_subvol == conf->subvolumes[i]))
7f4c2a
+                        continue;
7f4c2a
+
7f4c2a
+                STACK_WIND (frame, dht_rmdir_cbk,
7f4c2a
+                            conf->subvolumes[i],
7f4c2a
+                            conf->subvolumes[i]->fops->rmdir,
7f4c2a
+                            &local->loc, local->flags, NULL);
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        return 0;
7f4c2a
+
7f4c2a
+err:
7f4c2a
+        /* No harm in calling an extra rmdir unlock */
7f4c2a
+        dht_rmdir_unlock (frame, this);
7f4c2a
+        DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
7f4c2a
+                          &local->preparent, &local->postparent, NULL);
7f4c2a
+
7f4c2a
+        return 0;
7f4c2a
+}
7f4c2a
+
7f4c2a
+
7f4c2a
+int
7f4c2a
 dht_rmdir_do (call_frame_t *frame, xlator_t *this)
7f4c2a
 {
7f4c2a
         dht_local_t  *local = NULL;
7f4c2a
         dht_conf_t   *conf = NULL;
7f4c2a
-        int           i = 0;
7f4c2a
+        dht_lock_t   **lk_array = NULL;
7f4c2a
+        int           i = 0, ret = -1;
7f4c2a
+        int           count = 1;
7f4c2a
         xlator_t     *hashed_subvol = NULL;
7f4c2a
         char gfid[GF_UUID_BUF_SIZE] ={0};
7f4c2a
 
7f4c2a
@@ -6736,7 +6842,6 @@ dht_rmdir_do (call_frame_t *frame, xlator_t *this)
7f4c2a
 
7f4c2a
         local->call_cnt = conf->subvolume_cnt;
7f4c2a
 
7f4c2a
-
7f4c2a
         /* first remove from non-hashed_subvol */
7f4c2a
         hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
7f4c2a
 
7f4c2a
@@ -6760,20 +6865,49 @@ dht_rmdir_do (call_frame_t *frame, xlator_t *this)
7f4c2a
                 return 0;
7f4c2a
         }
7f4c2a
 
7f4c2a
-        for (i = 0; i < conf->subvolume_cnt; i++) {
7f4c2a
-                if (hashed_subvol &&
7f4c2a
-                    (hashed_subvol == conf->subvolumes[i]))
7f4c2a
-                        continue;
7f4c2a
+        count = conf->subvolume_cnt;
7f4c2a
 
7f4c2a
-                STACK_WIND (frame, dht_rmdir_cbk,
7f4c2a
-                            conf->subvolumes[i],
7f4c2a
-                            conf->subvolumes[i]->fops->rmdir,
7f4c2a
-                            &local->loc, local->flags, NULL);
7f4c2a
+        lk_array = GF_CALLOC (count, sizeof (*lk_array), gf_common_mt_char);
7f4c2a
+        if (lk_array == NULL) {
7f4c2a
+                local->op_ret = -1;
7f4c2a
+                local->op_errno = ENOMEM;
7f4c2a
+                goto err;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        for (i = 0; i < count; i++) {
7f4c2a
+                lk_array[i] = dht_lock_new (frame->this,
7f4c2a
+                                            conf->subvolumes[i],
7f4c2a
+                                            &local->loc, F_WRLCK,
7f4c2a
+                                            DHT_LAYOUT_HEAL_DOMAIN);
7f4c2a
+                if (lk_array[i] == NULL) {
7f4c2a
+                        local->op_ret = -1;
7f4c2a
+                        local->op_errno = EINVAL;
7f4c2a
+                        goto err;
7f4c2a
+                }
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        local->lock.locks = lk_array;
7f4c2a
+        local->lock.lk_count = count;
7f4c2a
+
7f4c2a
+        ret = dht_blocking_inodelk (frame, lk_array, count,
7f4c2a
+                                    IGNORE_ENOENT_ESTALE,
7f4c2a
+                                    dht_rmdir_lock_cbk);
7f4c2a
+        if (ret < 0) {
7f4c2a
+                local->lock.locks = NULL;
7f4c2a
+                local->lock.lk_count = 0;
7f4c2a
+                local->op_ret = -1;
7f4c2a
+                local->op_errno = errno ? errno : EINVAL;
7f4c2a
+                goto err;
7f4c2a
         }
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
 
7f4c2a
 err:
7f4c2a
+        if (lk_array != NULL) {
7f4c2a
+                dht_lock_array_free (lk_array, count);
7f4c2a
+                GF_FREE (lk_array);
7f4c2a
+        }
7f4c2a
+
7f4c2a
         DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
7f4c2a
                           &local->preparent, &local->postparent, NULL);
7f4c2a
         return 0;
7f4c2a
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
7f4c2a
index 1b5a084..7f99a06 100644
7f4c2a
--- a/xlators/cluster/dht/src/dht-common.h
7f4c2a
+++ b/xlators/cluster/dht/src/dht-common.h
7f4c2a
@@ -45,7 +45,7 @@ typedef int (*dht_defrag_cbk_fn_t) (xlator_t        *this, xlator_t *dst_node,
7f4c2a
                                     call_frame_t    *frame);
7f4c2a
 
7f4c2a
 typedef int (*dht_refresh_layout_unlock) (call_frame_t *frame, xlator_t *this,
7f4c2a
-                                         int op_ret);
7f4c2a
+                                         int op_ret, int invoke_cbk);
7f4c2a
 
7f4c2a
 typedef int (*dht_refresh_layout_done_handle) (call_frame_t *frame);
7f4c2a
 
7f4c2a
@@ -136,6 +136,11 @@ typedef enum {
7f4c2a
         qdstatfs_action_COMPARE,
7f4c2a
 } qdstatfs_action_t;
7f4c2a
 
7f4c2a
+typedef enum {
7f4c2a
+        FAIL_ON_ANY_ERROR,
7f4c2a
+        IGNORE_ENOENT_ESTALE
7f4c2a
+} dht_reaction_type_t;
7f4c2a
+
7f4c2a
 struct dht_skip_linkto_unlink {
7f4c2a
 
7f4c2a
         gf_boolean_t    handle_valid_link;
7f4c2a
@@ -266,6 +271,7 @@ struct dht_local {
7f4c2a
                 fop_inodelk_cbk_t   inodelk_cbk;
7f4c2a
                 dht_lock_t        **locks;
7f4c2a
                 int                 lk_count;
7f4c2a
+                dht_reaction_type_t reaction;
7f4c2a
 
7f4c2a
                 /* whether locking failed on _any_ of the "locks" above */
7f4c2a
                 int                 op_ret;
7f4c2a
@@ -1047,7 +1053,8 @@ dht_fill_dict_to_avoid_unlink_of_migrating_file (dict_t *dict);
7f4c2a
 
7f4c2a
 int
7f4c2a
 dht_nonblocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
7f4c2a
-                         int lk_count, fop_inodelk_cbk_t inodelk_cbk);
7f4c2a
+                         int lk_count, dht_reaction_type_t reaction,
7f4c2a
+                         fop_inodelk_cbk_t inodelk_cbk);
7f4c2a
 
7f4c2a
 /* same as dht_nonblocking_inodelk, but issues sequential blocking locks on
7f4c2a
  * @lk_array directly. locks are issued on some order which remains same
7f4c2a
@@ -1055,7 +1062,8 @@ dht_nonblocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
7f4c2a
  */
7f4c2a
 int
7f4c2a
 dht_blocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
7f4c2a
-                      int lk_count, fop_inodelk_cbk_t inodelk_cbk);
7f4c2a
+                      int lk_count, dht_reaction_type_t reaction,
7f4c2a
+                      fop_inodelk_cbk_t inodelk_cbk);
7f4c2a
 
7f4c2a
 int32_t
7f4c2a
 dht_unlock_inodelk (call_frame_t *frame, dht_lock_t **lk_array, int lk_count,
7f4c2a
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
7f4c2a
index 2e4a53c..1b3fbb0 100644
7f4c2a
--- a/xlators/cluster/dht/src/dht-helper.c
7f4c2a
+++ b/xlators/cluster/dht/src/dht-helper.c
7f4c2a
@@ -347,6 +347,7 @@ dht_lock_new (xlator_t *this, xlator_t *xl, loc_t *loc, short type,
7f4c2a
 
7f4c2a
         lock->xl = xl;
7f4c2a
         lock->type = type;
7f4c2a
+
7f4c2a
         lock->domain = gf_strdup (domain);
7f4c2a
         if (lock->domain == NULL) {
7f4c2a
                 dht_lock_free (lock);
7f4c2a
@@ -1692,7 +1693,8 @@ out:
7f4c2a
 
7f4c2a
 int
7f4c2a
 dht_nonblocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
7f4c2a
-                         int lk_count, fop_inodelk_cbk_t inodelk_cbk)
7f4c2a
+                         int lk_count, dht_reaction_type_t reaction,
7f4c2a
+                         fop_inodelk_cbk_t inodelk_cbk)
7f4c2a
 {
7f4c2a
         struct gf_flock  flock      = {0,};
7f4c2a
         int              i          = 0, ret = 0;
7f4c2a
@@ -1715,6 +1717,7 @@ dht_nonblocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
7f4c2a
         dht_set_lkowner (lk_array, lk_count, &lock_frame->root->lk_owner);
7f4c2a
 
7f4c2a
         local = lock_frame->local;
7f4c2a
+        local->lock.reaction = reaction;
7f4c2a
         local->main_frame = frame;
7f4c2a
 
7f4c2a
         local->call_cnt = lk_count;
7f4c2a
@@ -1745,21 +1748,42 @@ dht_blocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
                           int32_t op_ret, int32_t op_errno, dict_t *xdata)
7f4c2a
 {
7f4c2a
         int          lk_index = 0;
7f4c2a
+        int          i        = 0;
7f4c2a
         dht_local_t *local    = NULL;
7f4c2a
 
7f4c2a
         lk_index = (long) cookie;
7f4c2a
 
7f4c2a
         local = frame->local;
7f4c2a
-
7f4c2a
         if (op_ret == 0) {
7f4c2a
                 local->lock.locks[lk_index]->locked = _gf_true;
7f4c2a
         } else {
7f4c2a
-                local->lock.op_ret = -1;
7f4c2a
-                local->lock.op_errno = op_errno;
7f4c2a
-                goto cleanup;
7f4c2a
+                switch (op_errno) {
7f4c2a
+                case ESTALE:
7f4c2a
+                case ENOENT:
7f4c2a
+                        if (local->lock.reaction != IGNORE_ENOENT_ESTALE) {
7f4c2a
+                                local->lock.op_ret = -1;
7f4c2a
+                                local->lock.op_errno = op_errno;
7f4c2a
+                                goto cleanup;
7f4c2a
+                        }
7f4c2a
+                        break;
7f4c2a
+                default:
7f4c2a
+                        local->lock.op_ret = -1;
7f4c2a
+                        local->lock.op_errno = op_errno;
7f4c2a
+                        goto cleanup;
7f4c2a
+                }
7f4c2a
         }
7f4c2a
 
7f4c2a
         if (lk_index == (local->lock.lk_count - 1)) {
7f4c2a
+                for (i = 0; (i < local->lock.lk_count) &&
7f4c2a
+                     (!local->lock.locks[i]->locked); i++) {
7f4c2a
+                        ;
7f4c2a
+                }
7f4c2a
+
7f4c2a
+                if (i == local->lock.lk_count) {
7f4c2a
+                        local->lock.op_ret = -1;
7f4c2a
+                        local->lock.op_errno = op_errno;
7f4c2a
+                }
7f4c2a
+
7f4c2a
                 dht_inodelk_done (frame);
7f4c2a
         } else {
7f4c2a
                 dht_blocking_inodelk_rec (frame, ++lk_index);
7f4c2a
@@ -1833,7 +1857,8 @@ out:
7f4c2a
 
7f4c2a
 int
7f4c2a
 dht_blocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
7f4c2a
-                      int lk_count, fop_inodelk_cbk_t inodelk_cbk)
7f4c2a
+                      int lk_count, dht_reaction_type_t reaction,
7f4c2a
+                      fop_inodelk_cbk_t inodelk_cbk)
7f4c2a
 {
7f4c2a
         int           ret        = -1;
7f4c2a
         call_frame_t *lock_frame = NULL;
7f4c2a
@@ -1855,6 +1880,7 @@ dht_blocking_inodelk (call_frame_t *frame, dht_lock_t **lk_array,
7f4c2a
         dht_set_lkowner (lk_array, lk_count, &lock_frame->root->lk_owner);
7f4c2a
 
7f4c2a
         local = lock_frame->local;
7f4c2a
+        local->lock.reaction = reaction;
7f4c2a
         local->main_frame = frame;
7f4c2a
 
7f4c2a
         dht_blocking_inodelk_rec (lock_frame, 0);
7f4c2a
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c
7f4c2a
index 320f875..06d7ac8 100644
7f4c2a
--- a/xlators/cluster/dht/src/dht-rename.c
7f4c2a
+++ b/xlators/cluster/dht/src/dht-rename.c
7f4c2a
@@ -1307,7 +1307,7 @@ dht_rename_lock (call_frame_t *frame)
7f4c2a
         local->lock.lk_count = count;
7f4c2a
 
7f4c2a
         ret = dht_nonblocking_inodelk (frame, lk_array, count,
7f4c2a
-                                       dht_rename_lock_cbk);
7f4c2a
+                                       FAIL_ON_ANY_ERROR, dht_rename_lock_cbk);
7f4c2a
         if (ret < 0) {
7f4c2a
                 local->lock.locks = NULL;
7f4c2a
                 local->lock.lk_count = 0;
7f4c2a
diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c
7f4c2a
index cd1d97f..46491cf 100644
7f4c2a
--- a/xlators/cluster/dht/src/dht-selfheal.c
7f4c2a
+++ b/xlators/cluster/dht/src/dht-selfheal.c
7f4c2a
@@ -82,7 +82,7 @@ dht_selfheal_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
 }
7f4c2a
 
7f4c2a
 int
7f4c2a
-dht_selfheal_dir_finish (call_frame_t *frame, xlator_t *this, int ret)
7f4c2a
+dht_selfheal_dir_finish (call_frame_t *frame, xlator_t *this, int ret, int invoke_cbk)
7f4c2a
 {
7f4c2a
         dht_local_t  *local      = NULL, *lock_local = NULL;
7f4c2a
         call_frame_t *lock_frame = NULL;
7f4c2a
@@ -90,7 +90,6 @@ dht_selfheal_dir_finish (call_frame_t *frame, xlator_t *this, int ret)
7f4c2a
 
7f4c2a
         local = frame->local;
7f4c2a
         lock_count = dht_lock_count (local->lock.locks, local->lock.lk_count);
7f4c2a
-
7f4c2a
         if (lock_count == 0)
7f4c2a
                 goto done;
7f4c2a
 
7f4c2a
@@ -117,8 +116,9 @@ dht_selfheal_dir_finish (call_frame_t *frame, xlator_t *this, int ret)
7f4c2a
         lock_frame = NULL;
7f4c2a
 
7f4c2a
 done:
7f4c2a
-        local->selfheal.dir_cbk (frame, NULL, frame->this, ret,
7f4c2a
-                                 local->op_errno, NULL);
7f4c2a
+        if (!invoke_cbk)
7f4c2a
+                local->selfheal.dir_cbk (frame, NULL, frame->this, ret,
7f4c2a
+                                         local->op_errno, NULL);
7f4c2a
         if (lock_frame != NULL) {
7f4c2a
                 DHT_STACK_DESTROY (lock_frame);
7f4c2a
         }
7f4c2a
@@ -160,13 +160,13 @@ dht_refresh_layout_done (call_frame_t *frame)
7f4c2a
 
7f4c2a
                 dht_layout_unref (frame->this, heal);
7f4c2a
 
7f4c2a
-                dht_selfheal_dir_finish (frame, frame->this, 0);
7f4c2a
+                dht_selfheal_dir_finish (frame, frame->this, 0, 0);
7f4c2a
         }
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
 
7f4c2a
 err:
7f4c2a
-        dht_selfheal_dir_finish (frame, frame->this, -1);
7f4c2a
+        dht_selfheal_dir_finish (frame, frame->this, -1, 0);
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
 
7f4c2a
@@ -224,8 +224,9 @@ unlock:
7f4c2a
         return 0;
7f4c2a
 
7f4c2a
 err:
7f4c2a
-        local->refresh_layout_unlock (frame, this, -1);
7f4c2a
+        local->refresh_layout_unlock (frame, this, -1, 0);
7f4c2a
 
7f4c2a
+        dht_selfheal_dir_finish (frame, this, -1, 0);
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
 
7f4c2a
@@ -291,7 +292,8 @@ dht_refresh_layout (call_frame_t *frame)
7f4c2a
         return 0;
7f4c2a
 
7f4c2a
 out:
7f4c2a
-        local->refresh_layout_unlock (frame, this, -1);
7f4c2a
+        local->refresh_layout_unlock (frame, this, -1, 0);
7f4c2a
+        dht_selfheal_dir_finish (frame, this, -1, 0);
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
 
7f4c2a
@@ -319,7 +321,7 @@ dht_selfheal_layout_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
         return 0;
7f4c2a
 
7f4c2a
 err:
7f4c2a
-        dht_selfheal_dir_finish (frame, this, -1);
7f4c2a
+        dht_selfheal_dir_finish (frame, this, -1, 0);
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
 
7f4c2a
@@ -580,7 +582,7 @@ dht_selfheal_layout_lock (call_frame_t *frame, dht_layout_t *layout,
7f4c2a
         local->lock.locks = lk_array;
7f4c2a
         local->lock.lk_count = count;
7f4c2a
 
7f4c2a
-        ret = dht_blocking_inodelk (frame, lk_array, count,
7f4c2a
+        ret = dht_blocking_inodelk (frame, lk_array, count, FAIL_ON_ANY_ERROR,
7f4c2a
                                     dht_selfheal_layout_lock_cbk);
7f4c2a
         if (ret < 0) {
7f4c2a
                 local->lock.locks = NULL;
7f4c2a
@@ -591,13 +593,7 @@ dht_selfheal_layout_lock (call_frame_t *frame, dht_layout_t *layout,
7f4c2a
         return 0;
7f4c2a
 err:
7f4c2a
         if (lk_array != NULL) {
7f4c2a
-                int tmp_count = 0, i = 0;
7f4c2a
-
7f4c2a
-                for (i = 0; (i < count) && (lk_array[i]); i++, tmp_count++) {
7f4c2a
-                        ;
7f4c2a
-                }
7f4c2a
-
7f4c2a
-                dht_lock_array_free (lk_array, tmp_count);
7f4c2a
+                dht_lock_array_free (lk_array, count);
7f4c2a
                 GF_FREE (lk_array);
7f4c2a
         }
7f4c2a
 
7f4c2a
@@ -636,7 +632,7 @@ dht_selfheal_dir_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
         this_call_cnt = dht_frame_return (frame);
7f4c2a
 
7f4c2a
         if (is_last_call (this_call_cnt)) {
7f4c2a
-                dht_selfheal_dir_finish (frame, this, 0);
7f4c2a
+                dht_selfheal_dir_finish (frame, this, 0, 0);
7f4c2a
         }
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
@@ -831,7 +827,7 @@ dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout)
7f4c2a
                       missing_xattr, loc->path);
7f4c2a
 
7f4c2a
         if (missing_xattr == 0) {
7f4c2a
-                dht_selfheal_dir_finish (frame, this, 0);
7f4c2a
+                dht_selfheal_dir_finish (frame, this, 0, 0);
7f4c2a
                 return 0;
7f4c2a
         }
7f4c2a
 
7f4c2a
@@ -958,7 +954,7 @@ dht_selfheal_dir_xattr_for_nameless_lookup (call_frame_t *frame, loc_t *loc,
7f4c2a
                       missing_xattr, loc->path);
7f4c2a
 
7f4c2a
         if (missing_xattr == 0) {
7f4c2a
-                dht_selfheal_dir_finish (frame, this, 0);
7f4c2a
+                dht_selfheal_dir_finish (frame, this, 0, 0);
7f4c2a
                 return 0;
7f4c2a
         }
7f4c2a
 
7f4c2a
@@ -1026,7 +1022,7 @@ dht_selfheal_dir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
                                                 dht_should_heal_layout);
7f4c2a
 
7f4c2a
                 if (ret < 0) {
7f4c2a
-                        dht_selfheal_dir_finish (frame, this, -1);
7f4c2a
+                        dht_selfheal_dir_finish (frame, this, -1, 0);
7f4c2a
                 }
7f4c2a
         }
7f4c2a
 
7f4c2a
@@ -1057,7 +1053,7 @@ dht_selfheal_dir_setattr (call_frame_t *frame, loc_t *loc, struct iatt *stbuf,
7f4c2a
                                                 dht_should_heal_layout);
7f4c2a
 
7f4c2a
                 if (ret < 0) {
7f4c2a
-                        dht_selfheal_dir_finish (frame, this, -1);
7f4c2a
+                        dht_selfheal_dir_finish (frame, this, -1, 0);
7f4c2a
                 }
7f4c2a
 
7f4c2a
                 return 0;
7f4c2a
@@ -1095,7 +1091,7 @@ dht_selfheal_dir_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
         dht_layout_t  *layout = NULL;
7f4c2a
         call_frame_t  *prev = NULL;
7f4c2a
         xlator_t      *subvol = NULL;
7f4c2a
-        int            i = 0;
7f4c2a
+        int            i = 0, ret = -1;
7f4c2a
         int            this_call_cnt = 0;
7f4c2a
         char           gfid[GF_UUID_BUF_SIZE] = {0};
7f4c2a
 
7f4c2a
@@ -1114,7 +1110,6 @@ dht_selfheal_dir_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
         }
7f4c2a
 
7f4c2a
         if (op_ret) {
7f4c2a
-
7f4c2a
                 gf_uuid_unparse(local->loc.gfid, gfid);
7f4c2a
                 gf_msg (this->name, ((op_errno == EEXIST) ? GF_LOG_DEBUG :
7f4c2a
                                      GF_LOG_WARNING),
7f4c2a
@@ -1127,11 +1122,13 @@ dht_selfheal_dir_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
         dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
7f4c2a
         dht_iatt_merge (this, &local->preparent, preparent, prev->this);
7f4c2a
         dht_iatt_merge (this, &local->postparent, postparent, prev->this);
7f4c2a
+        ret = 0;
7f4c2a
 
7f4c2a
 out:
7f4c2a
         this_call_cnt = dht_frame_return (frame);
7f4c2a
 
7f4c2a
         if (is_last_call (this_call_cnt)) {
7f4c2a
+                dht_selfheal_dir_finish (frame, this, ret, -1);
7f4c2a
                 dht_selfheal_dir_setattr (frame, &local->loc, &local->stbuf, 0xffffff, layout);
7f4c2a
         }
7f4c2a
 
7f4c2a
@@ -1184,32 +1181,33 @@ out:
7f4c2a
 }
7f4c2a
 
7f4c2a
 int
7f4c2a
-dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
7f4c2a
-                        dht_layout_t *layout, int force)
7f4c2a
+dht_selfheal_dir_mkdir_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
7f4c2a
+                                 int32_t op_ret, int32_t op_errno, dict_t *xdata)
7f4c2a
 {
7f4c2a
-        int           missing_dirs = 0;
7f4c2a
+        dht_local_t  *local = NULL;
7f4c2a
         int           i     = 0;
7f4c2a
         int           ret   = -1;
7f4c2a
-        dht_local_t  *local = NULL;
7f4c2a
-        xlator_t     *this = NULL;
7f4c2a
         dict_t       *dict = NULL;
7f4c2a
+        dht_layout_t  *layout = NULL;
7f4c2a
+        loc_t        *loc   = NULL;
7f4c2a
 
7f4c2a
-        local = frame->local;
7f4c2a
-        this = frame->this;
7f4c2a
+        VALIDATE_OR_GOTO (this->private, err);
7f4c2a
 
7f4c2a
-        local->selfheal.force_mkdir = force ? _gf_true : _gf_false;
7f4c2a
+        local = frame->local;
7f4c2a
+        layout = local->layout;
7f4c2a
+        loc    = &local->loc;
7f4c2a
 
7f4c2a
-        for (i = 0; i < layout->cnt; i++) {
7f4c2a
-                if (layout->list[i].err == ENOENT || force)
7f4c2a
-                        missing_dirs++;
7f4c2a
-        }
7f4c2a
+        if (op_ret < 0) {
7f4c2a
+                gf_msg (this->name, GF_LOG_WARNING, op_errno,
7f4c2a
+                        DHT_MSG_INODE_LK_ERROR,
7f4c2a
+                        "acquiring inodelk failed for %s",
7f4c2a
+                        loc->path);
7f4c2a
 
7f4c2a
-        if (missing_dirs == 0) {
7f4c2a
-                dht_selfheal_dir_setattr (frame, loc, &local->stbuf, 0xffffffff, layout);
7f4c2a
-                return 0;
7f4c2a
+                local->op_ret = -1;
7f4c2a
+                local->op_errno = (op_errno == EAGAIN) ? EBUSY : op_errno;
7f4c2a
+                goto err;
7f4c2a
         }
7f4c2a
 
7f4c2a
-        local->call_cnt = missing_dirs;
7f4c2a
         if (!gf_uuid_is_null (local->gfid)) {
7f4c2a
                 dict = dict_new ();
7f4c2a
                 if (!dict)
7f4c2a
@@ -1223,6 +1221,7 @@ dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
7f4c2a
                                 " key = gfid-req", loc->path);
7f4c2a
         } else if (local->params) {
7f4c2a
                 /* Send the dictionary from higher layers directly */
7f4c2a
+
7f4c2a
                 dict = dict_ref (local->params);
7f4c2a
         }
7f4c2a
         /* Set acls */
7f4c2a
@@ -1234,8 +1233,18 @@ dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
7f4c2a
                         DHT_MSG_DICT_SET_FAILED,
7f4c2a
                         "dict is NULL, need to make sure gfids are same");
7f4c2a
 
7f4c2a
+
7f4c2a
+        /* We don't have to do a lookup here again:
7f4c2a
+            1) Parallel rmdir would had removed the directory and locking would
7f4c2a
+               have anyway failed with an ESTALE on all subvols. Hence selfheal
7f4c2a
+               will never create the directory.
7f4c2a
+            2) Parallel lookup creating directory does not have to be mutually
7f4c2a
+               exclusive for the mkdir phase of lookup selfheal.
7f4c2a
+        */
7f4c2a
+
7f4c2a
         for (i = 0; i < layout->cnt; i++) {
7f4c2a
-                if (layout->list[i].err == ENOENT || force) {
7f4c2a
+                if (layout->list[i].err == ENOENT ||
7f4c2a
+                    local->selfheal.force_mkdir) {
7f4c2a
                         gf_msg_debug (this->name, 0,
7f4c2a
                                       "Creating directory %s on subvol %s",
7f4c2a
                                       loc->path, layout->list[i].xlator->name);
7f4c2a
@@ -1254,6 +1263,82 @@ dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
7f4c2a
                 dict_unref (dict);
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
+
7f4c2a
+err:
7f4c2a
+        dht_selfheal_dir_finish (frame, this, -1, 0);
7f4c2a
+        return 0;
7f4c2a
+}
7f4c2a
+
7f4c2a
+int
7f4c2a
+dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
7f4c2a
+                        dht_layout_t *layout, int force)
7f4c2a
+{
7f4c2a
+        int           missing_dirs = 0;
7f4c2a
+        int           i     = 0;
7f4c2a
+        int           ret   = -1;
7f4c2a
+        int           count = 1;
7f4c2a
+        dht_local_t  *local = NULL;
7f4c2a
+        dht_conf_t   *conf  = NULL;
7f4c2a
+        xlator_t     *this = NULL;
7f4c2a
+        dht_lock_t   **lk_array = NULL;
7f4c2a
+
7f4c2a
+        local = frame->local;
7f4c2a
+        this = frame->this;
7f4c2a
+        conf = this->private;
7f4c2a
+
7f4c2a
+        local->selfheal.force_mkdir = force ? _gf_true : _gf_false;
7f4c2a
+
7f4c2a
+        for (i = 0; i < layout->cnt; i++) {
7f4c2a
+                if (layout->list[i].err == ENOENT || force)
7f4c2a
+                        missing_dirs++;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        if (missing_dirs == 0) {
7f4c2a
+                dht_selfheal_dir_setattr (frame, loc, &local->stbuf,
7f4c2a
+                                          0xffffffff, layout);
7f4c2a
+                return 0;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        local->call_cnt = missing_dirs;
7f4c2a
+        count = conf->subvolume_cnt;
7f4c2a
+
7f4c2a
+        /* Locking on all subvols in the mkdir phase of lookup selfheal is
7f4c2a
+           is done to synchronize with rmdir/rename.
7f4c2a
+        */
7f4c2a
+        lk_array = GF_CALLOC (count, sizeof (*lk_array), gf_common_mt_char);
7f4c2a
+        if (lk_array == NULL)
7f4c2a
+                goto err;
7f4c2a
+
7f4c2a
+        for (i = 0; i < count; i++) {
7f4c2a
+                lk_array[i] = dht_lock_new (frame->this,
7f4c2a
+                                            conf->subvolumes[i],
7f4c2a
+                                            &local->loc, F_WRLCK,
7f4c2a
+                                            DHT_LAYOUT_HEAL_DOMAIN);
7f4c2a
+                if (lk_array[i] == NULL)
7f4c2a
+                        goto err;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        local->lock.locks = lk_array;
7f4c2a
+        local->lock.lk_count = count;
7f4c2a
+
7f4c2a
+        ret = dht_blocking_inodelk (frame, lk_array, count,
7f4c2a
+                                    IGNORE_ENOENT_ESTALE,
7f4c2a
+                                    dht_selfheal_dir_mkdir_lock_cbk);
7f4c2a
+
7f4c2a
+        if (ret < 0) {
7f4c2a
+                local->lock.locks = NULL;
7f4c2a
+                local->lock.lk_count = 0;
7f4c2a
+                goto err;
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        return 0;
7f4c2a
+err:
7f4c2a
+        if (lk_array != NULL) {
7f4c2a
+                dht_lock_array_free (lk_array, count);
7f4c2a
+                GF_FREE (lk_array);
7f4c2a
+        }
7f4c2a
+
7f4c2a
+        return -1;
7f4c2a
 }
7f4c2a
 
7f4c2a
 int
7f4c2a
@@ -1825,7 +1910,7 @@ dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
7f4c2a
 
7f4c2a
 sorry_no_fix:
7f4c2a
         /* TODO: need to put appropriate local->op_errno */
7f4c2a
-        dht_selfheal_dir_finish (frame, this, ret);
7f4c2a
+        dht_selfheal_dir_finish (frame, this, ret, 0);
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
 }
7f4c2a
@@ -1893,7 +1978,7 @@ dht_selfheal_directory_for_nameless_lookup (call_frame_t *frame,
7f4c2a
 
7f4c2a
 sorry_no_fix:
7f4c2a
         /* TODO: need to put appropriate local->op_errno */
7f4c2a
-        dht_selfheal_dir_finish (frame, this, ret);
7f4c2a
+        dht_selfheal_dir_finish (frame, this, ret, 0);
7f4c2a
 
7f4c2a
         return 0;
7f4c2a
 
7f4c2a
@@ -2244,7 +2329,7 @@ dht_update_commit_hash_for_layout (call_frame_t *frame)
7f4c2a
         local->lock.locks = lk_array;
7f4c2a
         local->lock.lk_count = count;
7f4c2a
 
7f4c2a
-        ret = dht_blocking_inodelk (frame, lk_array, count,
7f4c2a
+        ret = dht_blocking_inodelk (frame, lk_array, count, FAIL_ON_ANY_ERROR,
7f4c2a
                                     dht_update_commit_hash_for_layout_resume);
7f4c2a
         if (ret < 0) {
7f4c2a
                 local->lock.locks = NULL;
7f4c2a
@@ -2255,13 +2340,7 @@ dht_update_commit_hash_for_layout (call_frame_t *frame)
7f4c2a
         return 0;
7f4c2a
 err:
7f4c2a
         if (lk_array != NULL) {
7f4c2a
-                int tmp_count = 0, i = 0;
7f4c2a
-
7f4c2a
-                for (i = 0; (i < count) && (lk_array[i]); i++, tmp_count++) {
7f4c2a
-                        ;
7f4c2a
-                }
7f4c2a
-
7f4c2a
-                dht_lock_array_free (lk_array, tmp_count);
7f4c2a
+                dht_lock_array_free (lk_array, count);
7f4c2a
                 GF_FREE (lk_array);
7f4c2a
         }
7f4c2a
 
7f4c2a
-- 
7f4c2a
1.7.1
7f4c2a