"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/xlators/features/leases/src/leases.h" (16 Sep 2020, 12816 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.h" 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 _LEASES_H
   12 #define _LEASES_H
   13 
   14 #ifndef _CONFIG_H
   15 #define _CONFIG_H
   16 #include "config.h"
   17 #endif
   18 
   19 #include <glusterfs/common-utils.h>
   20 #include <glusterfs/glusterfs.h>
   21 #include <glusterfs/xlator.h>
   22 #include <glusterfs/call-stub.h>
   23 #include <glusterfs/logging.h>
   24 #include <glusterfs/client_t.h>
   25 #include <glusterfs/lkowner.h>
   26 #include <glusterfs/locking.h>
   27 #include <glusterfs/upcall-utils.h>
   28 #include "timer-wheel.h"
   29 #include "leases-mem-types.h"
   30 #include "leases-messages.h"
   31 
   32 /* The time period for which a client lease lock will be stored after its been
   33  * recalled for the first time. */
   34 #define RECALL_LEASE_LK_TIMEOUT "60"
   35 
   36 #define DATA_MODIFY_FOP 0x0001
   37 #define BLOCKING_FOP 0x0002
   38 
   39 #define BLOCK_FOP 0x0001
   40 #define WIND_FOP 0x0002
   41 
   42 #define EXIT_IF_LEASES_OFF(this, label)                                        \
   43     do {                                                                       \
   44         if (!is_leases_enabled(this))                                          \
   45             goto label;                                                        \
   46     } while (0)
   47 
   48 #define EXIT_IF_INTERNAL_FOP(frame, xdata, label)                              \
   49     do {                                                                       \
   50         if (frame->root->pid < 0)                                              \
   51             goto label;                                                        \
   52         if (xdata && dict_get(xdata, GLUSTERFS_INTERNAL_FOP_KEY))              \
   53             goto label;                                                        \
   54     } while (0)
   55 
   56 #define GET_LEASE_ID(xdata, lease_id, client_uid)                              \
   57     do {                                                                       \
   58         int ret_val = -1;                                                      \
   59         ret_val = dict_get_bin(xdata, "lease-id", (void **)&lease_id);         \
   60         if (ret_val) {                                                         \
   61             ret_val = 0;                                                       \
   62             gf_msg_debug("leases", 0, "Lease id is not set for client:%s",     \
   63                          client_uid);                                          \
   64         }                                                                      \
   65     } while (0)
   66 
   67 #define GET_FLAGS(fop, fd_flags)                                               \
   68     do {                                                                       \
   69         if ((fd_flags & (O_WRONLY | O_RDWR)) && fop == GF_FOP_OPEN)            \
   70             fop_flags = DATA_MODIFY_FOP;                                       \
   71                                                                                \
   72         if (fop == GF_FOP_UNLINK || fop == GF_FOP_RENAME ||                    \
   73             fop == GF_FOP_TRUNCATE || fop == GF_FOP_FTRUNCATE ||               \
   74             fop == GF_FOP_FLUSH || fop == GF_FOP_FSYNC ||                      \
   75             fop == GF_FOP_WRITE || fop == GF_FOP_FALLOCATE ||                  \
   76             fop == GF_FOP_DISCARD || fop == GF_FOP_ZEROFILL ||                 \
   77             fop == GF_FOP_SETATTR || fop == GF_FOP_FSETATTR ||                 \
   78             fop == GF_FOP_LINK)                                                \
   79             fop_flags = DATA_MODIFY_FOP;                                       \
   80                                                                                \
   81         if (!(fd_flags & (O_NONBLOCK | O_NDELAY)))                             \
   82             fop_flags |= BLOCKING_FOP;                                         \
   83                                                                                \
   84     } while (0)
   85 
   86 #define GET_FLAGS_LK(cmd, l_type, fd_flags)                                    \
   87     do {                                                                       \
   88         /* TODO: handle F_RESLK_LCK and other glusterfs_lk_recovery_cmds_t */  \
   89         if ((cmd == F_SETLKW || cmd == F_SETLKW64 || cmd == F_SETLK ||         \
   90              cmd == F_SETLK64) &&                                              \
   91             l_type == F_WRLCK)                                                 \
   92             fop_flags = DATA_MODIFY_FOP;                                       \
   93                                                                                \
   94         if (fd_flags & (O_NONBLOCK | O_NDELAY) &&                              \
   95             (cmd == F_SETLKW || cmd == F_SETLKW64))                            \
   96             fop_flags |= BLOCKING_FOP;                                         \
   97                                                                                \
   98     } while (0)
   99 
  100 #define LEASE_BLOCK_FOP(inode, fop_name, frame, this, params...)               \
  101     do {                                                                       \
  102         call_stub_t *__stub = NULL;                                            \
  103         fop_stub_t *blk_fop = NULL;                                            \
  104         lease_inode_ctx_t *lease_ctx = NULL;                                   \
  105                                                                                \
  106         __stub = fop_##fop_name##_stub(frame, default_##fop_name##_resume,     \
  107                                        params);                                \
  108         if (!__stub) {                                                         \
  109             gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM,       \
  110                    "Unable to create stub");                                   \
  111             ret = -ENOMEM;                                                     \
  112             goto __out;                                                        \
  113         }                                                                      \
  114                                                                                \
  115         blk_fop = GF_CALLOC(1, sizeof(*blk_fop), gf_leases_mt_fop_stub_t);     \
  116         if (!blk_fop) {                                                        \
  117             gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM,       \
  118                    "Unable to create lease fop stub");                         \
  119             ret = -ENOMEM;                                                     \
  120             goto __out;                                                        \
  121         }                                                                      \
  122                                                                                \
  123         lease_ctx = lease_ctx_get(inode, this);                                \
  124         if (!lease_ctx) {                                                      \
  125             gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM,       \
  126                    "Unable to create/get inode ctx");                          \
  127             ret = -ENOMEM;                                                     \
  128             goto __out;                                                        \
  129         }                                                                      \
  130                                                                                \
  131         blk_fop->stub = __stub;                                                \
  132         pthread_mutex_lock(&lease_ctx->lock);                                  \
  133         {                                                                      \
  134             /*TODO: If the lease is unlocked btw check lease conflict and      \
  135              * by now, then this fop shouldn't be add to the blocked fop       \
  136              * list, can use generation number for the same?*/                 \
  137             list_add_tail(&blk_fop->list, &lease_ctx->blocked_list);           \
  138         }                                                                      \
  139         pthread_mutex_unlock(&lease_ctx->lock);                                \
  140                                                                                \
  141     __out:                                                                     \
  142         if (ret < 0) {                                                         \
  143             gf_msg(this->name, GF_LOG_WARNING, ENOMEM, LEASE_MSG_NO_MEM,       \
  144                    "Unable to create stub for blocking the fop:%s (%s)",       \
  145                    gf_fop_list[frame->root->op], strerror(ENOMEM));            \
  146             if (__stub != NULL) {                                              \
  147                 call_stub_destroy(__stub);                                     \
  148             }                                                                  \
  149             GF_FREE(blk_fop);                                                  \
  150             goto err;                                                          \
  151         }                                                                      \
  152     } while (0)
  153 
  154 struct _leases_private {
  155     struct list_head client_list;
  156     struct list_head recall_list;
  157     struct tvec_base *timer_wheel; /* timer wheel where the recall request
  158                                       is qued and waits for unlock/expiry */
  159     pthread_t recall_thr;
  160     pthread_mutex_t mutex;
  161     pthread_cond_t cond;
  162     int32_t recall_lease_timeout;
  163     gf_boolean_t inited_recall_thr;
  164     gf_boolean_t fini;
  165     gf_boolean_t leases_enabled;
  166 
  167     char _pad[1]; /* manual padding */
  168 };
  169 typedef struct _leases_private leases_private_t;
  170 
  171 struct _lease_client {
  172     char *client_uid;
  173     struct list_head client_list;
  174     struct list_head inode_list;
  175 };
  176 typedef struct _lease_client lease_client_t;
  177 
  178 struct _lease_inode {
  179     inode_t *inode;
  180     struct list_head
  181         list; /* This can be part of both inode_list and recall_list */
  182 };
  183 typedef struct _lease_inode lease_inode_t;
  184 
  185 struct _lease_fd_ctx {
  186     char *client_uid;
  187     char lease_id[LEASE_ID_SIZE];
  188 };
  189 typedef struct _lease_fd_ctx lease_fd_ctx_t;
  190 
  191 struct _lease_inode_ctx {
  192     struct list_head lease_id_list; /* clients that have taken leases */
  193     int lease_type_cnt[GF_LEASE_MAX_TYPE + 1];
  194     uint64_t lease_cnt;            /* Total number of leases on this inode */
  195     uint64_t openfd_cnt;           /* number of fds open */
  196     struct list_head blocked_list; /* List of fops blocked until the
  197                                       lease recall is complete */
  198     inode_t *inode;                /* this represents the inode on which the
  199                                       lock was taken, required mainly during
  200                                       disconnect cleanup */
  201     struct gf_tw_timer_list *timer;
  202     pthread_mutex_t lock;
  203     int lease_type;                  /* Types of leases acquired */
  204     gf_boolean_t recall_in_progress; /* if lease recall is sent on this inode */
  205     gf_boolean_t blocked_fops_resuming; /* if blocked fops are being resumed */
  206 
  207     char _pad[2]; /* manual padding */
  208 };
  209 typedef struct _lease_inode_ctx lease_inode_ctx_t;
  210 
  211 struct _lease_id_entry {
  212     struct list_head lease_id_list;
  213     char lease_id[LEASE_ID_SIZE];
  214     char *client_uid;                          /* uid of the client that has
  215                                                   taken the lease */
  216     int lease_type_cnt[GF_LEASE_MAX_TYPE + 1]; /* count of each lease type */
  217     uint64_t lease_cnt; /* Number of leases taken under the
  218                            given lease id */
  219     time_t recall_time; /* time @ which recall was sent */
  220     int lease_type;     /* Union of all the leases taken
  221                            under the given lease id */
  222     char _pad[4];       /* manual padding */
  223 };
  224 typedef struct _lease_id_entry lease_id_entry_t;
  225 
  226 /* Required? as stub itself will have list */
  227 struct __fop_stub {
  228     struct list_head list;
  229     call_stub_t *stub;
  230 };
  231 typedef struct __fop_stub fop_stub_t;
  232 
  233 struct __lease_timer_data {
  234     inode_t *inode;
  235     xlator_t *this;
  236 };
  237 typedef struct __lease_timer_data lease_timer_data_t;
  238 
  239 gf_boolean_t
  240 is_leases_enabled(xlator_t *this);
  241 
  242 lease_inode_ctx_t *
  243 lease_ctx_get(inode_t *inode, xlator_t *this);
  244 
  245 int
  246 process_lease_req(call_frame_t *frame, xlator_t *this, inode_t *inode,
  247                   struct gf_lease *lease);
  248 
  249 int
  250 check_lease_conflict(call_frame_t *frame, inode_t *inode, const char *lease_id,
  251                      uint32_t fop_flags);
  252 
  253 int
  254 cleanup_client_leases(xlator_t *this, const char *client_uid);
  255 
  256 void *
  257 expired_recall_cleanup(void *data);
  258 
  259 #endif /* _LEASES_H */