"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/xlators/features/upcall/src/upcall.c" (16 Sep 2020, 63299 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 "upcall.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2    Copyright (c) 2015 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 <unistd.h>
   12 #include <fcntl.h>
   13 #include <limits.h>
   14 #include <pthread.h>
   15 
   16 #include <glusterfs/glusterfs.h>
   17 #include <glusterfs/compat.h>
   18 #include <glusterfs/xlator.h>
   19 #include <glusterfs/logging.h>
   20 #include <glusterfs/common-utils.h>
   21 
   22 #include <glusterfs/statedump.h>
   23 
   24 #include "upcall.h"
   25 #include "upcall-mem-types.h"
   26 #include "glusterfs3-xdr.h"
   27 #include "protocol-common.h"
   28 #include <glusterfs/defaults.h>
   29 
   30 static int32_t
   31 up_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
   32             int32_t op_errno, fd_t *fd, dict_t *xdata)
   33 {
   34     client_t *client = NULL;
   35     uint32_t flags = 0;
   36     upcall_local_t *local = NULL;
   37 
   38     EXIT_IF_UPCALL_OFF(this, out);
   39 
   40     client = frame->root->client;
   41     local = frame->local;
   42 
   43     if ((op_ret < 0) || !local) {
   44         goto out;
   45     }
   46     flags = UP_UPDATE_CLIENT;
   47     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
   48                             NULL, NULL, NULL);
   49 
   50 out:
   51     UPCALL_STACK_UNWIND(open, frame, op_ret, op_errno, fd, xdata);
   52 
   53     return 0;
   54 }
   55 
   56 static int32_t
   57 up_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
   58         fd_t *fd, dict_t *xdata)
   59 {
   60     int32_t op_errno = ENOMEM;
   61     upcall_local_t *local = NULL;
   62 
   63     EXIT_IF_UPCALL_OFF(this, out);
   64 
   65     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
   66     if (!local) {
   67         goto err;
   68     }
   69 
   70 out:
   71     STACK_WIND(frame, up_open_cbk, FIRST_CHILD(this),
   72                FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
   73 
   74     return 0;
   75 
   76 err:
   77     UPCALL_STACK_UNWIND(open, frame, -1, op_errno, NULL, NULL);
   78 
   79     return 0;
   80 }
   81 
   82 static int32_t
   83 up_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
   84               int op_errno, struct iatt *prebuf, struct iatt *postbuf,
   85               dict_t *xdata)
   86 {
   87     client_t *client = NULL;
   88     uint32_t flags = 0;
   89     upcall_local_t *local = NULL;
   90 
   91     client = frame->root->client;
   92     local = frame->local;
   93 
   94     if ((op_ret < 0) || !local) {
   95         goto out;
   96     }
   97     flags = UP_WRITE_FLAGS;
   98     upcall_cache_invalidate(frame, this, client, local->inode, flags, postbuf,
   99                             NULL, NULL, NULL);
  100 
  101 out:
  102     UPCALL_STACK_UNWIND(writev, frame, op_ret, op_errno, prebuf, postbuf,
  103                         xdata);
  104 
  105     return 0;
  106 }
  107 
  108 static int32_t
  109 up_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
  110           int count, off_t off, uint32_t flags, struct iobref *iobref,
  111           dict_t *xdata)
  112 {
  113     int32_t op_errno = ENOMEM;
  114     upcall_local_t *local = NULL;
  115 
  116     EXIT_IF_UPCALL_OFF(this, out);
  117 
  118     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
  119     if (!local) {
  120         goto err;
  121     }
  122 
  123 out:
  124     STACK_WIND(frame, up_writev_cbk, FIRST_CHILD(this),
  125                FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags,
  126                iobref, xdata);
  127 
  128     return 0;
  129 
  130 err:
  131     UPCALL_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL);
  132 
  133     return 0;
  134 }
  135 
  136 static int32_t
  137 up_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  138              int op_errno, struct iovec *vector, int count, struct iatt *stbuf,
  139              struct iobref *iobref, dict_t *xdata)
  140 {
  141     client_t *client = NULL;
  142     uint32_t flags = 0;
  143     upcall_local_t *local = NULL;
  144 
  145     EXIT_IF_UPCALL_OFF(this, out);
  146 
  147     client = frame->root->client;
  148     local = frame->local;
  149 
  150     if ((op_ret < 0) || !local) {
  151         goto out;
  152     }
  153     flags = UP_UPDATE_CLIENT;
  154     upcall_cache_invalidate(frame, this, client, local->inode, flags, stbuf,
  155                             NULL, NULL, NULL);
  156 
  157 out:
  158     UPCALL_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, stbuf,
  159                         iobref, xdata);
  160 
  161     return 0;
  162 }
  163 
  164 static int32_t
  165 up_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
  166          off_t offset, uint32_t flags, dict_t *xdata)
  167 {
  168     int32_t op_errno = ENOMEM;
  169     upcall_local_t *local = NULL;
  170 
  171     EXIT_IF_UPCALL_OFF(this, out);
  172 
  173     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
  174     if (!local) {
  175         goto err;
  176     }
  177 
  178 out:
  179     STACK_WIND(frame, up_readv_cbk, FIRST_CHILD(this),
  180                FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata);
  181 
  182     return 0;
  183 
  184 err:
  185     UPCALL_STACK_UNWIND(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL);
  186 
  187     return 0;
  188 }
  189 
  190 static int32_t
  191 up_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
  192           int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
  193 {
  194     client_t *client = NULL;
  195     uint32_t flags = 0;
  196     upcall_local_t *local = NULL;
  197 
  198     EXIT_IF_UPCALL_OFF(this, out);
  199 
  200     client = frame->root->client;
  201     local = frame->local;
  202 
  203     if ((op_ret < 0) || !local) {
  204         goto out;
  205     }
  206     flags = UP_UPDATE_CLIENT;
  207     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
  208                             NULL, NULL, NULL);
  209 
  210 out:
  211     UPCALL_STACK_UNWIND(lk, frame, op_ret, op_errno, lock, xdata);
  212 
  213     return 0;
  214 }
  215 
  216 static int32_t
  217 up_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
  218       struct gf_flock *flock, dict_t *xdata)
  219 {
  220     int32_t op_errno = ENOMEM;
  221     upcall_local_t *local = NULL;
  222 
  223     EXIT_IF_UPCALL_OFF(this, out);
  224 
  225     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
  226     if (!local) {
  227         goto err;
  228     }
  229 
  230 out:
  231     STACK_WIND(frame, up_lk_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lk,
  232                fd, cmd, flock, xdata);
  233     return 0;
  234 
  235 err:
  236     UPCALL_STACK_UNWIND(lk, frame, -1, op_errno, NULL, NULL);
  237 
  238     return 0;
  239 }
  240 
  241 static int32_t
  242 up_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  243                 int op_errno, struct iatt *prebuf, struct iatt *postbuf,
  244                 dict_t *xdata)
  245 {
  246     client_t *client = NULL;
  247     uint32_t flags = 0;
  248     upcall_local_t *local = NULL;
  249 
  250     EXIT_IF_UPCALL_OFF(this, out);
  251 
  252     client = frame->root->client;
  253     local = frame->local;
  254 
  255     if ((op_ret < 0) || !local) {
  256         goto out;
  257     }
  258     flags = UP_WRITE_FLAGS;
  259     upcall_cache_invalidate(frame, this, client, local->inode, flags, postbuf,
  260                             NULL, NULL, NULL);
  261 
  262 out:
  263     UPCALL_STACK_UNWIND(truncate, frame, op_ret, op_errno, prebuf, postbuf,
  264                         xdata);
  265 
  266     return 0;
  267 }
  268 
  269 static int32_t
  270 up_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
  271             dict_t *xdata)
  272 {
  273     int32_t op_errno = ENOMEM;
  274     upcall_local_t *local = NULL;
  275 
  276     EXIT_IF_UPCALL_OFF(this, out);
  277 
  278     local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL);
  279     if (!local) {
  280         goto err;
  281     }
  282 
  283 out:
  284     STACK_WIND(frame, up_truncate_cbk, FIRST_CHILD(this),
  285                FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
  286 
  287     return 0;
  288 
  289 err:
  290     UPCALL_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL);
  291 
  292     return 0;
  293 }
  294 
  295 static int32_t
  296 up_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  297                int op_errno, struct iatt *statpre, struct iatt *statpost,
  298                dict_t *xdata)
  299 {
  300     client_t *client = NULL;
  301     uint32_t flags = 0;
  302     upcall_local_t *local = NULL;
  303 
  304     EXIT_IF_UPCALL_OFF(this, out);
  305 
  306     client = frame->root->client;
  307     local = frame->local;
  308 
  309     if ((op_ret < 0) || !local) {
  310         goto out;
  311     }
  312     /* XXX: setattr -> UP_SIZE or UP_OWN or UP_MODE or UP_TIMES
  313      * or INODE_UPDATE (or UP_PERM esp in case of ACLs -> INODE_INVALIDATE)
  314      * Need to check what attr is changed and accordingly pass UP_FLAGS.
  315      * Bug1200271.
  316      */
  317     flags = UP_ATTR_FLAGS;
  318     /* If mode bits have changed invalidate the xattrs, as posix-acl and
  319      * others store permission related information in xattrs. With changing
  320      * of permissions/mode, we need to make clients to forget all the
  321      * xattrs related to permissions.
  322      * TODO: Invalidate the xattr system.posix_acl_access alone.
  323      */
  324     if (is_same_mode(statpre->ia_prot, statpost->ia_prot) != 0)
  325         flags |= UP_XATTR;
  326 
  327     upcall_cache_invalidate(frame, this, client, local->inode, flags, statpost,
  328                             NULL, NULL, NULL);
  329 
  330 out:
  331     UPCALL_STACK_UNWIND(setattr, frame, op_ret, op_errno, statpre, statpost,
  332                         xdata);
  333 
  334     return 0;
  335 }
  336 
  337 static int32_t
  338 up_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf,
  339            int32_t valid, dict_t *xdata)
  340 {
  341     int32_t op_errno = ENOMEM;
  342     upcall_local_t *local = NULL;
  343 
  344     EXIT_IF_UPCALL_OFF(this, out);
  345 
  346     local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL);
  347     if (!local) {
  348         goto err;
  349     }
  350 
  351 out:
  352     STACK_WIND(frame, up_setattr_cbk, FIRST_CHILD(this),
  353                FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata);
  354 
  355     return 0;
  356 
  357 err:
  358     UPCALL_STACK_UNWIND(setattr, frame, -1, op_errno, NULL, NULL, NULL);
  359 
  360     return 0;
  361 }
  362 
  363 static int32_t
  364 up_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
  365               int32_t op_errno, struct iatt *stbuf, struct iatt *preoldparent,
  366               struct iatt *postoldparent, struct iatt *prenewparent,
  367               struct iatt *postnewparent, dict_t *xdata)
  368 {
  369     client_t *client = NULL;
  370     uint32_t flags = 0;
  371     upcall_local_t *local = NULL;
  372 
  373     EXIT_IF_UPCALL_OFF(this, out);
  374 
  375     client = frame->root->client;
  376     local = frame->local;
  377 
  378     if ((op_ret < 0) || !local) {
  379         goto out;
  380     }
  381     flags = (UP_RENAME_FLAGS | UP_PARENT_DENTRY_FLAGS);
  382     upcall_cache_invalidate(frame, this, client, local->inode, flags, stbuf,
  383                             postnewparent, postoldparent, NULL);
  384 
  385     flags = UP_UPDATE_CLIENT;
  386     upcall_cache_invalidate(frame, this, client, local->rename_oldloc.parent,
  387                             flags, postoldparent, NULL, NULL, NULL);
  388 
  389     if (local->rename_oldloc.parent == local->loc.parent)
  390         goto out;
  391 
  392     flags = UP_UPDATE_CLIENT;
  393     upcall_cache_invalidate(frame, this, client, local->loc.parent, flags,
  394                             postnewparent, NULL, NULL, NULL);
  395 
  396 out:
  397     UPCALL_STACK_UNWIND(rename, frame, op_ret, op_errno, stbuf, preoldparent,
  398                         postoldparent, prenewparent, postnewparent, xdata);
  399 
  400     return 0;
  401 }
  402 
  403 static int32_t
  404 up_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
  405           dict_t *xdata)
  406 {
  407     int32_t op_errno = ENOMEM;
  408     upcall_local_t *local = NULL;
  409 
  410     EXIT_IF_UPCALL_OFF(this, out);
  411 
  412     local = upcall_local_init(frame, this, newloc, NULL, oldloc->inode, NULL);
  413     if (!local) {
  414         goto err;
  415     }
  416 
  417     /* copy oldloc */
  418     loc_copy(&local->rename_oldloc, oldloc);
  419 out:
  420     STACK_WIND(frame, up_rename_cbk, FIRST_CHILD(this),
  421                FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata);
  422 
  423     return 0;
  424 
  425 err:
  426     UPCALL_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL,
  427                         NULL, NULL);
  428 
  429     return 0;
  430 }
  431 
  432 static int32_t
  433 up_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  434               int op_errno, struct iatt *preparent, struct iatt *postparent,
  435               dict_t *xdata)
  436 {
  437     client_t *client = NULL;
  438     uint32_t flags = 0;
  439     upcall_local_t *local = NULL;
  440 
  441     EXIT_IF_UPCALL_OFF(this, out);
  442 
  443     client = frame->root->client;
  444     local = frame->local;
  445 
  446     if ((op_ret < 0) || !local) {
  447         goto out;
  448     }
  449     flags = (UP_NLINK_FLAGS | UP_PARENT_DENTRY_FLAGS);
  450     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
  451                             postparent, NULL, NULL);
  452 
  453     flags = UP_UPDATE_CLIENT;
  454     upcall_cache_invalidate(frame, this, client, local->loc.parent, flags,
  455                             postparent, NULL, NULL, NULL);
  456 
  457 out:
  458     UPCALL_STACK_UNWIND(unlink, frame, op_ret, op_errno, preparent, postparent,
  459                         xdata);
  460 
  461     return 0;
  462 }
  463 
  464 static int32_t
  465 up_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
  466           dict_t *xdata)
  467 {
  468     int32_t op_errno = ENOMEM;
  469     upcall_local_t *local = NULL;
  470 
  471     EXIT_IF_UPCALL_OFF(this, out);
  472 
  473     local = upcall_local_init(frame, this, loc, NULL, loc->inode, NULL);
  474     if (!local) {
  475         goto err;
  476     }
  477 
  478 out:
  479     STACK_WIND(frame, up_unlink_cbk, FIRST_CHILD(this),
  480                FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
  481 
  482     return 0;
  483 
  484 err:
  485     UPCALL_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL);
  486 
  487     return 0;
  488 }
  489 
  490 static int32_t
  491 up_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  492             int op_errno, inode_t *inode, struct iatt *stbuf,
  493             struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
  494 {
  495     client_t *client = NULL;
  496     uint32_t flags = 0;
  497     upcall_local_t *local = NULL;
  498 
  499     EXIT_IF_UPCALL_OFF(this, out);
  500 
  501     client = frame->root->client;
  502     local = frame->local;
  503 
  504     if ((op_ret < 0) || !local) {
  505         goto out;
  506     }
  507     flags = (UP_NLINK_FLAGS | UP_PARENT_DENTRY_FLAGS);
  508     upcall_cache_invalidate(frame, this, client, local->inode, flags, stbuf,
  509                             postparent, NULL, NULL);
  510 
  511     flags = UP_UPDATE_CLIENT;
  512     upcall_cache_invalidate(frame, this, client, local->loc.parent, flags,
  513                             postparent, NULL, NULL, NULL);
  514 
  515 out:
  516     UPCALL_STACK_UNWIND(link, frame, op_ret, op_errno, inode, stbuf, preparent,
  517                         postparent, xdata);
  518 
  519     return 0;
  520 }
  521 
  522 static int32_t
  523 up_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
  524         dict_t *xdata)
  525 {
  526     int32_t op_errno = ENOMEM;
  527     upcall_local_t *local = NULL;
  528 
  529     EXIT_IF_UPCALL_OFF(this, out);
  530 
  531     local = upcall_local_init(frame, this, newloc, NULL, oldloc->inode, NULL);
  532     if (!local) {
  533         goto err;
  534     }
  535 
  536 out:
  537     STACK_WIND(frame, up_link_cbk, FIRST_CHILD(this),
  538                FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
  539 
  540     return 0;
  541 
  542 err:
  543     UPCALL_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL,
  544                         NULL);
  545 
  546     return 0;
  547 }
  548 
  549 static int32_t
  550 up_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  551              int op_errno, struct iatt *preparent, struct iatt *postparent,
  552              dict_t *xdata)
  553 {
  554     client_t *client = NULL;
  555     uint32_t flags = 0;
  556     upcall_local_t *local = NULL;
  557 
  558     EXIT_IF_UPCALL_OFF(this, out);
  559 
  560     client = frame->root->client;
  561     local = frame->local;
  562 
  563     if ((op_ret < 0) || !local) {
  564         goto out;
  565     }
  566 
  567     flags = (UP_NLINK_FLAGS | UP_PARENT_DENTRY_FLAGS);
  568     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
  569                             postparent, NULL, NULL);
  570 
  571     flags = UP_UPDATE_CLIENT;
  572     upcall_cache_invalidate(frame, this, client, local->loc.parent, flags,
  573                             postparent, NULL, NULL, NULL);
  574 
  575 out:
  576     UPCALL_STACK_UNWIND(rmdir, frame, op_ret, op_errno, preparent, postparent,
  577                         xdata);
  578 
  579     return 0;
  580 }
  581 
  582 static int32_t
  583 up_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
  584          dict_t *xdata)
  585 {
  586     int32_t op_errno = ENOMEM;
  587     upcall_local_t *local = NULL;
  588 
  589     EXIT_IF_UPCALL_OFF(this, out);
  590 
  591     local = upcall_local_init(frame, this, loc, NULL, loc->inode, NULL);
  592     if (!local) {
  593         goto err;
  594     }
  595 
  596 out:
  597     STACK_WIND(frame, up_rmdir_cbk, FIRST_CHILD(this),
  598                FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata);
  599 
  600     return 0;
  601 
  602 err:
  603     UPCALL_STACK_UNWIND(rmdir, frame, -1, op_errno, NULL, NULL, NULL);
  604 
  605     return 0;
  606 }
  607 
  608 static int32_t
  609 up_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  610              int op_errno, inode_t *inode, struct iatt *stbuf,
  611              struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
  612 {
  613     client_t *client = NULL;
  614     uint32_t flags = 0;
  615     upcall_local_t *local = NULL;
  616 
  617     EXIT_IF_UPCALL_OFF(this, out);
  618 
  619     client = frame->root->client;
  620     local = frame->local;
  621 
  622     if ((op_ret < 0) || !local) {
  623         goto out;
  624     }
  625 
  626     /* invalidate parent's entry too */
  627     flags = UP_TIMES;
  628     upcall_cache_invalidate(frame, this, client, local->inode, flags,
  629                             postparent, NULL, NULL, NULL);
  630 
  631     flags = UP_UPDATE_CLIENT;
  632     upcall_cache_invalidate(frame, this, client, local->loc.inode, flags, stbuf,
  633                             NULL, NULL, NULL);
  634 
  635 out:
  636     UPCALL_STACK_UNWIND(mkdir, frame, op_ret, op_errno, inode, stbuf, preparent,
  637                         postparent, xdata);
  638 
  639     return 0;
  640 }
  641 
  642 static int32_t
  643 up_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
  644          mode_t umask, dict_t *params)
  645 {
  646     int32_t op_errno = ENOMEM;
  647     upcall_local_t *local = NULL;
  648 
  649     EXIT_IF_UPCALL_OFF(this, out);
  650 
  651     local = upcall_local_init(frame, this, loc, NULL, loc->parent, NULL);
  652     if (!local) {
  653         goto err;
  654     }
  655 
  656 out:
  657     STACK_WIND(frame, up_mkdir_cbk, FIRST_CHILD(this),
  658                FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, params);
  659 
  660     return 0;
  661 
  662 err:
  663     UPCALL_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL,
  664                         NULL);
  665 
  666     return 0;
  667 }
  668 
  669 static int32_t
  670 up_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  671               int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf,
  672               struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
  673 {
  674     client_t *client = NULL;
  675     uint32_t flags = 0;
  676     upcall_local_t *local = NULL;
  677 
  678     EXIT_IF_UPCALL_OFF(this, out);
  679 
  680     client = frame->root->client;
  681     local = frame->local;
  682 
  683     if ((op_ret < 0) || !local) {
  684         goto out;
  685     }
  686 
  687     /* As its a new file create, no need of sending notification
  688      * However invalidate parent's entry and update that fact that the
  689      * client has accessed the newly created entry */
  690     flags = UP_TIMES;
  691     upcall_cache_invalidate(frame, this, client, local->inode, flags,
  692                             postparent, NULL, NULL, NULL);
  693 
  694     flags = UP_UPDATE_CLIENT;
  695     upcall_cache_invalidate(frame, this, client, local->loc.inode, flags, stbuf,
  696                             NULL, NULL, NULL);
  697 
  698 out:
  699     UPCALL_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, stbuf,
  700                         preparent, postparent, xdata);
  701 
  702     return 0;
  703 }
  704 
  705 static int32_t
  706 up_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
  707           mode_t mode, mode_t umask, fd_t *fd, dict_t *params)
  708 {
  709     int32_t op_errno = ENOMEM;
  710     upcall_local_t *local = NULL;
  711 
  712     EXIT_IF_UPCALL_OFF(this, out);
  713 
  714     local = upcall_local_init(frame, this, loc, NULL, loc->parent, NULL);
  715     if (!local) {
  716         goto err;
  717     }
  718 
  719 out:
  720     STACK_WIND(frame, up_create_cbk, FIRST_CHILD(this),
  721                FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd,
  722                params);
  723 
  724     return 0;
  725 
  726 err:
  727     UPCALL_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL,
  728                         NULL, NULL);
  729 
  730     return 0;
  731 }
  732 
  733 static int32_t
  734 up_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  735               int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr,
  736               struct iatt *postparent)
  737 {
  738     client_t *client = NULL;
  739     uint32_t flags = 0;
  740     upcall_local_t *local = NULL;
  741 
  742     EXIT_IF_UPCALL_OFF(this, out);
  743 
  744     client = frame->root->client;
  745     local = frame->local;
  746 
  747     if ((op_ret < 0) || !local) {
  748         goto out;
  749     }
  750     flags = UP_UPDATE_CLIENT;
  751     upcall_cache_invalidate(frame, this, client, local->inode, flags, stbuf,
  752                             NULL, NULL, NULL);
  753 
  754 out:
  755     UPCALL_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, stbuf, xattr,
  756                         postparent);
  757 
  758     return 0;
  759 }
  760 
  761 static int32_t
  762 up_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
  763 {
  764     int32_t op_errno = ENOMEM;
  765     upcall_local_t *local = NULL;
  766 
  767     EXIT_IF_UPCALL_OFF(this, out);
  768 
  769     local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL);
  770     if (!local) {
  771         goto err;
  772     }
  773 
  774 out:
  775     STACK_WIND(frame, up_lookup_cbk, FIRST_CHILD(this),
  776                FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
  777 
  778     return 0;
  779 
  780 err:
  781     UPCALL_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
  782 
  783     return 0;
  784 }
  785 
  786 static int32_t
  787 up_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
  788             int32_t op_errno, struct iatt *buf, dict_t *xdata)
  789 {
  790     client_t *client = NULL;
  791     uint32_t flags = 0;
  792     upcall_local_t *local = NULL;
  793 
  794     EXIT_IF_UPCALL_OFF(this, out);
  795 
  796     client = frame->root->client;
  797     local = frame->local;
  798 
  799     if ((op_ret < 0) || !local) {
  800         goto out;
  801     }
  802     flags = UP_UPDATE_CLIENT;
  803     upcall_cache_invalidate(frame, this, client, local->inode, flags, buf, NULL,
  804                             NULL, NULL);
  805 
  806 out:
  807     UPCALL_STACK_UNWIND(stat, frame, op_ret, op_errno, buf, xdata);
  808 
  809     return 0;
  810 }
  811 
  812 static int32_t
  813 up_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
  814 {
  815     int32_t op_errno = ENOMEM;
  816     upcall_local_t *local = NULL;
  817 
  818     EXIT_IF_UPCALL_OFF(this, out);
  819 
  820     local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL);
  821     if (!local) {
  822         goto err;
  823     }
  824 
  825 out:
  826     STACK_WIND(frame, up_stat_cbk, FIRST_CHILD(this),
  827                FIRST_CHILD(this)->fops->stat, loc, xdata);
  828 
  829     return 0;
  830 
  831 err:
  832     UPCALL_STACK_UNWIND(stat, frame, -1, op_errno, NULL, NULL);
  833 
  834     return 0;
  835 }
  836 
  837 static int32_t
  838 up_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
  839 {
  840     int32_t op_errno = ENOMEM;
  841     upcall_local_t *local = NULL;
  842 
  843     EXIT_IF_UPCALL_OFF(this, out);
  844 
  845     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
  846     if (!local) {
  847         goto err;
  848     }
  849 
  850 out:
  851     STACK_WIND(frame, up_stat_cbk, FIRST_CHILD(this),
  852                FIRST_CHILD(this)->fops->fstat, fd, xdata);
  853 
  854     return 0;
  855 
  856 err:
  857     UPCALL_STACK_UNWIND(fstat, frame, -1, op_errno, NULL, NULL);
  858 
  859     return 0;
  860 }
  861 
  862 static int32_t
  863 up_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
  864              dict_t *xdata)
  865 {
  866     int32_t op_errno = ENOMEM;
  867     upcall_local_t *local = NULL;
  868 
  869     EXIT_IF_UPCALL_OFF(this, out);
  870 
  871     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
  872     if (!local) {
  873         goto err;
  874     }
  875 
  876 out:
  877     STACK_WIND(frame, up_truncate_cbk, FIRST_CHILD(this),
  878                FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
  879 
  880     return 0;
  881 
  882 err:
  883     UPCALL_STACK_UNWIND(ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
  884 
  885     return 0;
  886 }
  887 
  888 static int32_t
  889 up_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  890               int op_errno, dict_t *xdata)
  891 {
  892     client_t *client = NULL;
  893     uint32_t flags = 0;
  894     upcall_local_t *local = NULL;
  895 
  896     EXIT_IF_UPCALL_OFF(this, out);
  897 
  898     client = frame->root->client;
  899     local = frame->local;
  900 
  901     if ((op_ret < 0) || !local) {
  902         goto out;
  903     }
  904     flags = UP_UPDATE_CLIENT;
  905     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
  906                             NULL, NULL, NULL);
  907 
  908 out:
  909     UPCALL_STACK_UNWIND(access, frame, op_ret, op_errno, xdata);
  910 
  911     return 0;
  912 }
  913 
  914 static int32_t
  915 up_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
  916           dict_t *xdata)
  917 {
  918     int32_t op_errno = ENOMEM;
  919     upcall_local_t *local = NULL;
  920 
  921     EXIT_IF_UPCALL_OFF(this, out);
  922 
  923     local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL);
  924     if (!local) {
  925         goto err;
  926     }
  927 
  928 out:
  929     STACK_WIND(frame, up_access_cbk, FIRST_CHILD(this),
  930                FIRST_CHILD(this)->fops->access, loc, mask, xdata);
  931 
  932     return 0;
  933 
  934 err:
  935     UPCALL_STACK_UNWIND(access, frame, -1, op_errno, NULL);
  936 
  937     return 0;
  938 }
  939 
  940 static int32_t
  941 up_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  942                 int op_errno, const char *path, struct iatt *stbuf,
  943                 dict_t *xdata)
  944 {
  945     client_t *client = NULL;
  946     uint32_t flags = 0;
  947     upcall_local_t *local = NULL;
  948 
  949     EXIT_IF_UPCALL_OFF(this, out);
  950 
  951     client = frame->root->client;
  952     local = frame->local;
  953 
  954     if ((op_ret < 0) || !local) {
  955         goto out;
  956     }
  957     flags = UP_UPDATE_CLIENT;
  958     upcall_cache_invalidate(frame, this, client, local->inode, flags, stbuf,
  959                             NULL, NULL, NULL);
  960 
  961 out:
  962     UPCALL_STACK_UNWIND(readlink, frame, op_ret, op_errno, path, stbuf, xdata);
  963 
  964     return 0;
  965 }
  966 
  967 static int32_t
  968 up_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
  969             dict_t *xdata)
  970 {
  971     int32_t op_errno = ENOMEM;
  972     upcall_local_t *local = NULL;
  973 
  974     EXIT_IF_UPCALL_OFF(this, out);
  975 
  976     local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL);
  977     if (!local) {
  978         goto err;
  979     }
  980 
  981 out:
  982     STACK_WIND(frame, up_readlink_cbk, FIRST_CHILD(this),
  983                FIRST_CHILD(this)->fops->readlink, loc, size, xdata);
  984 
  985     return 0;
  986 
  987 err:
  988     UPCALL_STACK_UNWIND(readlink, frame, -1, op_errno, NULL, NULL, NULL);
  989 
  990     return 0;
  991 }
  992 
  993 static int32_t
  994 up_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
  995              int32_t op_errno, inode_t *inode, struct iatt *buf,
  996              struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
  997 {
  998     client_t *client = NULL;
  999     uint32_t flags = 0;
 1000     upcall_local_t *local = NULL;
 1001 
 1002     EXIT_IF_UPCALL_OFF(this, out);
 1003 
 1004     client = frame->root->client;
 1005     local = frame->local;
 1006 
 1007     if ((op_ret < 0) || !local) {
 1008         goto out;
 1009     }
 1010 
 1011     /* invalidate parent's entry too */
 1012     flags = UP_TIMES;
 1013     upcall_cache_invalidate(frame, this, client, local->inode, flags,
 1014                             postparent, NULL, NULL, NULL);
 1015 
 1016     flags = UP_UPDATE_CLIENT;
 1017     upcall_cache_invalidate(frame, this, client, local->loc.inode, flags, buf,
 1018                             NULL, NULL, NULL);
 1019 
 1020 out:
 1021     UPCALL_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, buf, preparent,
 1022                         postparent, xdata);
 1023 
 1024     return 0;
 1025 }
 1026 
 1027 static int32_t
 1028 up_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
 1029          dev_t rdev, mode_t umask, dict_t *xdata)
 1030 {
 1031     int32_t op_errno = ENOMEM;
 1032     upcall_local_t *local = NULL;
 1033 
 1034     EXIT_IF_UPCALL_OFF(this, out);
 1035 
 1036     local = upcall_local_init(frame, this, loc, NULL, loc->parent, NULL);
 1037     if (!local) {
 1038         goto err;
 1039     }
 1040 
 1041 out:
 1042     STACK_WIND(frame, up_mknod_cbk, FIRST_CHILD(this),
 1043                FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata);
 1044 
 1045     return 0;
 1046 
 1047 err:
 1048     UPCALL_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL,
 1049                         NULL);
 1050 
 1051     return 0;
 1052 }
 1053 
 1054 static int32_t
 1055 up_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1056                int32_t op_ret, int32_t op_errno, inode_t *inode,
 1057                struct iatt *buf, struct iatt *preparent,
 1058                struct iatt *postparent, dict_t *xdata)
 1059 {
 1060     client_t *client = NULL;
 1061     uint32_t flags = 0;
 1062     upcall_local_t *local = NULL;
 1063 
 1064     EXIT_IF_UPCALL_OFF(this, out);
 1065 
 1066     client = frame->root->client;
 1067     local = frame->local;
 1068 
 1069     if ((op_ret < 0) || !local) {
 1070         goto out;
 1071     }
 1072 
 1073     /* invalidate parent's entry too */
 1074     flags = UP_TIMES;
 1075     upcall_cache_invalidate(frame, this, client, local->inode, flags,
 1076                             postparent, NULL, NULL, NULL);
 1077 
 1078     flags = UP_UPDATE_CLIENT;
 1079     upcall_cache_invalidate(frame, this, client, local->loc.inode, flags, buf,
 1080                             NULL, NULL, NULL);
 1081 
 1082 out:
 1083     UPCALL_STACK_UNWIND(symlink, frame, op_ret, op_errno, inode, buf, preparent,
 1084                         postparent, xdata);
 1085 
 1086     return 0;
 1087 }
 1088 
 1089 static int32_t
 1090 up_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath,
 1091            loc_t *loc, mode_t umask, dict_t *xdata)
 1092 {
 1093     int32_t op_errno = ENOMEM;
 1094     upcall_local_t *local = NULL;
 1095 
 1096     EXIT_IF_UPCALL_OFF(this, out);
 1097 
 1098     local = upcall_local_init(frame, this, loc, NULL, loc->parent, NULL);
 1099     if (!local) {
 1100         goto err;
 1101     }
 1102 
 1103 out:
 1104     STACK_WIND(frame, up_symlink_cbk, FIRST_CHILD(this),
 1105                FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata);
 1106 
 1107     return 0;
 1108 
 1109 err:
 1110     UPCALL_STACK_UNWIND(symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL,
 1111                         NULL);
 1112 
 1113     return 0;
 1114 }
 1115 
 1116 static int32_t
 1117 up_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1118                int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
 1119 {
 1120     client_t *client = NULL;
 1121     uint32_t flags = 0;
 1122     upcall_local_t *local = NULL;
 1123 
 1124     EXIT_IF_UPCALL_OFF(this, out);
 1125 
 1126     client = frame->root->client;
 1127     local = frame->local;
 1128 
 1129     if ((op_ret < 0) || !local) {
 1130         goto out;
 1131     }
 1132     flags = UP_UPDATE_CLIENT;
 1133     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
 1134                             NULL, NULL, NULL);
 1135 
 1136 out:
 1137     UPCALL_STACK_UNWIND(opendir, frame, op_ret, op_errno, fd, xdata);
 1138 
 1139     return 0;
 1140 }
 1141 
 1142 static int32_t
 1143 up_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
 1144            dict_t *xdata)
 1145 {
 1146     int32_t op_errno = ENOMEM;
 1147     upcall_local_t *local = NULL;
 1148 
 1149     EXIT_IF_UPCALL_OFF(this, out);
 1150 
 1151     local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL);
 1152     if (!local) {
 1153         goto err;
 1154     }
 1155 
 1156 out:
 1157     STACK_WIND(frame, up_opendir_cbk, FIRST_CHILD(this),
 1158                FIRST_CHILD(this)->fops->opendir, loc, fd, xdata);
 1159 
 1160     return 0;
 1161 
 1162 err:
 1163     UPCALL_STACK_UNWIND(opendir, frame, -1, op_errno, NULL, NULL);
 1164 
 1165     return 0;
 1166 }
 1167 
 1168 static int32_t
 1169 up_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
 1170               int32_t op_errno, struct statvfs *buf, dict_t *xdata)
 1171 {
 1172     client_t *client = NULL;
 1173     uint32_t flags = 0;
 1174     upcall_local_t *local = NULL;
 1175 
 1176     EXIT_IF_UPCALL_OFF(this, out);
 1177 
 1178     client = frame->root->client;
 1179     local = frame->local;
 1180 
 1181     if ((op_ret < 0) || !local) {
 1182         goto out;
 1183     }
 1184     flags = UP_UPDATE_CLIENT;
 1185     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
 1186                             NULL, NULL, NULL);
 1187 
 1188 out:
 1189     UPCALL_STACK_UNWIND(statfs, frame, op_ret, op_errno, buf, xdata);
 1190 
 1191     return 0;
 1192 }
 1193 
 1194 static int32_t
 1195 up_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
 1196 {
 1197     int32_t op_errno = ENOMEM;
 1198     upcall_local_t *local = NULL;
 1199 
 1200     EXIT_IF_UPCALL_OFF(this, out);
 1201 
 1202     local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL);
 1203     if (!local) {
 1204         goto err;
 1205     }
 1206 
 1207 out:
 1208     STACK_WIND(frame, up_statfs_cbk, FIRST_CHILD(this),
 1209                FIRST_CHILD(this)->fops->statfs, loc, xdata);
 1210 
 1211     return 0;
 1212 
 1213 err:
 1214     UPCALL_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL);
 1215 
 1216     return 0;
 1217 }
 1218 
 1219 static int32_t
 1220 up_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1221                int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
 1222                dict_t *xdata)
 1223 {
 1224     client_t *client = NULL;
 1225     uint32_t flags = 0;
 1226     upcall_local_t *local = NULL;
 1227 
 1228     EXIT_IF_UPCALL_OFF(this, out);
 1229 
 1230     client = frame->root->client;
 1231     local = frame->local;
 1232 
 1233     if ((op_ret < 0) || !local) {
 1234         goto out;
 1235     }
 1236     flags = UP_UPDATE_CLIENT;
 1237     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
 1238                             NULL, NULL, NULL);
 1239 
 1240 out:
 1241     UPCALL_STACK_UNWIND(readdir, frame, op_ret, op_errno, entries, xdata);
 1242 
 1243     return 0;
 1244 }
 1245 
 1246 static int32_t
 1247 up_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
 1248            off_t off, dict_t *xdata)
 1249 {
 1250     int32_t op_errno = ENOMEM;
 1251     upcall_local_t *local = NULL;
 1252 
 1253     EXIT_IF_UPCALL_OFF(this, out);
 1254 
 1255     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
 1256     if (!local) {
 1257         goto err;
 1258     }
 1259 
 1260 out:
 1261     STACK_WIND(frame, up_readdir_cbk, FIRST_CHILD(this),
 1262                FIRST_CHILD(this)->fops->readdir, fd, size, off, xdata);
 1263 
 1264     return 0;
 1265 
 1266 err:
 1267     UPCALL_STACK_UNWIND(readdir, frame, -1, op_errno, NULL, NULL);
 1268 
 1269     return 0;
 1270 }
 1271 
 1272 static int32_t
 1273 up_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1274                 int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
 1275                 dict_t *xdata)
 1276 {
 1277     client_t *client = NULL;
 1278     uint32_t flags = 0;
 1279     upcall_local_t *local = NULL;
 1280     gf_dirent_t *entry = NULL;
 1281 
 1282     EXIT_IF_UPCALL_OFF(this, out);
 1283 
 1284     client = frame->root->client;
 1285     local = frame->local;
 1286 
 1287     if ((op_ret < 0) || !local) {
 1288         goto out;
 1289     }
 1290     flags = UP_UPDATE_CLIENT;
 1291     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
 1292                             NULL, NULL, NULL);
 1293 
 1294     list_for_each_entry(entry, &entries->list, list)
 1295     {
 1296         if (entry->inode == NULL) {
 1297             continue;
 1298         }
 1299         upcall_cache_invalidate(frame, this, client, entry->inode, flags,
 1300                                 &entry->d_stat, NULL, NULL, NULL);
 1301     }
 1302 
 1303 out:
 1304     UPCALL_STACK_UNWIND(readdirp, frame, op_ret, op_errno, entries, xdata);
 1305 
 1306     return 0;
 1307 }
 1308 
 1309 static int32_t
 1310 up_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
 1311             off_t off, dict_t *dict)
 1312 {
 1313     int32_t op_errno = ENOMEM;
 1314     upcall_local_t *local = NULL;
 1315 
 1316     EXIT_IF_UPCALL_OFF(this, out);
 1317 
 1318     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
 1319     if (!local) {
 1320         goto err;
 1321     }
 1322 
 1323 out:
 1324     STACK_WIND(frame, up_readdirp_cbk, FIRST_CHILD(this),
 1325                FIRST_CHILD(this)->fops->readdirp, fd, size, off, dict);
 1326 
 1327     return 0;
 1328 
 1329 err:
 1330     UPCALL_STACK_UNWIND(readdirp, frame, -1, op_errno, NULL, NULL);
 1331 
 1332     return 0;
 1333 }
 1334 
 1335 static int32_t
 1336 up_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf,
 1337             int32_t valid, dict_t *xdata)
 1338 {
 1339     int32_t op_errno = ENOMEM;
 1340     upcall_local_t *local = NULL;
 1341 
 1342     EXIT_IF_UPCALL_OFF(this, out);
 1343 
 1344     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
 1345     if (!local) {
 1346         goto err;
 1347     }
 1348 
 1349 out:
 1350     STACK_WIND(frame, up_setattr_cbk, FIRST_CHILD(this),
 1351                FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata);
 1352 
 1353     return 0;
 1354 
 1355 err:
 1356     UPCALL_STACK_UNWIND(fsetattr, frame, -1, op_errno, NULL, NULL, NULL);
 1357 
 1358     return 0;
 1359 }
 1360 
 1361 static int32_t
 1362 up_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1363                  int32_t op_ret, int32_t op_errno, struct iatt *pre,
 1364                  struct iatt *post, dict_t *xdata)
 1365 {
 1366     client_t *client = NULL;
 1367     uint32_t flags = 0;
 1368     upcall_local_t *local = NULL;
 1369 
 1370     EXIT_IF_UPCALL_OFF(this, out);
 1371 
 1372     client = frame->root->client;
 1373     local = frame->local;
 1374 
 1375     if ((op_ret < 0) || !local) {
 1376         goto out;
 1377     }
 1378     flags = UP_WRITE_FLAGS;
 1379     upcall_cache_invalidate(frame, this, client, local->inode, flags, post,
 1380                             NULL, NULL, NULL);
 1381 
 1382 out:
 1383     UPCALL_STACK_UNWIND(fallocate, frame, op_ret, op_errno, pre, post, xdata);
 1384 
 1385     return 0;
 1386 }
 1387 
 1388 static int32_t
 1389 up_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
 1390              off_t offset, size_t len, dict_t *xdata)
 1391 {
 1392     int32_t op_errno = ENOMEM;
 1393     upcall_local_t *local = NULL;
 1394 
 1395     EXIT_IF_UPCALL_OFF(this, out);
 1396 
 1397     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
 1398     if (!local) {
 1399         goto err;
 1400     }
 1401 
 1402 out:
 1403     STACK_WIND(frame, up_fallocate_cbk, FIRST_CHILD(this),
 1404                FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len,
 1405                xdata);
 1406 
 1407     return 0;
 1408 
 1409 err:
 1410     UPCALL_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL);
 1411 
 1412     return 0;
 1413 }
 1414 
 1415 static int32_t
 1416 up_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1417                int32_t op_ret, int32_t op_errno, struct iatt *pre,
 1418                struct iatt *post, dict_t *xdata)
 1419 {
 1420     client_t *client = NULL;
 1421     uint32_t flags = 0;
 1422     upcall_local_t *local = NULL;
 1423 
 1424     EXIT_IF_UPCALL_OFF(this, out);
 1425 
 1426     client = frame->root->client;
 1427     local = frame->local;
 1428 
 1429     if ((op_ret < 0) || !local) {
 1430         goto out;
 1431     }
 1432     flags = UP_WRITE_FLAGS;
 1433     upcall_cache_invalidate(frame, this, client, local->inode, flags, post,
 1434                             NULL, NULL, NULL);
 1435 
 1436 out:
 1437     UPCALL_STACK_UNWIND(discard, frame, op_ret, op_errno, pre, post, xdata);
 1438 
 1439     return 0;
 1440 }
 1441 
 1442 static int32_t
 1443 up_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
 1444            size_t len, dict_t *xdata)
 1445 {
 1446     int32_t op_errno = ENOMEM;
 1447     upcall_local_t *local = NULL;
 1448 
 1449     EXIT_IF_UPCALL_OFF(this, out);
 1450 
 1451     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
 1452     if (!local) {
 1453         goto err;
 1454     }
 1455 
 1456 out:
 1457     STACK_WIND(frame, up_discard_cbk, FIRST_CHILD(this),
 1458                FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata);
 1459 
 1460     return 0;
 1461 
 1462 err:
 1463     UPCALL_STACK_UNWIND(discard, frame, -1, op_errno, NULL, NULL, NULL);
 1464 
 1465     return 0;
 1466 }
 1467 
 1468 static int32_t
 1469 up_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1470                 int32_t op_ret, int32_t op_errno, struct iatt *pre,
 1471                 struct iatt *post, dict_t *xdata)
 1472 {
 1473     client_t *client = NULL;
 1474     uint32_t flags = 0;
 1475     upcall_local_t *local = NULL;
 1476 
 1477     EXIT_IF_UPCALL_OFF(this, out);
 1478 
 1479     client = frame->root->client;
 1480     local = frame->local;
 1481 
 1482     if ((op_ret < 0) || !local) {
 1483         goto out;
 1484     }
 1485     flags = UP_WRITE_FLAGS;
 1486     upcall_cache_invalidate(frame, this, client, local->inode, flags, post,
 1487                             NULL, NULL, NULL);
 1488 
 1489 out:
 1490     UPCALL_STACK_UNWIND(zerofill, frame, op_ret, op_errno, pre, post, xdata);
 1491 
 1492     return 0;
 1493 }
 1494 
 1495 static int
 1496 up_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
 1497             off_t len, dict_t *xdata)
 1498 {
 1499     int32_t op_errno = ENOMEM;
 1500     upcall_local_t *local = NULL;
 1501 
 1502     EXIT_IF_UPCALL_OFF(this, out);
 1503 
 1504     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
 1505     if (!local) {
 1506         goto err;
 1507     }
 1508 
 1509 out:
 1510     STACK_WIND(frame, up_zerofill_cbk, FIRST_CHILD(this),
 1511                FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata);
 1512 
 1513     return 0;
 1514 
 1515 err:
 1516     UPCALL_STACK_UNWIND(zerofill, frame, -1, op_errno, NULL, NULL, NULL);
 1517 
 1518     return 0;
 1519 }
 1520 
 1521 static int32_t
 1522 up_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
 1523             int op_errno, off_t offset, dict_t *xdata)
 1524 {
 1525     client_t *client = NULL;
 1526     uint32_t flags = 0;
 1527     upcall_local_t *local = NULL;
 1528 
 1529     EXIT_IF_UPCALL_OFF(this, out);
 1530 
 1531     client = frame->root->client;
 1532     local = frame->local;
 1533 
 1534     if ((op_ret < 0) || !local) {
 1535         goto out;
 1536     }
 1537     flags = UP_UPDATE_CLIENT;
 1538     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
 1539                             NULL, NULL, NULL);
 1540 
 1541 out:
 1542     UPCALL_STACK_UNWIND(seek, frame, op_ret, op_errno, offset, xdata);
 1543 
 1544     return 0;
 1545 }
 1546 
 1547 static int32_t
 1548 up_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
 1549         gf_seek_what_t what, dict_t *xdata)
 1550 {
 1551     int32_t op_errno = ENOMEM;
 1552     upcall_local_t *local = NULL;
 1553 
 1554     EXIT_IF_UPCALL_OFF(this, out);
 1555 
 1556     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
 1557     if (!local) {
 1558         goto err;
 1559     }
 1560 
 1561 out:
 1562     STACK_WIND(frame, up_seek_cbk, FIRST_CHILD(this),
 1563                FIRST_CHILD(this)->fops->seek, fd, offset, what, xdata);
 1564 
 1565     return 0;
 1566 
 1567 err:
 1568     UPCALL_STACK_UNWIND(seek, frame, -1, op_errno, 0, NULL);
 1569 
 1570     return 0;
 1571 }
 1572 
 1573 static int32_t
 1574 up_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1575                 int32_t op_ret, int32_t op_errno, dict_t *xdata)
 1576 {
 1577     client_t *client = NULL;
 1578     uint32_t flags = 0;
 1579     upcall_local_t *local = NULL;
 1580     int ret = 0;
 1581     struct iatt stbuf = {
 1582         0,
 1583     };
 1584     upcall_private_t *priv = NULL;
 1585 
 1586     EXIT_IF_UPCALL_OFF(this, out);
 1587 
 1588     priv = this->private;
 1589     GF_VALIDATE_OR_GOTO(this->name, priv, out);
 1590 
 1591     client = frame->root->client;
 1592     local = frame->local;
 1593 
 1594     if ((op_ret < 0) || !local) {
 1595         goto out;
 1596     }
 1597 
 1598     flags = UP_XATTR;
 1599 
 1600     ret = up_filter_xattr(local->xattr, priv->xattrs);
 1601     if (ret < 0) {
 1602         op_ret = ret;
 1603         goto out;
 1604     }
 1605     if (!up_invalidate_needed(local->xattr))
 1606         goto out;
 1607 
 1608     ret = dict_get_iatt(xdata, GF_POSTSTAT, &stbuf);
 1609     if (ret == 0)
 1610         flags |= UP_TIMES;
 1611 
 1612     upcall_cache_invalidate(frame, this, client, local->inode, flags, &stbuf,
 1613                             NULL, NULL, local->xattr);
 1614 
 1615 out:
 1616     UPCALL_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata);
 1617 
 1618     return 0;
 1619 }
 1620 
 1621 static int32_t
 1622 up_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
 1623             int32_t flags, dict_t *xdata)
 1624 {
 1625     int32_t op_errno = ENOMEM;
 1626     upcall_local_t *local = NULL;
 1627 
 1628     EXIT_IF_UPCALL_OFF(this, out);
 1629 
 1630     local = upcall_local_init(frame, this, loc, NULL, loc->inode, dict);
 1631     if (!local) {
 1632         goto err;
 1633     }
 1634 
 1635 out:
 1636     STACK_WIND(frame, up_setxattr_cbk, FIRST_CHILD(this),
 1637                FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata);
 1638 
 1639     return 0;
 1640 
 1641 err:
 1642     UPCALL_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL);
 1643 
 1644     return 0;
 1645 }
 1646 
 1647 static int32_t
 1648 up_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1649                  int32_t op_ret, int32_t op_errno, dict_t *xdata)
 1650 {
 1651     client_t *client = NULL;
 1652     uint32_t flags = 0;
 1653     upcall_local_t *local = NULL;
 1654     int ret = 0;
 1655     struct iatt stbuf = {
 1656         0,
 1657     };
 1658     upcall_private_t *priv = NULL;
 1659 
 1660     EXIT_IF_UPCALL_OFF(this, out);
 1661 
 1662     priv = this->private;
 1663     GF_VALIDATE_OR_GOTO(this->name, priv, out);
 1664 
 1665     client = frame->root->client;
 1666     local = frame->local;
 1667 
 1668     if ((op_ret < 0) || !local) {
 1669         goto out;
 1670     }
 1671 
 1672     flags = UP_XATTR;
 1673 
 1674     ret = up_filter_xattr(local->xattr, priv->xattrs);
 1675     if (ret < 0) {
 1676         op_ret = ret;
 1677         goto out;
 1678     }
 1679     if (!up_invalidate_needed(local->xattr))
 1680         goto out;
 1681 
 1682     ret = dict_get_iatt(xdata, GF_POSTSTAT, &stbuf);
 1683     if (ret == 0)
 1684         flags |= UP_TIMES;
 1685 
 1686     upcall_cache_invalidate(frame, this, client, local->inode, flags, &stbuf,
 1687                             NULL, NULL, local->xattr);
 1688 
 1689 out:
 1690     UPCALL_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, xdata);
 1691 
 1692     return 0;
 1693 }
 1694 
 1695 static int32_t
 1696 up_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
 1697              int32_t flags, dict_t *xdata)
 1698 {
 1699     int32_t op_errno = ENOMEM;
 1700     upcall_local_t *local = NULL;
 1701 
 1702     EXIT_IF_UPCALL_OFF(this, out);
 1703 
 1704     local = upcall_local_init(frame, this, NULL, fd, fd->inode, dict);
 1705     if (!local) {
 1706         goto err;
 1707     }
 1708 
 1709 out:
 1710     STACK_WIND(frame, up_fsetxattr_cbk, FIRST_CHILD(this),
 1711                FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
 1712 
 1713     return 0;
 1714 
 1715 err:
 1716     UPCALL_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL);
 1717 
 1718     return 0;
 1719 }
 1720 
 1721 static int32_t
 1722 up_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1723                     int32_t op_ret, int32_t op_errno, dict_t *xdata)
 1724 {
 1725     client_t *client = NULL;
 1726     uint32_t flags = 0;
 1727     upcall_local_t *local = NULL;
 1728     struct iatt stbuf = {
 1729         0,
 1730     };
 1731     int ret = 0;
 1732     upcall_private_t *priv = NULL;
 1733 
 1734     EXIT_IF_UPCALL_OFF(this, out);
 1735 
 1736     priv = this->private;
 1737     GF_VALIDATE_OR_GOTO(this->name, priv, out);
 1738 
 1739     client = frame->root->client;
 1740     local = frame->local;
 1741 
 1742     if ((op_ret < 0) || !local) {
 1743         goto out;
 1744     }
 1745     flags = UP_XATTR_RM;
 1746 
 1747     ret = up_filter_xattr(local->xattr, priv->xattrs);
 1748     if (ret < 0) {
 1749         op_ret = ret;
 1750         goto out;
 1751     }
 1752     if (!up_invalidate_needed(local->xattr))
 1753         goto out;
 1754 
 1755     ret = dict_get_iatt(xdata, GF_POSTSTAT, &stbuf);
 1756     if (ret == 0)
 1757         flags |= UP_TIMES;
 1758 
 1759     upcall_cache_invalidate(frame, this, client, local->inode, flags, &stbuf,
 1760                             NULL, NULL, local->xattr);
 1761 
 1762 out:
 1763     UPCALL_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, xdata);
 1764     return 0;
 1765 }
 1766 
 1767 static int32_t
 1768 up_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
 1769                 dict_t *xdata)
 1770 {
 1771     int32_t op_errno = ENOMEM;
 1772     upcall_local_t *local = NULL;
 1773     dict_t *xattr = NULL;
 1774 
 1775     EXIT_IF_UPCALL_OFF(this, out);
 1776 
 1777     xattr = dict_for_key_value(name, "", 1, _gf_true);
 1778     if (!xattr) {
 1779         goto err;
 1780     }
 1781 
 1782     local = upcall_local_init(frame, this, NULL, fd, fd->inode, xattr);
 1783     if (!local) {
 1784         goto err;
 1785     }
 1786 
 1787 out:
 1788     if (xattr)
 1789         dict_unref(xattr);
 1790 
 1791     STACK_WIND(frame, up_fremovexattr_cbk, FIRST_CHILD(this),
 1792                FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata);
 1793     return 0;
 1794 
 1795 err:
 1796     if (xattr)
 1797         dict_unref(xattr);
 1798 
 1799     UPCALL_STACK_UNWIND(fremovexattr, frame, -1, op_errno, NULL);
 1800 
 1801     return 0;
 1802 }
 1803 
 1804 static int32_t
 1805 up_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1806                    int32_t op_ret, int32_t op_errno, dict_t *xdata)
 1807 {
 1808     client_t *client = NULL;
 1809     uint32_t flags = 0;
 1810     upcall_local_t *local = NULL;
 1811     struct iatt stbuf = {
 1812         0,
 1813     };
 1814     int ret = 0;
 1815     upcall_private_t *priv = NULL;
 1816 
 1817     EXIT_IF_UPCALL_OFF(this, out);
 1818 
 1819     priv = this->private;
 1820     GF_VALIDATE_OR_GOTO(this->name, priv, out);
 1821 
 1822     client = frame->root->client;
 1823     local = frame->local;
 1824 
 1825     if ((op_ret < 0) || !local) {
 1826         goto out;
 1827     }
 1828     flags = UP_XATTR_RM;
 1829 
 1830     ret = up_filter_xattr(local->xattr, priv->xattrs);
 1831     if (ret < 0) {
 1832         op_ret = ret;
 1833         goto out;
 1834     }
 1835     if (!up_invalidate_needed(local->xattr))
 1836         goto out;
 1837 
 1838     ret = dict_get_iatt(xdata, GF_POSTSTAT, &stbuf);
 1839     if (ret == 0)
 1840         flags |= UP_TIMES;
 1841 
 1842     upcall_cache_invalidate(frame, this, client, local->inode, flags, &stbuf,
 1843                             NULL, NULL, local->xattr);
 1844 
 1845 out:
 1846     UPCALL_STACK_UNWIND(removexattr, frame, op_ret, op_errno, xdata);
 1847     return 0;
 1848 }
 1849 
 1850 static int32_t
 1851 up_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
 1852                const char *name, dict_t *xdata)
 1853 {
 1854     int32_t op_errno = ENOMEM;
 1855     upcall_local_t *local = NULL;
 1856     dict_t *xattr = NULL;
 1857 
 1858     EXIT_IF_UPCALL_OFF(this, out);
 1859 
 1860     xattr = dict_for_key_value(name, "", 1, _gf_true);
 1861     if (!xattr) {
 1862         goto err;
 1863     }
 1864 
 1865     local = upcall_local_init(frame, this, loc, NULL, loc->inode, xattr);
 1866     if (!local) {
 1867         goto err;
 1868     }
 1869 
 1870 out:
 1871     if (xattr)
 1872         dict_unref(xattr);
 1873 
 1874     STACK_WIND(frame, up_removexattr_cbk, FIRST_CHILD(this),
 1875                FIRST_CHILD(this)->fops->removexattr, loc, name, xdata);
 1876     return 0;
 1877 
 1878 err:
 1879     if (xattr)
 1880         dict_unref(xattr);
 1881 
 1882     UPCALL_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL);
 1883 
 1884     return 0;
 1885 }
 1886 
 1887 static int32_t
 1888 up_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1889                  int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
 1890 {
 1891     client_t *client = NULL;
 1892     uint32_t flags = 0;
 1893     upcall_local_t *local = NULL;
 1894 
 1895     EXIT_IF_UPCALL_OFF(this, out);
 1896 
 1897     client = frame->root->client;
 1898     local = frame->local;
 1899 
 1900     if ((op_ret < 0) || !local) {
 1901         goto out;
 1902     }
 1903 
 1904     flags = UP_UPDATE_CLIENT;
 1905     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
 1906                             NULL, NULL, NULL);
 1907 
 1908 out:
 1909     UPCALL_STACK_UNWIND(fgetxattr, frame, op_ret, op_errno, dict, xdata);
 1910     return 0;
 1911 }
 1912 
 1913 static int32_t
 1914 up_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
 1915              dict_t *xdata)
 1916 {
 1917     int32_t op_errno = ENOMEM;
 1918     upcall_local_t *local = NULL;
 1919 
 1920     EXIT_IF_UPCALL_OFF(this, out);
 1921 
 1922     local = upcall_local_init(frame, this, NULL, NULL, fd->inode, NULL);
 1923     if (!local) {
 1924         goto err;
 1925     }
 1926 
 1927 out:
 1928     STACK_WIND(frame, up_fgetxattr_cbk, FIRST_CHILD(this),
 1929                FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata);
 1930     return 0;
 1931 err:
 1932     UPCALL_STACK_UNWIND(fgetxattr, frame, -1, op_errno, NULL, NULL);
 1933     return 0;
 1934 }
 1935 
 1936 static int32_t
 1937 up_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 1938                 int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
 1939 {
 1940     client_t *client = NULL;
 1941     uint32_t flags = 0;
 1942     upcall_local_t *local = NULL;
 1943 
 1944     EXIT_IF_UPCALL_OFF(this, out);
 1945 
 1946     client = frame->root->client;
 1947     local = frame->local;
 1948 
 1949     if ((op_ret < 0) || !local) {
 1950         goto out;
 1951     }
 1952 
 1953     flags = UP_UPDATE_CLIENT;
 1954     upcall_cache_invalidate(frame, this, client, local->inode, flags, NULL,
 1955                             NULL, NULL, NULL);
 1956 
 1957 out:
 1958     UPCALL_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata);
 1959     return 0;
 1960 }
 1961 
 1962 static int32_t
 1963 up_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name,
 1964             dict_t *xdata)
 1965 {
 1966     int32_t op_errno = ENOMEM;
 1967     upcall_local_t *local = NULL;
 1968 
 1969     EXIT_IF_UPCALL_OFF(this, out);
 1970 
 1971     local = upcall_local_init(frame, this, NULL, NULL, loc->inode, NULL);
 1972     if (!local) {
 1973         goto err;
 1974     }
 1975 
 1976 out:
 1977     STACK_WIND(frame, up_getxattr_cbk, FIRST_CHILD(this),
 1978                FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
 1979     return 0;
 1980 err:
 1981     UPCALL_STACK_UNWIND(getxattr, frame, -1, op_errno, NULL, NULL);
 1982     return 0;
 1983 }
 1984 
 1985 /* The xattrops here mainly tracks changes in afr pending xattr.
 1986  *    1. xattrop doesn't carry info saying post op/pre op.
 1987  *    2. Pre xattrop will have 0 value for all pending xattrs,
 1988  *       the cbk of pre xattrop carries the on-disk xattr value.
 1989  *       Non zero on-disk xattr indicates pending healing.
 1990  *    3. Post xattrop will either have 0 or 1 as value of pending xattrs,
 1991  *       0 on success, 1 on failure. But the post xattrop cbk will have
 1992  *       0 or 1 or any higher value.
 1993  *       0 - if no healing required*
 1994  *       1 - if this is the first time pending xattr is being set.
 1995  *       n - if there is already a pending xattr set, it will increment
 1996  *       the on-disk value and send that in cbk.
 1997  * Our aim is to send an invalidation, only the first time a pending
 1998  * xattr was set on a file. Below are some of the exceptions in handling
 1999  * xattrop:
 2000  * - Do not filter unregistered xattrs in the cbk, but in the call path.
 2001  *   Else, we will be invalidating on every preop, if the file already has
 2002  *   pending xattr set. Filtering unregistered xattrs on the fop path
 2003  *   ensures we invalidate only in postop, every time a postop comes with
 2004  *   pending xattr value 1.
 2005  * - Consider a brick is down, and the postop sets pending xattrs as long
 2006  *   as the other brick is down. But we do not want to invalidate every time
 2007  *   a pending xattr is set, but we want to invalidate only the first time
 2008  *   a pending xattr is set on any file. Hence, to identify if its the first
 2009  *   time a pending xattr is set, we compare the value of pending xattrs that
 2010  *   came in postop and postop cbk, if its same then its the first time.
 2011  */
 2012 static int32_t
 2013 up_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
 2014                int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
 2015 {
 2016     client_t *client = NULL;
 2017     upcall_local_t *local = NULL;
 2018 
 2019     EXIT_IF_UPCALL_OFF(this, out);
 2020 
 2021     client = frame->root->client;
 2022     local = frame->local;
 2023 
 2024     if ((op_ret < 0) || !local) {
 2025         goto out;
 2026     }
 2027 
 2028     if (up_invalidate_needed(local->xattr)) {
 2029         if (dict_foreach(local->xattr, up_compare_afr_xattr, dict) < 0)
 2030             goto out;
 2031 
 2032         upcall_cache_invalidate(frame, this, client, local->inode, UP_XATTR,
 2033                                 NULL, NULL, NULL, local->xattr);
 2034     }
 2035 out:
 2036     if (frame->root->op == GF_FOP_FXATTROP) {
 2037         UPCALL_STACK_UNWIND(fxattrop, frame, op_ret, op_errno, dict, xdata);
 2038     } else {
 2039         UPCALL_STACK_UNWIND(xattrop, frame, op_ret, op_errno, dict, xdata);
 2040     }
 2041     return 0;
 2042 }
 2043 
 2044 static int32_t
 2045 up_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc,
 2046            gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
 2047 {
 2048     int32_t op_errno = EINVAL;
 2049     upcall_local_t *local = NULL;
 2050     int ret = 0;
 2051     upcall_private_t *priv = NULL;
 2052 
 2053     EXIT_IF_UPCALL_OFF(this, out);
 2054 
 2055     priv = this->private;
 2056     GF_VALIDATE_OR_GOTO(this->name, priv, out);
 2057 
 2058     local = upcall_local_init(frame, this, loc, NULL, loc->inode, xattr);
 2059     if (!local) {
 2060         op_errno = ENOMEM;
 2061         goto err;
 2062     }
 2063 
 2064     ret = up_filter_xattr(local->xattr, priv->xattrs);
 2065     if (ret < 0) {
 2066         goto err;
 2067     }
 2068 
 2069 out:
 2070     STACK_WIND(frame, up_xattrop_cbk, FIRST_CHILD(this),
 2071                FIRST_CHILD(this)->fops->xattrop, loc, optype, xattr, xdata);
 2072     return 0;
 2073 err:
 2074     UPCALL_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL);
 2075     return 0;
 2076 }
 2077 
 2078 static int32_t
 2079 up_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd,
 2080             gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
 2081 {
 2082     int32_t op_errno = EINVAL;
 2083     upcall_local_t *local = NULL;
 2084     int ret = 0;
 2085     upcall_private_t *priv = NULL;
 2086 
 2087     EXIT_IF_UPCALL_OFF(this, out);
 2088 
 2089     priv = this->private;
 2090     GF_VALIDATE_OR_GOTO(this->name, priv, out);
 2091 
 2092     local = upcall_local_init(frame, this, NULL, fd, fd->inode, xattr);
 2093     if (!local) {
 2094         op_errno = ENOMEM;
 2095         goto err;
 2096     }
 2097 
 2098     ret = up_filter_xattr(local->xattr, priv->xattrs);
 2099     if (ret < 0) {
 2100         goto err;
 2101     }
 2102 
 2103 out:
 2104     STACK_WIND(frame, up_xattrop_cbk, FIRST_CHILD(this),
 2105                FIRST_CHILD(this)->fops->fxattrop, fd, optype, xattr, xdata);
 2106     return 0;
 2107 err:
 2108     STACK_UNWIND_STRICT(fxattrop, frame, -1, op_errno, NULL, NULL);
 2109     return 0;
 2110 }
 2111 
 2112 int32_t
 2113 mem_acct_init(xlator_t *this)
 2114 {
 2115     int ret = -1;
 2116 
 2117     if (!this)
 2118         return ret;
 2119 
 2120     ret = xlator_mem_acct_init(this, gf_upcall_mt_end + 1);
 2121 
 2122     if (ret != 0) {
 2123         gf_msg("upcall", GF_LOG_WARNING, 0, UPCALL_MSG_NO_MEMORY,
 2124                "Memory allocation failed");
 2125         return ret;
 2126     }
 2127 
 2128     return ret;
 2129 }
 2130 
 2131 void
 2132 upcall_local_wipe(xlator_t *this, upcall_local_t *local)
 2133 {
 2134     if (local) {
 2135         inode_unref(local->inode);
 2136         if (local->xattr)
 2137             dict_unref(local->xattr);
 2138         loc_wipe(&local->rename_oldloc);
 2139         loc_wipe(&local->loc);
 2140         if (local->fd)
 2141             fd_unref(local->fd);
 2142         mem_put(local);
 2143     }
 2144 }
 2145 
 2146 upcall_local_t *
 2147 upcall_local_init(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
 2148                   inode_t *inode, dict_t *xattr)
 2149 {
 2150     upcall_local_t *local = NULL;
 2151 
 2152     GF_VALIDATE_OR_GOTO("upcall", this, out);
 2153     GF_VALIDATE_OR_GOTO(this->name, frame, out);
 2154     GF_VALIDATE_OR_GOTO(this->name, inode, out);
 2155 
 2156     local = mem_get0(THIS->local_pool);
 2157 
 2158     if (!local)
 2159         goto out;
 2160 
 2161     local->inode = inode_ref(inode);
 2162     if (xattr)
 2163         local->xattr = dict_copy_with_ref(xattr, NULL);
 2164 
 2165     if (loc)
 2166         loc_copy(&local->loc, loc);
 2167     if (fd)
 2168         local->fd = fd_ref(fd);
 2169 
 2170     frame->local = local;
 2171 
 2172 out:
 2173     return local;
 2174 }
 2175 
 2176 static int32_t
 2177 update_xattrs(dict_t *dict, char *key, data_t *value, void *data)
 2178 {
 2179     dict_t *xattrs = data;
 2180     int ret = 0;
 2181 
 2182     ret = dict_set_int8(xattrs, key, 0);
 2183     return ret;
 2184 }
 2185 
 2186 int32_t
 2187 up_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata)
 2188 {
 2189     upcall_private_t *priv = NULL;
 2190     int ret = 0;
 2191 
 2192     priv = this->private;
 2193     GF_VALIDATE_OR_GOTO(this->name, priv, out);
 2194 
 2195     if (op != GF_IPC_TARGET_UPCALL)
 2196         goto wind;
 2197 
 2198     /* TODO: Bz-1371622 Along with the xattrs also store list of clients
 2199      * that are interested in notifications, so that the notification
 2200      * can be sent to the clients that have registered.
 2201      * Once this implemented there can be unregister of xattrs for
 2202      * notifications. Until then there is no unregister of xattrs*/
 2203     if (xdata && priv->xattrs) {
 2204         ret = dict_foreach(xdata, update_xattrs, priv->xattrs);
 2205     }
 2206 
 2207 out:
 2208     STACK_UNWIND_STRICT(ipc, frame, ret, 0, NULL);
 2209     return 0;
 2210 
 2211 wind:
 2212     STACK_WIND(frame, default_ipc_cbk, FIRST_CHILD(this),
 2213                FIRST_CHILD(this)->fops->ipc, op, xdata);
 2214     return 0;
 2215 }
 2216 
 2217 int
 2218 reconfigure(xlator_t *this, dict_t *options)
 2219 {
 2220     upcall_private_t *priv = NULL;
 2221     int ret = -1;
 2222 
 2223     priv = this->private;
 2224     GF_VALIDATE_OR_GOTO(this->name, priv, out);
 2225 
 2226     GF_OPTION_RECONF("cache-invalidation", priv->cache_invalidation_enabled,
 2227                      options, bool, out);
 2228     GF_OPTION_RECONF("cache-invalidation-timeout",
 2229                      priv->cache_invalidation_timeout, options, int32, out);
 2230 
 2231     ret = 0;
 2232 
 2233     if (priv->cache_invalidation_enabled && !priv->reaper_init_done) {
 2234         ret = upcall_reaper_thread_init(this);
 2235 
 2236         if (ret) {
 2237             gf_msg("upcall", GF_LOG_WARNING, 0, UPCALL_MSG_INTERNAL_ERROR,
 2238                    "reaper_thread creation failed (%s)."
 2239                    " Disabling cache_invalidation",
 2240                    strerror(errno));
 2241         }
 2242         priv->reaper_init_done = _gf_true;
 2243     }
 2244 
 2245 out:
 2246     return ret;
 2247 }
 2248 
 2249 int
 2250 init(xlator_t *this)
 2251 {
 2252     int ret = -1;
 2253     upcall_private_t *priv = NULL;
 2254 
 2255     priv = GF_CALLOC(1, sizeof(*priv), gf_upcall_mt_private_t);
 2256     if (!priv)
 2257         goto out;
 2258 
 2259     priv->xattrs = dict_new();
 2260     if (!priv->xattrs)
 2261         goto out;
 2262 
 2263     GF_OPTION_INIT("cache-invalidation", priv->cache_invalidation_enabled, bool,
 2264                    out);
 2265     GF_OPTION_INIT("cache-invalidation-timeout",
 2266                    priv->cache_invalidation_timeout, int32, out);
 2267 
 2268     LOCK_INIT(&priv->inode_ctx_lk);
 2269     INIT_LIST_HEAD(&priv->inode_ctx_list);
 2270 
 2271     priv->fini = 0;
 2272     priv->reaper_init_done = _gf_false;
 2273 
 2274     this->private = priv;
 2275     this->local_pool = mem_pool_new(upcall_local_t, 512);
 2276     ret = 0;
 2277 
 2278     if (priv->cache_invalidation_enabled) {
 2279         ret = upcall_reaper_thread_init(this);
 2280 
 2281         if (ret) {
 2282             gf_msg("upcall", GF_LOG_WARNING, 0, UPCALL_MSG_INTERNAL_ERROR,
 2283                    "reaper_thread creation failed (%s)."
 2284                    " Disabling cache_invalidation",
 2285                    strerror(errno));
 2286         }
 2287         priv->reaper_init_done = _gf_true;
 2288     }
 2289 out:
 2290     if (ret && priv) {
 2291         if (priv->xattrs)
 2292             dict_unref(priv->xattrs);
 2293 
 2294         GF_FREE(priv);
 2295     }
 2296 
 2297     return ret;
 2298 }
 2299 
 2300 void
 2301 fini(xlator_t *this)
 2302 {
 2303     upcall_private_t *priv = NULL;
 2304 
 2305     priv = this->private;
 2306     if (!priv) {
 2307         return;
 2308     }
 2309     this->private = NULL;
 2310 
 2311     priv->fini = 1;
 2312 
 2313     if (priv->reaper_thr) {
 2314         gf_thread_cleanup_xint(priv->reaper_thr);
 2315         priv->reaper_thr = 0;
 2316         priv->reaper_init_done = _gf_false;
 2317     }
 2318 
 2319     dict_unref(priv->xattrs);
 2320     LOCK_DESTROY(&priv->inode_ctx_lk);
 2321 
 2322     /* Do we need to cleanup the inode_ctxs? IMO not required
 2323      * as inode_forget would have been done on all the inodes
 2324      * before calling xlator_fini */
 2325     GF_FREE(priv);
 2326 
 2327     if (this->local_pool) {
 2328         mem_pool_destroy(this->local_pool);
 2329         this->local_pool = NULL;
 2330     }
 2331 
 2332     return;
 2333 }
 2334 
 2335 int
 2336 upcall_forget(xlator_t *this, inode_t *inode)
 2337 {
 2338     upcall_private_t *priv = this->private;
 2339 
 2340     if (!priv)
 2341         goto out;
 2342 
 2343     upcall_cleanup_inode_ctx(this, inode);
 2344 out:
 2345     return 0;
 2346 }
 2347 
 2348 int
 2349 upcall_release(xlator_t *this, fd_t *fd)
 2350 {
 2351     return 0;
 2352 }
 2353 
 2354 int
 2355 notify(xlator_t *this, int32_t event, void *data, ...)
 2356 {
 2357     int ret = -1;
 2358     struct gf_upcall *up_req = NULL;
 2359 
 2360     switch (event) {
 2361         case GF_EVENT_UPCALL: {
 2362             gf_log(this->name, GF_LOG_DEBUG, "Upcall Notify event = %d", event);
 2363 
 2364             up_req = (struct gf_upcall *)data;
 2365 
 2366             GF_VALIDATE_OR_GOTO(this->name, up_req, out);
 2367 
 2368             ret = default_notify(this, event, up_req);
 2369 
 2370             if (ret) {
 2371                 gf_msg(this->name, GF_LOG_WARNING, 0, UPCALL_MSG_NOTIFY_FAILED,
 2372                        "Failed to notify cache invalidation"
 2373                        " to client(%s)",
 2374                        up_req->client_uid);
 2375                 goto out;
 2376             }
 2377         } break;
 2378         default:
 2379             default_notify(this, event, data);
 2380             break;
 2381     }
 2382     ret = 0;
 2383 
 2384 out:
 2385     return ret;
 2386 }
 2387 
 2388 struct xlator_fops fops = {
 2389     .ipc = up_ipc,
 2390     /* fops which change only "ATIME" do not result
 2391      * in any cache invalidation. Hence upcall
 2392      * notifications are not sent in this case.
 2393      * But however, we need to store/update the
 2394      * client info in the upcall state to be able
 2395      * to notify them in case of any changes done
 2396      * to the data.
 2397      *
 2398      * Below such fops do not trigger upcall
 2399      * notifications but will add/update
 2400      * clients info in the upcall inode ctx.*/
 2401     .lookup = up_lookup,
 2402     .open = up_open,
 2403     .statfs = up_statfs,
 2404     .opendir = up_opendir,
 2405     .readdir = up_readdir,
 2406     .readdirp = up_readdirp,
 2407     .stat = up_stat,
 2408     .fstat = up_fstat,
 2409     .access = up_access,
 2410     .readlink = up_readlink,
 2411     .readv = up_readv,
 2412     .lk = up_lk,
 2413     .seek = up_seek,
 2414 
 2415     /* fops doing  write */
 2416     .truncate = up_truncate,
 2417     .ftruncate = up_ftruncate,
 2418     .writev = up_writev,
 2419     .zerofill = up_zerofill,
 2420     .fallocate = up_fallocate,
 2421     .discard = up_discard,
 2422 
 2423     /* fops changing attributes */
 2424     .fsetattr = up_fsetattr,
 2425     .setattr = up_setattr,
 2426 
 2427     /* fops affecting parent dirent */
 2428     .mknod = up_mknod,
 2429     .create = up_create,
 2430     .symlink = up_symlink,
 2431     .mkdir = up_mkdir,
 2432 
 2433     /* fops affecting both file and parent
 2434      * cache entries */
 2435     .unlink = up_unlink,
 2436     .link = up_link,
 2437     .rmdir = up_rmdir,
 2438     .rename = up_rename,
 2439 
 2440     .setxattr = up_setxattr,
 2441     .fsetxattr = up_fsetxattr,
 2442     .getxattr = up_getxattr,
 2443     .fgetxattr = up_fgetxattr,
 2444     .fremovexattr = up_fremovexattr,
 2445     .removexattr = up_removexattr,
 2446     .xattrop = up_xattrop,
 2447     .fxattrop = up_fxattrop,
 2448 
 2449 #ifdef NOT_SUPPORTED
 2450     /* internal lk fops */
 2451     .inodelk = up_inodelk,
 2452     .finodelk = up_finodelk,
 2453     .entrylk = up_entrylk,
 2454     .fentrylk = up_fentrylk,
 2455 
 2456     /* Below fops follow 'WRITE' which
 2457      * would have already sent upcall
 2458      * notifications */
 2459     .flush = up_flush,
 2460     .fsync = up_fsync,
 2461     .fsyncdir = up_fsyncdir,
 2462 #endif
 2463 };
 2464 
 2465 struct xlator_cbks cbks = {
 2466     .forget = upcall_forget,
 2467     .release = upcall_release,
 2468 };
 2469 
 2470 struct volume_options options[] = {
 2471     {
 2472         .key = {"cache-invalidation"},
 2473         .type = GF_OPTION_TYPE_BOOL,
 2474         .default_value = "off",
 2475         .description = "When \"on\", sends cache-invalidation"
 2476                        " notifications.",
 2477         .op_version = {GD_OP_VERSION_3_7_0},
 2478         .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
 2479         .tags = {"cache", "cacheconsistency", "upcall"},
 2480     },
 2481     {.key = {"cache-invalidation-timeout"},
 2482      .type = GF_OPTION_TYPE_INT,
 2483      .default_value = CACHE_INVALIDATION_TIMEOUT,
 2484      .description = "After 'timeout' seconds since the time"
 2485                     " client accessed any file, cache-invalidation"
 2486                     " notifications are no longer sent to that client.",
 2487      .op_version = {GD_OP_VERSION_3_7_0},
 2488      .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
 2489      .tags = {"cache", "cachetimeout", "upcall"}},
 2490     {.key = {NULL}},
 2491 };
 2492 
 2493 xlator_api_t xlator_api = {
 2494     .init = init,
 2495     .fini = fini,
 2496     .notify = notify,
 2497     .reconfigure = reconfigure,
 2498     .mem_acct_init = mem_acct_init,
 2499     .op_version = {1}, /* Present from the initial version */
 2500     .fops = &fops,
 2501     .cbks = &cbks,
 2502     .options = options,
 2503     .identifier = "upcall",
 2504     .category = GF_MAINTAINED,
 2505 };