"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/api/src/glfs-handleops.c" (16 Sep 2020, 61708 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 "glfs-handleops.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 8.0_vs_8.1.

    1 /*
    2  *  Copyright (c) 2013-2018 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 "glfs-internal.h"
   12 #include "glfs-mem-types.h"
   13 #include <glusterfs/syncop.h>
   14 #include "glfs.h"
   15 #include "glfs-handles.h"
   16 #include "gfapi-messages.h"
   17 
   18 int
   19 glfs_listxattr_process(void *value, size_t size, dict_t *xattr);
   20 
   21 void
   22 glfs_iatt_from_stat(struct stat *stat, int valid, struct iatt *iatt,
   23                     int *glvalid)
   24 {
   25     /* validate in args */
   26     if ((stat == NULL) || (iatt == NULL) || (glvalid == NULL)) {
   27         errno = EINVAL;
   28         return;
   29     }
   30 
   31     *glvalid = 0;
   32 
   33     if (valid & GFAPI_SET_ATTR_MODE) {
   34         iatt->ia_prot = ia_prot_from_st_mode(stat->st_mode);
   35         *glvalid |= GF_SET_ATTR_MODE;
   36     }
   37 
   38     if (valid & GFAPI_SET_ATTR_UID) {
   39         iatt->ia_uid = stat->st_uid;
   40         *glvalid |= GF_SET_ATTR_UID;
   41     }
   42 
   43     if (valid & GFAPI_SET_ATTR_GID) {
   44         iatt->ia_gid = stat->st_gid;
   45         *glvalid |= GF_SET_ATTR_GID;
   46     }
   47 
   48     if (valid & GFAPI_SET_ATTR_ATIME) {
   49         iatt->ia_atime = stat->st_atime;
   50         iatt->ia_atime_nsec = ST_ATIM_NSEC(stat);
   51         *glvalid |= GF_SET_ATTR_ATIME;
   52     }
   53 
   54     if (valid & GFAPI_SET_ATTR_MTIME) {
   55         iatt->ia_mtime = stat->st_mtime;
   56         iatt->ia_mtime_nsec = ST_MTIM_NSEC(stat);
   57         *glvalid |= GF_SET_ATTR_MTIME;
   58     }
   59 
   60     return;
   61 }
   62 
   63 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lookupat, 3.7.4)
   64 struct glfs_object *
   65 pub_glfs_h_lookupat(struct glfs *fs, struct glfs_object *parent,
   66                     const char *path, struct stat *stat, int follow)
   67 {
   68     int ret = 0;
   69     xlator_t *subvol = NULL;
   70     inode_t *inode = NULL;
   71     struct iatt iatt = {
   72         0,
   73     };
   74     struct glfs_object *object = NULL;
   75     loc_t loc = {
   76         0,
   77     };
   78 
   79     DECLARE_OLD_THIS;
   80 
   81     /* validate in args */
   82     if (path == NULL) {
   83         errno = EINVAL;
   84         return NULL;
   85     }
   86 
   87     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
   88 
   89     /* get the active volume */
   90     subvol = glfs_active_subvol(fs);
   91     if (!subvol) {
   92         errno = EIO;
   93         goto out;
   94     }
   95 
   96     /* get/refresh the in arg objects inode in correlation to the xlator */
   97     if (parent) {
   98         inode = glfs_resolve_inode(fs, subvol, parent);
   99         if (!inode) {
  100             errno = ESTALE;
  101             goto out;
  102         }
  103     }
  104 
  105     /* fop/op */
  106     ret = glfs_resolve_at(fs, subvol, inode, path, &loc, &iatt, follow, 0);
  107 
  108     /* populate out args */
  109     if (!ret) {
  110         if (stat)
  111             glfs_iatt_to_stat(fs, &iatt, stat);
  112 
  113         ret = glfs_create_object(&loc, &object);
  114     }
  115 
  116 out:
  117     loc_wipe(&loc);
  118 
  119     if (inode)
  120         inode_unref(inode);
  121 
  122     glfs_subvol_done(fs, subvol);
  123 
  124     __GLFS_EXIT_FS;
  125 
  126 invalid_fs:
  127     return object;
  128 }
  129 
  130 GFAPI_SYMVER_PUBLIC(glfs_h_lookupat34, glfs_h_lookupat, 3.4.2)
  131 struct glfs_object *
  132 pub_glfs_h_lookupat34(struct glfs *fs, struct glfs_object *parent,
  133                       const char *path, struct stat *stat)
  134 {
  135     return pub_glfs_h_lookupat(fs, parent, path, stat, 0);
  136 }
  137 
  138 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_statfs, 3.7.0)
  139 int
  140 pub_glfs_h_statfs(struct glfs *fs, struct glfs_object *object,
  141                   struct statvfs *statvfs)
  142 {
  143     int ret = -1;
  144     xlator_t *subvol = NULL;
  145     inode_t *inode = NULL;
  146     loc_t loc = {
  147         0,
  148     };
  149 
  150     DECLARE_OLD_THIS;
  151 
  152     /* validate in args */
  153     if ((fs == NULL) || (object == NULL || statvfs == NULL)) {
  154         errno = EINVAL;
  155         return -1;
  156     }
  157 
  158     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  159 
  160     /* get the active volume */
  161     subvol = glfs_active_subvol(fs);
  162     if (!subvol) {
  163         ret = -1;
  164         errno = EIO;
  165         goto out;
  166     }
  167 
  168     /* get/refresh the in arg objects inode in correlation to the xlator */
  169     inode = glfs_resolve_inode(fs, subvol, object);
  170     if (!inode) {
  171         errno = ESTALE;
  172         goto out;
  173     }
  174 
  175     /* populate loc */
  176     GLFS_LOC_FILL_INODE(inode, loc, out);
  177 
  178     /* fop/op */
  179     ret = syncop_statfs(subvol, &loc, statvfs, NULL, NULL);
  180     DECODE_SYNCOP_ERR(ret);
  181 
  182     loc_wipe(&loc);
  183 
  184 out:
  185     if (inode)
  186         inode_unref(inode);
  187 
  188     glfs_subvol_done(fs, subvol);
  189 
  190     __GLFS_EXIT_FS;
  191 
  192 invalid_fs:
  193     return ret;
  194 }
  195 
  196 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_stat, 3.4.2)
  197 int
  198 pub_glfs_h_stat(struct glfs *fs, struct glfs_object *object, struct stat *stat)
  199 {
  200     int ret = -1;
  201     xlator_t *subvol = NULL;
  202     inode_t *inode = NULL;
  203     loc_t loc = {
  204         0,
  205     };
  206     struct iatt iatt = {
  207         0,
  208     };
  209 
  210     DECLARE_OLD_THIS;
  211 
  212     /* validate in args */
  213     if ((fs == NULL) || (object == NULL)) {
  214         errno = EINVAL;
  215         return -1;
  216     }
  217 
  218     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  219 
  220     /* get the active volume */
  221     subvol = glfs_active_subvol(fs);
  222     if (!subvol) {
  223         ret = -1;
  224         errno = EIO;
  225         goto out;
  226     }
  227 
  228     /* get/refresh the in arg objects inode in correlation to the xlator */
  229     inode = glfs_resolve_inode(fs, subvol, object);
  230     if (!inode) {
  231         errno = ESTALE;
  232         goto out;
  233     }
  234 
  235     /* populate loc */
  236     GLFS_LOC_FILL_INODE(inode, loc, out);
  237 
  238     /* fop/op */
  239     ret = syncop_stat(subvol, &loc, &iatt, NULL, NULL);
  240     DECODE_SYNCOP_ERR(ret);
  241 
  242     /* populate out args */
  243     if (!ret && stat) {
  244         glfs_iatt_to_stat(fs, &iatt, stat);
  245     }
  246 out:
  247     loc_wipe(&loc);
  248 
  249     if (inode)
  250         inode_unref(inode);
  251 
  252     glfs_subvol_done(fs, subvol);
  253 
  254     __GLFS_EXIT_FS;
  255 
  256 invalid_fs:
  257     return ret;
  258 }
  259 
  260 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getattrs, 3.4.2)
  261 int
  262 pub_glfs_h_getattrs(struct glfs *fs, struct glfs_object *object,
  263                     struct stat *stat)
  264 {
  265     int ret = -1;
  266     xlator_t *subvol = NULL;
  267     inode_t *inode = NULL;
  268     struct iatt iatt = {
  269         0,
  270     };
  271 
  272     /* validate in args */
  273     if ((fs == NULL) || (object == NULL)) {
  274         errno = EINVAL;
  275         return -1;
  276     }
  277 
  278     DECLARE_OLD_THIS;
  279     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  280 
  281     /* get the active volume */
  282     subvol = glfs_active_subvol(fs);
  283     if (!subvol) {
  284         ret = -1;
  285         errno = EIO;
  286         goto out;
  287     }
  288 
  289     /* get/refresh the in arg objects inode in correlation to the xlator */
  290     inode = glfs_resolve_inode(fs, subvol, object);
  291     if (!inode) {
  292         ret = 0;
  293         errno = ESTALE;
  294         goto out;
  295     }
  296 
  297     /* fop/op */
  298     ret = glfs_resolve_base(fs, subvol, inode, &iatt);
  299 
  300     /* populate out args */
  301     if (!ret && stat) {
  302         glfs_iatt_to_stat(fs, &iatt, stat);
  303     }
  304 
  305 out:
  306     if (inode)
  307         inode_unref(inode);
  308 
  309     glfs_subvol_done(fs, subvol);
  310 
  311     __GLFS_EXIT_FS;
  312 
  313 invalid_fs:
  314     return ret;
  315 }
  316 
  317 int
  318 glfs_h_getxattrs_common(struct glfs *fs, struct glfs_object *object,
  319                         dict_t **xattr, const char *name,
  320                         gf_boolean_t is_listxattr)
  321 {
  322     int ret = 0;
  323     xlator_t *subvol = NULL;
  324     inode_t *inode = NULL;
  325     loc_t loc = {
  326         0,
  327     };
  328 
  329     /* validate in args */
  330     if ((fs == NULL) || (object == NULL)) {
  331         errno = EINVAL;
  332         return -1;
  333     }
  334 
  335     if (!is_listxattr) {
  336         if (!name || *name == '\0') {
  337             errno = EINVAL;
  338             return -1;
  339         }
  340 
  341         if (strlen(name) > GF_XATTR_NAME_MAX) {
  342             errno = ENAMETOOLONG;
  343             return -1;
  344         }
  345     }
  346     /* get the active volume */
  347     subvol = glfs_active_subvol(fs);
  348     if (!subvol) {
  349         ret = -1;
  350         errno = EIO;
  351         goto out;
  352     }
  353 
  354     /* get/refresh the in arg objects inode in correlation to the xlator */
  355     inode = glfs_resolve_inode(fs, subvol, object);
  356     if (!inode) {
  357         errno = ESTALE;
  358         goto out;
  359     }
  360 
  361     /* populate loc */
  362     GLFS_LOC_FILL_INODE(inode, loc, out);
  363 
  364     ret = syncop_getxattr(subvol, &loc, xattr, name, NULL, NULL);
  365     DECODE_SYNCOP_ERR(ret);
  366 
  367 out:
  368     loc_wipe(&loc);
  369 
  370     if (inode)
  371         inode_unref(inode);
  372 
  373     glfs_subvol_done(fs, subvol);
  374 
  375     return ret;
  376 }
  377 
  378 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getxattrs, 3.5.1)
  379 int
  380 pub_glfs_h_getxattrs(struct glfs *fs, struct glfs_object *object,
  381                      const char *name, void *value, size_t size)
  382 {
  383     int ret = -1;
  384     dict_t *xattr = NULL;
  385 
  386     /* validate in args */
  387     if ((fs == NULL) || (object == NULL)) {
  388         errno = EINVAL;
  389         return -1;
  390     }
  391 
  392     DECLARE_OLD_THIS;
  393     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  394 
  395     ret = glfs_h_getxattrs_common(fs, object, &xattr, name, (name == NULL));
  396     if (ret)
  397         goto out;
  398 
  399     /* If @name is NULL, means get all the xattrs (i.e listxattr). */
  400     if (name)
  401         ret = glfs_getxattr_process(value, size, xattr, name);
  402     else
  403         ret = glfs_listxattr_process(value, size, xattr);
  404 
  405 out:
  406     if (xattr)
  407         dict_unref(xattr);
  408 
  409     __GLFS_EXIT_FS;
  410 
  411 invalid_fs:
  412     return ret;
  413 }
  414 
  415 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setattrs, 3.4.2)
  416 int
  417 pub_glfs_h_setattrs(struct glfs *fs, struct glfs_object *object,
  418                     struct stat *stat, int valid)
  419 {
  420     int ret = -1;
  421     xlator_t *subvol = NULL;
  422     inode_t *inode = NULL;
  423     loc_t loc = {
  424         0,
  425     };
  426     struct iatt iatt = {
  427         0,
  428     };
  429     int glvalid = 0;
  430 
  431     /* validate in args */
  432     if ((fs == NULL) || (object == NULL) || (stat == NULL)) {
  433         errno = EINVAL;
  434         return -1;
  435     }
  436 
  437     DECLARE_OLD_THIS;
  438     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  439 
  440     /* get the active volume */
  441     subvol = glfs_active_subvol(fs);
  442     if (!subvol) {
  443         ret = -1;
  444         errno = EIO;
  445         goto out;
  446     }
  447 
  448     /* get/refresh the in arg objects inode in correlation to the xlator */
  449     inode = glfs_resolve_inode(fs, subvol, object);
  450     if (!inode) {
  451         errno = ESTALE;
  452         goto out;
  453     }
  454 
  455     /* map valid masks from in args */
  456     glfs_iatt_from_stat(stat, valid, &iatt, &glvalid);
  457 
  458     /* populate loc */
  459     GLFS_LOC_FILL_INODE(inode, loc, out);
  460 
  461     /* fop/op */
  462     ret = syncop_setattr(subvol, &loc, &iatt, glvalid, 0, 0, NULL, NULL);
  463     DECODE_SYNCOP_ERR(ret);
  464 out:
  465     loc_wipe(&loc);
  466 
  467     if (inode)
  468         inode_unref(inode);
  469 
  470     glfs_subvol_done(fs, subvol);
  471 
  472     __GLFS_EXIT_FS;
  473 
  474 invalid_fs:
  475     return ret;
  476 }
  477 
  478 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setxattrs, 3.5.0)
  479 int
  480 pub_glfs_h_setxattrs(struct glfs *fs, struct glfs_object *object,
  481                      const char *name, const void *value, size_t size,
  482                      int flags)
  483 {
  484     int ret = -1;
  485     xlator_t *subvol = NULL;
  486     inode_t *inode = NULL;
  487     loc_t loc = {
  488         0,
  489     };
  490     dict_t *xattr = NULL;
  491     void *value_cp = NULL;
  492 
  493     /* validate in args */
  494     if ((fs == NULL) || (object == NULL) || (name == NULL) || (value == NULL)) {
  495         errno = EINVAL;
  496         return -1;
  497     }
  498 
  499     if (!name || *name == '\0') {
  500         errno = EINVAL;
  501         return -1;
  502     }
  503 
  504     if (strlen(name) > GF_XATTR_NAME_MAX) {
  505         errno = ENAMETOOLONG;
  506         return -1;
  507     }
  508 
  509     DECLARE_OLD_THIS;
  510     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  511 
  512     /* get the active volume */
  513     subvol = glfs_active_subvol(fs);
  514     if (!subvol) {
  515         ret = -1;
  516         errno = EIO;
  517         goto out;
  518     }
  519 
  520     /* get/refresh the in arg objects inode in correlation to the xlator */
  521     inode = glfs_resolve_inode(fs, subvol, object);
  522     if (!inode) {
  523         errno = ESTALE;
  524         goto out;
  525     }
  526 
  527     value_cp = gf_memdup(value, size);
  528     GF_CHECK_ALLOC_AND_LOG(subvol->name, value_cp, ret,
  529                            "Failed to"
  530                            " duplicate setxattr value",
  531                            out);
  532 
  533     xattr = dict_for_key_value(name, value_cp, size, _gf_false);
  534     if (!xattr) {
  535         GF_FREE(value_cp);
  536         ret = -1;
  537         errno = ENOMEM;
  538         goto out;
  539     }
  540 
  541     /* populate loc */
  542     GLFS_LOC_FILL_INODE(inode, loc, out);
  543 
  544     /* fop/op */
  545     ret = syncop_setxattr(subvol, &loc, xattr, flags, NULL, NULL);
  546     DECODE_SYNCOP_ERR(ret);
  547 
  548 out:
  549     loc_wipe(&loc);
  550 
  551     if (inode)
  552         inode_unref(inode);
  553 
  554     if (xattr)
  555         dict_unref(xattr);
  556 
  557     glfs_subvol_done(fs, subvol);
  558 
  559     __GLFS_EXIT_FS;
  560 
  561 invalid_fs:
  562     return ret;
  563 }
  564 
  565 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_removexattrs, 3.5.1)
  566 int
  567 pub_glfs_h_removexattrs(struct glfs *fs, struct glfs_object *object,
  568                         const char *name)
  569 {
  570     int ret = -1;
  571     xlator_t *subvol = NULL;
  572     inode_t *inode = NULL;
  573     loc_t loc = {
  574         0,
  575     };
  576 
  577     /* validate in args */
  578     if ((fs == NULL) || (object == NULL) || (name == NULL)) {
  579         errno = EINVAL;
  580         return -1;
  581     }
  582 
  583     DECLARE_OLD_THIS;
  584     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  585 
  586     /* get the active volume */
  587     subvol = glfs_active_subvol(fs);
  588     if (!subvol) {
  589         ret = -1;
  590         errno = EIO;
  591         goto out;
  592     }
  593 
  594     /* get/refresh the in arg objects inode in correlation to the xlator */
  595     inode = glfs_resolve_inode(fs, subvol, object);
  596     if (!inode) {
  597         errno = ESTALE;
  598         goto out;
  599     }
  600 
  601     /* populate loc */
  602     GLFS_LOC_FILL_INODE(inode, loc, out);
  603 
  604     /* fop/op */
  605     ret = syncop_removexattr(subvol, &loc, name, NULL, NULL);
  606     DECODE_SYNCOP_ERR(ret);
  607 
  608 out:
  609     loc_wipe(&loc);
  610 
  611     if (inode)
  612         inode_unref(inode);
  613 
  614     glfs_subvol_done(fs, subvol);
  615 
  616     __GLFS_EXIT_FS;
  617 
  618 invalid_fs:
  619     return ret;
  620 }
  621 
  622 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_open, 3.4.2)
  623 struct glfs_fd *
  624 pub_glfs_h_open(struct glfs *fs, struct glfs_object *object, int flags)
  625 {
  626     int ret = -1;
  627     struct glfs_fd *glfd = NULL;
  628     xlator_t *subvol = NULL;
  629     inode_t *inode = NULL;
  630     loc_t loc = {
  631         0,
  632     };
  633     dict_t *fop_attr = NULL;
  634 
  635     /* validate in args */
  636     if ((fs == NULL) || (object == NULL)) {
  637         errno = EINVAL;
  638         return NULL;
  639     }
  640 
  641     DECLARE_OLD_THIS;
  642     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  643 
  644     /* get the active volume */
  645     subvol = glfs_active_subvol(fs);
  646     if (!subvol) {
  647         errno = EIO;
  648         goto out;
  649     }
  650 
  651     /* get/refresh the in arg objects inode in correlation to the xlator */
  652     inode = glfs_resolve_inode(fs, subvol, object);
  653     if (!inode) {
  654         errno = ESTALE;
  655         goto out;
  656     }
  657 
  658     /* check types to open */
  659     if (IA_ISDIR(inode->ia_type)) {
  660         ret = -1;
  661         errno = EISDIR;
  662         goto out;
  663     }
  664 
  665     if (!IA_ISREG(inode->ia_type)) {
  666         ret = -1;
  667         errno = EINVAL;
  668         goto out;
  669     }
  670 
  671     glfd = glfs_fd_new(fs);
  672     if (!glfd) {
  673         ret = -1;
  674         errno = ENOMEM;
  675         goto out;
  676     }
  677 
  678     glfd->fd = fd_create(inode, getpid());
  679     if (!glfd->fd) {
  680         ret = -1;
  681         errno = ENOMEM;
  682         goto out;
  683     }
  684     glfd->fd->flags = flags;
  685 
  686     /* populate loc */
  687     GLFS_LOC_FILL_INODE(inode, loc, out);
  688 
  689     /* fop/op */
  690     ret = get_fop_attr_thrd_key(&fop_attr);
  691     if (ret)
  692         gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
  693 
  694     ret = syncop_open(subvol, &loc, flags, glfd->fd, fop_attr, NULL);
  695     DECODE_SYNCOP_ERR(ret);
  696 
  697     glfd->fd->flags = flags;
  698 
  699 out:
  700     loc_wipe(&loc);
  701 
  702     if (inode)
  703         inode_unref(inode);
  704     if (fop_attr)
  705         dict_unref(fop_attr);
  706 
  707     if (ret && glfd) {
  708         GF_REF_PUT(glfd);
  709         glfd = NULL;
  710     } else if (glfd) {
  711         glfd_set_state_bind(glfd);
  712     }
  713 
  714     glfs_subvol_done(fs, subvol);
  715 
  716     __GLFS_EXIT_FS;
  717 
  718 invalid_fs:
  719     return glfd;
  720 }
  721 
  722 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat, 3.4.2)
  723 struct glfs_object *
  724 pub_glfs_h_creat(struct glfs *fs, struct glfs_object *parent, const char *path,
  725                  int flags, mode_t mode, struct stat *stat)
  726 {
  727     int ret = -1;
  728     fd_t *fd = NULL;
  729     xlator_t *subvol = NULL;
  730     inode_t *inode = NULL;
  731     loc_t loc = {
  732         0,
  733     };
  734     struct iatt iatt = {
  735         0,
  736     };
  737     uuid_t gfid;
  738     dict_t *xattr_req = NULL;
  739     struct glfs_object *object = NULL;
  740 
  741     /* validate in args */
  742     if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
  743         errno = EINVAL;
  744         return NULL;
  745     }
  746 
  747     DECLARE_OLD_THIS;
  748     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  749 
  750     /* get the active volume */
  751     subvol = glfs_active_subvol(fs);
  752     if (!subvol) {
  753         ret = -1;
  754         errno = EIO;
  755         goto out;
  756     }
  757 
  758     /* get/refresh the in arg objects inode in correlation to the xlator */
  759     inode = glfs_resolve_inode(fs, subvol, parent);
  760     if (!inode) {
  761         ret = -1;
  762         errno = ESTALE;
  763         goto out;
  764     }
  765 
  766     xattr_req = dict_new();
  767     if (!xattr_req) {
  768         ret = -1;
  769         errno = ENOMEM;
  770         goto out;
  771     }
  772 
  773     gf_uuid_generate(gfid);
  774     ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
  775     if (ret) {
  776         ret = -1;
  777         errno = ENOMEM;
  778         goto out;
  779     }
  780 
  781     GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
  782 
  783     fd = fd_create(loc.inode, getpid());
  784     if (!fd) {
  785         ret = -1;
  786         errno = ENOMEM;
  787         goto out;
  788     }
  789     fd->flags = flags;
  790 
  791     /* fop/op */
  792     ret = syncop_create(subvol, &loc, flags, mode, fd, &iatt, xattr_req, NULL);
  793     DECODE_SYNCOP_ERR(ret);
  794 
  795     /* populate out args */
  796     if (ret == 0) {
  797         ret = glfs_loc_link(&loc, &iatt);
  798         if (ret != 0) {
  799             goto out;
  800         }
  801 
  802         if (stat)
  803             glfs_iatt_to_stat(fs, &iatt, stat);
  804 
  805         ret = glfs_create_object(&loc, &object);
  806     }
  807 
  808 out:
  809     if (ret && object != NULL) {
  810         /* Release the held reference */
  811         glfs_h_close(object);
  812         object = NULL;
  813     }
  814 
  815     loc_wipe(&loc);
  816 
  817     if (inode)
  818         inode_unref(inode);
  819 
  820     if (xattr_req)
  821         dict_unref(xattr_req);
  822 
  823     if (fd)
  824         fd_unref(fd);
  825 
  826     glfs_subvol_done(fs, subvol);
  827 
  828     __GLFS_EXIT_FS;
  829 
  830 invalid_fs:
  831     return object;
  832 }
  833 
  834 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat_open, 6.6)
  835 struct glfs_object *
  836 pub_glfs_h_creat_open(struct glfs *fs, struct glfs_object *parent,
  837                       const char *path, int flags, mode_t mode,
  838                       struct stat *stat, struct glfs_fd **out_fd)
  839 {
  840     int ret = -1;
  841     struct glfs_fd *glfd = NULL;
  842     xlator_t *subvol = NULL;
  843     inode_t *inode = NULL;
  844     loc_t loc = {
  845         0,
  846     };
  847     struct iatt iatt = {
  848         0,
  849     };
  850     uuid_t gfid;
  851     dict_t *xattr_req = NULL;
  852     struct glfs_object *object = NULL;
  853     dict_t *fop_attr = NULL;
  854 
  855     /* validate in args */
  856     if ((fs == NULL) || (parent == NULL) || (path == NULL) ||
  857         (out_fd == NULL)) {
  858         errno = EINVAL;
  859         return NULL;
  860     }
  861 
  862     DECLARE_OLD_THIS;
  863     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  864 
  865     /* get the active volume */
  866     subvol = glfs_active_subvol(fs);
  867     if (!subvol) {
  868         ret = -1;
  869         goto out;
  870     }
  871 
  872     /* get/refresh the in arg objects inode in correlation to the xlator */
  873     inode = glfs_resolve_inode(fs, subvol, parent);
  874     if (!inode) {
  875         ret = -1;
  876         goto out;
  877     }
  878 
  879     xattr_req = dict_new();
  880     if (!xattr_req) {
  881         ret = -1;
  882         errno = ENOMEM;
  883         goto out;
  884     }
  885 
  886     gf_uuid_generate(gfid);
  887     ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
  888     if (ret) {
  889         ret = -1;
  890         errno = ENOMEM;
  891         goto out;
  892     }
  893 
  894     GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
  895 
  896     glfd = glfs_fd_new(fs);
  897     if (!glfd) {
  898         ret = -1;
  899         errno = ENOMEM;
  900         goto out;
  901     }
  902 
  903     glfd->fd = fd_create(loc.inode, getpid());
  904     if (!glfd->fd) {
  905         ret = -1;
  906         errno = ENOMEM;
  907         goto out;
  908     }
  909     glfd->fd->flags = flags;
  910 
  911     ret = get_fop_attr_thrd_key(&fop_attr);
  912     if (ret)
  913         gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
  914 
  915     /* fop/op */
  916     ret = syncop_create(subvol, &loc, flags, mode, glfd->fd, &iatt, xattr_req,
  917                         NULL);
  918     DECODE_SYNCOP_ERR(ret);
  919 
  920     /* populate out args */
  921     if (ret == 0) {
  922         glfd->fd->flags = flags;
  923 
  924         ret = glfs_loc_link(&loc, &iatt);
  925         if (ret != 0) {
  926             goto out;
  927         }
  928 
  929         if (stat)
  930             glfs_iatt_to_stat(fs, &iatt, stat);
  931 
  932         ret = glfs_create_object(&loc, &object);
  933     }
  934 
  935 out:
  936     if (ret && object != NULL) {
  937         /* Release the held reference */
  938         glfs_h_close(object);
  939         object = NULL;
  940     }
  941 
  942     loc_wipe(&loc);
  943 
  944     if (inode)
  945         inode_unref(inode);
  946 
  947     if (fop_attr)
  948         dict_unref(fop_attr);
  949 
  950     if (xattr_req)
  951         dict_unref(xattr_req);
  952 
  953     if (ret && glfd) {
  954         GF_REF_PUT(glfd);
  955     } else if (glfd) {
  956         glfd_set_state_bind(glfd);
  957         *out_fd = glfd;
  958     }
  959 
  960     glfs_subvol_done(fs, subvol);
  961 
  962     __GLFS_EXIT_FS;
  963 
  964 invalid_fs:
  965     return object;
  966 }
  967 
  968 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mkdir, 3.4.2)
  969 struct glfs_object *
  970 pub_glfs_h_mkdir(struct glfs *fs, struct glfs_object *parent, const char *path,
  971                  mode_t mode, struct stat *stat)
  972 {
  973     int ret = -1;
  974     xlator_t *subvol = NULL;
  975     inode_t *inode = NULL;
  976     loc_t loc = {
  977         0,
  978     };
  979     struct iatt iatt = {
  980         0,
  981     };
  982     uuid_t gfid;
  983     dict_t *xattr_req = NULL;
  984     struct glfs_object *object = NULL;
  985 
  986     /* validate in args */
  987     if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
  988         errno = EINVAL;
  989         return NULL;
  990     }
  991 
  992     DECLARE_OLD_THIS;
  993     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
  994 
  995     /* get the active volume */
  996     subvol = glfs_active_subvol(fs);
  997     if (!subvol) {
  998         ret = -1;
  999         errno = EIO;
 1000         goto out;
 1001     }
 1002 
 1003     /* get/refresh the in arg objects inode in correlation to the xlator */
 1004     inode = glfs_resolve_inode(fs, subvol, parent);
 1005     if (!inode) {
 1006         errno = ESTALE;
 1007         goto out;
 1008     }
 1009 
 1010     xattr_req = dict_new();
 1011     if (!xattr_req) {
 1012         ret = -1;
 1013         errno = ENOMEM;
 1014         goto out;
 1015     }
 1016 
 1017     gf_uuid_generate(gfid);
 1018     ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
 1019     if (ret) {
 1020         ret = -1;
 1021         errno = ENOMEM;
 1022         goto out;
 1023     }
 1024 
 1025     GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
 1026 
 1027     /* fop/op */
 1028     ret = syncop_mkdir(subvol, &loc, mode, &iatt, xattr_req, NULL);
 1029     DECODE_SYNCOP_ERR(ret);
 1030 
 1031     /* populate out args */
 1032     if (ret == 0) {
 1033         ret = glfs_loc_link(&loc, &iatt);
 1034         if (ret != 0) {
 1035             goto out;
 1036         }
 1037 
 1038         if (stat)
 1039             glfs_iatt_to_stat(fs, &iatt, stat);
 1040 
 1041         ret = glfs_create_object(&loc, &object);
 1042     }
 1043 
 1044 out:
 1045     if (ret && object != NULL) {
 1046         glfs_h_close(object);
 1047         object = NULL;
 1048     }
 1049 
 1050     loc_wipe(&loc);
 1051 
 1052     if (inode)
 1053         inode_unref(inode);
 1054 
 1055     if (xattr_req)
 1056         dict_unref(xattr_req);
 1057 
 1058     glfs_subvol_done(fs, subvol);
 1059 
 1060     __GLFS_EXIT_FS;
 1061 
 1062 invalid_fs:
 1063     return object;
 1064 }
 1065 
 1066 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mknod, 3.4.2)
 1067 struct glfs_object *
 1068 pub_glfs_h_mknod(struct glfs *fs, struct glfs_object *parent, const char *path,
 1069                  mode_t mode, dev_t dev, struct stat *stat)
 1070 {
 1071     int ret = -1;
 1072     xlator_t *subvol = NULL;
 1073     inode_t *inode = NULL;
 1074     loc_t loc = {
 1075         0,
 1076     };
 1077     struct iatt iatt = {
 1078         0,
 1079     };
 1080     uuid_t gfid;
 1081     dict_t *xattr_req = NULL;
 1082     struct glfs_object *object = NULL;
 1083 
 1084     /* validate in args */
 1085     if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
 1086         errno = EINVAL;
 1087         return NULL;
 1088     }
 1089 
 1090     DECLARE_OLD_THIS;
 1091     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1092 
 1093     /* get the active volume */
 1094     subvol = glfs_active_subvol(fs);
 1095     if (!subvol) {
 1096         ret = -1;
 1097         errno = EIO;
 1098         goto out;
 1099     }
 1100 
 1101     /* get/refresh the in arg objects inode in correlation to the xlator */
 1102     inode = glfs_resolve_inode(fs, subvol, parent);
 1103     if (!inode) {
 1104         errno = ESTALE;
 1105         goto out;
 1106     }
 1107 
 1108     xattr_req = dict_new();
 1109     if (!xattr_req) {
 1110         ret = -1;
 1111         errno = ENOMEM;
 1112         goto out;
 1113     }
 1114 
 1115     gf_uuid_generate(gfid);
 1116     ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
 1117     if (ret) {
 1118         ret = -1;
 1119         errno = ENOMEM;
 1120         goto out;
 1121     }
 1122 
 1123     GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
 1124 
 1125     /* fop/op */
 1126     ret = syncop_mknod(subvol, &loc, mode, dev, &iatt, xattr_req, NULL);
 1127     DECODE_SYNCOP_ERR(ret);
 1128 
 1129     /* populate out args */
 1130     if (ret == 0) {
 1131         ret = glfs_loc_link(&loc, &iatt);
 1132         if (ret != 0) {
 1133             goto out;
 1134         }
 1135 
 1136         if (stat)
 1137             glfs_iatt_to_stat(fs, &iatt, stat);
 1138 
 1139         ret = glfs_create_object(&loc, &object);
 1140     }
 1141 out:
 1142     if (ret && object != NULL) {
 1143         glfs_h_close(object);
 1144         object = NULL;
 1145     }
 1146 
 1147     loc_wipe(&loc);
 1148 
 1149     if (inode)
 1150         inode_unref(inode);
 1151 
 1152     if (xattr_req)
 1153         dict_unref(xattr_req);
 1154 
 1155     glfs_subvol_done(fs, subvol);
 1156 
 1157     __GLFS_EXIT_FS;
 1158 
 1159 invalid_fs:
 1160     return object;
 1161 }
 1162 
 1163 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_unlink, 3.4.2)
 1164 int
 1165 pub_glfs_h_unlink(struct glfs *fs, struct glfs_object *parent, const char *path)
 1166 {
 1167     int ret = -1;
 1168     xlator_t *subvol = NULL;
 1169     inode_t *inode = NULL;
 1170     loc_t loc = {
 1171         0,
 1172     };
 1173 
 1174     /* validate in args */
 1175     if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
 1176         errno = EINVAL;
 1177         return -1;
 1178     }
 1179 
 1180     DECLARE_OLD_THIS;
 1181     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1182 
 1183     /* get the active volume */
 1184     subvol = glfs_active_subvol(fs);
 1185     if (!subvol) {
 1186         ret = -1;
 1187         errno = EIO;
 1188         goto out;
 1189     }
 1190 
 1191     /* get/refresh the in arg objects inode in correlation to the xlator */
 1192     inode = glfs_resolve_inode(fs, subvol, parent);
 1193     if (!inode) {
 1194         errno = ESTALE;
 1195         goto out;
 1196     }
 1197 
 1198     ret = glfs_resolve_at(fs, subvol, inode, path, &loc, NULL, 0, 0);
 1199     if (ret != 0) {
 1200         goto out;
 1201     }
 1202 
 1203     if (!IA_ISDIR(loc.inode->ia_type)) {
 1204         ret = syncop_unlink(subvol, &loc, NULL, NULL);
 1205         DECODE_SYNCOP_ERR(ret);
 1206         if (ret != 0) {
 1207             goto out;
 1208         }
 1209     } else {
 1210         ret = syncop_rmdir(subvol, &loc, 0, NULL, NULL);
 1211         DECODE_SYNCOP_ERR(ret);
 1212         if (ret != 0) {
 1213             goto out;
 1214         }
 1215     }
 1216 
 1217     if (ret == 0)
 1218         ret = glfs_loc_unlink(&loc);
 1219 
 1220 out:
 1221     loc_wipe(&loc);
 1222 
 1223     if (inode)
 1224         inode_unref(inode);
 1225 
 1226     glfs_subvol_done(fs, subvol);
 1227 
 1228     __GLFS_EXIT_FS;
 1229 
 1230 invalid_fs:
 1231     return ret;
 1232 }
 1233 
 1234 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_opendir, 3.4.2)
 1235 struct glfs_fd *
 1236 pub_glfs_h_opendir(struct glfs *fs, struct glfs_object *object)
 1237 {
 1238     int ret = -1;
 1239     struct glfs_fd *glfd = NULL;
 1240     xlator_t *subvol = NULL;
 1241     inode_t *inode = NULL;
 1242     loc_t loc = {
 1243         0,
 1244     };
 1245 
 1246     /* validate in args */
 1247     if ((fs == NULL) || (object == NULL)) {
 1248         errno = EINVAL;
 1249         return NULL;
 1250     }
 1251 
 1252     DECLARE_OLD_THIS;
 1253     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1254 
 1255     /* get the active volume */
 1256     subvol = glfs_active_subvol(fs);
 1257     if (!subvol) {
 1258         ret = -1;
 1259         errno = EIO;
 1260         goto out;
 1261     }
 1262 
 1263     /* get/refresh the in arg objects inode in correlation to the xlator */
 1264     inode = glfs_resolve_inode(fs, subvol, object);
 1265     if (!inode) {
 1266         errno = ESTALE;
 1267         goto out;
 1268     }
 1269 
 1270     if (!IA_ISDIR(inode->ia_type)) {
 1271         ret = -1;
 1272         errno = ENOTDIR;
 1273         goto out;
 1274     }
 1275 
 1276     glfd = glfs_fd_new(fs);
 1277     if (!glfd)
 1278         goto out;
 1279 
 1280     INIT_LIST_HEAD(&glfd->entries);
 1281 
 1282     glfd->fd = fd_create(inode, getpid());
 1283     if (!glfd->fd) {
 1284         ret = -1;
 1285         errno = ENOMEM;
 1286         goto out;
 1287     }
 1288 
 1289     GLFS_LOC_FILL_INODE(inode, loc, out);
 1290 
 1291     /* fop/op */
 1292     ret = syncop_opendir(subvol, &loc, glfd->fd, NULL, NULL);
 1293     DECODE_SYNCOP_ERR(ret);
 1294 
 1295 out:
 1296     loc_wipe(&loc);
 1297 
 1298     if (inode)
 1299         inode_unref(inode);
 1300 
 1301     if (ret && glfd) {
 1302         GF_REF_PUT(glfd);
 1303         glfd = NULL;
 1304     } else if (glfd) {
 1305         glfd_set_state_bind(glfd);
 1306     }
 1307 
 1308     glfs_subvol_done(fs, subvol);
 1309 
 1310     __GLFS_EXIT_FS;
 1311 
 1312 invalid_fs:
 1313     return glfd;
 1314 }
 1315 
 1316 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_access, 3.6.0)
 1317 int
 1318 pub_glfs_h_access(struct glfs *fs, struct glfs_object *object, int mask)
 1319 {
 1320     int ret = -1;
 1321     xlator_t *subvol = NULL;
 1322     inode_t *inode = NULL;
 1323     loc_t loc = {
 1324         0,
 1325     };
 1326 
 1327     DECLARE_OLD_THIS;
 1328 
 1329     /* validate in args */
 1330     if ((fs == NULL) || (object == NULL)) {
 1331         errno = EINVAL;
 1332         return ret;
 1333     }
 1334 
 1335     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1336 
 1337     /* get the active volume */
 1338     subvol = glfs_active_subvol(fs);
 1339     if (!subvol) {
 1340         ret = -1;
 1341         errno = EIO;
 1342         goto out;
 1343     }
 1344 
 1345     /* get/refresh the in arg objects inode in correlation to the xlator */
 1346     inode = glfs_resolve_inode(fs, subvol, object);
 1347     if (!inode) {
 1348         errno = ESTALE;
 1349         goto out;
 1350     }
 1351 
 1352     GLFS_LOC_FILL_INODE(inode, loc, out);
 1353 
 1354     /* fop/op */
 1355 
 1356     ret = syncop_access(subvol, &loc, mask, NULL, NULL);
 1357     DECODE_SYNCOP_ERR(ret);
 1358 
 1359 out:
 1360     loc_wipe(&loc);
 1361 
 1362     if (inode)
 1363         inode_unref(inode);
 1364 
 1365     glfs_subvol_done(fs, subvol);
 1366 
 1367     __GLFS_EXIT_FS;
 1368 
 1369 invalid_fs:
 1370     return ret;
 1371 }
 1372 
 1373 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_extract_handle, 3.4.2)
 1374 ssize_t
 1375 pub_glfs_h_extract_handle(struct glfs_object *object, unsigned char *handle,
 1376                           int len)
 1377 {
 1378     ssize_t ret = -1;
 1379 
 1380     /* validate in args */
 1381     if (object == NULL) {
 1382         errno = EINVAL;
 1383         goto out;
 1384     }
 1385 
 1386     if (!handle || !len) {
 1387         ret = GFAPI_HANDLE_LENGTH;
 1388         goto out;
 1389     }
 1390 
 1391     if (len < GFAPI_HANDLE_LENGTH) {
 1392         errno = ERANGE;
 1393         goto out;
 1394     }
 1395 
 1396     memcpy(handle, object->gfid, GFAPI_HANDLE_LENGTH);
 1397 
 1398     ret = GFAPI_HANDLE_LENGTH;
 1399 
 1400 out:
 1401     return ret;
 1402 }
 1403 
 1404 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_create_from_handle, 3.4.2)
 1405 struct glfs_object *
 1406 pub_glfs_h_create_from_handle(struct glfs *fs, unsigned char *handle, int len,
 1407                               struct stat *stat)
 1408 {
 1409     loc_t loc = {
 1410         0,
 1411     };
 1412     int ret = -1;
 1413     struct iatt iatt = {
 1414         0,
 1415     };
 1416     inode_t *newinode = NULL;
 1417     xlator_t *subvol = NULL;
 1418     struct glfs_object *object = NULL;
 1419     uint64_t ctx_value = LOOKUP_NOT_NEEDED;
 1420     gf_boolean_t lookup_needed = _gf_false;
 1421 
 1422     /* validate in args */
 1423     if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) {
 1424         errno = EINVAL;
 1425         return NULL;
 1426     }
 1427 
 1428     DECLARE_OLD_THIS;
 1429     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1430 
 1431     /* get the active volume */
 1432     subvol = glfs_active_subvol(fs);
 1433     if (!subvol) {
 1434         errno = EIO;
 1435         goto out;
 1436     }
 1437 
 1438     memcpy(loc.gfid, handle, GFAPI_HANDLE_LENGTH);
 1439 
 1440     /* make sure the gfid received is valid */
 1441     GF_VALIDATE_OR_GOTO("glfs_h_create_from_handle",
 1442                         !(gf_uuid_is_null(loc.gfid)), out);
 1443 
 1444     newinode = inode_find(subvol->itable, loc.gfid);
 1445     if (newinode) {
 1446         if (!stat) /* No need of lookup */
 1447             goto found;
 1448 
 1449         lookup_needed = inode_needs_lookup(newinode, THIS);
 1450         if (lookup_needed) {
 1451             loc.inode = newinode;
 1452         } else {
 1453             /* populate loc */
 1454             GLFS_LOC_FILL_INODE(newinode, loc, fill_out);
 1455 
 1456             /* fop/op */
 1457             ret = syncop_stat(subvol, &loc, &iatt, NULL, NULL);
 1458             DECODE_SYNCOP_ERR(ret);
 1459 
 1460             if (ret) {
 1461             fill_out:
 1462                 /* Drop the reference hold in inode_find */
 1463                 inode_unref(newinode);
 1464                 goto out;
 1465             }
 1466 
 1467             glfs_iatt_to_stat(fs, &iatt, stat);
 1468             goto found;
 1469         }
 1470     } else {
 1471         loc.inode = inode_new(subvol->itable);
 1472         if (!loc.inode) {
 1473             errno = ENOMEM;
 1474             goto out;
 1475         }
 1476     }
 1477 
 1478     ret = syncop_lookup(subvol, &loc, &iatt, 0, 0, 0);
 1479     DECODE_SYNCOP_ERR(ret);
 1480     if (ret) {
 1481         gf_smsg(subvol->name, GF_LOG_WARNING, errno,
 1482                 API_MSG_INODE_REFRESH_FAILED, "gfid=%s", uuid_utoa(loc.gfid),
 1483                 "error=%s", strerror(errno), NULL);
 1484         goto out;
 1485     }
 1486 
 1487     newinode = inode_link(loc.inode, 0, 0, &iatt);
 1488     if (newinode) {
 1489         if (newinode == loc.inode) {
 1490             inode_ctx_set(newinode, THIS, &ctx_value);
 1491         }
 1492         inode_lookup(newinode);
 1493     } else {
 1494         gf_smsg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED,
 1495                 "gfid=%s", uuid_utoa(loc.gfid), NULL);
 1496         goto out;
 1497     }
 1498 
 1499     /* populate stat */
 1500     if (stat)
 1501         glfs_iatt_to_stat(fs, &iatt, stat);
 1502 
 1503 found:
 1504     object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t);
 1505     if (object == NULL) {
 1506         errno = ENOMEM;
 1507         ret = -1;
 1508         goto out;
 1509     }
 1510 
 1511     /* populate the return object */
 1512     object->inode = newinode;
 1513     gf_uuid_copy(object->gfid, object->inode->gfid);
 1514 
 1515 out:
 1516     /* TODO: Check where the inode ref is being held? */
 1517     loc_wipe(&loc);
 1518 
 1519     glfs_subvol_done(fs, subvol);
 1520 
 1521     __GLFS_EXIT_FS;
 1522 
 1523 invalid_fs:
 1524     return object;
 1525 }
 1526 
 1527 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_close, 3.4.2)
 1528 int
 1529 pub_glfs_h_close(struct glfs_object *object)
 1530 {
 1531     /* since glfs_h_* objects hold a reference to inode
 1532      * it is safe to keep lookup count to '0' */
 1533     inode_forget(object->inode, 0);
 1534     inode_unref(object->inode);
 1535     GF_FREE(object);
 1536 
 1537     return 0;
 1538 }
 1539 
 1540 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_truncate, 3.4.2)
 1541 int
 1542 pub_glfs_h_truncate(struct glfs *fs, struct glfs_object *object, off_t offset)
 1543 {
 1544     loc_t loc = {
 1545         0,
 1546     };
 1547     int ret = -1;
 1548     xlator_t *subvol = NULL;
 1549     inode_t *inode = NULL;
 1550 
 1551     DECLARE_OLD_THIS;
 1552 
 1553     /* validate in args */
 1554     if (object == NULL) {
 1555         errno = EINVAL;
 1556         return -1;
 1557     }
 1558 
 1559     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1560 
 1561     /* get the active volume */
 1562     subvol = glfs_active_subvol(fs);
 1563     if (!subvol) {
 1564         ret = -1;
 1565         errno = EIO;
 1566         goto out;
 1567     }
 1568 
 1569     /* get/refresh the in arg objects inode in correlation to the xlator */
 1570     inode = glfs_resolve_inode(fs, subvol, object);
 1571     if (!inode) {
 1572         errno = ESTALE;
 1573         goto out;
 1574     }
 1575 
 1576     GLFS_LOC_FILL_INODE(inode, loc, out);
 1577 
 1578     /* fop/op */
 1579     ret = syncop_truncate(subvol, &loc, (off_t)offset, NULL, NULL);
 1580     DECODE_SYNCOP_ERR(ret);
 1581 
 1582     /* populate out args */
 1583     if (ret == 0)
 1584         ret = glfs_loc_unlink(&loc);
 1585 
 1586 out:
 1587     loc_wipe(&loc);
 1588 
 1589     if (inode)
 1590         inode_unref(inode);
 1591 
 1592     glfs_subvol_done(fs, subvol);
 1593 
 1594     __GLFS_EXIT_FS;
 1595 
 1596 invalid_fs:
 1597     return ret;
 1598 }
 1599 
 1600 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_symlink, 3.4.2)
 1601 struct glfs_object *
 1602 pub_glfs_h_symlink(struct glfs *fs, struct glfs_object *parent,
 1603                    const char *name, const char *data, struct stat *stat)
 1604 {
 1605     int ret = -1;
 1606     xlator_t *subvol = NULL;
 1607     inode_t *inode = NULL;
 1608     loc_t loc = {
 1609         0,
 1610     };
 1611     struct iatt iatt = {
 1612         0,
 1613     };
 1614     uuid_t gfid;
 1615     dict_t *xattr_req = NULL;
 1616     struct glfs_object *object = NULL;
 1617 
 1618     DECLARE_OLD_THIS;
 1619 
 1620     /* validate in args */
 1621     if ((parent == NULL) || (name == NULL) || (data == NULL)) {
 1622         errno = EINVAL;
 1623         return NULL;
 1624     }
 1625 
 1626     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1627 
 1628     /* get the active volume */
 1629     subvol = glfs_active_subvol(fs);
 1630     if (!subvol) {
 1631         ret = -1;
 1632         errno = EIO;
 1633         goto out;
 1634     }
 1635 
 1636     /* get/refresh the in arg objects inode in correlation to the xlator */
 1637     inode = glfs_resolve_inode(fs, subvol, parent);
 1638     if (!inode) {
 1639         errno = ESTALE;
 1640         goto out;
 1641     }
 1642 
 1643     xattr_req = dict_new();
 1644     if (!xattr_req) {
 1645         ret = -1;
 1646         errno = ENOMEM;
 1647         goto out;
 1648     }
 1649 
 1650     gf_uuid_generate(gfid);
 1651     ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
 1652     if (ret) {
 1653         ret = -1;
 1654         errno = ENOMEM;
 1655         goto out;
 1656     }
 1657 
 1658     GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, name);
 1659 
 1660     /* fop/op */
 1661     ret = syncop_symlink(subvol, &loc, data, &iatt, xattr_req, NULL);
 1662     DECODE_SYNCOP_ERR(ret);
 1663 
 1664     /* populate out args */
 1665     if (ret == 0) {
 1666         ret = glfs_loc_link(&loc, &iatt);
 1667         if (ret != 0) {
 1668             goto out;
 1669         }
 1670 
 1671         if (stat)
 1672             glfs_iatt_to_stat(fs, &iatt, stat);
 1673 
 1674         ret = glfs_create_object(&loc, &object);
 1675     }
 1676 
 1677 out:
 1678     if (ret && object != NULL) {
 1679         pub_glfs_h_close(object);
 1680         object = NULL;
 1681     }
 1682 
 1683     loc_wipe(&loc);
 1684 
 1685     if (inode)
 1686         inode_unref(inode);
 1687 
 1688     if (xattr_req)
 1689         dict_unref(xattr_req);
 1690 
 1691     glfs_subvol_done(fs, subvol);
 1692 
 1693     __GLFS_EXIT_FS;
 1694 
 1695 invalid_fs:
 1696     return object;
 1697 }
 1698 
 1699 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_readlink, 3.4.2)
 1700 int
 1701 pub_glfs_h_readlink(struct glfs *fs, struct glfs_object *object, char *buf,
 1702                     size_t bufsiz)
 1703 {
 1704     loc_t loc = {
 1705         0,
 1706     };
 1707     int ret = -1;
 1708     xlator_t *subvol = NULL;
 1709     inode_t *inode = NULL;
 1710     char *linkval = NULL;
 1711 
 1712     DECLARE_OLD_THIS;
 1713 
 1714     /* validate in args */
 1715     if ((object == NULL) || (buf == NULL)) {
 1716         errno = EINVAL;
 1717         return -1;
 1718     }
 1719 
 1720     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1721 
 1722     /* get the active volume */
 1723     subvol = glfs_active_subvol(fs);
 1724     if (!subvol) {
 1725         ret = -1;
 1726         errno = EIO;
 1727         goto out;
 1728     }
 1729 
 1730     /* get/refresh the in arg objects inode in correlation to the xlator */
 1731     inode = glfs_resolve_inode(fs, subvol, object);
 1732     if (!inode) {
 1733         errno = ESTALE;
 1734         goto out;
 1735     }
 1736 
 1737     GLFS_LOC_FILL_INODE(inode, loc, out);
 1738 
 1739     /* fop/op */
 1740     ret = syncop_readlink(subvol, &loc, &linkval, bufsiz, NULL, NULL);
 1741     DECODE_SYNCOP_ERR(ret);
 1742 
 1743     /* populate out args */
 1744     if (ret > 0)
 1745         memcpy(buf, linkval, ret);
 1746 
 1747 out:
 1748     loc_wipe(&loc);
 1749 
 1750     if (inode)
 1751         inode_unref(inode);
 1752 
 1753     if (linkval)
 1754         GF_FREE(linkval);
 1755 
 1756     glfs_subvol_done(fs, subvol);
 1757 
 1758     __GLFS_EXIT_FS;
 1759 
 1760 invalid_fs:
 1761     return ret;
 1762 }
 1763 
 1764 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_link, 3.4.2)
 1765 int
 1766 pub_glfs_h_link(struct glfs *fs, struct glfs_object *linksrc,
 1767                 struct glfs_object *parent, const char *name)
 1768 {
 1769     int ret = -1;
 1770     xlator_t *subvol = NULL;
 1771     inode_t *inode = NULL;
 1772     inode_t *pinode = NULL;
 1773     loc_t oldloc = {
 1774         0,
 1775     };
 1776     loc_t newloc = {
 1777         0,
 1778     };
 1779     struct iatt iatt = {
 1780         0,
 1781     };
 1782 
 1783     DECLARE_OLD_THIS;
 1784 
 1785     /* validate in args */
 1786     if ((linksrc == NULL) || (parent == NULL) || (name == NULL)) {
 1787         errno = EINVAL;
 1788         return -1;
 1789     }
 1790 
 1791     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1792 
 1793     /* get the active volume */
 1794     subvol = glfs_active_subvol(fs);
 1795     if (!subvol) {
 1796         ret = -1;
 1797         errno = EIO;
 1798         goto out;
 1799     }
 1800 
 1801     /* get/refresh the in arg objects inode in correlation to the xlator */
 1802     inode = glfs_resolve_inode(fs, subvol, linksrc);
 1803     if (!inode) {
 1804         errno = ESTALE;
 1805         goto out;
 1806     }
 1807 
 1808     if (inode->ia_type == IA_IFDIR) {
 1809         ret = -1;
 1810         errno = EISDIR;
 1811         goto out;
 1812     }
 1813 
 1814     GLFS_LOC_FILL_INODE(inode, oldloc, out);
 1815 
 1816     /* get/refresh the in arg objects inode in correlation to the xlator */
 1817     pinode = glfs_resolve_inode(fs, subvol, parent);
 1818     if (!pinode) {
 1819         errno = ESTALE;
 1820         goto out;
 1821     }
 1822 
 1823     /* setup newloc based on parent */
 1824     newloc.parent = inode_ref(pinode);
 1825     newloc.name = name;
 1826     ret = glfs_loc_touchup(&newloc);
 1827     if (ret != 0) {
 1828         errno = EINVAL;
 1829         goto out;
 1830     }
 1831 
 1832     /* Filling the inode of the hard link to be same as that of the
 1833      * original file
 1834      */
 1835     newloc.inode = inode_ref(inode);
 1836 
 1837     /* fop/op */
 1838     ret = syncop_link(subvol, &oldloc, &newloc, &iatt, NULL, NULL);
 1839     DECODE_SYNCOP_ERR(ret);
 1840 
 1841     if (ret == 0)
 1842         ret = glfs_loc_link(&newloc, &iatt);
 1843 out:
 1844     loc_wipe(&oldloc);
 1845     loc_wipe(&newloc);
 1846 
 1847     if (inode)
 1848         inode_unref(inode);
 1849 
 1850     if (pinode)
 1851         inode_unref(pinode);
 1852 
 1853     glfs_subvol_done(fs, subvol);
 1854 
 1855     __GLFS_EXIT_FS;
 1856 
 1857 invalid_fs:
 1858     return ret;
 1859 }
 1860 
 1861 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2)
 1862 int
 1863 pub_glfs_h_rename(struct glfs *fs, struct glfs_object *olddir,
 1864                   const char *oldname, struct glfs_object *newdir,
 1865                   const char *newname)
 1866 {
 1867     int ret = -1;
 1868     xlator_t *subvol = NULL;
 1869     inode_t *oldpinode = NULL;
 1870     inode_t *newpinode = NULL;
 1871     loc_t oldloc = {
 1872         0,
 1873     };
 1874     loc_t newloc = {
 1875         0,
 1876     };
 1877     struct iatt oldiatt = {
 1878         0,
 1879     };
 1880     struct iatt newiatt = {
 1881         0,
 1882     };
 1883 
 1884     DECLARE_OLD_THIS;
 1885 
 1886     /* validate in args */
 1887     if ((olddir == NULL) || (oldname == NULL) || (newdir == NULL) ||
 1888         (newname == NULL)) {
 1889         errno = EINVAL;
 1890         return -1;
 1891     }
 1892 
 1893     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1894 
 1895     /* get the active volume */
 1896     subvol = glfs_active_subvol(fs);
 1897     if (!subvol) {
 1898         ret = -1;
 1899         errno = EIO;
 1900         goto out;
 1901     }
 1902 
 1903     /* get/refresh the in arg objects inode in correlation to the xlator */
 1904     oldpinode = glfs_resolve_inode(fs, subvol, olddir);
 1905     if (!oldpinode) {
 1906         errno = ESTALE;
 1907         goto out;
 1908     }
 1909 
 1910     ret = glfs_resolve_at(fs, subvol, oldpinode, oldname, &oldloc, &oldiatt, 0,
 1911                           0);
 1912     if (ret != 0) {
 1913         goto out;
 1914     }
 1915 
 1916     /* get/refresh the in arg objects inode in correlation to the xlator */
 1917     newpinode = glfs_resolve_inode(fs, subvol, newdir);
 1918     if (!newpinode) {
 1919         errno = ESTALE;
 1920         goto out;
 1921     }
 1922 
 1923     ret = glfs_resolve_at(fs, subvol, newpinode, newname, &newloc, &newiatt, 0,
 1924                           0);
 1925 
 1926     if (ret && errno != ENOENT && newloc.parent)
 1927         goto out;
 1928 
 1929     if (newiatt.ia_type != IA_INVAL) {
 1930         if ((oldiatt.ia_type == IA_IFDIR) != (newiatt.ia_type == IA_IFDIR)) {
 1931             /* Either both old and new must be dirs,
 1932              * or both must be non-dirs. Else, fail.
 1933              */
 1934             ret = -1;
 1935             errno = EEXIST;
 1936             goto out;
 1937         }
 1938     }
 1939 
 1940     /* TODO: check if new or old is a prefix of the other, and fail EINVAL */
 1941 
 1942     ret = syncop_rename(subvol, &oldloc, &newloc, NULL, NULL);
 1943     DECODE_SYNCOP_ERR(ret);
 1944 
 1945     if (ret == 0) {
 1946         inode_rename(oldloc.parent->table, oldloc.parent, oldloc.name,
 1947                      newloc.parent, newloc.name, oldloc.inode, &oldiatt);
 1948 
 1949         if (newloc.inode && !inode_has_dentry(newloc.inode))
 1950             inode_forget(newloc.inode, 0);
 1951     }
 1952 
 1953 out:
 1954     loc_wipe(&oldloc);
 1955     loc_wipe(&newloc);
 1956 
 1957     if (oldpinode)
 1958         inode_unref(oldpinode);
 1959 
 1960     if (newpinode)
 1961         inode_unref(newpinode);
 1962 
 1963     glfs_subvol_done(fs, subvol);
 1964 
 1965     __GLFS_EXIT_FS;
 1966 
 1967 invalid_fs:
 1968     return ret;
 1969 }
 1970 
 1971 /*
 1972  * Given a handle/gfid, find if the corresponding inode is present in
 1973  * the inode table. If yes create and return the corresponding glfs_object.
 1974  */
 1975 struct glfs_object *
 1976 glfs_h_find_handle(struct glfs *fs, unsigned char *handle, int len)
 1977 {
 1978     inode_t *newinode = NULL;
 1979     xlator_t *subvol = NULL;
 1980     struct glfs_object *object = NULL;
 1981     uuid_t gfid;
 1982 
 1983     /* validate in args */
 1984     if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) {
 1985         errno = EINVAL;
 1986         return NULL;
 1987     }
 1988 
 1989     DECLARE_OLD_THIS;
 1990     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 1991 
 1992     /* get the active volume */
 1993     subvol = glfs_active_subvol(fs);
 1994     if (!subvol) {
 1995         errno = EIO;
 1996         goto out;
 1997     }
 1998 
 1999     memcpy(gfid, handle, GFAPI_HANDLE_LENGTH);
 2000 
 2001     /* make sure the gfid received is valid */
 2002     GF_VALIDATE_OR_GOTO("glfs_h_find_handle", !(gf_uuid_is_null(gfid)), out);
 2003 
 2004     newinode = inode_find(subvol->itable, gfid);
 2005     if (!newinode) {
 2006         goto out;
 2007     }
 2008 
 2009     object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t);
 2010     if (object == NULL) {
 2011         errno = ENOMEM;
 2012         goto out;
 2013     }
 2014 
 2015     /* populate the return object. The ref taken here
 2016      * is un'refed when the application does glfs_h_close() */
 2017     object->inode = inode_ref(newinode);
 2018     gf_uuid_copy(object->gfid, object->inode->gfid);
 2019 
 2020 out:
 2021     /* inode_find takes a reference. Unref it. */
 2022     if (newinode)
 2023         inode_unref(newinode);
 2024 
 2025     glfs_subvol_done(fs, subvol);
 2026 
 2027     __GLFS_EXIT_FS;
 2028 
 2029 invalid_fs:
 2030     return object;
 2031 }
 2032 
 2033 static void
 2034 glfs_free_upcall_inode(void *to_free)
 2035 {
 2036     struct glfs_upcall_inode *arg = to_free;
 2037 
 2038     if (!arg)
 2039         return;
 2040 
 2041     if (arg->object)
 2042         glfs_h_close(arg->object);
 2043     if (arg->p_object)
 2044         glfs_h_close(arg->p_object);
 2045     if (arg->oldp_object)
 2046         glfs_h_close(arg->oldp_object);
 2047 
 2048     GF_FREE(arg);
 2049 }
 2050 
 2051 int
 2052 glfs_h_poll_cache_invalidation(struct glfs *fs, struct glfs_upcall *up_arg,
 2053                                struct gf_upcall *upcall_data)
 2054 {
 2055     int ret = -1;
 2056     struct glfs_object *p_object = NULL;
 2057     struct glfs_object *oldp_object = NULL;
 2058     struct glfs_object *object = NULL;
 2059     struct gf_upcall_cache_invalidation *ca_data = NULL;
 2060     struct glfs_upcall_inode *up_inode_arg = NULL;
 2061 
 2062     ca_data = upcall_data->data;
 2063     GF_VALIDATE_OR_GOTO("glfs_h_poll_cache_invalidation", ca_data, out);
 2064 
 2065     object = glfs_h_find_handle(fs, upcall_data->gfid, GFAPI_HANDLE_LENGTH);
 2066     if (!object) {
 2067         /* The reason handle creation will fail is because we
 2068          * couldn't find the inode in the gfapi inode table.
 2069          *
 2070          * But since application would have taken inode_ref, the
 2071          * only case when this can happen is when it has closed
 2072          * the handle and hence will no more be interested in
 2073          * the upcall for this particular gfid.
 2074          */
 2075         gf_smsg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_CREATE_HANDLE_FAILED,
 2076                 "gfid=%s", uuid_utoa(upcall_data->gfid), NULL);
 2077         errno = ESTALE;
 2078         goto out;
 2079     }
 2080 
 2081     up_inode_arg = GF_CALLOC(1, sizeof(struct glfs_upcall_inode),
 2082                              glfs_mt_upcall_inode_t);
 2083     GF_VALIDATE_OR_GOTO("glfs_h_poll_cache_invalidation", up_inode_arg, out);
 2084 
 2085     up_inode_arg->object = object;
 2086     up_inode_arg->flags = ca_data->flags;
 2087     up_inode_arg->expire_time_attr = ca_data->expire_time_attr;
 2088 
 2089     /* XXX: Update stat as well in case of UP_*_TIMES.
 2090      * This will be addressed as part of INODE_UPDATE */
 2091     if (ca_data->flags & GFAPI_INODE_UPDATE_FLAGS) {
 2092         glfs_iatt_to_stat(fs, &ca_data->stat, &up_inode_arg->buf);
 2093     }
 2094 
 2095     if (ca_data->flags & GFAPI_UP_PARENT_TIMES) {
 2096         p_object = glfs_h_find_handle(fs, ca_data->p_stat.ia_gfid,
 2097                                       GFAPI_HANDLE_LENGTH);
 2098         if (!p_object) {
 2099             gf_smsg(THIS->name, GF_LOG_DEBUG, errno,
 2100                     API_MSG_CREATE_HANDLE_FAILED, "gfid=%s",
 2101                     uuid_utoa(ca_data->p_stat.ia_gfid), NULL);
 2102             errno = ESTALE;
 2103             goto out;
 2104         }
 2105 
 2106         glfs_iatt_to_stat(fs, &ca_data->p_stat, &up_inode_arg->p_buf);
 2107     }
 2108     up_inode_arg->p_object = p_object;
 2109 
 2110     /* In case of RENAME, update old parent as well */
 2111     if (ca_data->flags & GFAPI_UP_RENAME) {
 2112         oldp_object = glfs_h_find_handle(fs, ca_data->oldp_stat.ia_gfid,
 2113                                          GFAPI_HANDLE_LENGTH);
 2114         if (!oldp_object) {
 2115             gf_smsg(THIS->name, GF_LOG_DEBUG, errno,
 2116                     API_MSG_CREATE_HANDLE_FAILED, "gfid=%s",
 2117                     uuid_utoa(ca_data->oldp_stat.ia_gfid), NULL);
 2118             errno = ESTALE;
 2119             /* By the time we receive upcall old parent_dir may
 2120              * have got removed. We still need to send upcall
 2121              * for the file/dir and current parent handles. */
 2122             up_inode_arg->oldp_object = NULL;
 2123             ret = 0;
 2124         }
 2125 
 2126         glfs_iatt_to_stat(fs, &ca_data->oldp_stat, &up_inode_arg->oldp_buf);
 2127     }
 2128     up_inode_arg->oldp_object = oldp_object;
 2129 
 2130     up_arg->reason = GLFS_UPCALL_INODE_INVALIDATE;
 2131     up_arg->event = up_inode_arg;
 2132     up_arg->free_event = glfs_free_upcall_inode;
 2133 
 2134     ret = 0;
 2135 
 2136 out:
 2137     if (ret) {
 2138         /* Close p_object and oldp_object as well if being referenced.*/
 2139         if (object)
 2140             glfs_h_close(object);
 2141 
 2142         /* Set reason to prevent applications from using ->event */
 2143         up_arg->reason = GLFS_UPCALL_EVENT_NULL;
 2144         GF_FREE(up_inode_arg);
 2145     }
 2146     return ret;
 2147 }
 2148 
 2149 void
 2150 glfs_release_upcall(void *ptr)
 2151 {
 2152     struct glfs_upcall *to_free = ptr;
 2153 
 2154     if (to_free->event)
 2155         to_free->free_event(to_free->event);
 2156 }
 2157 
 2158 /*
 2159  * This API is used to poll for upcall events stored in the upcall list.
 2160  * Current users of this API is NFS-Ganesha. In case of any event received, it
 2161  * will be mapped appropriately into 'glfs_upcall' along with the handle object
 2162  * to be passed to NFS-Ganesha.
 2163  *
 2164  * On success, applications need to check if up_arg is not-NULL or errno is not
 2165  * ENOENT. glfs_upcall_get_reason() can be used to decide what kind of event
 2166  * has been received.
 2167  *
 2168  * Current supported upcall_events:
 2169  *      GLFS_UPCALL_INODE_INVALIDATE
 2170  *
 2171  * After processing the event, applications need to free 'up_arg' by calling
 2172  * glfs_free().
 2173  *
 2174  * Also similar to I/Os, the application should ideally stop polling before
 2175  * calling glfs_fini(..). Hence making an assumption that 'fs' & ctx structures
 2176  * cannot be freed while in this routine.
 2177  */
 2178 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_poll_upcall, 3.7.16)
 2179 int
 2180 pub_glfs_h_poll_upcall(struct glfs *fs, struct glfs_upcall **up_arg)
 2181 {
 2182     upcall_entry *u_list = NULL;
 2183     upcall_entry *tmp = NULL;
 2184     xlator_t *subvol = NULL;
 2185     glusterfs_ctx_t *ctx = NULL;
 2186     int ret = -1;
 2187     struct gf_upcall *upcall_data = NULL;
 2188 
 2189     DECLARE_OLD_THIS;
 2190 
 2191     if (!up_arg) {
 2192         errno = EINVAL;
 2193         goto err;
 2194     }
 2195 
 2196     __GLFS_ENTRY_VALIDATE_FS(fs, err);
 2197 
 2198     /* get the active volume */
 2199     subvol = glfs_active_subvol(fs);
 2200     if (!subvol) {
 2201         errno = EIO;
 2202         goto restore;
 2203     }
 2204 
 2205     /* Ideally applications should stop polling before calling
 2206      * 'glfs_fini'. Yet cross check if cleanup has started. */
 2207     pthread_mutex_lock(&fs->mutex);
 2208     {
 2209         ctx = fs->ctx;
 2210 
 2211         if (ctx->cleanup_started) {
 2212             pthread_mutex_unlock(&fs->mutex);
 2213             goto out;
 2214         }
 2215 
 2216         fs->pin_refcnt++;
 2217 
 2218         /* once we call this function, the applications seems to be
 2219          * interested in events, enable caching them */
 2220         fs->cache_upcalls = _gf_true;
 2221     }
 2222     pthread_mutex_unlock(&fs->mutex);
 2223 
 2224     pthread_mutex_lock(&fs->upcall_list_mutex);
 2225     {
 2226         list_for_each_entry_safe(u_list, tmp, &fs->upcall_list, upcall_list)
 2227         {
 2228             list_del_init(&u_list->upcall_list);
 2229             upcall_data = &u_list->upcall_data;
 2230             break;
 2231         }
 2232     }
 2233     /* No other thread can delete this entry. So unlock it */
 2234     pthread_mutex_unlock(&fs->upcall_list_mutex);
 2235 
 2236     if (upcall_data) {
 2237         switch (upcall_data->event_type) {
 2238             case GF_UPCALL_CACHE_INVALIDATION:
 2239                 *up_arg = GLFS_CALLOC(1, sizeof(struct gf_upcall),
 2240                                       glfs_release_upcall,
 2241                                       glfs_mt_upcall_entry_t);
 2242                 if (!*up_arg) {
 2243                     errno = ENOMEM;
 2244                     break; /* goto free u_list */
 2245                 }
 2246 
 2247                 /* XXX: Need to revisit this to support
 2248                  * GLFS_UPCALL_INODE_UPDATE if required. */
 2249                 ret = glfs_h_poll_cache_invalidation(fs, *up_arg, upcall_data);
 2250                 if (ret || (*up_arg)->reason == GLFS_UPCALL_EVENT_NULL) {
 2251                     /* It could so happen that the file which got
 2252                      * upcall notification may have got deleted by
 2253                      * the same client. Irrespective of the error,
 2254                      * return with an error or success+ENOENT. */
 2255                     if ((*up_arg)->reason == GLFS_UPCALL_EVENT_NULL)
 2256                         errno = ENOENT;
 2257 
 2258                     GLFS_FREE(*up_arg);
 2259                     *up_arg = NULL;
 2260                 }
 2261                 break;
 2262             case GF_UPCALL_RECALL_LEASE:
 2263                 gf_log("glfs_h_poll_upcall", GF_LOG_DEBUG,
 2264                        "UPCALL_RECALL_LEASE is not implemented yet");
 2265             /* fallthrough till we support leases */
 2266             case GF_UPCALL_EVENT_NULL:
 2267                 /* no 'default:' label, to force handling all upcall events */
 2268                 errno = ENOENT;
 2269                 break;
 2270         }
 2271 
 2272         GF_FREE(u_list->upcall_data.data);
 2273         GF_FREE(u_list);
 2274     } else {
 2275         /* fs->upcall_list was empty, no upcall events cached */
 2276         errno = ENOENT;
 2277     }
 2278 
 2279     ret = 0;
 2280 
 2281 out:
 2282     pthread_mutex_lock(&fs->mutex);
 2283     {
 2284         fs->pin_refcnt--;
 2285     }
 2286     pthread_mutex_unlock(&fs->mutex);
 2287 
 2288     glfs_subvol_done(fs, subvol);
 2289 
 2290 restore:
 2291     __GLFS_EXIT_FS;
 2292 err:
 2293     return ret;
 2294 }
 2295 
 2296 static gf_boolean_t log_upcall370 = _gf_true; /* log once */
 2297 
 2298 /* The old glfs_h_poll_upcall interface requires intimate knowledge of the
 2299  * structures that are returned to the calling application. This is not
 2300  * recommended, as the returned structures need to returned correctly (handles
 2301  * closed, memory free'd with the unavailable GF_FREE(), and possibly more.)
 2302  *
 2303  * To the best of our knowledge, only NFS-Ganesha uses the upcall events
 2304  * through gfapi. We keep this backwards compatibility function around so that
 2305  * applications using the existing implementation do not break.
 2306  *
 2307  * WARNING: this function will be removed in the future.
 2308  */
 2309 GFAPI_SYMVER_PUBLIC(glfs_h_poll_upcall370, glfs_h_poll_upcall, 3.7.0)
 2310 int
 2311 pub_glfs_h_poll_upcall370(struct glfs *fs, struct glfs_callback_arg *up_arg)
 2312 {
 2313     struct glfs_upcall *upcall = NULL;
 2314     int ret = -1;
 2315 
 2316     if (log_upcall370) {
 2317         log_upcall370 = _gf_false;
 2318         gf_log(THIS->name, GF_LOG_WARNING,
 2319                "this application is "
 2320                "compiled against an old version of libgfapi, it "
 2321                "should use glfs_free() to release the structure "
 2322                "returned by glfs_h_poll_upcall() - for more details, "
 2323                "see http://review.gluster.org/14701");
 2324     }
 2325 
 2326     ret = pub_glfs_h_poll_upcall(fs, &upcall);
 2327     if (ret == 0) {
 2328         up_arg->fs = fs;
 2329         if ((errno == ENOENT) || !upcall || !upcall->event) {
 2330             up_arg->reason = GLFS_UPCALL_EVENT_NULL;
 2331             goto out;
 2332         }
 2333 
 2334         up_arg->reason = upcall->reason;
 2335 
 2336         if (upcall->reason == GLFS_UPCALL_INODE_INVALIDATE) {
 2337             struct glfs_callback_inode_arg *cb_inode = NULL;
 2338             struct glfs_upcall_inode *up_inode = NULL;
 2339 
 2340             cb_inode = GF_CALLOC(1, sizeof(struct glfs_callback_inode_arg),
 2341                                  glfs_mt_upcall_inode_t);
 2342             if (!cb_inode) {
 2343                 errno = ENOMEM;
 2344                 ret = -1;
 2345                 goto out;
 2346             }
 2347 
 2348             up_inode = upcall->event;
 2349 
 2350             /* copy attributes one by one, the memory layout might
 2351              * be different between the old glfs_callback_inode_arg
 2352              * and new glfs_upcall_inode */
 2353             cb_inode->object = up_inode->object;
 2354             cb_inode->flags = up_inode->flags;
 2355             memcpy(&cb_inode->buf, &up_inode->buf, sizeof(struct stat));
 2356             cb_inode->expire_time_attr = up_inode->expire_time_attr;
 2357             cb_inode->p_object = up_inode->p_object;
 2358             memcpy(&cb_inode->p_buf, &up_inode->p_buf, sizeof(struct stat));
 2359             cb_inode->oldp_object = up_inode->oldp_object;
 2360             memcpy(&cb_inode->oldp_buf, &up_inode->oldp_buf,
 2361                    sizeof(struct stat));
 2362 
 2363             up_arg->event_arg = cb_inode;
 2364         }
 2365     }
 2366 
 2367 out:
 2368     if (upcall) {
 2369         /* we can not use glfs_free() here, objects need to stay */
 2370         GF_FREE(upcall->event);
 2371         GF_FREE(upcall);
 2372     }
 2373 
 2374     return ret;
 2375 }
 2376 
 2377 #ifdef HAVE_ACL_LIBACL_H
 2378 #include <glusterfs/glusterfs-acl.h>
 2379 #include <acl/libacl.h>
 2380 
 2381 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0)
 2382 int
 2383 pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object,
 2384                    const acl_type_t type, const acl_t acl)
 2385 {
 2386     int ret = -1;
 2387     char *acl_s = NULL;
 2388     const char *acl_key = NULL;
 2389     struct glfs_object *new_object = NULL;
 2390 
 2391     DECLARE_OLD_THIS;
 2392 
 2393     if (!object || !acl) {
 2394         errno = EINVAL;
 2395         return ret;
 2396     }
 2397 
 2398     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 2399 
 2400     acl_key = gf_posix_acl_get_key(type);
 2401     if (!acl_key)
 2402         goto out;
 2403 
 2404     acl_s = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE | TEXT_NUMERIC_IDS);
 2405     if (!acl_s)
 2406         goto out;
 2407 
 2408     if (IA_ISLNK(object->inode->ia_type)) {
 2409         new_object = glfs_h_resolve_symlink(fs, object);
 2410         if (new_object == NULL)
 2411             goto out;
 2412     } else
 2413         new_object = object;
 2414 
 2415     ret = pub_glfs_h_setxattrs(fs, new_object, acl_key, acl_s,
 2416                                strlen(acl_s) + 1, 0);
 2417 
 2418     acl_free(acl_s);
 2419 
 2420 out:
 2421     if (IA_ISLNK(object->inode->ia_type) && new_object)
 2422         glfs_h_close(new_object);
 2423 
 2424     __GLFS_EXIT_FS;
 2425 
 2426 invalid_fs:
 2427     return ret;
 2428 }
 2429 
 2430 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0)
 2431 acl_t
 2432 pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object,
 2433                    const acl_type_t type)
 2434 {
 2435     int ret = 0;
 2436     acl_t acl = NULL;
 2437     char *acl_s = NULL;
 2438     dict_t *xattr = NULL;
 2439     const char *acl_key = NULL;
 2440     struct glfs_object *new_object = NULL;
 2441 
 2442     DECLARE_OLD_THIS;
 2443 
 2444     if (!object) {
 2445         errno = EINVAL;
 2446         return NULL;
 2447     }
 2448 
 2449     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 2450 
 2451     acl_key = gf_posix_acl_get_key(type);
 2452     if (!acl_key)
 2453         goto out;
 2454 
 2455     if (IA_ISLNK(object->inode->ia_type)) {
 2456         new_object = glfs_h_resolve_symlink(fs, object);
 2457         if (new_object == NULL)
 2458             goto out;
 2459     } else
 2460         new_object = object;
 2461 
 2462     ret = glfs_h_getxattrs_common(fs, new_object, &xattr, acl_key, _gf_false);
 2463     if (ret)
 2464         goto out;
 2465 
 2466     ret = dict_get_str(xattr, (char *)acl_key, &acl_s);
 2467     if (ret)
 2468         goto out;
 2469 
 2470     acl = acl_from_text(acl_s);
 2471 
 2472 out:
 2473     if (xattr)
 2474         dict_unref(xattr);
 2475 
 2476     if (IA_ISLNK(object->inode->ia_type) && new_object)
 2477         glfs_h_close(new_object);
 2478 
 2479     __GLFS_EXIT_FS;
 2480 
 2481 invalid_fs:
 2482     return acl;
 2483 }
 2484 #else /* !HAVE_ACL_LIBACL_H */
 2485 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0)
 2486 acl_t
 2487 pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object,
 2488                    const acl_type_t type)
 2489 {
 2490     errno = ENOTSUP;
 2491     return NULL;
 2492 }
 2493 
 2494 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0)
 2495 int
 2496 pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object,
 2497                    const acl_type_t type, const acl_t acl)
 2498 {
 2499     errno = ENOTSUP;
 2500     return -1;
 2501 }
 2502 #endif
 2503 
 2504 /* The API to perform read using anonymous fd */
 2505 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_read, 3.7.0)
 2506 ssize_t
 2507 pub_glfs_h_anonymous_read(struct glfs *fs, struct glfs_object *object,
 2508                           const void *buf, size_t count, off_t offset)
 2509 {
 2510     struct iovec iov = {
 2511         0,
 2512     };
 2513     ssize_t ret = 0;
 2514 
 2515     /* validate in args */
 2516     if ((fs == NULL) || (object == NULL)) {
 2517         errno = EINVAL;
 2518         return -1;
 2519     }
 2520 
 2521     iov.iov_base = (void *)buf;
 2522     iov.iov_len = count;
 2523 
 2524     ret = glfs_anonymous_preadv(fs, object, &iov, 1, offset, 0);
 2525 
 2526     return ret;
 2527 }
 2528 
 2529 /* The API to perform write using anonymous fd */
 2530 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_write, 3.7.0)
 2531 ssize_t
 2532 pub_glfs_h_anonymous_write(struct glfs *fs, struct glfs_object *object,
 2533                            const void *buf, size_t count, off_t offset)
 2534 {
 2535     struct iovec iov = {
 2536         0,
 2537     };
 2538     ssize_t ret = 0;
 2539 
 2540     /* validate in args */
 2541     if ((fs == NULL) || (object == NULL)) {
 2542         errno = EINVAL;
 2543         return -1;
 2544     }
 2545 
 2546     iov.iov_base = (void *)buf;
 2547     iov.iov_len = count;
 2548 
 2549     ret = glfs_anonymous_pwritev(fs, object, &iov, 1, offset, 0);
 2550 
 2551     return ret;
 2552 }
 2553 
 2554 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_object_copy, 3.11.0)
 2555 struct glfs_object *
 2556 pub_glfs_object_copy(struct glfs_object *src)
 2557 {
 2558     struct glfs_object *object = NULL;
 2559 
 2560     GF_VALIDATE_OR_GOTO("glfs_dup_object", src, out);
 2561 
 2562     object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t);
 2563     if (object == NULL) {
 2564         errno = ENOMEM;
 2565         gf_smsg(THIS->name, GF_LOG_WARNING, errno, API_MSG_CREATE_HANDLE_FAILED,
 2566                 "glfs_dup_object gfid=%s", uuid_utoa(src->inode->gfid), NULL);
 2567         return NULL;
 2568     }
 2569 
 2570     object->inode = inode_ref(src->inode);
 2571     gf_uuid_copy(object->gfid, src->inode->gfid);
 2572 
 2573 out:
 2574     return object;
 2575 }
 2576 
 2577 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_object, 3.11.0)
 2578 struct glfs_object *
 2579 pub_glfs_xreaddirplus_get_object(struct glfs_xreaddirp_stat *xstat)
 2580 {
 2581     GF_VALIDATE_OR_GOTO("glfs_xreaddirplus_get_object", xstat, out);
 2582 
 2583     if (!(xstat->flags_handled & GFAPI_XREADDIRP_HANDLE))
 2584         gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_HANDLE_NOT_SET,
 2585                 "GFAPI_XREADDIRP_HANDLE xstat=%p", xstat, "handle=%x",
 2586                 xstat->flags_handled, NULL);
 2587 
 2588     return xstat->object;
 2589 
 2590 out:
 2591     return NULL;
 2592 }
 2593 
 2594 GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lease, 4.0.0)
 2595 int
 2596 pub_glfs_h_lease(struct glfs *fs, struct glfs_object *object,
 2597                  struct glfs_lease *lease)
 2598 {
 2599     int ret = -1;
 2600     xlator_t *subvol = NULL;
 2601     inode_t *inode = NULL;
 2602     loc_t loc = {
 2603         0,
 2604     };
 2605     struct gf_lease gf_lease = {
 2606         0,
 2607     };
 2608 
 2609     /* validate in args */
 2610     if ((fs == NULL) || (object == NULL)) {
 2611         errno = EINVAL;
 2612         return -1;
 2613     }
 2614 
 2615     DECLARE_OLD_THIS;
 2616     __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
 2617 
 2618     /* get the active volume */
 2619     subvol = glfs_active_subvol(fs);
 2620     if (!subvol) {
 2621         ret = -1;
 2622         errno = EIO;
 2623         goto out;
 2624     }
 2625 
 2626     /* get/refresh the in arg objects inode in correlation to the xlator */
 2627     inode = glfs_resolve_inode(fs, subvol, object);
 2628     if (!inode) {
 2629         errno = ESTALE;
 2630         goto out;
 2631     }
 2632 
 2633     /* populate loc */
 2634     GLFS_LOC_FILL_INODE(inode, loc, out);
 2635 
 2636     glfs_lease_to_gf_lease(lease, &gf_lease);
 2637 
 2638     ret = syncop_lease(subvol, &loc, &gf_lease, NULL, NULL);
 2639     DECODE_SYNCOP_ERR(ret);
 2640 
 2641     gf_lease_to_glfs_lease(&gf_lease, lease);
 2642 
 2643 out:
 2644     loc_wipe(&loc);
 2645 
 2646     if (inode)
 2647         inode_unref(inode);
 2648 
 2649     glfs_subvol_done(fs, subvol);
 2650 
 2651     __GLFS_EXIT_FS;
 2652 
 2653 invalid_fs:
 2654     return ret;
 2655 }