"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/xlators/cluster/dht/src/dht-inode-read.c" (16 Sep 2020, 44194 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-inode-read.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 
   13 static int
   14 dht_access2(xlator_t *this, xlator_t *dst_node, call_frame_t *frame, int ret);
   15 static int
   16 dht_readv2(xlator_t *this, xlator_t *dst_node, call_frame_t *frame, int ret);
   17 static int
   18 dht_attr2(xlator_t *this, xlator_t *dst_node, call_frame_t *frame, int ret);
   19 static int
   20 dht_open2(xlator_t *this, xlator_t *dst_node, call_frame_t *frame, int ret);
   21 static int
   22 dht_flush2(xlator_t *this, xlator_t *dst_node, call_frame_t *frame, int ret);
   23 static int
   24 dht_lk2(xlator_t *this, xlator_t *dst_node, call_frame_t *frame, int ret);
   25 static int
   26 dht_fsync2(xlator_t *this, xlator_t *dst_node, call_frame_t *frame, int ret);
   27 static int
   28 dht_common_xattrop2(xlator_t *this, xlator_t *subvol, call_frame_t *frame,
   29                     int ret);
   30 
   31 static int
   32 dht_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
   33              int op_errno, fd_t *fd, dict_t *xdata)
   34 {
   35     dht_local_t *local = NULL;
   36     xlator_t *prev = NULL;
   37     int ret = 0;
   38 
   39     local = frame->local;
   40     prev = cookie;
   41 
   42     local->op_errno = op_errno;
   43     if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
   44         gf_msg_debug(this->name, op_errno, "subvolume %s returned -1",
   45                      prev->name);
   46         goto out;
   47     }
   48 
   49     /* Update ctx if the fd has been opened on the target*/
   50     if (!op_ret && (local->call_cnt == 1)) {
   51         dht_fd_ctx_set(this, fd, prev);
   52         goto out;
   53     }
   54 
   55     if (!op_ret || (local->call_cnt != 1))
   56         goto out;
   57 
   58     /* rebalance would have happened */
   59     local->rebalance.target_op_fn = dht_open2;
   60     ret = dht_rebalance_complete_check(this, frame);
   61     if (!ret)
   62         return 0;
   63 
   64 out:
   65     DHT_STACK_UNWIND(open, frame, op_ret, op_errno, local->fd, xdata);
   66 
   67     return 0;
   68 }
   69 
   70 static int
   71 dht_open2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret)
   72 {
   73     dht_local_t *local = NULL;
   74     int op_errno = EINVAL;
   75 
   76     if (!frame || !frame->local)
   77         goto out;
   78 
   79     local = frame->local;
   80     op_errno = local->op_errno;
   81 
   82     if (we_are_not_migrating(ret)) {
   83         /* This DHT layer is not migrating the file */
   84         DHT_STACK_UNWIND(open, frame, -1, local->op_errno, NULL,
   85                          local->rebalance.xdata);
   86         return 0;
   87     }
   88 
   89     if (subvol == NULL)
   90         goto out;
   91 
   92     local->call_cnt = 2;
   93 
   94     STACK_WIND_COOKIE(frame, dht_open_cbk, subvol, subvol, subvol->fops->open,
   95                       &local->loc, local->rebalance.flags, local->fd,
   96                       local->xattr_req);
   97     return 0;
   98 
   99 out:
  100     DHT_STACK_UNWIND(open, frame, -1, op_errno, NULL, NULL);
  101     return 0;
  102 }
  103 
  104 int
  105 dht_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, fd_t *fd,
  106          dict_t *xdata)
  107 {
  108     xlator_t *subvol = NULL;
  109     int op_errno = -1;
  110     dht_local_t *local = NULL;
  111 
  112     VALIDATE_OR_GOTO(frame, err);
  113     VALIDATE_OR_GOTO(this, err);
  114     VALIDATE_OR_GOTO(fd, err);
  115 
  116     local = dht_local_init(frame, loc, fd, GF_FOP_OPEN);
  117     if (!local) {
  118         op_errno = ENOMEM;
  119         goto err;
  120     }
  121 
  122     subvol = local->cached_subvol;
  123     if (!subvol) {
  124         gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd);
  125         op_errno = EINVAL;
  126         goto err;
  127     }
  128     if (xdata)
  129         local->xattr_req = dict_ref(xdata);
  130 
  131     local->rebalance.flags = flags;
  132     local->call_cnt = 1;
  133 
  134     STACK_WIND_COOKIE(frame, dht_open_cbk, subvol, subvol, subvol->fops->open,
  135                       loc, flags, fd, xdata);
  136 
  137     return 0;
  138 
  139 err:
  140     op_errno = (op_errno == -1) ? errno : op_errno;
  141     DHT_STACK_UNWIND(open, frame, -1, op_errno, NULL, NULL);
  142 
  143     return 0;
  144 }
  145 
  146 int
  147 dht_file_attr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  148                   int op_errno, struct iatt *stbuf, dict_t *xdata)
  149 {
  150     xlator_t *subvol1 = 0;
  151     xlator_t *subvol2 = 0;
  152     dht_local_t *local = NULL;
  153     xlator_t *prev = NULL;
  154     int ret = -1;
  155     inode_t *inode = NULL;
  156 
  157     GF_VALIDATE_OR_GOTO("dht", frame, err);
  158     GF_VALIDATE_OR_GOTO("dht", this, out);
  159     GF_VALIDATE_OR_GOTO("dht", frame->local, out);
  160     GF_VALIDATE_OR_GOTO("dht", cookie, out);
  161 
  162     local = frame->local;
  163     prev = cookie;
  164 
  165     if ((local->fop == GF_FOP_FSTAT) &&
  166         dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
  167         ret = dht_check_and_open_fd_on_subvol(this, frame);
  168         if (ret)
  169             goto out;
  170         return 0;
  171     }
  172 
  173     if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
  174         local->op_errno = op_errno;
  175         gf_msg_debug(this->name, op_errno, "subvolume %s returned -1",
  176                      prev->name);
  177         goto out;
  178     }
  179 
  180     if (local->call_cnt != 1)
  181         goto out;
  182 
  183     local->op_errno = op_errno;
  184     local->op_ret = op_ret;
  185 
  186     /* Check if the rebalance phase2 is true */
  187     if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(stbuf)) {
  188         local->rebalance.target_op_fn = dht_attr2;
  189         dht_set_local_rebalance(this, local, NULL, NULL, stbuf, xdata);
  190         inode = (local->fd) ? local->fd->inode : local->loc.inode;
  191 
  192         dht_inode_ctx_get_mig_info(this, inode, &subvol1, &subvol2);
  193         if (dht_mig_info_is_invalid(local->cached_subvol, subvol1, subvol2)) {
  194             /* Phase 2 of migration */
  195             ret = dht_rebalance_complete_check(this, frame);
  196             if (!ret)
  197                 return 0;
  198         } else {
  199             /* it is a non-fd op or it is an fd based Fop and
  200                opened on the dst.*/
  201             if (local->fd && !dht_fd_open_on_dst(this, local->fd, subvol2)) {
  202                 ret = dht_rebalance_complete_check(this, frame);
  203                 if (!ret)
  204                     return 0;
  205             } else {
  206                 dht_attr2(this, subvol2, frame, 0);
  207                 return 0;
  208             }
  209         }
  210     }
  211 
  212 out:
  213     DHT_STRIP_PHASE1_FLAGS(stbuf);
  214     DHT_STACK_UNWIND(stat, frame, op_ret, op_errno, stbuf, xdata);
  215 err:
  216     return 0;
  217 }
  218 
  219 static int
  220 dht_attr2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret)
  221 {
  222     dht_local_t *local = NULL;
  223     int op_errno = EINVAL;
  224 
  225     local = frame->local;
  226     if (!local)
  227         goto out;
  228 
  229     op_errno = local->op_errno;
  230 
  231     if (we_are_not_migrating(ret)) {
  232         /* This dht xlator is not migrating the file. Unwind and
  233          * pass on the original mode bits so the higher DHT layer
  234          * can handle this.
  235          */
  236         DHT_STACK_UNWIND(stat, frame, local->op_ret, op_errno,
  237                          &local->rebalance.postbuf, local->rebalance.xdata);
  238         return 0;
  239     }
  240 
  241     if (subvol == NULL)
  242         goto out;
  243 
  244     local->call_cnt = 2;
  245 
  246     if (local->fop == GF_FOP_FSTAT) {
  247         STACK_WIND_COOKIE(frame, dht_file_attr_cbk, subvol, subvol,
  248                           subvol->fops->fstat, local->fd, local->xattr_req);
  249     } else {
  250         STACK_WIND_COOKIE(frame, dht_file_attr_cbk, subvol, subvol,
  251                           subvol->fops->stat, &local->loc, local->xattr_req);
  252     }
  253 
  254     return 0;
  255 
  256 out:
  257     DHT_STACK_UNWIND(stat, frame, -1, op_errno, NULL, NULL);
  258     return 0;
  259 }
  260 
  261 static int
  262 dht_attr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  263              int op_errno, struct iatt *stbuf, dict_t *xdata)
  264 {
  265     dht_local_t *local = NULL;
  266     int this_call_cnt = 0;
  267     xlator_t *prev = NULL;
  268     local = frame->local;
  269     prev = cookie;
  270 
  271     LOCK(&frame->lock);
  272     {
  273         if (op_ret == -1) {
  274             local->op_errno = op_errno;
  275             UNLOCK(&frame->lock);
  276             gf_msg_debug(this->name, op_errno, "subvolume %s returned -1",
  277                          prev->name);
  278 
  279             goto post_unlock;
  280         }
  281 
  282         dht_iatt_merge(this, &local->stbuf, stbuf);
  283 
  284         local->op_ret = 0;
  285     }
  286     UNLOCK(&frame->lock);
  287 post_unlock:
  288     this_call_cnt = dht_frame_return(frame);
  289     if (is_last_call(this_call_cnt)) {
  290         DHT_STACK_UNWIND(stat, frame, local->op_ret, local->op_errno,
  291                          &local->stbuf, xdata);
  292     }
  293 
  294     return 0;
  295 }
  296 
  297 int
  298 dht_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
  299 {
  300     xlator_t *subvol = NULL;
  301     int op_errno = -1;
  302     dht_local_t *local = NULL;
  303     dht_layout_t *layout = NULL;
  304     int i = 0;
  305     int call_cnt = 0;
  306 
  307     VALIDATE_OR_GOTO(frame, err);
  308     VALIDATE_OR_GOTO(this, err);
  309     VALIDATE_OR_GOTO(loc, err);
  310     VALIDATE_OR_GOTO(loc->inode, err);
  311     VALIDATE_OR_GOTO(loc->path, err);
  312 
  313     local = dht_local_init(frame, loc, NULL, GF_FOP_STAT);
  314     if (!local) {
  315         op_errno = ENOMEM;
  316         goto err;
  317     }
  318 
  319     layout = local->layout;
  320     if (!layout) {
  321         gf_msg_debug(this->name, 0, "no layout for path=%s", loc->path);
  322         op_errno = EINVAL;
  323         goto err;
  324     }
  325     if (xdata)
  326         local->xattr_req = dict_ref(xdata);
  327 
  328     if (IA_ISREG(loc->inode->ia_type)) {
  329         local->call_cnt = 1;
  330 
  331         subvol = local->cached_subvol;
  332 
  333         STACK_WIND_COOKIE(frame, dht_file_attr_cbk, subvol, subvol,
  334                           subvol->fops->stat, loc, xdata);
  335 
  336         return 0;
  337     }
  338 
  339     local->call_cnt = call_cnt = layout->cnt;
  340 
  341     for (i = 0; i < call_cnt; i++) {
  342         subvol = layout->list[i].xlator;
  343 
  344         STACK_WIND_COOKIE(frame, dht_attr_cbk, subvol, subvol,
  345                           subvol->fops->stat, loc, xdata);
  346     }
  347 
  348     return 0;
  349 
  350 err:
  351     op_errno = (op_errno == -1) ? errno : op_errno;
  352     DHT_STACK_UNWIND(stat, frame, -1, op_errno, NULL, NULL);
  353 
  354     return 0;
  355 }
  356 
  357 int
  358 dht_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
  359 {
  360     xlator_t *subvol = NULL;
  361     int op_errno = -1;
  362     dht_local_t *local = NULL;
  363     dht_layout_t *layout = NULL;
  364     int i = 0;
  365     int call_cnt = 0;
  366 
  367     VALIDATE_OR_GOTO(frame, err);
  368     VALIDATE_OR_GOTO(this, err);
  369     VALIDATE_OR_GOTO(fd, err);
  370 
  371     local = dht_local_init(frame, NULL, fd, GF_FOP_FSTAT);
  372     if (!local) {
  373         op_errno = ENOMEM;
  374         goto err;
  375     }
  376 
  377     layout = local->layout;
  378     if (!layout) {
  379         gf_msg(this->name, GF_LOG_ERROR, 0, 0, "no layout for fd=%p", fd);
  380         op_errno = EINVAL;
  381         goto err;
  382     }
  383     if (xdata)
  384         local->xattr_req = dict_ref(xdata);
  385 
  386     if (IA_ISREG(fd->inode->ia_type)) {
  387         local->call_cnt = 1;
  388 
  389         subvol = local->cached_subvol;
  390 
  391         STACK_WIND_COOKIE(frame, dht_file_attr_cbk, subvol, subvol,
  392                           subvol->fops->fstat, fd, xdata);
  393         return 0;
  394     }
  395 
  396     local->call_cnt = call_cnt = layout->cnt;
  397 
  398     for (i = 0; i < call_cnt; i++) {
  399         subvol = layout->list[i].xlator;
  400         STACK_WIND_COOKIE(frame, dht_attr_cbk, subvol, subvol,
  401                           subvol->fops->fstat, fd, xdata);
  402     }
  403 
  404     return 0;
  405 
  406 err:
  407     op_errno = (op_errno == -1) ? errno : op_errno;
  408     DHT_STACK_UNWIND(fstat, frame, -1, op_errno, NULL, NULL);
  409 
  410     return 0;
  411 }
  412 
  413 int
  414 dht_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  415               int op_errno, struct iovec *vector, int count, struct iatt *stbuf,
  416               struct iobref *iobref, dict_t *xdata)
  417 {
  418     dht_local_t *local = NULL;
  419     int ret = 0;
  420     xlator_t *src_subvol = 0;
  421     xlator_t *dst_subvol = 0;
  422 
  423     local = frame->local;
  424     if (!local) {
  425         op_ret = -1;
  426         op_errno = EINVAL;
  427         goto out;
  428     }
  429 
  430     /* This is already second try, no need for re-check */
  431     if (local->call_cnt != 1)
  432         goto out;
  433 
  434     if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
  435         ret = dht_check_and_open_fd_on_subvol(this, frame);
  436         if (ret)
  437             goto out;
  438         return 0;
  439     }
  440 
  441     if ((op_ret == -1) && !dht_inode_missing(op_errno))
  442         goto out;
  443 
  444     local->op_errno = op_errno;
  445     if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(stbuf)) {
  446         local->op_ret = op_ret;
  447         local->rebalance.target_op_fn = dht_readv2;
  448         dht_set_local_rebalance(this, local, NULL, NULL, stbuf, xdata);
  449         /* File would be migrated to other node */
  450         ret = dht_inode_ctx_get_mig_info(this, local->fd->inode, &src_subvol,
  451                                          &dst_subvol);
  452 
  453         if (dht_mig_info_is_invalid(local->cached_subvol, src_subvol,
  454                                     dst_subvol) ||
  455             !dht_fd_open_on_dst(this, local->fd, dst_subvol)) {
  456             ret = dht_rebalance_complete_check(this, frame);
  457             if (!ret)
  458                 return 0;
  459         } else {
  460             /* value is already set in fd_ctx, that means no need
  461                to check for whether its complete or not. */
  462             dht_readv2(this, dst_subvol, frame, 0);
  463             return 0;
  464         }
  465     }
  466 
  467 out:
  468     DHT_STRIP_PHASE1_FLAGS(stbuf);
  469 
  470     DHT_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, stbuf,
  471                      iobref, xdata);
  472 
  473     return 0;
  474 }
  475 
  476 static int
  477 dht_readv2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret)
  478 {
  479     dht_local_t *local = NULL;
  480     int op_errno = EINVAL;
  481 
  482     local = frame->local;
  483     if (!local)
  484         goto out;
  485 
  486     op_errno = local->op_errno;
  487 
  488     if (we_are_not_migrating(ret)) {
  489         /* This dht xlator is not migrating the file. Unwind and
  490          * pass on the original mode bits so the higher DHT layer
  491          * can handle this.
  492          */
  493         DHT_STACK_UNWIND(readv, frame, local->op_ret, op_errno, NULL, 0,
  494                          &local->rebalance.postbuf, NULL,
  495                          local->rebalance.xdata);
  496         return 0;
  497     }
  498 
  499     if (subvol == NULL)
  500         goto out;
  501 
  502     local->call_cnt = 2;
  503 
  504     STACK_WIND(frame, dht_readv_cbk, subvol, subvol->fops->readv, local->fd,
  505                local->rebalance.size, local->rebalance.offset,
  506                local->rebalance.flags, local->xattr_req);
  507 
  508     return 0;
  509 
  510 out:
  511     DHT_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL);
  512     return 0;
  513 }
  514 
  515 int
  516 dht_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off,
  517           uint32_t flags, dict_t *xdata)
  518 {
  519     xlator_t *subvol = NULL;
  520     int op_errno = -1;
  521     dht_local_t *local = NULL;
  522 
  523     VALIDATE_OR_GOTO(frame, err);
  524     VALIDATE_OR_GOTO(this, err);
  525     VALIDATE_OR_GOTO(fd, err);
  526 
  527     local = dht_local_init(frame, NULL, fd, GF_FOP_READ);
  528     if (!local) {
  529         op_errno = ENOMEM;
  530         goto err;
  531     }
  532 
  533     subvol = local->cached_subvol;
  534     if (!subvol) {
  535         gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd);
  536         op_errno = EINVAL;
  537         goto err;
  538     }
  539 
  540     if (xdata)
  541         local->xattr_req = dict_ref(xdata);
  542 
  543     local->rebalance.offset = off;
  544     local->rebalance.size = size;
  545     local->rebalance.flags = flags;
  546     local->call_cnt = 1;
  547 
  548     STACK_WIND(frame, dht_readv_cbk, subvol, subvol->fops->readv, local->fd,
  549                local->rebalance.size, local->rebalance.offset,
  550                local->rebalance.flags, local->xattr_req);
  551 
  552     return 0;
  553 
  554 err:
  555     op_errno = (op_errno == -1) ? errno : op_errno;
  556     DHT_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL);
  557 
  558     return 0;
  559 }
  560 
  561 static int
  562 dht_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  563                int op_errno, dict_t *xdata)
  564 {
  565     int ret = -1;
  566     dht_local_t *local = NULL;
  567     xlator_t *subvol = NULL;
  568     xlator_t *prev = NULL;
  569 
  570     local = frame->local;
  571     prev = cookie;
  572 
  573     if (!prev)
  574         goto out;
  575     if (local->call_cnt != 1)
  576         goto out;
  577     if ((op_ret == -1) &&
  578         ((op_errno == ENOTCONN) || dht_inode_missing(op_errno)) &&
  579         IA_ISDIR(local->loc.inode->ia_type)) {
  580         subvol = dht_subvol_next_available(this, prev);
  581         if (!subvol)
  582             goto out;
  583 
  584         /* check if we are done with visiting every node */
  585         if (subvol == local->cached_subvol) {
  586             goto out;
  587         }
  588 
  589         STACK_WIND_COOKIE(frame, dht_access_cbk, subvol, subvol,
  590                           subvol->fops->access, &local->loc,
  591                           local->rebalance.flags, NULL);
  592         return 0;
  593     }
  594     if ((op_ret == -1) && dht_inode_missing(op_errno) &&
  595         !(IA_ISDIR(local->loc.inode->ia_type))) {
  596         /* File would be migrated to other node */
  597         local->op_errno = op_errno;
  598         local->rebalance.target_op_fn = dht_access2;
  599         ret = dht_rebalance_complete_check(frame->this, frame);
  600         if (!ret)
  601             return 0;
  602     }
  603 
  604 out:
  605     DHT_STACK_UNWIND(access, frame, op_ret, op_errno, xdata);
  606     return 0;
  607 }
  608 
  609 static int
  610 dht_access2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret)
  611 {
  612     dht_local_t *local = NULL;
  613     int op_errno = EINVAL;
  614 
  615     local = frame->local;
  616     if (!local)
  617         goto out;
  618 
  619     op_errno = local->op_errno;
  620 
  621     if (we_are_not_migrating(ret)) {
  622         /* This dht xlator is not migrating the file. Unwind and
  623          * pass on the original mode bits so the higher DHT layer
  624          * can handle this.
  625          */
  626 
  627         DHT_STACK_UNWIND(access, frame, -1, op_errno, NULL);
  628         return 0;
  629     }
  630 
  631     if (subvol == NULL)
  632         goto out;
  633 
  634     local->call_cnt = 2;
  635 
  636     STACK_WIND_COOKIE(frame, dht_access_cbk, subvol, subvol,
  637                       subvol->fops->access, &local->loc, local->rebalance.flags,
  638                       local->xattr_req);
  639 
  640     return 0;
  641 
  642 out:
  643     DHT_STACK_UNWIND(access, frame, -1, op_errno, NULL);
  644     return 0;
  645 }
  646 
  647 int
  648 dht_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
  649            dict_t *xdata)
  650 {
  651     xlator_t *subvol = NULL;
  652     int op_errno = -1;
  653     dht_local_t *local = NULL;
  654 
  655     VALIDATE_OR_GOTO(frame, err);
  656     VALIDATE_OR_GOTO(this, err);
  657     VALIDATE_OR_GOTO(loc, err);
  658     VALIDATE_OR_GOTO(loc->inode, err);
  659     VALIDATE_OR_GOTO(loc->path, err);
  660 
  661     local = dht_local_init(frame, loc, NULL, GF_FOP_ACCESS);
  662     if (!local) {
  663         op_errno = ENOMEM;
  664         goto err;
  665     }
  666 
  667     local->rebalance.flags = mask;
  668     local->call_cnt = 1;
  669     subvol = local->cached_subvol;
  670     if (!subvol) {
  671         gf_msg_debug(this->name, 0, "no cached subvolume for path=%s",
  672                      loc->path);
  673         op_errno = EINVAL;
  674         goto err;
  675     }
  676     if (xdata)
  677         local->xattr_req = dict_ref(xdata);
  678 
  679     STACK_WIND_COOKIE(frame, dht_access_cbk, subvol, subvol,
  680                       subvol->fops->access, loc, mask, xdata);
  681 
  682     return 0;
  683 
  684 err:
  685     op_errno = (op_errno == -1) ? errno : op_errno;
  686     DHT_STACK_UNWIND(access, frame, -1, op_errno, NULL);
  687 
  688     return 0;
  689 }
  690 
  691 int
  692 dht_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  693               int op_errno, dict_t *xdata)
  694 {
  695     dht_local_t *local = NULL;
  696     xlator_t *subvol = 0;
  697     int ret = 0;
  698 
  699     local = frame->local;
  700 
  701     local->op_errno = op_errno;
  702 
  703     if (local->call_cnt != 1)
  704         goto out;
  705 
  706     if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
  707         ret = dht_check_and_open_fd_on_subvol(this, frame);
  708         if (ret)
  709             goto out;
  710         return 0;
  711     }
  712 
  713     local->rebalance.target_op_fn = dht_flush2;
  714 
  715     local->op_ret = op_ret;
  716     local->op_errno = op_errno;
  717 
  718     /* If context is set, then send flush() it to the destination */
  719     dht_inode_ctx_get_mig_info(this, local->fd->inode, NULL, &subvol);
  720     if (subvol && dht_fd_open_on_dst(this, local->fd, subvol)) {
  721         dht_flush2(this, subvol, frame, 0);
  722         return 0;
  723     }
  724 
  725     if (op_errno == EREMOTE) {
  726         ret = dht_rebalance_complete_check(this, frame);
  727         if (!ret) {
  728             return 0;
  729         }
  730     }
  731 
  732 out:
  733     DHT_STACK_UNWIND(flush, frame, op_ret, op_errno, xdata);
  734 
  735     return 0;
  736 }
  737 
  738 static int
  739 dht_flush2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret)
  740 {
  741     dht_local_t *local = NULL;
  742     int32_t op_errno = EINVAL;
  743 
  744     if ((frame == NULL) || (frame->local == NULL))
  745         goto out;
  746 
  747     local = frame->local;
  748 
  749     op_errno = local->op_errno;
  750 
  751     if (subvol == NULL)
  752         goto out;
  753 
  754     local->call_cnt = 2; /* This is the second attempt */
  755 
  756     STACK_WIND(frame, dht_flush_cbk, subvol, subvol->fops->flush, local->fd,
  757                local->xattr_req);
  758 
  759     return 0;
  760 
  761 out:
  762     DHT_STACK_UNWIND(flush, frame, -1, op_errno, NULL);
  763     return 0;
  764 }
  765 
  766 int
  767 dht_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
  768 {
  769     xlator_t *subvol = NULL;
  770     int op_errno = -1;
  771     dht_local_t *local = NULL;
  772 
  773     VALIDATE_OR_GOTO(frame, err);
  774     VALIDATE_OR_GOTO(this, err);
  775     VALIDATE_OR_GOTO(fd, err);
  776 
  777     local = dht_local_init(frame, NULL, fd, GF_FOP_FLUSH);
  778     if (!local) {
  779         op_errno = ENOMEM;
  780         goto err;
  781     }
  782 
  783     subvol = local->cached_subvol;
  784     if (!subvol) {
  785         gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd);
  786         op_errno = EINVAL;
  787         goto err;
  788     }
  789 
  790     if (xdata)
  791         local->xattr_req = dict_ref(xdata);
  792 
  793     local->call_cnt = 1;
  794 
  795     STACK_WIND(frame, dht_flush_cbk, subvol, subvol->fops->flush, fd,
  796                local->xattr_req);
  797     return 0;
  798 
  799 err:
  800     op_errno = (op_errno == -1) ? errno : op_errno;
  801     DHT_STACK_UNWIND(flush, frame, -1, op_errno, NULL);
  802 
  803     return 0;
  804 }
  805 
  806 int
  807 dht_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  808               int op_errno, struct iatt *prebuf, struct iatt *postbuf,
  809               dict_t *xdata)
  810 {
  811     dht_local_t *local = NULL;
  812     xlator_t *prev = NULL;
  813     int ret = -1;
  814     inode_t *inode = NULL;
  815     xlator_t *src_subvol = 0;
  816     xlator_t *dst_subvol = 0;
  817 
  818     local = frame->local;
  819     prev = cookie;
  820 
  821     local->op_errno = op_errno;
  822 
  823     if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
  824         ret = dht_check_and_open_fd_on_subvol(this, frame);
  825         if (ret)
  826             goto out;
  827         return 0;
  828     }
  829 
  830     if (op_ret == -1 && !dht_inode_missing(op_errno)) {
  831         gf_msg_debug(this->name, op_errno, "subvolume %s returned -1",
  832                      prev->name);
  833         goto out;
  834     }
  835 
  836     if (local->call_cnt != 1) {
  837         if (local->stbuf.ia_blocks) {
  838             dht_iatt_merge(this, postbuf, &local->stbuf);
  839             dht_iatt_merge(this, prebuf, &local->prebuf);
  840         }
  841         goto out;
  842     }
  843 
  844     local->op_ret = op_ret;
  845     inode = local->fd->inode;
  846 
  847     local->rebalance.target_op_fn = dht_fsync2;
  848     dht_set_local_rebalance(this, local, NULL, prebuf, postbuf, xdata);
  849 
  850     if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(postbuf)) {
  851         ret = dht_rebalance_complete_check(this, frame);
  852         if (!ret)
  853             return 0;
  854     }
  855 
  856     /* Check if the rebalance phase1 is true */
  857     if (IS_DHT_MIGRATION_PHASE1(postbuf)) {
  858         dht_iatt_merge(this, &local->stbuf, postbuf);
  859         dht_iatt_merge(this, &local->prebuf, prebuf);
  860 
  861         dht_inode_ctx_get_mig_info(this, inode, &src_subvol, &dst_subvol);
  862 
  863         if (dht_mig_info_is_invalid(local->cached_subvol, src_subvol,
  864                                     dst_subvol) ||
  865             !dht_fd_open_on_dst(this, local->fd, dst_subvol)) {
  866             ret = dht_rebalance_in_progress_check(this, frame);
  867             if (!ret)
  868                 return 0;
  869         } else {
  870             dht_fsync2(this, dst_subvol, frame, 0);
  871             return 0;
  872         }
  873     }
  874 
  875 out:
  876     DHT_STRIP_PHASE1_FLAGS(postbuf);
  877     DHT_STRIP_PHASE1_FLAGS(prebuf);
  878 
  879     DHT_STACK_UNWIND(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata);
  880 
  881     return 0;
  882 }
  883 
  884 static int
  885 dht_fsync2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret)
  886 {
  887     dht_local_t *local = NULL;
  888     int32_t op_errno = EINVAL;
  889 
  890     if ((frame == NULL) || (frame->local == NULL))
  891         goto out;
  892 
  893     local = frame->local;
  894     op_errno = local->op_errno;
  895 
  896     if (we_are_not_migrating(ret)) {
  897         /* This dht xlator is not migrating the file. Unwind and
  898          * pass on the original mode bits so the higher DHT layer
  899          * can handle this.
  900          */
  901         DHT_STACK_UNWIND(fsync, frame, local->op_ret, op_errno,
  902                          &local->rebalance.prebuf, &local->rebalance.postbuf,
  903                          local->rebalance.xdata);
  904         return 0;
  905     }
  906 
  907     if (subvol == NULL)
  908         goto out;
  909 
  910     local->call_cnt = 2; /* This is the second attempt */
  911 
  912     STACK_WIND_COOKIE(frame, dht_fsync_cbk, subvol, subvol, subvol->fops->fsync,
  913                       local->fd, local->rebalance.flags, local->xattr_req);
  914 
  915     return 0;
  916 
  917 out:
  918     DHT_STACK_UNWIND(fsync, frame, -1, op_errno, NULL, NULL, NULL);
  919     return 0;
  920 }
  921 
  922 int
  923 dht_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
  924           dict_t *xdata)
  925 {
  926     xlator_t *subvol = NULL;
  927     int op_errno = -1;
  928     dht_local_t *local = NULL;
  929 
  930     VALIDATE_OR_GOTO(frame, err);
  931     VALIDATE_OR_GOTO(this, err);
  932     VALIDATE_OR_GOTO(fd, err);
  933 
  934     local = dht_local_init(frame, NULL, fd, GF_FOP_FSYNC);
  935     if (!local) {
  936         op_errno = ENOMEM;
  937 
  938         goto err;
  939     }
  940     if (xdata)
  941         local->xattr_req = dict_ref(xdata);
  942 
  943     local->call_cnt = 1;
  944     local->rebalance.flags = datasync;
  945 
  946     subvol = local->cached_subvol;
  947 
  948     STACK_WIND_COOKIE(frame, dht_fsync_cbk, subvol, subvol, subvol->fops->fsync,
  949                       local->fd, local->rebalance.flags, local->xattr_req);
  950     return 0;
  951 
  952 err:
  953     op_errno = (op_errno == -1) ? errno : op_errno;
  954     DHT_STACK_UNWIND(fsync, frame, -1, op_errno, NULL, NULL, NULL);
  955 
  956     return 0;
  957 }
  958 
  959 /* TODO: for 'lk()' call, we need some other special error, may be ESTALE to
  960    indicate that lock migration happened on the fd, so we can consider it as
  961    phase 2 of migration */
  962 static int
  963 dht_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  964            int op_errno, struct gf_flock *flock, dict_t *xdata)
  965 {
  966     dht_local_t *local = NULL;
  967     int ret = -1;
  968     xlator_t *subvol = NULL;
  969 
  970     local = frame->local;
  971 
  972     if (!local) {
  973         op_ret = -1;
  974         op_errno = EINVAL;
  975         goto out;
  976     }
  977 
  978     if (local->call_cnt != 1)
  979         goto out;
  980 
  981     local->rebalance.target_op_fn = dht_lk2;
  982 
  983     local->op_ret = op_ret;
  984     local->op_errno = op_errno;
  985 
  986     if (xdata)
  987         local->rebalance.xdata = dict_ref(xdata);
  988 
  989     if (op_errno == EREMOTE) {
  990         dht_inode_ctx_get_mig_info(this, local->fd->inode, NULL, &subvol);
  991         if (subvol && dht_fd_open_on_dst(this, local->fd, subvol)) {
  992             dht_lk2(this, subvol, frame, 0);
  993             return 0;
  994         } else {
  995             ret = dht_rebalance_complete_check(this, frame);
  996             if (!ret) {
  997                 return 0;
  998             }
  999         }
 1000     }
 1001 
 1002 out:
 1003     dht_lk_inode_unref(frame, op_ret);
 1004     DHT_STACK_UNWIND(lk, frame, op_ret, op_errno, flock, xdata);
 1005 
 1006     return 0;
 1007 }
 1008 
 1009 static int
 1010 dht_lk2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret)
 1011 {
 1012     dht_local_t *local = NULL;
 1013     int32_t op_errno = EINVAL;
 1014 
 1015     if ((frame == NULL) || (frame->local == NULL))
 1016         goto out;
 1017 
 1018     local = frame->local;
 1019 
 1020     op_errno = local->op_errno;
 1021 
 1022     if (subvol == NULL)
 1023         goto out;
 1024 
 1025     local->call_cnt = 2; /* This is the second attempt */
 1026 
 1027     STACK_WIND(frame, dht_lk_cbk, subvol, subvol->fops->lk, local->fd,
 1028                local->rebalance.lock_cmd, &local->rebalance.flock,
 1029                local->xattr_req);
 1030 
 1031     return 0;
 1032 
 1033 out:
 1034     DHT_STACK_UNWIND(lk, frame, -1, op_errno, NULL, NULL);
 1035     return 0;
 1036 }
 1037 
 1038 int
 1039 dht_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int cmd,
 1040        struct gf_flock *flock, dict_t *xdata)
 1041 {
 1042     xlator_t *lock_subvol = NULL;
 1043     int op_errno = -1;
 1044     dht_local_t *local = NULL;
 1045 
 1046     VALIDATE_OR_GOTO(frame, err);
 1047     VALIDATE_OR_GOTO(this, err);
 1048     VALIDATE_OR_GOTO(fd, err);
 1049 
 1050     local = dht_local_init(frame, NULL, fd, GF_FOP_LK);
 1051     if (!local) {
 1052         op_errno = ENOMEM;
 1053         goto err;
 1054     }
 1055 
 1056     local->lock_type = flock->l_type;
 1057     lock_subvol = dht_get_lock_subvolume(this, flock, local);
 1058     if (!lock_subvol) {
 1059         gf_msg_debug(this->name, 0, "no lock subvolume for path=%p", fd);
 1060         op_errno = EINVAL;
 1061         goto err;
 1062     }
 1063 
 1064     /*
 1065             local->cached_subvol = lock_subvol;
 1066             ret = dht_check_and_open_fd_on_subvol (this, frame);
 1067             if (ret)
 1068                     goto err;
 1069     */
 1070     if (xdata)
 1071         local->xattr_req = dict_ref(xdata);
 1072 
 1073     local->rebalance.flock = *flock;
 1074     local->rebalance.lock_cmd = cmd;
 1075 
 1076     local->call_cnt = 1;
 1077 
 1078     STACK_WIND(frame, dht_lk_cbk, lock_subvol, lock_subvol->fops->lk, fd, cmd,
 1079                flock, xdata);
 1080 
 1081     return 0;
 1082 
 1083 err:
 1084     op_errno = (op_errno == -1) ? errno : op_errno;
 1085     DHT_STACK_UNWIND(lk, frame, -1, op_errno, NULL, NULL);
 1086 
 1087     return 0;
 1088 }
 1089 
 1090 static int
 1091 dht_lease_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
 1092               int op_errno, struct gf_lease *lease, dict_t *xdata)
 1093 {
 1094     DHT_STACK_UNWIND(lease, frame, op_ret, op_errno, lease, xdata);
 1095 
 1096     return 0;
 1097 }
 1098 
 1099 int
 1100 dht_lease(call_frame_t *frame, xlator_t *this, loc_t *loc,
 1101           struct gf_lease *lease, dict_t *xdata)
 1102 {
 1103     xlator_t *subvol = NULL;
 1104     int op_errno = -1;
 1105 
 1106     VALIDATE_OR_GOTO(frame, err);
 1107     VALIDATE_OR_GOTO(this, err);
 1108     VALIDATE_OR_GOTO(loc, err);
 1109 
 1110     subvol = dht_subvol_get_cached(this, loc->inode);
 1111     if (!subvol) {
 1112         gf_msg_debug(this->name, 0, "no cached subvolume for path=%s",
 1113                      loc->path);
 1114         op_errno = EINVAL;
 1115         goto err;
 1116     }
 1117 
 1118     /* TODO: for rebalance, we need to preserve the fop arguments */
 1119     STACK_WIND(frame, dht_lease_cbk, subvol, subvol->fops->lease, loc, lease,
 1120                xdata);
 1121 
 1122     return 0;
 1123 
 1124 err:
 1125     op_errno = (op_errno == -1) ? errno : op_errno;
 1126     DHT_STACK_UNWIND(lease, frame, -1, op_errno, NULL, NULL);
 1127 
 1128     return 0;
 1129 }
 1130 
 1131 /* Symlinks are currently not migrated, so no need for any check here */
 1132 static int
 1133 dht_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
 1134                  int op_errno, const char *path, struct iatt *stbuf,
 1135                  dict_t *xdata)
 1136 {
 1137     dht_local_t *local = NULL;
 1138 
 1139     local = frame->local;
 1140     if (op_ret == -1)
 1141         goto err;
 1142 
 1143     if (!local) {
 1144         op_ret = -1;
 1145         op_errno = EINVAL;
 1146     }
 1147 
 1148 err:
 1149     DHT_STRIP_PHASE1_FLAGS(stbuf);
 1150     DHT_STACK_UNWIND(readlink, frame, op_ret, op_errno, path, stbuf, xdata);
 1151 
 1152     return 0;
 1153 }
 1154 
 1155 int
 1156 dht_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
 1157              dict_t *xdata)
 1158 {
 1159     xlator_t *subvol = NULL;
 1160     int op_errno = -1;
 1161     dht_local_t *local = NULL;
 1162 
 1163     VALIDATE_OR_GOTO(frame, err);
 1164     VALIDATE_OR_GOTO(this, err);
 1165     VALIDATE_OR_GOTO(loc, err);
 1166     VALIDATE_OR_GOTO(loc->inode, err);
 1167     VALIDATE_OR_GOTO(loc->path, err);
 1168 
 1169     local = dht_local_init(frame, loc, NULL, GF_FOP_READLINK);
 1170     if (!local) {
 1171         op_errno = ENOMEM;
 1172         goto err;
 1173     }
 1174 
 1175     subvol = local->cached_subvol;
 1176     if (!subvol) {
 1177         gf_msg_debug(this->name, 0, "no cached subvolume for path=%s",
 1178                      loc->path);
 1179         op_errno = EINVAL;
 1180         goto err;
 1181     }
 1182 
 1183     STACK_WIND(frame, dht_readlink_cbk, subvol, subvol->fops->readlink, loc,
 1184                size, xdata);
 1185 
 1186     return 0;
 1187 
 1188 err:
 1189     op_errno = (op_errno == -1) ? errno : op_errno;
 1190     DHT_STACK_UNWIND(readlink, frame, -1, op_errno, NULL, NULL, NULL);
 1191 
 1192     return 0;
 1193 }
 1194 
 1195 /* Get both DHT_IATT_IN_XDATA_KEY and DHT_MODE_IN_XDATA_KEY
 1196  * Use DHT_MODE_IN_XDATA_KEY if available, else fall back to
 1197  * DHT_IATT_IN_XDATA_KEY
 1198  * This will return a dummy iatt with only the mode and type set
 1199  */
 1200 static int
 1201 dht_read_iatt_from_xdata(dict_t *xdata, struct iatt *stbuf)
 1202 {
 1203     int ret = -1;
 1204     int32_t mode = 0;
 1205 
 1206     ret = dict_get_int32(xdata, DHT_MODE_IN_XDATA_KEY, &mode);
 1207 
 1208     if (ret) {
 1209         ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&stbuf);
 1210     } else {
 1211         stbuf->ia_prot = ia_prot_from_st_mode(mode);
 1212         stbuf->ia_type = ia_type_from_st_mode(mode);
 1213     }
 1214 
 1215     return ret;
 1216 }
 1217 
 1218 int
 1219 dht_common_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1220                        int32_t op_ret, int32_t op_errno, dict_t *dict,
 1221                        dict_t *xdata)
 1222 {
 1223     dht_local_t *local = NULL;
 1224     call_frame_t *call_frame = NULL;
 1225     xlator_t *prev = NULL;
 1226     xlator_t *src_subvol = NULL;
 1227     xlator_t *dst_subvol = NULL;
 1228     struct iatt stbuf = {
 1229         0,
 1230     };
 1231     int ret = -1;
 1232     inode_t *inode = NULL;
 1233 
 1234     local = frame->local;
 1235     call_frame = cookie;
 1236     prev = call_frame->this;
 1237 
 1238     local->op_errno = op_errno;
 1239 
 1240     if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
 1241         gf_msg_debug(this->name, op_errno, "subvolume %s returned -1.",
 1242                      prev->name);
 1243         goto out;
 1244     }
 1245 
 1246     if (local->call_cnt != 1)
 1247         goto out;
 1248 
 1249     if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
 1250         ret = dht_check_and_open_fd_on_subvol(this, frame);
 1251         if (ret)
 1252             goto out;
 1253         return 0;
 1254     }
 1255 
 1256     ret = dht_read_iatt_from_xdata(xdata, &stbuf);
 1257 
 1258     if ((!op_ret) && (ret)) {
 1259         /* This is a potential problem and can cause corruption
 1260          * with sharding.
 1261          * Oh well. We tried.
 1262          */
 1263         goto out;
 1264     }
 1265 
 1266     local->op_ret = op_ret;
 1267     local->rebalance.target_op_fn = dht_common_xattrop2;
 1268     if (xdata)
 1269         local->rebalance.xdata = dict_ref(xdata);
 1270 
 1271     if (dict)
 1272         local->rebalance.dict = dict_ref(dict);
 1273 
 1274     /* Phase 2 of migration */
 1275     if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(&stbuf)) {
 1276         ret = dht_rebalance_complete_check(this, frame);
 1277         if (!ret)
 1278             return 0;
 1279     }
 1280 
 1281     /* Check if the rebalance phase1 is true */
 1282     if (IS_DHT_MIGRATION_PHASE1(&stbuf)) {
 1283         inode = local->loc.inode ? local->loc.inode : local->fd->inode;
 1284         dht_inode_ctx_get_mig_info(this, inode, &src_subvol, &dst_subvol);
 1285 
 1286         if (dht_mig_info_is_invalid(local->cached_subvol, src_subvol,
 1287                                     dst_subvol) ||
 1288             !dht_fd_open_on_dst(this, local->fd, dst_subvol)) {
 1289             ret = dht_rebalance_in_progress_check(this, frame);
 1290             if (!ret)
 1291                 return 0;
 1292         } else {
 1293             dht_common_xattrop2(this, dst_subvol, frame, 0);
 1294             return 0;
 1295         }
 1296     }
 1297 
 1298 out:
 1299     if (local->fop == GF_FOP_XATTROP) {
 1300         DHT_STACK_UNWIND(xattrop, frame, op_ret, op_errno, dict, xdata);
 1301     } else {
 1302         DHT_STACK_UNWIND(fxattrop, frame, op_ret, op_errno, dict, xdata);
 1303     }
 1304 
 1305     return 0;
 1306 }
 1307 
 1308 static int
 1309 dht_common_xattrop2(xlator_t *this, xlator_t *subvol, call_frame_t *frame,
 1310                     int ret)
 1311 {
 1312     dht_local_t *local = NULL;
 1313     int32_t op_errno = EINVAL;
 1314 
 1315     if ((frame == NULL) || (frame->local == NULL))
 1316         goto out;
 1317 
 1318     local = frame->local;
 1319     op_errno = local->op_errno;
 1320 
 1321     if (we_are_not_migrating(ret)) {
 1322         /* This dht xlator is not migrating the file. Unwind and
 1323          * pass on the original mode bits so the higher DHT layer
 1324          * can handle this.
 1325          */
 1326         if (local->fop == GF_FOP_XATTROP) {
 1327             DHT_STACK_UNWIND(xattrop, frame, local->op_ret, op_errno,
 1328                              local->rebalance.dict, local->rebalance.xdata);
 1329         } else {
 1330             DHT_STACK_UNWIND(fxattrop, frame, local->op_ret, op_errno,
 1331                              local->rebalance.dict, local->rebalance.xdata);
 1332         }
 1333 
 1334         return 0;
 1335     }
 1336 
 1337     if (subvol == NULL)
 1338         goto out;
 1339 
 1340     local->call_cnt = 2; /* This is the second attempt */
 1341 
 1342     if (local->fop == GF_FOP_XATTROP) {
 1343         STACK_WIND(frame, dht_common_xattrop_cbk, subvol, subvol->fops->xattrop,
 1344                    &local->loc, local->rebalance.flags, local->rebalance.xattr,
 1345                    local->xattr_req);
 1346     } else {
 1347         STACK_WIND(frame, dht_common_xattrop_cbk, subvol,
 1348                    subvol->fops->fxattrop, local->fd, local->rebalance.flags,
 1349                    local->rebalance.xattr, local->xattr_req);
 1350     }
 1351 
 1352     return 0;
 1353 
 1354 out:
 1355 
 1356     /* If local is unavailable we could be unwinding the wrong
 1357      * function here */
 1358 
 1359     if (local && (local->fop == GF_FOP_XATTROP)) {
 1360         DHT_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL);
 1361     } else {
 1362         DHT_STACK_UNWIND(fxattrop, frame, -1, op_errno, NULL, NULL);
 1363     }
 1364     return 0;
 1365 }
 1366 
 1367 static int
 1368 dht_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1369                 int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
 1370 {
 1371     DHT_STACK_UNWIND(xattrop, frame, op_ret, op_errno, dict, xdata);
 1372     return 0;
 1373 }
 1374 
 1375 /* Set both DHT_IATT_IN_XDATA_KEY and DHT_MODE_IN_XDATA_KEY
 1376  * Use DHT_MODE_IN_XDATA_KEY if available. Else fall back to
 1377  * DHT_IATT_IN_XDATA_KEY
 1378  */
 1379 static int
 1380 dht_request_iatt_in_xdata(dict_t *xattr_req)
 1381 {
 1382     int ret = -1;
 1383 
 1384     ret = dict_set_int8(xattr_req, DHT_MODE_IN_XDATA_KEY, 1);
 1385     ret = dict_set_int8(xattr_req, DHT_IATT_IN_XDATA_KEY, 1);
 1386 
 1387     /* At least one call succeeded */
 1388     return ret;
 1389 }
 1390 
 1391 int
 1392 dht_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc,
 1393             gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
 1394 {
 1395     xlator_t *subvol = NULL;
 1396     int op_errno = -1;
 1397     dht_local_t *local = NULL;
 1398     int ret = -1;
 1399 
 1400     VALIDATE_OR_GOTO(frame, err);
 1401     VALIDATE_OR_GOTO(this, err);
 1402     VALIDATE_OR_GOTO(loc, err);
 1403     VALIDATE_OR_GOTO(loc->inode, err);
 1404 
 1405     local = dht_local_init(frame, loc, NULL, GF_FOP_XATTROP);
 1406     if (!local) {
 1407         op_errno = ENOMEM;
 1408         goto err;
 1409     }
 1410 
 1411     subvol = local->cached_subvol;
 1412     if (!subvol) {
 1413         gf_msg_debug(this->name, 0, "no cached subvolume for gfid=%s",
 1414                      uuid_utoa(loc->inode->gfid));
 1415         op_errno = EINVAL;
 1416         goto err;
 1417     }
 1418 
 1419     /* Todo : Handle dirs as well. At the moment the only xlator above dht
 1420      * that uses xattrop is sharding and that is only for files */
 1421 
 1422     if (IA_ISDIR(loc->inode->ia_type)) {
 1423         STACK_WIND(frame, dht_xattrop_cbk, subvol, subvol->fops->xattrop, loc,
 1424                    flags, dict, xdata);
 1425 
 1426     } else {
 1427         local->xattr_req = xdata ? dict_ref(xdata) : dict_new();
 1428         local->call_cnt = 1;
 1429 
 1430         local->rebalance.xattr = dict_ref(dict);
 1431         local->rebalance.flags = flags;
 1432 
 1433         ret = dht_request_iatt_in_xdata(local->xattr_req);
 1434 
 1435         if (ret) {
 1436             gf_msg_debug(this->name, 0,
 1437                          "Failed to set dictionary key %s file=%s",
 1438                          DHT_IATT_IN_XDATA_KEY, loc->path);
 1439         }
 1440 
 1441         STACK_WIND(frame, dht_common_xattrop_cbk, subvol, subvol->fops->xattrop,
 1442                    loc, local->rebalance.flags, local->rebalance.xattr,
 1443                    local->xattr_req);
 1444     }
 1445 
 1446     return 0;
 1447 
 1448 err:
 1449     op_errno = (op_errno == -1) ? errno : op_errno;
 1450     DHT_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL);
 1451 
 1452     return 0;
 1453 }
 1454 
 1455 static int
 1456 dht_fxattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1457                  int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
 1458 {
 1459     DHT_STACK_UNWIND(fxattrop, frame, op_ret, op_errno, dict, xdata);
 1460     return 0;
 1461 }
 1462 
 1463 int
 1464 dht_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd,
 1465              gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
 1466 {
 1467     xlator_t *subvol = NULL;
 1468     int op_errno = -1;
 1469     dht_local_t *local = NULL;
 1470     int ret = -1;
 1471 
 1472     VALIDATE_OR_GOTO(frame, err);
 1473     VALIDATE_OR_GOTO(this, err);
 1474     VALIDATE_OR_GOTO(fd, err);
 1475 
 1476     subvol = dht_subvol_get_cached(this, fd->inode);
 1477     if (!subvol) {
 1478         gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd);
 1479         op_errno = EINVAL;
 1480         goto err;
 1481     }
 1482 
 1483     local = dht_local_init(frame, NULL, fd, GF_FOP_FXATTROP);
 1484     if (!local) {
 1485         op_errno = ENOMEM;
 1486         goto err;
 1487     }
 1488 
 1489     /* Todo : Handle dirs as well. At the moment the only xlator above dht
 1490      * that uses xattrop is sharding and that is only for files */
 1491 
 1492     if (IA_ISDIR(fd->inode->ia_type)) {
 1493         STACK_WIND(frame, dht_fxattrop_cbk, subvol, subvol->fops->fxattrop, fd,
 1494                    flags, dict, xdata);
 1495 
 1496     } else {
 1497         local->xattr_req = xdata ? dict_ref(xdata) : dict_new();
 1498         local->call_cnt = 1;
 1499 
 1500         local->rebalance.xattr = dict_ref(dict);
 1501         local->rebalance.flags = flags;
 1502 
 1503         ret = dht_request_iatt_in_xdata(local->xattr_req);
 1504 
 1505         if (ret) {
 1506             gf_msg_debug(this->name, 0, "Failed to set dictionary key %s fd=%p",
 1507                          DHT_IATT_IN_XDATA_KEY, fd);
 1508         }
 1509 
 1510         STACK_WIND(frame, dht_common_xattrop_cbk, subvol,
 1511                    subvol->fops->fxattrop, fd, local->rebalance.flags,
 1512                    local->rebalance.xattr, local->xattr_req);
 1513     }
 1514 
 1515     return 0;
 1516 
 1517 err:
 1518     op_errno = (op_errno == -1) ? errno : op_errno;
 1519     DHT_STACK_UNWIND(fxattrop, frame, -1, op_errno, NULL, NULL);
 1520 
 1521     return 0;
 1522 }
 1523 
 1524 /* Currently no translators on top of 'distribute' will be using
 1525  * below fops, hence not implementing 'migration' related checks
 1526  */
 1527 
 1528 static int
 1529 dht_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1530                 int32_t op_ret, int32_t op_errno, dict_t *xdata)
 1531 
 1532 {
 1533     dht_lk_inode_unref(frame, op_ret);
 1534     DHT_STACK_UNWIND(inodelk, frame, op_ret, op_errno, xdata);
 1535     return 0;
 1536 }
 1537 
 1538 int32_t
 1539 dht_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc,
 1540             int32_t cmd, struct gf_flock *lock, dict_t *xdata)
 1541 {
 1542     xlator_t *lock_subvol = NULL;
 1543     int op_errno = -1;
 1544     dht_local_t *local = NULL;
 1545 
 1546     VALIDATE_OR_GOTO(frame, err);
 1547     VALIDATE_OR_GOTO(this, err);
 1548     VALIDATE_OR_GOTO(loc, err);
 1549     VALIDATE_OR_GOTO(loc->inode, err);
 1550 
 1551     local = dht_local_init(frame, loc, NULL, GF_FOP_INODELK);
 1552     if (!local) {
 1553         op_errno = ENOMEM;
 1554         goto err;
 1555     }
 1556 
 1557     local->lock_type = lock->l_type;
 1558     lock_subvol = dht_get_lock_subvolume(this, lock, local);
 1559     if (!lock_subvol) {
 1560         gf_msg_debug(this->name, 0, "no lock subvolume for path=%s", loc->path);
 1561         op_errno = EINVAL;
 1562         goto err;
 1563     }
 1564 
 1565     local->call_cnt = 1;
 1566 
 1567     STACK_WIND(frame, dht_inodelk_cbk, lock_subvol, lock_subvol->fops->inodelk,
 1568                volume, loc, cmd, lock, xdata);
 1569 
 1570     return 0;
 1571 
 1572 err:
 1573     op_errno = (op_errno == -1) ? errno : op_errno;
 1574     DHT_STACK_UNWIND(inodelk, frame, -1, op_errno, NULL);
 1575 
 1576     return 0;
 1577 }
 1578 
 1579 int
 1580 dht_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1581                  int32_t op_ret, int32_t op_errno, dict_t *xdata)
 1582 
 1583 {
 1584     dht_local_t *local = NULL;
 1585     int ret = 0;
 1586 
 1587     GF_VALIDATE_OR_GOTO("dht", frame, out);
 1588     GF_VALIDATE_OR_GOTO("dht", this, out);
 1589     GF_VALIDATE_OR_GOTO("dht", frame->local, out);
 1590 
 1591     local = frame->local;
 1592 
 1593     if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {
 1594         ret = dht_check_and_open_fd_on_subvol(this, frame);
 1595         if (ret)
 1596             goto out;
 1597         return 0;
 1598     }
 1599 
 1600 out:
 1601     dht_lk_inode_unref(frame, op_ret);
 1602     DHT_STACK_UNWIND(finodelk, frame, op_ret, op_errno, xdata);
 1603 
 1604     return 0;
 1605 }
 1606 
 1607 int
 1608 dht_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
 1609              int32_t cmd, struct gf_flock *lock, dict_t *xdata)
 1610 {
 1611     xlator_t *lock_subvol = NULL;
 1612     dht_local_t *local = NULL;
 1613     int op_errno = -1;
 1614 
 1615     VALIDATE_OR_GOTO(frame, err);
 1616     VALIDATE_OR_GOTO(this, err);
 1617     VALIDATE_OR_GOTO(fd, err);
 1618 
 1619     local = dht_local_init(frame, NULL, fd, GF_FOP_INODELK);
 1620     if (!local) {
 1621         op_errno = ENOMEM;
 1622         goto err;
 1623     }
 1624 
 1625     local->call_cnt = 1;
 1626     local->lock_type = lock->l_type;
 1627 
 1628     lock_subvol = dht_get_lock_subvolume(this, lock, local);
 1629     if (!lock_subvol) {
 1630         gf_msg_debug(this->name, 0, "no lock subvolume for fd=%p", fd);
 1631         op_errno = EINVAL;
 1632         goto err;
 1633     }
 1634 
 1635     /*
 1636             local->cached_subvol = lock_subvol;
 1637             ret = dht_check_and_open_fd_on_subvol (this, frame);
 1638             if (ret)
 1639                     goto err;
 1640     */
 1641     local->rebalance.flock = *lock;
 1642     local->rebalance.lock_cmd = cmd;
 1643     local->key = gf_strdup(volume);
 1644 
 1645     if (xdata)
 1646         local->xattr_req = dict_ref(xdata);
 1647 
 1648     STACK_WIND(frame, dht_finodelk_cbk, lock_subvol,
 1649                lock_subvol->fops->finodelk, volume, fd, cmd, lock, xdata);
 1650 
 1651     return 0;
 1652 
 1653 err:
 1654     op_errno = (op_errno == -1) ? errno : op_errno;
 1655     DHT_STACK_UNWIND(finodelk, frame, -1, op_errno, NULL);
 1656 
 1657     return 0;
 1658 }