"Fossies" - the Fresh Open Source Software Archive

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

    1 /*
    2   Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.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 "string.h"
   12 
   13 #include "nfs.h"
   14 #include "nfs-inodes.h"
   15 #include "nfs-fops.h"
   16 #include <glusterfs/xlator.h>
   17 #include "nfs-messages.h"
   18 
   19 #include <libgen.h>
   20 
   21 #define inodes_nfl_to_prog_data(nflocal, pcbk, fram)                           \
   22     do {                                                                       \
   23         nflocal = fram->local;                                                 \
   24         fram->local = nflocal->proglocal;                                      \
   25         *VOID(&pcbk) = nflocal->progcbk;                                       \
   26         nfs_fop_local_wipe(nflocal->nfsx, nflocal);                            \
   27     } while (0)
   28 
   29 void
   30 nfl_inodes_init(struct nfs_fop_local *nfl, inode_t *inode, inode_t *parent,
   31                 inode_t *newparent, const char *name, const char *newname)
   32 {
   33     if (!nfl)
   34         return;
   35 
   36     if (inode)
   37         nfl->inode = inode_ref(inode);
   38 
   39     if (parent)
   40         nfl->parent = inode_ref(parent);
   41 
   42     if (newparent)
   43         nfl->newparent = inode_ref(newparent);
   44 
   45     if (name)
   46         snprintf(nfl->path, NFS_NAME_MAX, "%s", name);
   47 
   48     if (newname)
   49         snprintf(nfl->newpath, NFS_NAME_MAX, "%s", newname);
   50     return;
   51 }
   52 
   53 int32_t
   54 nfs_inode_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
   55                      int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
   56                      struct iatt *buf, struct iatt *preparent,
   57                      struct iatt *postparent, dict_t *xdata)
   58 {
   59     struct nfs_fop_local *nfl = frame->local;
   60     fop_create_cbk_t progcbk = NULL;
   61     inode_t *linked_inode = NULL;
   62 
   63     if (op_ret == -1)
   64         goto do_not_link;
   65 
   66     linked_inode = inode_link(inode, nfl->parent, nfl->path, buf);
   67 
   68 do_not_link:
   69     /* NFS does not need it, upper layers should not expect the pointer to
   70      * be a valid fd.
   71      */
   72     fd_unref(fd);
   73 
   74     inodes_nfl_to_prog_data(nfl, progcbk, frame);
   75     if (progcbk)
   76         progcbk(frame, cookie, this, op_ret, op_errno, fd, inode, buf,
   77                 preparent, postparent, xdata);
   78 
   79     if (linked_inode) {
   80         inode_lookup(linked_inode);
   81         inode_unref(linked_inode);
   82     }
   83 
   84     return 0;
   85 }
   86 
   87 int
   88 nfs_inode_create(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
   89                  int flags, int mode, fop_create_cbk_t cbk, void *local)
   90 {
   91     struct nfs_fop_local *nfl = NULL;
   92     int ret = -EFAULT;
   93     fd_t *newfd = NULL;
   94 
   95     if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
   96         return ret;
   97 
   98     nfs_fop_handle_local_init(NULL, nfsx, nfl, cbk, local, ret, err);
   99 
  100     newfd = fd_create(pathloc->inode, 0);
  101     if (!newfd) {
  102         gf_msg(GF_NFS, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
  103                "Failed to create new fd");
  104         ret = -ENOMEM;
  105         goto wipe_nfl;
  106     }
  107 
  108     /* The parent and base name will be needed to link the new inode
  109      * into the inode table.
  110      */
  111     nfl_inodes_init(nfl, pathloc->inode, pathloc->parent, NULL, pathloc->name,
  112                     NULL);
  113     ret = nfs_fop_create(nfsx, xl, nfu, pathloc, flags, mode, newfd,
  114                          nfs_inode_create_cbk, nfl);
  115 wipe_nfl:
  116     if (ret < 0)
  117         nfs_fop_local_wipe(xl, nfl);
  118 
  119 err:
  120     return ret;
  121 }
  122 
  123 int32_t
  124 nfs_inode_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  125                     int32_t op_ret, int32_t op_errno, inode_t *inode,
  126                     struct iatt *buf, struct iatt *preparent,
  127                     struct iatt *postparent, dict_t *xdata)
  128 {
  129     struct nfs_fop_local *nfl = frame->local;
  130     fop_mkdir_cbk_t progcbk = NULL;
  131     inode_t *linked_inode = NULL;
  132 
  133     if (op_ret == -1)
  134         goto do_not_link;
  135 
  136     linked_inode = inode_link(inode, nfl->parent, nfl->path, buf);
  137 
  138 do_not_link:
  139     inodes_nfl_to_prog_data(nfl, progcbk, frame);
  140     if (progcbk)
  141         progcbk(frame, cookie, this, op_ret, op_errno, inode, buf, preparent,
  142                 postparent, xdata);
  143 
  144     if (linked_inode) {
  145         inode_lookup(linked_inode);
  146         inode_unref(linked_inode);
  147     }
  148 
  149     return 0;
  150 }
  151 
  152 int
  153 nfs_inode_mkdir(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
  154                 int mode, fop_mkdir_cbk_t cbk, void *local)
  155 {
  156     struct nfs_fop_local *nfl = NULL;
  157     int ret = -EFAULT;
  158 
  159     if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
  160         return ret;
  161 
  162     nfs_fop_handle_local_init(NULL, nfsx, nfl, cbk, local, ret, err);
  163     nfl_inodes_init(nfl, pathloc->inode, pathloc->parent, NULL, pathloc->name,
  164                     NULL);
  165     ret = nfs_fop_mkdir(nfsx, xl, nfu, pathloc, mode, nfs_inode_mkdir_cbk, nfl);
  166     if (ret < 0)
  167         nfs_fop_local_wipe(nfsx, nfl);
  168 
  169 err:
  170     return ret;
  171 }
  172 
  173 int32_t
  174 nfs_inode_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  175                    int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
  176 {
  177     struct nfs_fop_local *nfl = NULL;
  178     fop_open_cbk_t progcbk = NULL;
  179 
  180     if ((op_ret == -1) && (fd))
  181         fd_unref(fd);
  182     /* Not needed here since the fd is cached in higher layers and the bind
  183      * must happen atomically when the fd gets added to the fd LRU.
  184      */
  185     /*        else
  186                     fd_bind (fd);
  187     */
  188     inodes_nfl_to_prog_data(nfl, progcbk, frame);
  189     if (progcbk)
  190         progcbk(frame, cookie, this, op_ret, op_errno, fd, xdata);
  191     return 0;
  192 }
  193 
  194 int
  195 nfs_inode_open(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
  196                int32_t flags, fop_open_cbk_t cbk, void *local)
  197 {
  198     struct nfs_fop_local *nfl = NULL;
  199     fd_t *newfd = NULL;
  200     int ret = -EFAULT;
  201 
  202     if ((!nfsx) || (!xl) || (!loc) || (!nfu))
  203         return ret;
  204 
  205     newfd = fd_create(loc->inode, 0);
  206     if (!newfd) {
  207         gf_msg(GF_NFS, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
  208                "Failed to create fd");
  209         ret = -ENOMEM;
  210         goto err;
  211     }
  212 
  213     nfs_fop_handle_local_init(NULL, nfsx, nfl, cbk, local, ret, fd_err);
  214     ret = nfs_fop_open(nfsx, xl, nfu, loc, flags, newfd, nfs_inode_open_cbk,
  215                        nfl);
  216 
  217     if (ret < 0)
  218         nfs_fop_local_wipe(xl, nfl);
  219 
  220 fd_err:
  221     if (ret < 0)
  222         if (newfd)
  223             fd_unref(newfd);
  224 
  225 err:
  226 
  227     return ret;
  228 }
  229 
  230 int32_t
  231 nfs_inode_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  232                      int32_t op_ret, int32_t op_errno, struct iatt *buf,
  233                      struct iatt *preoldparent, struct iatt *postoldparent,
  234                      struct iatt *prenewparent, struct iatt *postnewparent,
  235                      dict_t *xdata)
  236 {
  237     struct nfs_fop_local *nfl = NULL;
  238     fop_rename_cbk_t progcbk = NULL;
  239 
  240     nfl = frame->local;
  241     if (op_ret == -1)
  242         goto do_not_link;
  243 
  244     inode_rename(this->itable, nfl->parent, nfl->path, nfl->newparent,
  245                  nfl->newpath, nfl->inode, buf);
  246 
  247 do_not_link:
  248     inodes_nfl_to_prog_data(nfl, progcbk, frame);
  249     if (progcbk)
  250         progcbk(frame, cookie, this, op_ret, op_errno, buf, preoldparent,
  251                 postoldparent, prenewparent, postnewparent, xdata);
  252     return 0;
  253 }
  254 
  255 int
  256 nfs_inode_rename(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
  257                  loc_t *newloc, fop_rename_cbk_t cbk, void *local)
  258 {
  259     struct nfs_fop_local *nfl = NULL;
  260     int ret = -EFAULT;
  261 
  262     if ((!nfsx) || (!xl) || (!oldloc) || (!newloc))
  263         return ret;
  264 
  265     nfs_fop_handle_local_init(NULL, nfsx, nfl, cbk, local, ret, err);
  266     nfl_inodes_init(nfl, oldloc->inode, oldloc->parent, newloc->parent,
  267                     oldloc->name, newloc->name);
  268     ret = nfs_fop_rename(nfsx, xl, nfu, oldloc, newloc, nfs_inode_rename_cbk,
  269                          nfl);
  270 
  271 err:
  272     if (ret < 0)
  273         nfs_fop_local_wipe(xl, nfl);
  274 
  275     return ret;
  276 }
  277 
  278 int32_t
  279 nfs_inode_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  280                    int32_t op_ret, int32_t op_errno, inode_t *inode,
  281                    struct iatt *buf, struct iatt *preparent,
  282                    struct iatt *postparent, dict_t *xdata)
  283 {
  284     struct nfs_fop_local *nfl = NULL;
  285     fop_link_cbk_t progcbk = NULL;
  286     inode_t *linked_inode = NULL;
  287 
  288     if (op_ret == -1)
  289         goto do_not_link;
  290 
  291     nfl = frame->local;
  292     linked_inode = inode_link(inode, nfl->newparent, nfl->path, buf);
  293 
  294 do_not_link:
  295     inodes_nfl_to_prog_data(nfl, progcbk, frame);
  296     if (progcbk)
  297         progcbk(frame, cookie, this, op_ret, op_errno, inode, buf, preparent,
  298                 postparent, xdata);
  299 
  300     if (linked_inode) {
  301         inode_lookup(linked_inode);
  302         inode_unref(linked_inode);
  303     }
  304 
  305     return 0;
  306 }
  307 
  308 int
  309 nfs_inode_link(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
  310                loc_t *newloc, fop_link_cbk_t cbk, void *local)
  311 {
  312     struct nfs_fop_local *nfl = NULL;
  313     int ret = -EFAULT;
  314 
  315     if ((!nfsx) || (!xl) || (!oldloc) || (!newloc) || (!nfu))
  316         return -EFAULT;
  317 
  318     nfs_fop_handle_local_init(NULL, nfsx, nfl, cbk, local, ret, err);
  319     nfl_inodes_init(nfl, NULL, NULL, newloc->parent, newloc->name, NULL);
  320     ret = nfs_fop_link(nfsx, xl, nfu, oldloc, newloc, nfs_inode_link_cbk, nfl);
  321 
  322 err:
  323     if (ret < 0)
  324         nfs_fop_local_wipe(xl, nfl);
  325 
  326     return ret;
  327 }
  328 
  329 int32_t
  330 nfs_inode_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  331                      int32_t op_ret, int32_t op_errno, struct iatt *preparent,
  332                      struct iatt *postparent, dict_t *xdata)
  333 {
  334     struct nfs_fop_local *nfl = NULL;
  335     fop_unlink_cbk_t progcbk = NULL;
  336 
  337     nfl = frame->local;
  338 
  339     if (op_ret == -1)
  340         goto do_not_unlink;
  341 
  342     inode_unlink(nfl->inode, nfl->parent, nfl->path);
  343     inode_forget(nfl->inode, 0);
  344 
  345 do_not_unlink:
  346     inodes_nfl_to_prog_data(nfl, progcbk, frame);
  347     if (progcbk)
  348         progcbk(frame, cookie, this, op_ret, op_errno, preparent, postparent,
  349                 xdata);
  350     return 0;
  351 }
  352 
  353 int
  354 nfs_inode_unlink(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
  355                  fop_unlink_cbk_t cbk, void *local)
  356 {
  357     struct nfs_fop_local *nfl = NULL;
  358     int ret = -EFAULT;
  359 
  360     if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
  361         return -EFAULT;
  362 
  363     nfs_fop_handle_local_init(NULL, nfsx, nfl, cbk, local, ret, err);
  364     nfl_inodes_init(nfl, pathloc->inode, pathloc->parent, NULL, pathloc->name,
  365                     NULL);
  366     ret = nfs_fop_unlink(nfsx, xl, nfu, pathloc, nfs_inode_unlink_cbk, nfl);
  367 
  368 err:
  369     if (ret < 0)
  370         nfs_fop_local_wipe(xl, nfl);
  371 
  372     return ret;
  373 }
  374 
  375 int32_t
  376 nfs_inode_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  377                     int32_t op_ret, int32_t op_errno, struct iatt *preparent,
  378                     struct iatt *postparent, dict_t *xdata)
  379 {
  380     struct nfs_fop_local *nfl = NULL;
  381     fop_rmdir_cbk_t progcbk = NULL;
  382 
  383     nfl = frame->local;
  384 
  385     if (op_ret == -1)
  386         goto do_not_unlink;
  387 
  388     inode_unlink(nfl->inode, nfl->parent, nfl->path);
  389     inode_forget(nfl->inode, 0);
  390 
  391 do_not_unlink:
  392     inodes_nfl_to_prog_data(nfl, progcbk, frame);
  393     if (progcbk)
  394         progcbk(frame, cookie, this, op_ret, op_errno, preparent, postparent,
  395                 xdata);
  396 
  397     return 0;
  398 }
  399 
  400 int
  401 nfs_inode_rmdir(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
  402                 fop_rmdir_cbk_t cbk, void *local)
  403 {
  404     struct nfs_fop_local *nfl = NULL;
  405     int ret = -EFAULT;
  406 
  407     if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
  408         return ret;
  409 
  410     nfs_fop_handle_local_init(NULL, nfsx, nfl, cbk, local, ret, err);
  411     nfl_inodes_init(nfl, pathloc->inode, pathloc->parent, NULL, pathloc->name,
  412                     NULL);
  413 
  414     ret = nfs_fop_rmdir(nfsx, xl, nfu, pathloc, nfs_inode_rmdir_cbk, nfl);
  415 
  416 err:
  417     if (ret < 0)
  418         nfs_fop_local_wipe(xl, nfl);
  419     return ret;
  420 }
  421 
  422 int32_t
  423 nfs_inode_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  424                     int32_t op_ret, int32_t op_errno, inode_t *inode,
  425                     struct iatt *buf, struct iatt *preparent,
  426                     struct iatt *postparent, dict_t *xdata)
  427 {
  428     struct nfs_fop_local *nfl = NULL;
  429     fop_mknod_cbk_t progcbk = NULL;
  430     inode_t *linked_inode = NULL;
  431 
  432     nfl = frame->local;
  433 
  434     if (op_ret == -1)
  435         goto do_not_link;
  436 
  437     linked_inode = inode_link(inode, nfl->parent, nfl->path, buf);
  438 
  439 do_not_link:
  440     inodes_nfl_to_prog_data(nfl, progcbk, frame);
  441     if (progcbk)
  442         progcbk(frame, cookie, this, op_ret, op_errno, inode, buf, preparent,
  443                 postparent, xdata);
  444 
  445     if (linked_inode) {
  446         inode_lookup(linked_inode);
  447         inode_unref(linked_inode);
  448     }
  449 
  450     return 0;
  451 }
  452 
  453 int
  454 nfs_inode_mknod(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
  455                 mode_t mode, dev_t dev, fop_mknod_cbk_t cbk, void *local)
  456 {
  457     struct nfs_fop_local *nfl = NULL;
  458     int ret = -EFAULT;
  459 
  460     if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
  461         return ret;
  462 
  463     nfs_fop_handle_local_init(NULL, nfsx, nfl, cbk, local, ret, err);
  464     nfl_inodes_init(nfl, pathloc->inode, pathloc->parent, NULL, pathloc->name,
  465                     NULL);
  466 
  467     ret = nfs_fop_mknod(nfsx, xl, nfu, pathloc, mode, dev, nfs_inode_mknod_cbk,
  468                         nfl);
  469 
  470 err:
  471     if (ret < 0)
  472         nfs_fop_local_wipe(xl, nfl);
  473 
  474     return ret;
  475 }
  476 
  477 int32_t
  478 nfs_inode_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  479                       int32_t op_ret, int32_t op_errno, inode_t *inode,
  480                       struct iatt *buf, struct iatt *preparent,
  481                       struct iatt *postparent, dict_t *xdata)
  482 {
  483     struct nfs_fop_local *nfl = NULL;
  484     fop_symlink_cbk_t progcbk = NULL;
  485     inode_t *linked_inode = NULL;
  486 
  487     nfl = frame->local;
  488     if (op_ret == -1)
  489         goto do_not_link;
  490 
  491     linked_inode = inode_link(inode, nfl->parent, nfl->path, buf);
  492 
  493 do_not_link:
  494     inodes_nfl_to_prog_data(nfl, progcbk, frame);
  495     if (progcbk)
  496         progcbk(frame, cookie, this, op_ret, op_errno, inode, buf, preparent,
  497                 postparent, xdata);
  498 
  499     if (linked_inode) {
  500         inode_lookup(linked_inode);
  501         inode_unref(linked_inode);
  502     }
  503 
  504     return 0;
  505 }
  506 
  507 int
  508 nfs_inode_symlink(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, char *target,
  509                   loc_t *pathloc, fop_symlink_cbk_t cbk, void *local)
  510 {
  511     struct nfs_fop_local *nfl = NULL;
  512     int ret = -EFAULT;
  513 
  514     if ((!nfsx) || (!xl) || (!target) || (!pathloc) || (!nfu))
  515         return ret;
  516 
  517     nfs_fop_handle_local_init(NULL, nfsx, nfl, cbk, local, ret, err);
  518     nfl_inodes_init(nfl, pathloc->inode, pathloc->parent, NULL, pathloc->name,
  519                     NULL);
  520     ret = nfs_fop_symlink(nfsx, xl, nfu, target, pathloc, nfs_inode_symlink_cbk,
  521                           nfl);
  522 
  523 err:
  524     if (ret < 0)
  525         nfs_fop_local_wipe(xl, nfl);
  526 
  527     return ret;
  528 }
  529 
  530 int32_t
  531 nfs_inode_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  532                       int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
  533 {
  534     struct nfs_fop_local *nfl = NULL;
  535     fop_open_cbk_t progcbk = NULL;
  536 
  537     if (op_ret != -1)
  538         fd_bind(fd);
  539 
  540     inodes_nfl_to_prog_data(nfl, progcbk, frame);
  541 
  542     if (progcbk)
  543         progcbk(frame, cookie, this, op_ret, op_errno, fd, xdata);
  544 
  545     return 0;
  546 }
  547 
  548 int
  549 nfs_inode_opendir(xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
  550                   fop_opendir_cbk_t cbk, void *local)
  551 {
  552     struct nfs_fop_local *nfl = NULL;
  553     fd_t *newfd = NULL;
  554     int ret = -EFAULT;
  555 
  556     if ((!nfsx) || (!xl) || (!loc) || (!nfu))
  557         return ret;
  558 
  559     newfd = fd_create(loc->inode, 0);
  560     if (!newfd) {
  561         gf_msg(GF_NFS, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY,
  562                "Failed to create fd");
  563         ret = -ENOMEM;
  564         goto err;
  565     }
  566 
  567     nfs_fop_handle_local_init(NULL, nfsx, nfl, cbk, local, ret, err);
  568     ret = nfs_fop_opendir(nfsx, xl, nfu, loc, newfd, nfs_inode_opendir_cbk,
  569                           nfl);
  570 
  571 err:
  572     if (ret < 0) {
  573         if (newfd)
  574             fd_unref(newfd);
  575         nfs_fop_local_wipe(xl, nfl);
  576     }
  577 
  578     return ret;
  579 }