"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/xlators/cluster/dht/src/dht-layout.c" (16 Sep 2020, 20532 Bytes) of package /linux/misc/glusterfs-8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "dht-layout.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2   Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
    3   This file is part of GlusterFS.
    4 
    5   This file is licensed to you under your choice of the GNU Lesser
    6   General Public License, version 3 or any later version (LGPLv3 or
    7   later), or the GNU General Public License, version 2 (GPLv2), in all
    8   cases as published by the Free Software Foundation.
    9 */
   10 
   11 #include "dht-common.h"
   12 #include <glusterfs/byte-order.h>
   13 #include "unittest/unittest.h"
   14 
   15 #define layout_base_size (sizeof(dht_layout_t))
   16 
   17 #define layout_entry_size (sizeof((dht_layout_t *)NULL)->list[0])
   18 
   19 #define layout_size(cnt) (layout_base_size + (cnt * layout_entry_size))
   20 
   21 dht_layout_t *
   22 dht_layout_new(xlator_t *this, int cnt)
   23 {
   24     dht_layout_t *layout = NULL;
   25     dht_conf_t *conf = NULL;
   26 
   27     REQUIRE(NULL != this);
   28     REQUIRE(cnt >= 0);
   29 
   30     conf = this->private;
   31 
   32     layout = GF_CALLOC(1, layout_size(cnt), gf_dht_mt_dht_layout_t);
   33     if (!layout) {
   34         goto out;
   35     }
   36 
   37     layout->type = DHT_HASH_TYPE_DM;
   38     layout->cnt = cnt;
   39 
   40     if (conf) {
   41         layout->spread_cnt = conf->dir_spread_cnt;
   42         layout->gen = conf->gen;
   43     }
   44 
   45     GF_ATOMIC_INIT(layout->ref, 1);
   46 
   47     ENSURE(NULL != layout);
   48     ENSURE(layout->type == DHT_HASH_TYPE_DM);
   49     ENSURE(layout->cnt == cnt);
   50     ENSURE(GF_ATOMIC_GET(layout->ref) == 1);
   51 out:
   52     return layout;
   53 }
   54 
   55 dht_layout_t *
   56 dht_layout_get(xlator_t *this, inode_t *inode)
   57 {
   58     dht_layout_t *layout = NULL;
   59     int ret = 0;
   60 
   61     ret = dht_inode_ctx_layout_get(inode, this, &layout);
   62     if ((!ret) && layout) {
   63         GF_ATOMIC_INC(layout->ref);
   64     }
   65     return layout;
   66 }
   67 
   68 int
   69 dht_layout_set(xlator_t *this, inode_t *inode, dht_layout_t *layout)
   70 {
   71     dht_conf_t *conf = NULL;
   72     int oldret = -1;
   73     int ret = -1;
   74     dht_layout_t *old_layout;
   75 
   76     conf = this->private;
   77     if (!conf || !layout)
   78         goto out;
   79 
   80     LOCK(&conf->layout_lock);
   81     {
   82         oldret = dht_inode_ctx_layout_get(inode, this, &old_layout);
   83         if (layout)
   84             GF_ATOMIC_INC(layout->ref);
   85         ret = dht_inode_ctx_layout_set(inode, this, layout);
   86     }
   87     UNLOCK(&conf->layout_lock);
   88 
   89     if (!oldret) {
   90         dht_layout_unref(this, old_layout);
   91     }
   92     if (ret)
   93         GF_ATOMIC_DEC(layout->ref);
   94 
   95 out:
   96     return ret;
   97 }
   98 
   99 void
  100 dht_layout_unref(xlator_t *this, dht_layout_t *layout)
  101 {
  102     int ref = 0;
  103 
  104     if (!layout || layout->preset || !this->private)
  105         return;
  106 
  107     ref = GF_ATOMIC_DEC(layout->ref);
  108 
  109     if (!ref)
  110         GF_FREE(layout);
  111 }
  112 
  113 dht_layout_t *
  114 dht_layout_ref(xlator_t *this, dht_layout_t *layout)
  115 {
  116     if (layout->preset || !this->private)
  117         return layout;
  118 
  119     GF_ATOMIC_INC(layout->ref);
  120 
  121     return layout;
  122 }
  123 
  124 xlator_t *
  125 dht_layout_search(xlator_t *this, dht_layout_t *layout, const char *name)
  126 {
  127     uint32_t hash = 0;
  128     xlator_t *subvol = NULL;
  129     int i = 0;
  130     int ret = 0;
  131 
  132     ret = dht_hash_compute(this, layout->type, name, &hash);
  133     if (ret != 0) {
  134         gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_COMPUTE_HASH_FAILED,
  135                 "type=%d", layout->type, "name=%s", name, NULL);
  136         goto out;
  137     }
  138 
  139     for (i = 0; i < layout->cnt; i++) {
  140         if (layout->list[i].start <= hash && layout->list[i].stop >= hash) {
  141             subvol = layout->list[i].xlator;
  142             break;
  143         }
  144     }
  145 
  146     if (!subvol) {
  147         gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED,
  148                 "hash-value=0x%x", hash, NULL);
  149     }
  150 
  151 out:
  152     return subvol;
  153 }
  154 
  155 dht_layout_t *
  156 dht_layout_for_subvol(xlator_t *this, xlator_t *subvol)
  157 {
  158     dht_conf_t *conf = NULL;
  159     dht_layout_t *layout = NULL;
  160     int i = 0;
  161 
  162     conf = this->private;
  163     if (!conf)
  164         goto out;
  165 
  166     for (i = 0; i < conf->subvolume_cnt; i++) {
  167         if (conf->subvolumes[i] == subvol) {
  168             layout = conf->file_layouts[i];
  169             break;
  170         }
  171     }
  172 
  173 out:
  174     return layout;
  175 }
  176 
  177 int
  178 dht_layouts_init(xlator_t *this, dht_conf_t *conf)
  179 {
  180     dht_layout_t *layout = NULL;
  181     int i = 0;
  182     int ret = -1;
  183 
  184     if (!conf)
  185         goto out;
  186 
  187     conf->file_layouts = GF_CALLOC(conf->subvolume_cnt, sizeof(dht_layout_t *),
  188                                    gf_dht_mt_dht_layout_t);
  189     if (!conf->file_layouts) {
  190         goto out;
  191     }
  192 
  193     for (i = 0; i < conf->subvolume_cnt; i++) {
  194         layout = dht_layout_new(this, 1);
  195 
  196         if (!layout) {
  197             goto out;
  198         }
  199 
  200         layout->preset = 1;
  201 
  202         layout->list[0].xlator = conf->subvolumes[i];
  203 
  204         conf->file_layouts[i] = layout;
  205     }
  206 
  207     ret = 0;
  208 out:
  209     return ret;
  210 }
  211 
  212 int
  213 dht_disk_layout_extract(xlator_t *this, dht_layout_t *layout, int pos,
  214                         int32_t **disk_layout_p)
  215 {
  216     int ret = -1;
  217     int32_t *disk_layout = NULL;
  218 
  219     disk_layout = GF_CALLOC(5, sizeof(int), gf_dht_mt_int32_t);
  220     if (!disk_layout) {
  221         goto out;
  222     }
  223 
  224     disk_layout[0] = hton32(layout->list[pos].commit_hash);
  225     disk_layout[1] = hton32(layout->type);
  226     disk_layout[2] = hton32(layout->list[pos].start);
  227     disk_layout[3] = hton32(layout->list[pos].stop);
  228 
  229     if (disk_layout_p)
  230         *disk_layout_p = disk_layout;
  231     else
  232         GF_FREE(disk_layout);
  233 
  234     ret = 0;
  235 
  236 out:
  237     return ret;
  238 }
  239 
  240 int
  241 dht_disk_layout_extract_for_subvol(xlator_t *this, dht_layout_t *layout,
  242                                    xlator_t *subvol, int32_t **disk_layout_p)
  243 {
  244     int i = 0;
  245 
  246     for (i = 0; i < layout->cnt; i++) {
  247         if (layout->list[i].xlator == subvol)
  248             break;
  249     }
  250 
  251     if (i == layout->cnt)
  252         return -1;
  253 
  254     return dht_disk_layout_extract(this, layout, i, disk_layout_p);
  255 }
  256 
  257 static int
  258 dht_disk_layout_merge(xlator_t *this, dht_layout_t *layout, int pos,
  259                       void *disk_layout_raw, int disk_layout_len)
  260 {
  261     int type = 0;
  262     int start_off = 0;
  263     int stop_off = 0;
  264     int commit_hash = 0;
  265     int disk_layout[4];
  266 
  267     if (!disk_layout_raw) {
  268         gf_smsg(this->name, GF_LOG_CRITICAL, 0, DHT_MSG_LAYOUT_MERGE_FAILED,
  269                 NULL);
  270         return -1;
  271     }
  272 
  273     GF_ASSERT(disk_layout_len == sizeof(disk_layout));
  274 
  275     memcpy(disk_layout, disk_layout_raw, disk_layout_len);
  276 
  277     type = ntoh32(disk_layout[1]);
  278     switch (type) {
  279         case DHT_HASH_TYPE_DM_USER:
  280             gf_msg_debug(this->name, 0, "found user-set layout");
  281             layout->type = type;
  282             /* Fall through. */
  283         case DHT_HASH_TYPE_DM:
  284             break;
  285         default:
  286             gf_smsg(this->name, GF_LOG_CRITICAL, 0, DHT_MSG_INVALID_DISK_LAYOUT,
  287                     "layout=%d", disk_layout[1], NULL);
  288             return -1;
  289     }
  290 
  291     commit_hash = ntoh32(disk_layout[0]);
  292     start_off = ntoh32(disk_layout[2]);
  293     stop_off = ntoh32(disk_layout[3]);
  294 
  295     layout->list[pos].commit_hash = commit_hash;
  296     layout->list[pos].start = start_off;
  297     layout->list[pos].stop = stop_off;
  298 
  299     gf_msg_trace(this->name, 0,
  300                  "merged to layout: 0x%x - 0x%x (hash 0x%x, type %d) from %s",
  301                  start_off, stop_off, commit_hash, type,
  302                  layout->list[pos].xlator->name);
  303 
  304     return 0;
  305 }
  306 
  307 int
  308 dht_layout_merge(xlator_t *this, dht_layout_t *layout, xlator_t *subvol,
  309                  int op_ret, int op_errno, dict_t *xattr)
  310 {
  311     int i = 0;
  312     int ret = -1;
  313     int err = -1;
  314     void *disk_layout_raw = NULL;
  315     int disk_layout_len = 0;
  316     dht_conf_t *conf = this->private;
  317 
  318     if (op_ret != 0) {
  319         err = op_errno;
  320     }
  321 
  322     if (!layout)
  323         goto out;
  324 
  325     for (i = 0; i < layout->cnt; i++) {
  326         if (layout->list[i].xlator == NULL) {
  327             layout->list[i].err = err;
  328             layout->list[i].xlator = subvol;
  329             break;
  330         }
  331     }
  332 
  333     if (op_ret != 0) {
  334         ret = 0;
  335         goto out;
  336     }
  337 
  338     if (xattr) {
  339         /* during lookup and not mkdir */
  340         ret = dict_get_ptr_and_len(xattr, conf->xattr_name, &disk_layout_raw,
  341                                    &disk_layout_len);
  342     }
  343 
  344     if (ret != 0) {
  345         layout->list[i].err = 0;
  346         gf_msg_trace(this->name, 0, "Missing disk layout on %s. err = %d",
  347                      subvol->name, err);
  348         ret = 0;
  349         goto out;
  350     }
  351 
  352     ret = dht_disk_layout_merge(this, layout, i, disk_layout_raw,
  353                                 disk_layout_len);
  354     if (ret != 0) {
  355         gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_MERGE_FAILED,
  356                 "subvolume=%s", subvol->name, NULL);
  357         goto out;
  358     }
  359 
  360     if (layout->commit_hash == 0) {
  361         layout->commit_hash = layout->list[i].commit_hash;
  362     } else if (layout->commit_hash != layout->list[i].commit_hash) {
  363         layout->commit_hash = DHT_LAYOUT_HASH_INVALID;
  364     }
  365 
  366     layout->list[i].err = 0;
  367 
  368 out:
  369     return ret;
  370 }
  371 
  372 void
  373 dht_layout_entry_swap(dht_layout_t *layout, int i, int j)
  374 {
  375     uint32_t start_swap = 0;
  376     uint32_t stop_swap = 0;
  377     uint32_t commit_hash_swap = 0;
  378     xlator_t *xlator_swap = 0;
  379     int err_swap = 0;
  380 
  381     start_swap = layout->list[i].start;
  382     stop_swap = layout->list[i].stop;
  383     xlator_swap = layout->list[i].xlator;
  384     err_swap = layout->list[i].err;
  385     commit_hash_swap = layout->list[i].commit_hash;
  386 
  387     layout->list[i].start = layout->list[j].start;
  388     layout->list[i].stop = layout->list[j].stop;
  389     layout->list[i].xlator = layout->list[j].xlator;
  390     layout->list[i].err = layout->list[j].err;
  391     layout->list[i].commit_hash = layout->list[j].commit_hash;
  392 
  393     layout->list[j].start = start_swap;
  394     layout->list[j].stop = stop_swap;
  395     layout->list[j].xlator = xlator_swap;
  396     layout->list[j].err = err_swap;
  397     layout->list[j].commit_hash = commit_hash_swap;
  398 }
  399 
  400 void
  401 dht_layout_range_swap(dht_layout_t *layout, int i, int j)
  402 {
  403     uint32_t start_swap = 0;
  404     uint32_t stop_swap = 0;
  405 
  406     start_swap = layout->list[i].start;
  407     stop_swap = layout->list[i].stop;
  408 
  409     layout->list[i].start = layout->list[j].start;
  410     layout->list[i].stop = layout->list[j].stop;
  411 
  412     layout->list[j].start = start_swap;
  413     layout->list[j].stop = stop_swap;
  414 }
  415 static int64_t
  416 dht_layout_entry_cmp_volname(dht_layout_t *layout, int i, int j)
  417 {
  418     return (strcmp(layout->list[i].xlator->name, layout->list[j].xlator->name));
  419 }
  420 
  421 gf_boolean_t
  422 dht_is_subvol_in_layout(dht_layout_t *layout, xlator_t *xlator)
  423 {
  424     int i = 0;
  425 
  426     for (i = 0; i < layout->cnt; i++) {
  427         /* Check if xlator is already part of layout, and layout is
  428          * non-zero. */
  429         if (!strcmp(layout->list[i].xlator->name, xlator->name)) {
  430             if (layout->list[i].start != layout->list[i].stop)
  431                 return _gf_true;
  432             break;
  433         }
  434     }
  435     return _gf_false;
  436 }
  437 
  438 static int64_t
  439 dht_layout_entry_cmp(dht_layout_t *layout, int i, int j)
  440 {
  441     int64_t diff = 0;
  442 
  443     /* swap zero'ed out layouts to front, if needed */
  444     if (!layout->list[j].start && !layout->list[j].stop) {
  445         diff = (int64_t)layout->list[i].stop - (int64_t)layout->list[j].stop;
  446         goto out;
  447     }
  448     diff = (int64_t)layout->list[i].start - (int64_t)layout->list[j].start;
  449 
  450 out:
  451     return diff;
  452 }
  453 
  454 int
  455 dht_layout_sort(dht_layout_t *layout)
  456 {
  457     int i = 0;
  458     int j = 0;
  459     int64_t ret = 0;
  460 
  461     /* TODO: O(n^2) -- bad bad */
  462 
  463     for (i = 0; i < layout->cnt - 1; i++) {
  464         for (j = i + 1; j < layout->cnt; j++) {
  465             ret = dht_layout_entry_cmp(layout, i, j);
  466             if (ret > 0)
  467                 dht_layout_entry_swap(layout, i, j);
  468         }
  469     }
  470 
  471     return 0;
  472 }
  473 
  474 void
  475 dht_layout_sort_volname(dht_layout_t *layout)
  476 {
  477     int i = 0;
  478     int j = 0;
  479     int64_t ret = 0;
  480 
  481     /* TODO: O(n^2) -- bad bad */
  482 
  483     for (i = 0; i < layout->cnt - 1; i++) {
  484         for (j = i + 1; j < layout->cnt; j++) {
  485             ret = dht_layout_entry_cmp_volname(layout, i, j);
  486             if (ret > 0)
  487                 dht_layout_entry_swap(layout, i, j);
  488         }
  489     }
  490 }
  491 
  492 void
  493 dht_layout_anomalies(xlator_t *this, loc_t *loc, dht_layout_t *layout,
  494                      uint32_t *holes_p, uint32_t *overlaps_p,
  495                      uint32_t *missing_p, uint32_t *down_p, uint32_t *misc_p,
  496                      uint32_t *no_space_p)
  497 {
  498     uint32_t overlaps = 0;
  499     uint32_t missing = 0;
  500     uint32_t down = 0;
  501     uint32_t misc = 0;
  502     uint32_t hole_cnt = 0;
  503     uint32_t overlap_cnt = 0;
  504     int i = 0;
  505     uint32_t prev_stop = 0;
  506     uint32_t last_stop = 0;
  507     char is_virgin = 1;
  508     uint32_t no_space = 0;
  509 
  510     /* This function scans through the layout spread of a directory to
  511        check if there are any anomalies. Prior to calling this function
  512        the layout entries should be sorted in the ascending order.
  513 
  514        If the layout entry has err != 0
  515             then increment the corresponding anomaly.
  516        else
  517             if (start of the current layout entry > stop + 1 of previous
  518                non erroneous layout entry)
  519                     then it indicates a hole in the layout
  520             if (start of the current layout entry < stop + 1 of previous
  521                 non erroneous layout entry)
  522                      then it indicates an overlap in the layout
  523     */
  524     last_stop = layout->list[0].start - 1;
  525     prev_stop = last_stop;
  526 
  527     for (i = 0; i < layout->cnt; i++) {
  528         switch (layout->list[i].err) {
  529             case -1:
  530             case ENOENT:
  531             case ESTALE:
  532                 missing++;
  533                 continue;
  534             case ENOTCONN:
  535                 down++;
  536                 continue;
  537             case ENOSPC:
  538                 no_space++;
  539                 continue;
  540             case 0:
  541                 /* if err == 0 and start == stop, then it is a non misc++;
  542                  * participating subvolume(spread-cnt). Then, do not
  543                  * check for anomalies. If start != stop, then treat it
  544                  * as misc err */
  545                 if (layout->list[i].start == layout->list[i].stop) {
  546                     continue;
  547                 }
  548                 break;
  549             default:
  550                 misc++;
  551                 continue;
  552         }
  553 
  554         is_virgin = 0;
  555 
  556         if ((prev_stop + 1) < layout->list[i].start) {
  557             hole_cnt++;
  558         }
  559 
  560         if ((prev_stop + 1) > layout->list[i].start) {
  561             overlap_cnt++;
  562             overlaps += ((prev_stop + 1) - layout->list[i].start);
  563         }
  564         prev_stop = layout->list[i].stop;
  565     }
  566 
  567     if ((last_stop - prev_stop) || is_virgin)
  568         hole_cnt++;
  569 
  570     if (holes_p)
  571         *holes_p = hole_cnt;
  572 
  573     if (overlaps_p)
  574         *overlaps_p = overlap_cnt;
  575 
  576     if (missing_p)
  577         *missing_p = missing;
  578 
  579     if (down_p)
  580         *down_p = down;
  581 
  582     if (misc_p)
  583         *misc_p = misc;
  584 
  585     if (no_space_p)
  586         *no_space_p = no_space;
  587 }
  588 
  589 int
  590 dht_layout_missing_dirs(dht_layout_t *layout)
  591 {
  592     int i = 0, missing = 0;
  593 
  594     if (layout == NULL)
  595         goto out;
  596 
  597     for (i = 0; i < layout->cnt; i++) {
  598         if ((layout->list[i].err == ENOENT) ||
  599             ((layout->list[i].err == -1) && (layout->list[i].start == 0) &&
  600              (layout->list[i].stop == 0))) {
  601             missing++;
  602         }
  603     }
  604 
  605 out:
  606     return missing;
  607 }
  608 
  609 int
  610 dht_layout_normalize(xlator_t *this, loc_t *loc, dht_layout_t *layout)
  611 {
  612     int ret = 0;
  613     uint32_t holes = 0;
  614     uint32_t overlaps = 0;
  615     uint32_t missing = 0;
  616     uint32_t down = 0;
  617     uint32_t misc = 0, missing_dirs = 0;
  618     char gfid[GF_UUID_BUF_SIZE] = {0};
  619 
  620     ret = dht_layout_sort(layout);
  621     if (ret == -1) {
  622         gf_smsg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_SORT_FAILED,
  623                 NULL);
  624         goto out;
  625     }
  626 
  627     gf_uuid_unparse(loc->gfid, gfid);
  628 
  629     dht_layout_anomalies(this, loc, layout, &holes, &overlaps, &missing, &down,
  630                          &misc, NULL);
  631 
  632     if (holes || overlaps) {
  633         if (missing == layout->cnt) {
  634             gf_msg_debug(this->name, 0,
  635                          "Directory %s looked up first time"
  636                          " gfid = %s",
  637                          loc->path, gfid);
  638         } else {
  639             gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_ANOMALIES_INFO,
  640                     "path=%s", loc->path, "gfid=%s", gfid, "holes=%d", holes,
  641                     "overlaps=%d", overlaps, NULL);
  642         }
  643         ret = -1;
  644     }
  645 
  646     if (ret >= 0) {
  647         missing_dirs = dht_layout_missing_dirs(layout);
  648         /* TODO During DHT selfheal rewrite (almost) find a better place
  649          * to detect this - probably in dht_layout_anomalies()
  650          */
  651         if (missing_dirs > 0)
  652             ret += missing_dirs;
  653     }
  654 
  655 out:
  656     return ret;
  657 }
  658 
  659 int
  660 dht_dir_has_layout(dict_t *xattr, char *name)
  661 {
  662     void *disk_layout_raw = NULL;
  663 
  664     return dict_get_ptr(xattr, name, &disk_layout_raw);
  665 }
  666 
  667 int
  668 dht_layout_dir_mismatch(xlator_t *this, dht_layout_t *layout, xlator_t *subvol,
  669                         loc_t *loc, dict_t *xattr)
  670 {
  671     int idx = 0;
  672     int pos = -1;
  673     int ret = 0;
  674     int err = 0;
  675     int dict_ret = 0;
  676     int32_t disk_layout[4];
  677     void *disk_layout_raw = NULL;
  678     uint32_t start_off = -1;
  679     uint32_t stop_off = -1;
  680     uint32_t commit_hash = -1;
  681     dht_conf_t *conf = this->private;
  682     char gfid[GF_UUID_BUF_SIZE] = {0};
  683 
  684     if (loc && loc->inode)
  685         gf_uuid_unparse(loc->inode->gfid, gfid);
  686 
  687     for (idx = 0; idx < layout->cnt; idx++) {
  688         if (layout->list[idx].xlator == subvol) {
  689             pos = idx;
  690             break;
  691         }
  692     }
  693 
  694     if (pos == -1) {
  695         if (loc) {
  696             gf_msg_debug(this->name, 0, "%s - no layout info for subvolume %s",
  697                          loc ? loc->path : "path not found", subvol->name);
  698         }
  699         ret = 1;
  700         goto out;
  701     }
  702 
  703     err = layout->list[pos].err;
  704 
  705     if (!xattr) {
  706         if (err == 0) {
  707             if (loc) {
  708                 gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_XATTR_DICT_NULL,
  709                         "path=%s", loc->path, NULL);
  710             } else {
  711                 gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_XATTR_DICT_NULL,
  712                         "path not found", NULL);
  713             }
  714             ret = -1;
  715         }
  716         goto out;
  717     }
  718 
  719     dict_ret = dict_get_ptr(xattr, conf->xattr_name, &disk_layout_raw);
  720 
  721     if (dict_ret < 0) {
  722         if (err == 0 && layout->list[pos].stop) {
  723             if (loc) {
  724                 gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_DISK_LAYOUT_MISSING,
  725                         "path=%s", loc->path, "gfid=%s", gfid, NULL);
  726             } else {
  727                 gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_DISK_LAYOUT_MISSING,
  728                         "path not found"
  729                         "gfid=%s",
  730                         gfid, NULL);
  731             }
  732             ret = -1;
  733         }
  734         goto out;
  735     }
  736 
  737     memcpy(disk_layout, disk_layout_raw, sizeof(disk_layout));
  738 
  739     start_off = ntoh32(disk_layout[2]);
  740     stop_off = ntoh32(disk_layout[3]);
  741     commit_hash = ntoh32(disk_layout[0]);
  742 
  743     if ((layout->list[pos].start != start_off) ||
  744         (layout->list[pos].stop != stop_off) ||
  745         (layout->list[pos].commit_hash != commit_hash)) {
  746         gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_INFO, "subvol=%s",
  747                 layout->list[pos].xlator->name, "inode-layout:start=0x%x",
  748                 layout->list[pos].start, "inode-layout:stop=0x%x",
  749                 layout->list[pos].stop, "layout-commit-hash=0x%x; ",
  750                 layout->list[pos].commit_hash, "disk-layout:start-off=0x%x",
  751                 start_off, "disk-layout:top-off=0x%x", stop_off,
  752                 "commit-hash=0x%x", commit_hash, NULL);
  753         ret = 1;
  754     } else {
  755         ret = 0;
  756     }
  757 out:
  758     return ret;
  759 }
  760 
  761 int
  762 dht_layout_preset(xlator_t *this, xlator_t *subvol, inode_t *inode)
  763 {
  764     dht_layout_t *layout = NULL;
  765     int ret = -1;
  766     dht_conf_t *conf = NULL;
  767 
  768     conf = this->private;
  769     if (!conf)
  770         goto out;
  771 
  772     layout = dht_layout_for_subvol(this, subvol);
  773     if (!layout) {
  774         gf_smsg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_NO_LAYOUT_INFO,
  775                 "subvolume=%s", subvol ? subvol->name : "<nil>", NULL);
  776         ret = -1;
  777         goto out;
  778     }
  779 
  780     gf_msg_debug(this->name, 0, "file = %s, subvol = %s",
  781                  uuid_utoa(inode->gfid), subvol ? subvol->name : "<nil>");
  782 
  783     LOCK(&conf->layout_lock);
  784     {
  785         dht_inode_ctx_layout_set(inode, this, layout);
  786     }
  787 
  788     UNLOCK(&conf->layout_lock);
  789 
  790     ret = 0;
  791 out:
  792     return ret;
  793 }
  794 
  795 int
  796 dht_layout_index_for_subvol(dht_layout_t *layout, xlator_t *subvol)
  797 {
  798     int i = 0, ret = -1;
  799 
  800     for (i = 0; i < layout->cnt; i++) {
  801         if (layout->list[i].xlator == subvol) {
  802             ret = i;
  803             break;
  804         }
  805     }
  806 
  807     return ret;
  808 }