summaryrefslogtreecommitdiffstats
path: root/xlators/features/upcall/src/upcall.h
blob: 7cbec22bbf2318a8de02a7f40f03e5c8c29e0959 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
   This file is part of GlusterFS.

   This file is licensed to you under your choice of the GNU Lesser
   General Public License, version 3 or any later version (LGPLv3 or
   later), or the GNU General Public License, version 2 (GPLv2), in all
   cases as published by the Free Software Foundation.
*/
#ifndef __UPCALL_H__
#define __UPCALL_H__

#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif

#include "compat-errno.h"
#include "stack.h"
#include "call-stub.h"
#include "upcall-mem-types.h"
#include "client_t.h"
#include "rpcsvc.h"
#include "lkowner.h"
#include "locking.h"
#include "upcall-messages.h"
#include "upcall-cache-invalidation.h"

#define EXIT_IF_UPCALL_OFF(this, label) do {                       \
        if (!is_upcall_enabled(this))                              \
                goto label;                                        \
} while (0)

#define UPCALL_STACK_UNWIND(fop, frame, params ...) do {        \
        upcall_local_t *__local = NULL;                         \
        xlator_t *__xl          = NULL;                         \
        if (frame) {                                            \
                        __xl         = frame->this;             \
                        __local      = frame->local;            \
                        frame->local = NULL;                    \
        }                                                       \
        STACK_UNWIND_STRICT (fop, frame, params);               \
        upcall_local_wipe (__xl, __local);                      \
} while (0)

#define UPCALL_STACK_DESTROY(frame) do {                   \
                upcall_local_t *__local = NULL;            \
                xlator_t    *__xl    = NULL;               \
                __xl                 = frame->this;        \
                __local              = frame->local;       \
                frame->local         = NULL;               \
                STACK_DESTROY (frame->root);               \
                upcall_local_wipe (__xl, __local);         \
} while (0)

struct _upcall_private_t {
        gf_boolean_t     cache_invalidation_enabled;
        int32_t          cache_invalidation_timeout;
};
typedef struct _upcall_private_t upcall_private_t;

enum _upcall_event_type_t {
        EVENT_NULL,
        CACHE_INVALIDATION,
};
typedef enum _upcall_event_type_t upcall_event_type_t;

struct _upcall_client_t {
        struct list_head client_list;
        /* strdup to store client_uid, strdup. Free it explicitly */
        char *client_uid;
        time_t access_time; /* time last accessed */
        /* the amount of time which client can cache this entry */
        uint32_t expire_time_attr;
};
typedef struct _upcall_client_t upcall_client_t;

/* Upcall entries are maintained in inode_ctx */
struct _upcall_inode_ctx_t {
        struct list_head client_list;
        pthread_mutex_t client_list_lock; /* mutex for clients list
                                                of this upcall entry */
};
typedef struct _upcall_inode_ctx_t upcall_inode_ctx_t;

struct _notify_event_data {
        uuid_t gfid;
        upcall_client_t *client_entry;
        upcall_event_type_t event_type;
        uint32_t invalidate_flags;
        /* any extra data needed, like inode flags
         * to be invalidated incase of cache invalidation,
         * may be fd for lease recalls */
        void *extra;
};
typedef struct _notify_event_data notify_event_data_t;

struct upcall_local {
        /* XXX: need to check if we can store
         * pointers in 'local' which may get freed
         * in future by other thread
         */
        upcall_inode_ctx_t *upcall_inode_ctx;
        inode_t   *inode;
};
typedef struct upcall_local upcall_local_t;

void upcall_local_wipe (xlator_t *this, upcall_local_t *local);
upcall_local_t *upcall_local_init (call_frame_t *frame, xlator_t *this, inode_t *inode);

upcall_client_t *add_upcall_client (call_frame_t *frame, uuid_t gfid,
                                    client_t *client,
                                    upcall_inode_ctx_t *up_inode_ctx);
upcall_client_t *__add_upcall_client (call_frame_t *frame, uuid_t gfid,
                                      client_t *client,
                                      upcall_inode_ctx_t *up_inode_ctx);
upcall_client_t *__get_upcall_client (call_frame_t *frame, uuid_t gfid,
                                      client_t *client,
                                      upcall_inode_ctx_t *up_inode_ctx);
int __upcall_cleanup_client_entry (upcall_client_t *up_client);

int __upcall_inode_ctx_set (inode_t *inode, xlator_t *this);
upcall_inode_ctx_t *__upcall_inode_ctx_get (inode_t *inode, xlator_t *this);
upcall_inode_ctx_t *upcall_inode_ctx_get (inode_t *inode, xlator_t *this);
int upcall_cleanup_inode_ctx (xlator_t *this, inode_t *inode);
void upcall_cache_forget (xlator_t *this, inode_t *inode,
                          upcall_inode_ctx_t *up_inode_ctx);

/* Xlator options */
gf_boolean_t is_upcall_enabled(xlator_t *this);

/* Cache invalidation specific */
void upcall_cache_invalidate (call_frame_t *frame, xlator_t *this, client_t *client,
                              inode_t *inode, uint32_t flags);
void upcall_client_cache_invalidate (xlator_t *xl, uuid_t gfid,
                                     upcall_client_t *up_client_entry,
                                     uint32_t flags);

#endif /* __UPCALL_H__ */