"Fossies" - the Fresh Open Source Software Archive

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

    1 /*
    2   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
    3   This file is part of GlusterFS.
    4 
    5   This file is licensed to you under your choice of the GNU Lesser
    6   General Public License, version 3 or any later version (LGPLv3 or
    7   later), or the GNU General Public License, version 2 (GPLv2), in all
    8   cases as published by the Free Software Foundation.
    9 */
   10 
   11 #include "arbiter.h"
   12 #include "arbiter-mem-types.h"
   13 #include <glusterfs/glusterfs.h>
   14 #include <glusterfs/xlator.h>
   15 #include <glusterfs/logging.h>
   16 
   17 static arbiter_inode_ctx_t *
   18 __arbiter_inode_ctx_get(inode_t *inode, xlator_t *this)
   19 {
   20     arbiter_inode_ctx_t *ctx = NULL;
   21     int ret = 0;
   22     uint64_t ctx_addr = 0;
   23 
   24     ret = __inode_ctx_get(inode, this, &ctx_addr);
   25     if (ret == 0) {
   26         ctx = (arbiter_inode_ctx_t *)(long)ctx_addr;
   27         goto out;
   28     }
   29 
   30     ctx = GF_CALLOC(1, sizeof(*ctx), gf_arbiter_mt_inode_ctx_t);
   31     if (!ctx)
   32         goto out;
   33 
   34     ret = __inode_ctx_put(inode, this, (uint64_t)(uintptr_t)ctx);
   35     if (ret) {
   36         GF_FREE(ctx);
   37         ctx = NULL;
   38         gf_log_callingfn(this->name, GF_LOG_ERROR,
   39                          "failed to "
   40                          "set the inode ctx (%s)",
   41                          uuid_utoa(inode->gfid));
   42     }
   43 out:
   44     return ctx;
   45 }
   46 
   47 static arbiter_inode_ctx_t *
   48 arbiter_inode_ctx_get(inode_t *inode, xlator_t *this)
   49 {
   50     arbiter_inode_ctx_t *ctx = NULL;
   51 
   52     LOCK(&inode->lock);
   53     {
   54         ctx = __arbiter_inode_ctx_get(inode, this);
   55     }
   56     UNLOCK(&inode->lock);
   57     return ctx;
   58 }
   59 
   60 int32_t
   61 arbiter_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
   62                    int32_t op_ret, int32_t op_errno, inode_t *inode,
   63                    struct iatt *buf, dict_t *xdata, struct iatt *postparent)
   64 {
   65     arbiter_inode_ctx_t *ctx = NULL;
   66 
   67     if (op_ret != 0)
   68         goto unwind;
   69     ctx = arbiter_inode_ctx_get(inode, this);
   70     if (!ctx) {
   71         op_ret = -1;
   72         op_errno = ENOMEM;
   73         goto unwind;
   74     }
   75     memcpy(&ctx->iattbuf, buf, sizeof(ctx->iattbuf));
   76 
   77 unwind:
   78     STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xdata,
   79                         postparent);
   80     return 0;
   81 }
   82 
   83 int32_t
   84 arbiter_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
   85 {
   86     STACK_WIND(frame, arbiter_lookup_cbk, FIRST_CHILD(this),
   87                FIRST_CHILD(this)->fops->lookup, loc, xdata);
   88     return 0;
   89 }
   90 
   91 int32_t
   92 arbiter_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
   93                  dict_t *xdata)
   94 {
   95     arbiter_inode_ctx_t *ctx = NULL;
   96     struct iatt *buf = NULL;
   97     int32_t op_ret = 0;
   98     int32_t op_errno = 0;
   99 
  100     ctx = arbiter_inode_ctx_get(loc->inode, this);
  101     if (!ctx) {
  102         op_ret = -1;
  103         op_errno = ENOMEM;
  104         goto unwind;
  105     }
  106     buf = &ctx->iattbuf;
  107 unwind:
  108     STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, buf, buf, NULL);
  109     return 0;
  110 }
  111 
  112 int32_t
  113 arbiter_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
  114                   dict_t *xdata)
  115 
  116 {
  117     arbiter_inode_ctx_t *ctx = NULL;
  118     struct iatt *buf = NULL;
  119     int32_t op_ret = 0;
  120     int32_t op_errno = 0;
  121 
  122     ctx = arbiter_inode_ctx_get(fd->inode, this);
  123     if (!ctx) {
  124         op_ret = -1;
  125         op_errno = ENOMEM;
  126         goto unwind;
  127     }
  128     buf = &ctx->iattbuf;
  129 unwind:
  130     STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, buf, buf, NULL);
  131     return 0;
  132 }
  133 
  134 dict_t *
  135 arbiter_fill_writev_xdata(fd_t *fd, dict_t *xdata, xlator_t *this)
  136 {
  137     dict_t *rsp_xdata = NULL;
  138     int32_t ret = 0;
  139     int is_append = 1;
  140 
  141     if (!fd || !fd->inode || gf_uuid_is_null(fd->inode->gfid)) {
  142         goto out;
  143     }
  144 
  145     if (!xdata)
  146         goto out;
  147 
  148     rsp_xdata = dict_new();
  149     if (!rsp_xdata)
  150         goto out;
  151 
  152     if (dict_get(xdata, GLUSTERFS_OPEN_FD_COUNT)) {
  153         ret = dict_set_uint32(rsp_xdata, GLUSTERFS_OPEN_FD_COUNT,
  154                               fd->inode->fd_count);
  155         if (ret < 0) {
  156             gf_msg_debug(this->name, 0,
  157                          "Failed to set dict value"
  158                          " for GLUSTERFS_OPEN_FD_COUNT");
  159         }
  160     }
  161     if (dict_get(xdata, GLUSTERFS_WRITE_IS_APPEND)) {
  162         ret = dict_set_uint32(rsp_xdata, GLUSTERFS_WRITE_IS_APPEND, is_append);
  163         if (ret < 0) {
  164             gf_msg_debug(this->name, 0,
  165                          "Failed to set dict value"
  166                          " for GLUSTERFS_WRITE_IS_APPEND");
  167         }
  168     }
  169 out:
  170     return rsp_xdata;
  171 }
  172 
  173 int32_t
  174 arbiter_writev(call_frame_t *frame, xlator_t *this, fd_t *fd,
  175                struct iovec *vector, int32_t count, off_t off, uint32_t flags,
  176                struct iobref *iobref, dict_t *xdata)
  177 {
  178     arbiter_inode_ctx_t *ctx = NULL;
  179     struct iatt *buf = NULL;
  180     dict_t *rsp_xdata = NULL;
  181     int op_ret = 0;
  182     int op_errno = 0;
  183 
  184     ctx = arbiter_inode_ctx_get(fd->inode, this);
  185     if (!ctx) {
  186         op_ret = -1;
  187         op_errno = ENOMEM;
  188         goto unwind;
  189     }
  190     buf = &ctx->iattbuf;
  191     op_ret = iov_length(vector, count);
  192     rsp_xdata = arbiter_fill_writev_xdata(fd, xdata, this);
  193 unwind:
  194     STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, buf, buf, rsp_xdata);
  195     if (rsp_xdata)
  196         dict_unref(rsp_xdata);
  197     return 0;
  198 }
  199 
  200 int32_t
  201 arbiter_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd,
  202                   int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
  203 {
  204     arbiter_inode_ctx_t *ctx = NULL;
  205     struct iatt *buf = NULL;
  206     int op_ret = 0;
  207     int op_errno = 0;
  208 
  209     ctx = arbiter_inode_ctx_get(fd->inode, this);
  210     if (!ctx) {
  211         op_ret = -1;
  212         op_errno = ENOMEM;
  213         goto unwind;
  214     }
  215     buf = &ctx->iattbuf;
  216 unwind:
  217     STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, buf, buf, NULL);
  218     return 0;
  219 }
  220 
  221 int32_t
  222 arbiter_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
  223                 size_t len, dict_t *xdata)
  224 {
  225     arbiter_inode_ctx_t *ctx = NULL;
  226     struct iatt *buf = NULL;
  227     int op_ret = 0;
  228     int op_errno = 0;
  229 
  230     ctx = arbiter_inode_ctx_get(fd->inode, this);
  231     if (!ctx) {
  232         op_ret = -1;
  233         op_errno = ENOMEM;
  234         goto unwind;
  235     }
  236     buf = &ctx->iattbuf;
  237 unwind:
  238     STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, buf, buf, NULL);
  239     return 0;
  240 }
  241 
  242 int32_t
  243 arbiter_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
  244                  off_t len, dict_t *xdata)
  245 {
  246     arbiter_inode_ctx_t *ctx = NULL;
  247     struct iatt *buf = NULL;
  248     int op_ret = 0;
  249     int op_errno = 0;
  250 
  251     ctx = arbiter_inode_ctx_get(fd->inode, this);
  252     if (!ctx) {
  253         op_ret = -1;
  254         op_errno = ENOMEM;
  255         goto unwind;
  256     }
  257     buf = &ctx->iattbuf;
  258 unwind:
  259     STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, buf, buf, NULL);
  260     return 0;
  261 }
  262 
  263 static int32_t
  264 arbiter_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
  265               off_t offset, uint32_t flags, dict_t *xdata)
  266 {
  267     STACK_UNWIND_STRICT(readv, frame, -1, ENOSYS, NULL, 0, NULL, NULL, NULL);
  268     return 0;
  269 }
  270 
  271 static int32_t
  272 arbiter_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
  273              gf_seek_what_t what, dict_t *xdata)
  274 {
  275     STACK_UNWIND_STRICT(seek, frame, -1, ENOSYS, 0, xdata);
  276     return 0;
  277 }
  278 
  279 int32_t
  280 mem_acct_init(xlator_t *this)
  281 {
  282     int ret = -1;
  283 
  284     ret = xlator_mem_acct_init(this, gf_arbiter_mt_end + 1);
  285     if (ret)
  286         gf_log(this->name, GF_LOG_ERROR,
  287                "Memory accounting "
  288                "initialization failed.");
  289     return ret;
  290 }
  291 
  292 int
  293 reconfigure(xlator_t *this, dict_t *options)
  294 {
  295     return 0;
  296 }
  297 
  298 int
  299 arbiter_forget(xlator_t *this, inode_t *inode)
  300 {
  301     arbiter_inode_ctx_t *ctx = NULL;
  302     uint64_t ctx_addr = 0;
  303 
  304     inode_ctx_del(inode, this, &ctx_addr);
  305     if (!ctx_addr)
  306         return 0;
  307     ctx = (arbiter_inode_ctx_t *)(long)ctx_addr;
  308     GF_FREE(ctx);
  309     return 0;
  310 }
  311 
  312 int32_t
  313 init(xlator_t *this)
  314 {
  315     if (!this->children || this->children->next) {
  316         gf_log(this->name, GF_LOG_ERROR,
  317                "'arbiter' not configured with exactly one child");
  318         return -1;
  319     }
  320 
  321     if (!this->parents)
  322         gf_log(this->name, GF_LOG_ERROR, "dangling volume. check volfile ");
  323 
  324     return 0;
  325 }
  326 
  327 void
  328 fini(xlator_t *this)
  329 {
  330     return;
  331 }
  332 
  333 struct xlator_fops fops = {
  334     .lookup = arbiter_lookup,
  335 
  336     /* Return success for these inode write FOPS without winding it down to
  337      * posix; this is needed for AFR write transaction logic to work.*/
  338     .truncate = arbiter_truncate,
  339     .writev = arbiter_writev,
  340     .ftruncate = arbiter_ftruncate,
  341     .fallocate = arbiter_fallocate,
  342     .discard = arbiter_discard,
  343     .zerofill = arbiter_zerofill,
  344 
  345     /* AFR is not expected to wind these inode read FOPS initiated by the
  346      * application to the arbiter brick. But in case a bug causes them
  347      * to be called, we return ENOSYS. */
  348     .readv = arbiter_readv,
  349     .seek = arbiter_seek,
  350 
  351     /* The following inode read FOPS initiated by the application are not
  352      * wound by AFR either but internal logic like  shd, glfsheal and
  353      * client side healing in AFR will send them for selfheal/ inode refresh
  354      * operations etc.,so we need to wind them down to posix:
  355      *
  356      * (f)stat, readdir(p), readlink, (f)getxattr.*/
  357 
  358     /* All other FOPs not listed here are safe to be wound down to posix.*/
  359 };
  360 
  361 struct xlator_cbks cbks = {
  362     .forget = arbiter_forget,
  363 };
  364 
  365 struct volume_options options[] = {
  366     {.key = {NULL}},
  367 };
  368 
  369 xlator_api_t xlator_api = {
  370     .init = init,
  371     .fini = fini,
  372     .reconfigure = reconfigure,
  373     .mem_acct_init = mem_acct_init,
  374     .op_version = {1}, /* Present from the initial version */
  375     .fops = &fops,
  376     .cbks = &cbks,
  377     .options = options,
  378     .identifier = "arbiter",
  379     .category = GF_MAINTAINED,
  380 };