diff options
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 2 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-selfheal.c | 67 | 
2 files changed, 58 insertions, 11 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 4f006b97919..e7e6882f955 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -1600,7 +1600,7 @@ unwind_hashed_and_cached:          DHT_STRIP_PHASE1_FLAGS (&local->stbuf);          dht_set_fixed_dir_stat (&local->postparent);          DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, -                          local->loc.inode, &local->stbuf, local->xattr, +                          local->inode, &local->stbuf, local->xattr,                            &local->postparent);          return 0;  } diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c index 4f447ab7649..3da1279b8db 100644 --- a/xlators/cluster/dht/src/dht-selfheal.c +++ b/xlators/cluster/dht/src/dht-selfheal.c @@ -1944,23 +1944,50 @@ dht_selfheal_new_directory (call_frame_t *frame,                              dht_selfheal_dir_cbk_t dir_cbk,                              dht_layout_t *layout)  { -        dht_local_t *local = NULL; -        int          ret   = 0; +        dht_local_t *local                   = NULL; +        int          ret                     = 0; +        inode_t     *linked_inode            = NULL, *inode = NULL; +        loc_t       *loc                     = NULL; +        char         pgfid[GF_UUID_BUF_SIZE] = {0}; +        char         gfid[GF_UUID_BUF_SIZE]  = {0}; +        int32_t      op_errno                = EIO;          local = frame->local; +        loc = &local->loc; + +        gf_uuid_unparse(local->stbuf.ia_gfid, gfid); +        gf_uuid_unparse(loc->parent->gfid, pgfid); + +        linked_inode = inode_link (loc->inode, loc->parent, loc->name, +                                   &local->stbuf); +        if (!linked_inode) { +                gf_msg (frame->this->name, GF_LOG_WARNING, 0, +                        DHT_MSG_DIR_SELFHEAL_FAILED, +                        "linking inode failed (%s/%s) => %s", +                        pgfid, loc->name, gfid); +                ret = -1; +                goto out; +        } + +        inode = loc->inode; +        loc->inode = linked_inode; +        inode_unref (inode); +          local->selfheal.dir_cbk = dir_cbk;          local->selfheal.layout = dht_layout_ref (frame->this, layout);          dht_layout_sort_volname (layout);          dht_selfheal_layout_new_directory (frame, &local->loc, layout); +        op_errno = ENOMEM;          ret = dht_selfheal_layout_lock (frame, layout, _gf_true,                                          dht_selfheal_dir_xattr,                                          dht_should_heal_layout); +out:          if (ret < 0) { -                dir_cbk (frame, NULL, frame->this, -1, ENOMEM, NULL); +                dir_cbk (frame, NULL, frame->this, -1, op_errno, NULL);          }          return 0; @@ -1998,17 +2025,37 @@ int  dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,                          loc_t *loc, dht_layout_t *layout)  { -        dht_local_t *local    = NULL; -        uint32_t     down     = 0; -        uint32_t     misc     = 0; -        int          ret      = 0; -        xlator_t    *this     = NULL; -        char         gfid[GF_UUID_BUF_SIZE] = {0}; +        dht_local_t *local                   = NULL; +        uint32_t     down                    = 0; +        uint32_t     misc                    = 0; +        int          ret                     = 0; +        xlator_t    *this                    = NULL; +        char         pgfid[GF_UUID_BUF_SIZE] = {0}; +        char         gfid[GF_UUID_BUF_SIZE]  = {0}; +        inode_t     *linked_inode            = NULL, *inode = NULL;          local = frame->local;          this = frame->this; -        gf_uuid_unparse(loc->gfid, gfid); +        if (!__is_root_gfid (local->stbuf.ia_gfid)) { +                gf_uuid_unparse(local->stbuf.ia_gfid, gfid); +                gf_uuid_unparse(loc->parent->gfid, pgfid); + +                linked_inode = inode_link (loc->inode, loc->parent, loc->name, +                                           &local->stbuf); +                if (!linked_inode) { +                        gf_msg (this->name, GF_LOG_WARNING, 0, +                                DHT_MSG_DIR_SELFHEAL_FAILED, +                                "linking inode failed (%s/%s) => %s", +                                pgfid, loc->name, gfid); +                        ret = 0; +                        goto sorry_no_fix; +                } + +                inode = loc->inode; +                loc->inode = linked_inode; +                inode_unref (inode); +        }          dht_layout_anomalies (this, loc, layout,                                &local->selfheal.hole_cnt,  | 
