"Fossies" - the Fresh Open Source Software Archive

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

    1 /*
    2    Copyright (c) 2015-2016 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 #ifndef _CONFIG_H
   12 #define _CONFIG_H
   13 #include "config.h"
   14 #endif
   15 
   16 #include "leases.h"
   17 
   18 int32_t
   19 leases_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
   20                 int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
   21 {
   22     STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, xdata);
   23 
   24     return 0;
   25 }
   26 
   27 int32_t
   28 leases_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
   29             fd_t *fd, dict_t *xdata)
   30 {
   31     uint32_t fop_flags = 0;
   32     int32_t op_errno = EINVAL;
   33     int ret = 0;
   34     lease_fd_ctx_t *fd_ctx = NULL;
   35     char *lease_id = NULL;
   36 
   37     EXIT_IF_LEASES_OFF(this, out);
   38     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
   39 
   40     fd_ctx = GF_CALLOC(1, sizeof(*fd_ctx), gf_leases_mt_fd_ctx_t);
   41     if (!fd_ctx) {
   42         op_errno = ENOMEM;
   43         goto err;
   44     }
   45 
   46     fd_ctx->client_uid = gf_strdup(frame->root->client->client_uid);
   47     if (!fd_ctx->client_uid) {
   48         op_errno = ENOMEM;
   49         goto err;
   50     }
   51 
   52     GET_FLAGS(frame->root->op, flags);
   53     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
   54     if (lease_id != NULL)
   55         memcpy(fd_ctx->lease_id, lease_id, LEASE_ID_SIZE);
   56     else
   57         memset(fd_ctx->lease_id, 0, LEASE_ID_SIZE);
   58 
   59     ret = fd_ctx_set(fd, this, (uint64_t)(uintptr_t)fd_ctx);
   60     if (ret) {
   61         op_errno = ENOMEM;
   62         goto err;
   63     }
   64 
   65     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
   66     if (ret < 0)
   67         goto err;
   68     else if (ret == BLOCK_FOP)
   69         goto block;
   70     else if (ret == WIND_FOP)
   71         goto out;
   72 
   73 block:
   74     LEASE_BLOCK_FOP(fd->inode, open, frame, this, loc, flags, fd, xdata);
   75     return 0;
   76 
   77 out:
   78     STACK_WIND(frame, leases_open_cbk, FIRST_CHILD(this),
   79                FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
   80     return 0;
   81 
   82 err:
   83     if (fd_ctx) {
   84         GF_FREE(fd_ctx->client_uid);
   85         GF_FREE(fd_ctx);
   86     }
   87 
   88     STACK_UNWIND_STRICT(open, frame, -1, op_errno, NULL, NULL);
   89     return 0;
   90 }
   91 
   92 int32_t
   93 leases_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
   94                   int op_errno, struct iatt *prebuf, struct iatt *postbuf,
   95                   dict_t *xdata)
   96 {
   97     STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf,
   98                         xdata);
   99 
  100     return 0;
  101 }
  102 
  103 int32_t
  104 leases_writev(call_frame_t *frame, xlator_t *this, fd_t *fd,
  105               struct iovec *vector, int count, off_t off, uint32_t flags,
  106               struct iobref *iobref, dict_t *xdata)
  107 {
  108     uint32_t fop_flags = 0;
  109     char *lease_id = NULL;
  110     int ret = 0;
  111 
  112     EXIT_IF_LEASES_OFF(this, out);
  113     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  114 
  115     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  116     GET_FLAGS(frame->root->op, fd->flags);
  117 
  118     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  119     if (ret < 0)
  120         goto err;
  121     else if (ret == BLOCK_FOP)
  122         goto block;
  123     else if (ret == WIND_FOP)
  124         goto out;
  125 
  126 block:
  127     LEASE_BLOCK_FOP(fd->inode, writev, frame, this, fd, vector, count, off,
  128                     flags, iobref, xdata);
  129     return 0;
  130 
  131 out:
  132     STACK_WIND(frame, leases_writev_cbk, FIRST_CHILD(this),
  133                FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags,
  134                iobref, xdata);
  135     return 0;
  136 
  137 err:
  138     STACK_UNWIND_STRICT(writev, frame, -1, errno, NULL, NULL, NULL);
  139     return 0;
  140 }
  141 
  142 int32_t
  143 leases_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  144                  int op_errno, struct iovec *vector, int count,
  145                  struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
  146 {
  147     STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, vector, count, stbuf,
  148                         iobref, xdata);
  149 
  150     return 0;
  151 }
  152 
  153 int32_t
  154 leases_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
  155              off_t offset, uint32_t flags, dict_t *xdata)
  156 {
  157     uint32_t fop_flags = 0;
  158     char *lease_id = NULL;
  159     int ret = 0;
  160 
  161     EXIT_IF_LEASES_OFF(this, out);
  162     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  163 
  164     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  165     GET_FLAGS(frame->root->op, fd->flags);
  166 
  167     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  168     if (ret < 0)
  169         goto err;
  170     else if (ret == BLOCK_FOP)
  171         goto block;
  172     else if (ret == WIND_FOP)
  173         goto out;
  174 
  175 block:
  176     LEASE_BLOCK_FOP(fd->inode, readv, frame, this, fd, size, offset, flags,
  177                     xdata);
  178     return 0;
  179 
  180 out:
  181     STACK_WIND(frame, leases_readv_cbk, FIRST_CHILD(this),
  182                FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata);
  183     return 0;
  184 
  185 err:
  186     STACK_UNWIND_STRICT(readv, frame, -1, errno, NULL, 0, NULL, NULL, NULL);
  187     return 0;
  188 }
  189 
  190 int32_t
  191 leases_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
  192               int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
  193 {
  194     STACK_UNWIND_STRICT(lk, frame, op_ret, op_errno, lock, xdata);
  195 
  196     return 0;
  197 }
  198 
  199 int32_t
  200 leases_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
  201           struct gf_flock *flock, dict_t *xdata)
  202 {
  203     uint32_t fop_flags = 0;
  204     char *lease_id = NULL;
  205     int ret = 0;
  206 
  207     EXIT_IF_LEASES_OFF(this, out);
  208     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  209 
  210     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  211     GET_FLAGS_LK(cmd, flock->l_type, fd->flags);
  212 
  213     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  214     if (ret < 0)
  215         goto err;
  216     else if (ret == BLOCK_FOP)
  217         goto block;
  218     else if (ret == WIND_FOP)
  219         goto out;
  220 
  221 block:
  222     LEASE_BLOCK_FOP(fd->inode, lk, frame, this, fd, cmd, flock, xdata);
  223     return 0;
  224 
  225 out:
  226     STACK_WIND(frame, leases_lk_cbk, FIRST_CHILD(this),
  227                FIRST_CHILD(this)->fops->lk, fd, cmd, flock, xdata);
  228     return 0;
  229 
  230 err:
  231     STACK_UNWIND_STRICT(lk, frame, -1, errno, NULL, NULL);
  232     return 0;
  233 }
  234 
  235 int32_t
  236 leases_lease(call_frame_t *frame, xlator_t *this, loc_t *loc,
  237              struct gf_lease *lease, dict_t *xdata)
  238 {
  239     int32_t op_errno = 0;
  240     int ret = 0;
  241     struct gf_lease nullease = {
  242         0,
  243     };
  244     int32_t op_ret = 0;
  245 
  246     EXIT_IF_LEASES_OFF(this, out);
  247     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  248 
  249     ret = process_lease_req(frame, this, loc->inode, lease);
  250     if (ret < 0) {
  251         op_errno = -ret;
  252         op_ret = -1;
  253     }
  254     goto unwind;
  255 
  256 out:
  257     gf_msg(this->name, GF_LOG_ERROR, EINVAL, LEASE_MSG_NOT_ENABLED,
  258            "\"features/leases\" translator is not enabled. "
  259            "You need to enable it for proper functioning of your "
  260            "application");
  261     op_errno = ENOSYS;
  262     op_ret = -1;
  263 
  264 unwind:
  265     STACK_UNWIND_STRICT(lease, frame, op_ret, op_errno,
  266                         (op_errno == ENOSYS) ? &nullease : lease, xdata);
  267     return 0;
  268 }
  269 
  270 int32_t
  271 leases_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  272                     int op_ret, int op_errno, struct iatt *prebuf,
  273                     struct iatt *postbuf, dict_t *xdata)
  274 {
  275     STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, prebuf, postbuf,
  276                         xdata);
  277 
  278     return 0;
  279 }
  280 
  281 int32_t
  282 leases_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
  283                 dict_t *xdata)
  284 {
  285     uint32_t fop_flags = 0;
  286     char *lease_id = NULL;
  287     int ret = 0;
  288 
  289     EXIT_IF_LEASES_OFF(this, out);
  290     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  291 
  292     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  293     GET_FLAGS(frame->root->op, 0);
  294 
  295     ret = check_lease_conflict(frame, loc->inode, lease_id, fop_flags);
  296     if (ret < 0)
  297         goto err;
  298     else if (ret == BLOCK_FOP)
  299         goto block;
  300     else if (ret == WIND_FOP)
  301         goto out;
  302 
  303 block:
  304     LEASE_BLOCK_FOP(loc->inode, truncate, frame, this, loc, offset, xdata);
  305     return 0;
  306 
  307 out:
  308     STACK_WIND(frame, leases_truncate_cbk, FIRST_CHILD(this),
  309                FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
  310     return 0;
  311 
  312 err:
  313     STACK_UNWIND_STRICT(truncate, frame, -1, errno, NULL, NULL, NULL);
  314     return 0;
  315 }
  316 
  317 int32_t
  318 leases_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  319                    int op_ret, int op_errno, struct iatt *statpre,
  320                    struct iatt *statpost, dict_t *xdata)
  321 {
  322     STACK_UNWIND_STRICT(setattr, frame, op_ret, op_errno, statpre, statpost,
  323                         xdata);
  324 
  325     return 0;
  326 }
  327 
  328 int32_t
  329 leases_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
  330                struct iatt *stbuf, int32_t valid, dict_t *xdata)
  331 {
  332     uint32_t fop_flags = 0;
  333     char *lease_id = NULL;
  334     int ret = 0;
  335 
  336     EXIT_IF_LEASES_OFF(this, out);
  337     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  338 
  339     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  340     GET_FLAGS(frame->root->op, 0);
  341 
  342     ret = check_lease_conflict(frame, loc->inode, lease_id, fop_flags);
  343     if (ret < 0)
  344         goto err;
  345     else if (ret == BLOCK_FOP)
  346         goto block;
  347     else if (ret == WIND_FOP)
  348         goto out;
  349 
  350 block:
  351     LEASE_BLOCK_FOP(loc->inode, setattr, frame, this, loc, stbuf, valid, xdata);
  352     return 0;
  353 
  354 out:
  355     STACK_WIND(frame, leases_setattr_cbk, FIRST_CHILD(this),
  356                FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata);
  357     return 0;
  358 
  359 err:
  360     STACK_UNWIND_STRICT(setattr, frame, -1, errno, NULL, NULL, NULL);
  361     return 0;
  362 }
  363 
  364 int32_t
  365 leases_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  366                   int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
  367                   struct iatt *preoldparent, struct iatt *postoldparent,
  368                   struct iatt *prenewparent, struct iatt *postnewparent,
  369                   dict_t *xdata)
  370 {
  371     STACK_UNWIND_STRICT(rename, frame, op_ret, op_errno, stbuf, preoldparent,
  372                         postoldparent, prenewparent, postnewparent, xdata);
  373 
  374     return 0;
  375 }
  376 
  377 int32_t
  378 leases_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
  379               dict_t *xdata)
  380 {
  381     uint32_t fop_flags = 0;
  382     char *lease_id = NULL;
  383     int ret = 0;
  384 
  385     EXIT_IF_LEASES_OFF(this, out);
  386     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  387 
  388     /* should the lease be also checked for newloc */
  389     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  390     GET_FLAGS(frame->root->op, 0);
  391 
  392     ret = check_lease_conflict(frame, oldloc->inode, lease_id, fop_flags);
  393     if (ret < 0)
  394         goto err;
  395     else if (ret == BLOCK_FOP)
  396         goto block;
  397     else if (ret == WIND_FOP)
  398         goto out;
  399 
  400 block:
  401     LEASE_BLOCK_FOP(oldloc->inode, rename, frame, this, oldloc, newloc, xdata);
  402     return 0;
  403 
  404 out:
  405     STACK_WIND(frame, leases_rename_cbk, FIRST_CHILD(this),
  406                FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata);
  407     return 0;
  408 
  409 err:
  410     STACK_UNWIND_STRICT(rename, frame, -1, errno, NULL, NULL, NULL, NULL, NULL,
  411                         NULL);
  412     return 0;
  413 }
  414 
  415 int32_t
  416 leases_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  417                   int op_errno, struct iatt *preparent, struct iatt *postparent,
  418                   dict_t *xdata)
  419 {
  420     STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent,
  421                         xdata);
  422 
  423     return 0;
  424 }
  425 
  426 int32_t
  427 leases_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
  428               dict_t *xdata)
  429 {
  430     uint32_t fop_flags = 0;
  431     char *lease_id = NULL;
  432     int ret = 0;
  433 
  434     EXIT_IF_LEASES_OFF(this, out);
  435     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  436 
  437     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  438     GET_FLAGS(frame->root->op, 0);
  439 
  440     ret = check_lease_conflict(frame, loc->inode, lease_id, fop_flags);
  441     if (ret < 0)
  442         goto err;
  443     else if (ret == BLOCK_FOP)
  444         goto block;
  445     else if (ret == WIND_FOP)
  446         goto out;
  447 
  448 block:
  449     LEASE_BLOCK_FOP(loc->inode, unlink, frame, this, loc, xflag, xdata);
  450     return 0;
  451 
  452 out:
  453     STACK_WIND(frame, leases_unlink_cbk, FIRST_CHILD(this),
  454                FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
  455     return 0;
  456 
  457 err:
  458     STACK_UNWIND_STRICT(unlink, frame, -1, errno, NULL, NULL, NULL);
  459     return 0;
  460 }
  461 
  462 int32_t
  463 leases_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  464                 int op_errno, inode_t *inode, struct iatt *stbuf,
  465                 struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
  466 {
  467     STACK_UNWIND_STRICT(link, frame, op_ret, op_errno, inode, stbuf, preparent,
  468                         postparent, xdata);
  469 
  470     return 0;
  471 }
  472 
  473 int32_t
  474 leases_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
  475             dict_t *xdata)
  476 {
  477     uint32_t fop_flags = 0;
  478     char *lease_id = NULL;
  479     int ret = 0;
  480 
  481     EXIT_IF_LEASES_OFF(this, out);
  482     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  483 
  484     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  485     GET_FLAGS(frame->root->op, 0);
  486 
  487     ret = check_lease_conflict(frame, oldloc->inode, lease_id, fop_flags);
  488     if (ret < 0)
  489         goto err;
  490     else if (ret == BLOCK_FOP)
  491         goto block;
  492     else if (ret == WIND_FOP)
  493         goto out;
  494 
  495 block:
  496     LEASE_BLOCK_FOP(oldloc->inode, link, frame, this, oldloc, newloc, xdata);
  497     return 0;
  498 out:
  499     STACK_WIND(frame, leases_link_cbk, FIRST_CHILD(this),
  500                FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
  501     return 0;
  502 
  503 err:
  504     STACK_UNWIND_STRICT(link, frame, -1, errno, NULL, NULL, NULL, NULL, NULL);
  505     return 0;
  506 }
  507 
  508 int32_t
  509 leases_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
  510                   int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf,
  511                   struct iatt *preparent, struct iatt *postparent,
  512                   dict_t *xdata)
  513 {
  514     STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, stbuf,
  515                         preparent, postparent, xdata);
  516 
  517     return 0;
  518 }
  519 
  520 int32_t
  521 leases_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
  522               mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
  523 {
  524     uint32_t fop_flags = 0;
  525     char *lease_id = NULL;
  526     int ret = 0;
  527 
  528     EXIT_IF_LEASES_OFF(this, out);
  529     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  530 
  531     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  532     GET_FLAGS(frame->root->op, flags);
  533 
  534     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  535     if (ret < 0)
  536         goto err;
  537     else if (ret == BLOCK_FOP)
  538         goto block;
  539     else if (ret == WIND_FOP)
  540         goto out;
  541 
  542 block:
  543     LEASE_BLOCK_FOP(fd->inode, create, frame, this, loc, flags, mode, umask, fd,
  544                     xdata);
  545     return 0;
  546 
  547 out:
  548     STACK_WIND(frame, leases_create_cbk, FIRST_CHILD(this),
  549                FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd,
  550                xdata);
  551     return 0;
  552 
  553 err:
  554     STACK_UNWIND_STRICT(create, frame, -1, errno, NULL, NULL, NULL, NULL, NULL,
  555                         NULL);
  556     return 0;
  557 }
  558 
  559 int32_t
  560 leases_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  561                  int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
  562                  struct iatt *postbuf, dict_t *xdata)
  563 {
  564     STACK_UNWIND_STRICT(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata);
  565     return 0;
  566 }
  567 
  568 int32_t
  569 leases_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
  570              dict_t *xdata)
  571 {
  572     uint32_t fop_flags = 0;
  573     char *lease_id = NULL;
  574     int ret = 0;
  575 
  576     EXIT_IF_LEASES_OFF(this, out);
  577     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  578 
  579     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  580     GET_FLAGS(frame->root->op, fd->flags);
  581 
  582     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  583     if (ret < 0)
  584         goto err;
  585     else if (ret == BLOCK_FOP)
  586         goto block;
  587     else if (ret == WIND_FOP)
  588         goto out;
  589 
  590 block:
  591     LEASE_BLOCK_FOP(fd->inode, fsync, frame, this, fd, flags, xdata);
  592     return 0;
  593 
  594 out:
  595     STACK_WIND(frame, leases_fsync_cbk, FIRST_CHILD(this),
  596                FIRST_CHILD(this)->fops->fsync, fd, flags, xdata);
  597     return 0;
  598 err:
  599     STACK_UNWIND_STRICT(fsync, frame, -1, errno, NULL, NULL, NULL);
  600     return 0;
  601 }
  602 
  603 int32_t
  604 leases_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  605                      int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
  606                      struct iatt *postbuf, dict_t *xdata)
  607 {
  608     STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, prebuf, postbuf,
  609                         xdata);
  610     return 0;
  611 }
  612 
  613 int32_t
  614 leases_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
  615                  dict_t *xdata)
  616 {
  617     uint32_t fop_flags = 0;
  618     char *lease_id = NULL;
  619     int ret = 0;
  620 
  621     EXIT_IF_LEASES_OFF(this, out);
  622     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  623 
  624     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  625     GET_FLAGS(frame->root->op, 0); /* TODO:fd->flags?*/
  626 
  627     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  628     if (ret < 0)
  629         goto err;
  630     else if (ret == BLOCK_FOP)
  631         goto block;
  632     else if (ret == WIND_FOP)
  633         goto out;
  634 
  635 block:
  636     LEASE_BLOCK_FOP(fd->inode, ftruncate, frame, this, fd, offset, xdata);
  637     return 0;
  638 
  639 out:
  640     STACK_WIND(frame, leases_ftruncate_cbk, FIRST_CHILD(this),
  641                FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
  642     return 0;
  643 
  644 err:
  645     STACK_UNWIND_STRICT(ftruncate, frame, -1, errno, NULL, NULL, NULL);
  646     return 0;
  647 }
  648 
  649 int32_t
  650 leases_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  651                     int32_t op_ret, int32_t op_errno, struct iatt *statpre,
  652                     struct iatt *statpost, dict_t *xdata)
  653 {
  654     STACK_UNWIND_STRICT(fsetattr, frame, op_ret, op_errno, statpre, statpost,
  655                         xdata);
  656     return 0;
  657 }
  658 
  659 int32_t
  660 leases_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd,
  661                 struct iatt *stbuf, int32_t valid, dict_t *xdata)
  662 {
  663     uint32_t fop_flags = 0;
  664     char *lease_id = NULL;
  665     int ret = 0;
  666 
  667     EXIT_IF_LEASES_OFF(this, out);
  668     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  669 
  670     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  671     GET_FLAGS(frame->root->op, fd->flags);
  672 
  673     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  674     if (ret < 0)
  675         goto err;
  676     else if (ret == BLOCK_FOP)
  677         goto block;
  678     else if (ret == WIND_FOP)
  679         goto out;
  680 
  681 block:
  682     LEASE_BLOCK_FOP(fd->inode, fsetattr, frame, this, fd, stbuf, valid, xdata);
  683     return 0;
  684 
  685 out:
  686     STACK_WIND(frame, leases_fsetattr_cbk, FIRST_CHILD(this),
  687                FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata);
  688     return 0;
  689 
  690 err:
  691     STACK_UNWIND_STRICT(fsetattr, frame, -1, errno, NULL, NULL, NULL);
  692     return 0;
  693 }
  694 
  695 int32_t
  696 leases_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  697                      int32_t op_ret, int32_t op_errno, struct iatt *pre,
  698                      struct iatt *post, dict_t *xdata)
  699 {
  700     STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, pre, post, xdata);
  701 
  702     return 0;
  703 }
  704 
  705 int32_t
  706 leases_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
  707                  off_t offset, size_t len, dict_t *xdata)
  708 {
  709     uint32_t fop_flags = 0;
  710     char *lease_id = NULL;
  711     int ret = 0;
  712 
  713     EXIT_IF_LEASES_OFF(this, out);
  714     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  715 
  716     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  717     GET_FLAGS(frame->root->op, fd->flags);
  718 
  719     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  720     if (ret < 0)
  721         goto err;
  722     else if (ret == BLOCK_FOP)
  723         goto block;
  724     else if (ret == WIND_FOP)
  725         goto out;
  726 
  727 block:
  728     LEASE_BLOCK_FOP(fd->inode, fallocate, frame, this, fd, mode, offset, len,
  729                     xdata);
  730     return 0;
  731 
  732 out:
  733     STACK_WIND(frame, leases_fallocate_cbk, FIRST_CHILD(this),
  734                FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len,
  735                xdata);
  736     return 0;
  737 
  738 err:
  739     STACK_UNWIND_STRICT(fallocate, frame, -1, errno, NULL, NULL, NULL);
  740     return 0;
  741 }
  742 
  743 int32_t
  744 leases_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  745                    int32_t op_ret, int32_t op_errno, struct iatt *pre,
  746                    struct iatt *post, dict_t *xdata)
  747 {
  748     STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, pre, post, xdata);
  749 
  750     return 0;
  751 }
  752 
  753 int32_t
  754 leases_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
  755                size_t len, dict_t *xdata)
  756 {
  757     uint32_t fop_flags = 0;
  758     char *lease_id = NULL;
  759     int ret = 0;
  760 
  761     EXIT_IF_LEASES_OFF(this, out);
  762     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  763 
  764     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  765     GET_FLAGS(frame->root->op, fd->flags);
  766 
  767     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  768     if (ret < 0)
  769         goto err;
  770     else if (ret == BLOCK_FOP)
  771         goto block;
  772     else if (ret == WIND_FOP)
  773         goto out;
  774 
  775 block:
  776     LEASE_BLOCK_FOP(fd->inode, discard, frame, this, fd, offset, len, xdata);
  777     return 0;
  778 
  779 out:
  780     STACK_WIND(frame, leases_discard_cbk, FIRST_CHILD(this),
  781                FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata);
  782     return 0;
  783 
  784 err:
  785     STACK_UNWIND_STRICT(discard, frame, -1, errno, NULL, NULL, NULL);
  786     return 0;
  787 }
  788 
  789 int32_t
  790 leases_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  791                     int32_t op_ret, int32_t op_errno, struct iatt *pre,
  792                     struct iatt *post, dict_t *xdata)
  793 {
  794     STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, pre, post, xdata);
  795 
  796     return 0;
  797 }
  798 
  799 int
  800 leases_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
  801                 off_t len, dict_t *xdata)
  802 {
  803     uint32_t fop_flags = 0;
  804     char *lease_id = NULL;
  805     int ret = 0;
  806 
  807     EXIT_IF_LEASES_OFF(this, out);
  808     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  809 
  810     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  811     GET_FLAGS(frame->root->op, fd->flags);
  812 
  813     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  814     if (ret < 0)
  815         goto err;
  816     else if (ret == BLOCK_FOP)
  817         goto block;
  818     else if (ret == WIND_FOP)
  819         goto out;
  820 
  821 block:
  822     LEASE_BLOCK_FOP(fd->inode, zerofill, frame, this, fd, offset, len, xdata);
  823     return 0;
  824 
  825 out:
  826     STACK_WIND(frame, leases_zerofill_cbk, FIRST_CHILD(this),
  827                FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata);
  828     return 0;
  829 
  830 err:
  831     STACK_UNWIND_STRICT(zerofill, frame, -1, errno, NULL, NULL, NULL);
  832     return 0;
  833 }
  834 
  835 int
  836 leases_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
  837                  int32_t op_ret, int32_t op_errno, dict_t *xdata)
  838 {
  839     STACK_UNWIND_STRICT(flush, frame, op_ret, op_errno, xdata);
  840 
  841     return 0;
  842 }
  843 
  844 int
  845 leases_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
  846 {
  847     uint32_t fop_flags = 0;
  848     char *lease_id = NULL;
  849     int ret = 0;
  850     lease_fd_ctx_t *fd_ctx = NULL;
  851     uint64_t ctx = 0;
  852 
  853     EXIT_IF_LEASES_OFF(this, out);
  854     EXIT_IF_INTERNAL_FOP(frame, xdata, out);
  855 
  856     GET_LEASE_ID(xdata, lease_id, frame->root->client->client_uid);
  857     GET_FLAGS(frame->root->op, fd->flags);
  858 
  859     ret = check_lease_conflict(frame, fd->inode, lease_id, fop_flags);
  860     if (ret < 0)
  861         goto err;
  862     else if (ret == BLOCK_FOP)
  863         goto block;
  864     else if (ret == WIND_FOP)
  865         goto out;
  866 
  867 block:
  868     LEASE_BLOCK_FOP(fd->inode, flush, frame, this, fd, xdata);
  869     return 0;
  870 
  871 out:
  872     /* *
  873      * currently release is not called after the close fop from the
  874      * application. Hence lease fd ctx is reset on here.
  875      * This is actually not the right way, since flush can be called
  876      * not only from the close op.
  877      * TODO :
  878      *     - Either identify the flush is called from close call on fd from
  879      *     from the application.
  880      *                      OR
  881      *     - Find why release is not called post the last close call
  882      */
  883     ret = fd_ctx_get(fd, this, &ctx);
  884     if (ret == 0) {
  885         fd_ctx = (lease_fd_ctx_t *)(long)ctx;
  886         if (fd_ctx->client_uid) {
  887             GF_FREE(fd_ctx->client_uid);
  888             fd_ctx->client_uid = NULL;
  889         }
  890         memset(fd_ctx->lease_id, 0, LEASE_ID_SIZE);
  891     }
  892     STACK_WIND(frame, leases_flush_cbk, FIRST_CHILD(this),
  893                FIRST_CHILD(this)->fops->flush, fd, xdata);
  894     return 0;
  895 
  896 err:
  897     STACK_UNWIND_STRICT(create, frame, -1, errno, NULL, NULL, NULL, NULL, NULL,
  898                         NULL);
  899     return 0;
  900 }
  901 
  902 int32_t
  903 mem_acct_init(xlator_t *this)
  904 {
  905     int ret = -1;
  906 
  907     if (!this)
  908         return ret;
  909 
  910     ret = xlator_mem_acct_init(this, gf_leases_mt_end + 1);
  911 
  912     if (ret != 0) {
  913         gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM,
  914                "mem account init failed");
  915         return ret;
  916     }
  917 
  918     return ret;
  919 }
  920 
  921 static int
  922 leases_init_priv(xlator_t *this)
  923 {
  924     int ret = 0;
  925     leases_private_t *priv = NULL;
  926 
  927     priv = this->private;
  928     GF_ASSERT(priv);
  929 
  930     if (!priv->timer_wheel) {
  931         priv->timer_wheel = glusterfs_ctx_tw_get(this->ctx);
  932         if (!priv->timer_wheel) {
  933             ret = -1;
  934             goto out;
  935         }
  936     }
  937 
  938     if (!priv->inited_recall_thr) {
  939         ret = gf_thread_create(&priv->recall_thr, NULL, expired_recall_cleanup,
  940                                this, "leasercl");
  941         if (!ret)
  942             priv->inited_recall_thr = _gf_true;
  943     }
  944 
  945 out:
  946     return ret;
  947 }
  948 
  949 int
  950 reconfigure(xlator_t *this, dict_t *options)
  951 {
  952     leases_private_t *priv = NULL;
  953     int ret = -1;
  954 
  955     priv = this->private;
  956     GF_ASSERT(priv);
  957 
  958     /* TODO: In case of reconfigure, if its enabling the leases
  959      * its not an issue, but if its disabling the leases, there
  960      * is more to it, like recall all the existing leases, wait
  961      * for unlock of all the leases etc., hence not supporting the
  962      * reconfigure for now.
  963 
  964     GF_OPTION_RECONF ("leases", priv->leases_enabled,
  965                       options, bool, out);
  966 
  967     if (priv->leases_enabled) {
  968             ret = leases_init_priv (this);
  969             if (ret)
  970                     goto out;
  971     }
  972     */
  973 
  974     GF_OPTION_RECONF("lease-lock-recall-timeout", priv->recall_lease_timeout,
  975                      options, int32, out);
  976 
  977     ret = 0;
  978 out:
  979     return ret;
  980 }
  981 
  982 int
  983 init(xlator_t *this)
  984 {
  985     int ret = -1;
  986     leases_private_t *priv = NULL;
  987 
  988     priv = GF_CALLOC(1, sizeof(*priv), gf_leases_mt_private_t);
  989     if (!priv) {
  990         gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM,
  991                "Leases init failed");
  992         goto out;
  993     }
  994 
  995     GF_OPTION_INIT("leases", priv->leases_enabled, bool, out);
  996     GF_OPTION_INIT("lease-lock-recall-timeout", priv->recall_lease_timeout,
  997                    int32, out);
  998     pthread_mutex_init(&priv->mutex, NULL);
  999     INIT_LIST_HEAD(&priv->client_list);
 1000     INIT_LIST_HEAD(&priv->recall_list);
 1001 
 1002     this->private = priv;
 1003 
 1004     if (priv->leases_enabled) {
 1005         ret = leases_init_priv(this);
 1006         if (ret)
 1007             goto out;
 1008     }
 1009 
 1010     ret = 0;
 1011 
 1012 out:
 1013     if (ret) {
 1014         GF_FREE(priv);
 1015         this->private = NULL;
 1016     }
 1017 
 1018     return ret;
 1019 }
 1020 
 1021 void
 1022 fini(xlator_t *this)
 1023 {
 1024     leases_private_t *priv = NULL;
 1025 
 1026     priv = this->private;
 1027     if (!priv) {
 1028         return;
 1029     }
 1030     this->private = NULL;
 1031 
 1032     priv->fini = _gf_true;
 1033     pthread_cond_broadcast(&priv->cond);
 1034     if (priv->recall_thr) {
 1035         gf_thread_cleanup_xint(priv->recall_thr);
 1036         priv->recall_thr = 0;
 1037         priv->inited_recall_thr = _gf_false;
 1038     }
 1039 
 1040     if (priv->timer_wheel) {
 1041         glusterfs_ctx_tw_put(this->ctx);
 1042     }
 1043 
 1044     GF_FREE(priv);
 1045     return;
 1046 }
 1047 
 1048 static int
 1049 leases_forget(xlator_t *this, inode_t *inode)
 1050 {
 1051     /* TODO:leases_cleanup_inode_ctx (this, inode); */
 1052     return 0;
 1053 }
 1054 
 1055 static int
 1056 leases_release(xlator_t *this, fd_t *fd)
 1057 {
 1058     int ret = -1;
 1059     uint64_t tmp = 0;
 1060     lease_fd_ctx_t *fd_ctx = NULL;
 1061 
 1062     if (fd == NULL) {
 1063         goto out;
 1064     }
 1065 
 1066     gf_log(this->name, GF_LOG_TRACE, "Releasing all leases with fd %p", fd);
 1067 
 1068     ret = fd_ctx_del(fd, this, &tmp);
 1069     if (ret) {
 1070         gf_log(this->name, GF_LOG_DEBUG, "Could not get fdctx");
 1071         goto out;
 1072     }
 1073 
 1074     fd_ctx = (lease_fd_ctx_t *)(long)tmp;
 1075     if (fd_ctx)
 1076         GF_FREE(fd_ctx);
 1077 out:
 1078     return ret;
 1079 }
 1080 
 1081 static int
 1082 leases_clnt_disconnect_cbk(xlator_t *this, client_t *client)
 1083 {
 1084     int ret = 0;
 1085 
 1086     EXIT_IF_LEASES_OFF(this, out);
 1087 
 1088     ret = cleanup_client_leases(this, client->client_uid);
 1089 out:
 1090     return ret;
 1091 }
 1092 
 1093 struct xlator_fops fops = {
 1094     /* Metadata modifying fops */
 1095     .fsetattr = leases_fsetattr,
 1096     .setattr = leases_setattr,
 1097 
 1098     /* File Data reading fops */
 1099     .open = leases_open,
 1100     .readv = leases_readv,
 1101 
 1102     /* File Data modifying fops */
 1103     .truncate = leases_truncate,
 1104     .ftruncate = leases_ftruncate,
 1105     .writev = leases_writev,
 1106     .zerofill = leases_zerofill,
 1107     .fallocate = leases_fallocate,
 1108     .discard = leases_discard,
 1109     .lk = leases_lk,
 1110     .fsync = leases_fsync,
 1111     .flush = leases_flush,
 1112     .lease = leases_lease,
 1113 
 1114     /* Directory Data modifying fops */
 1115     .create = leases_create,
 1116     .rename = leases_rename,
 1117     .unlink = leases_unlink,
 1118     .link = leases_link,
 1119 
 1120 #ifdef NOT_SUPPORTED
 1121     /* internal lk fops */
 1122     .inodelk = leases_inodelk,
 1123     .finodelk = leases_finodelk,
 1124     .entrylk = leases_entrylk,
 1125     .fentrylk = leases_fentrylk,
 1126 
 1127     /* Internal special fops*/
 1128     .xattrop = leases_xattrop,
 1129     .fxattrop = leases_fxattrop,
 1130 #endif
 1131 };
 1132 
 1133 struct xlator_cbks cbks = {
 1134     .forget = leases_forget,
 1135     .release = leases_release,
 1136     .client_disconnect = leases_clnt_disconnect_cbk,
 1137 };
 1138 
 1139 struct volume_options options[] = {
 1140     {.key = {"leases"},
 1141      .type = GF_OPTION_TYPE_BOOL,
 1142      .default_value = "off",
 1143      .op_version = {GD_OP_VERSION_3_8_0},
 1144      .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
 1145      .description = "When \"on\", enables leases support"},
 1146     {.key = {"lease-lock-recall-timeout"},
 1147      .type = GF_OPTION_TYPE_INT,
 1148      .default_value = RECALL_LEASE_LK_TIMEOUT,
 1149      .op_version = {GD_OP_VERSION_3_8_0},
 1150      .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
 1151      .description = "After 'timeout' seconds since the recall_lease"
 1152                     " request has been sent to the client, the lease lock"
 1153                     " will be forcefully purged by the server."},
 1154     {.key = {NULL}},
 1155 };
 1156 
 1157 xlator_api_t xlator_api = {
 1158     .init = init,
 1159     .fini = fini,
 1160     .reconfigure = reconfigure,
 1161     .mem_acct_init = mem_acct_init,
 1162     .op_version = {1}, /* Present from the initial version */
 1163     .fops = &fops,
 1164     .cbks = &cbks,
 1165     .options = options,
 1166     .identifier = "leases",
 1167     .category = GF_MAINTAINED,
 1168 };