summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/stripe/src/stripe.h
blob: 53b683c735caee8e6f709839ad32e4c7a4c54dae (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
/*
  Copyright (c) 2008-2012 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 _STRIPE_H_
#define _STRIPE_H_

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

#include "xlator.h"
#include "logging.h"
#include "defaults.h"
#include "common-utils.h"
#include "compat.h"
#include "compat-errno.h"
#include "stripe-mem-types.h"
#include "libxlator.h"
#include <fnmatch.h>
#include <signal.h>

#define STRIPE_PATHINFO_HEADER "STRIPE:"
#define STRIPE_MIN_BLOCK_SIZE  (16*GF_UNIT_KB)

#define STRIPE_STACK_UNWIND(fop, frame, params ...) do {           \
                stripe_local_t *__local = NULL;                    \
                if (frame) {                                       \
                        __local = frame->local;                    \
                        frame->local = NULL;                       \
                }                                                  \
                STACK_UNWIND_STRICT (fop, frame, params);          \
                if (__local) {                                     \
                        stripe_local_wipe(__local);                \
                        mem_put (__local);       \
                }                                                  \
        } while (0)

#define STRIPE_STACK_DESTROY(frame) do {                        \
                stripe_local_t *__local = NULL;                 \
                __local = frame->local;                         \
                frame->local = NULL;                            \
                STACK_DESTROY (frame->root);                    \
                if (__local) {                                  \
                        stripe_local_wipe (__local);            \
                        mem_put (__local);    \
                }                                               \
        } while (0)

#define STRIPE_VALIDATE_FCTX(fctx, label) do {                  \
        int     idx = 0;                                        \
        if (!fctx) {                                            \
                op_errno = EINVAL;                              \
                goto label;                                     \
        }                                                       \
        for (idx = 0; idx < fctx->stripe_count; idx++) {        \
                if (!fctx->xl_array[idx]) {                     \
                        gf_log (this->name, GF_LOG_ERROR,       \
                                "fctx->xl_array[%d] is NULL",   \
                                idx);                           \
                        op_errno = ESTALE;                      \
                        goto label;                             \
                }                                               \
        }                                                       \
       } while (0)

typedef struct stripe_xattr_sort {
        int   pos;
        int   xattr_len;
        char *xattr_value;
} stripe_xattr_sort_t;

/**
 * struct stripe_options : This keeps the pattern and the block-size
 *     information, which is used for striping on a file.
 */
struct stripe_options {
        struct stripe_options *next;
        char                   path_pattern[256];
        uint64_t               block_size;
};

/**
 * Private structure for stripe translator
 */
struct stripe_private {
        struct stripe_options  *pattern;
        xlator_t              **xl_array;
        uint64_t                block_size;
        gf_lock_t               lock;
        uint8_t                 nodes_down;
        int8_t                  first_child_down;
        int8_t                  child_count;
        int8_t                 *state; /* Current state of child node */
        gf_boolean_t            xattr_supported;  /* default yes */
	gf_boolean_t		coalesce;
        char                    vol_uuid[UUID_SIZE + 1];
};

/**
 * Used to keep info about the replies received from readv/writev calls
 */
struct stripe_replies {
        struct iovec *vector;
        int32_t       count;    //count of vector
        int32_t       op_ret;   //op_ret of readv
        int32_t       op_errno;
        int32_t       requested_size;
        struct iatt   stbuf;    /* 'stbuf' is also a part of reply */
};

typedef struct _stripe_fd_ctx {
        off_t      stripe_size;
        int        stripe_count;
	int	   stripe_coalesce;
        int        static_array;
        xlator_t **xl_array;
} stripe_fd_ctx_t;


/**
 * Local structure to be passed with all the frames in case of STACK_WIND
 */
struct stripe_local; /* this itself is used inside the structure; */

struct stripe_local {
        struct stripe_local *next;
        call_frame_t        *orig_frame;

        stripe_fd_ctx_t     *fctx;

        /* Used by _cbk functions */
        struct iatt          stbuf;
        struct iatt          pre_buf;
        struct iatt          post_buf;
        struct iatt          preparent;
        struct iatt          postparent;

        off_t                stbuf_size;
        off_t                prebuf_size;
        off_t                postbuf_size;
        off_t                preparent_size;
        off_t                postparent_size;

        blkcnt_t             stbuf_blocks;
        blkcnt_t             prebuf_blocks;
        blkcnt_t             postbuf_blocks;
        blkcnt_t             preparent_blocks;
        blkcnt_t             postparent_blocks;

        struct stripe_replies *replies;
        struct statvfs        statvfs_buf;
        dir_entry_t          *entry;

        int8_t               revalidate;
        int8_t               failed;
        int8_t               unwind;

        size_t               readv_size;
        int32_t              entry_count;
        int32_t              node_index;
        int32_t              call_count;
        int32_t              wind_count; /* used instead of child_cound
                                            in case of read and write */
        int32_t              op_ret;
        int32_t              op_errno;
        int32_t              count;
        int32_t              flags;
        char                *name;
        inode_t             *inode;

        loc_t                loc;
        loc_t                loc2;

        mode_t               mode;
        dev_t                rdev;
        /* For File I/O fops */
        dict_t              *xdata;

        stripe_xattr_sort_t *xattr_list;
        int32_t              xattr_total_len;
        int32_t              nallocs;
        char xsel[256];

        struct marker_str    marker;

        /* General usage */
        off_t                offset;
        off_t                stripe_size;

        int xattr_self_heal_needed;
        int entry_self_heal_needed;

        int8_t              *list;
        struct gf_flock         lock;
        fd_t                *fd;
        void                *value;
        struct iobref       *iobref;
        gf_dirent_t          entries;
        gf_dirent_t         *dirent;
        dict_t              *xattr;
        uuid_t               ia_gfid;

        int                  xflag;
        mode_t               umask;
};

typedef struct stripe_local   stripe_local_t;
typedef struct stripe_private stripe_private_t;

/*
 * Determine the stripe index of a particular frame based on the translator.
 */
static inline int32_t stripe_get_frame_index(stripe_fd_ctx_t *fctx,
					     call_frame_t *prev)
{
	int32_t i, idx = -1;

	for (i = 0; i < fctx->stripe_count; i++) {
		if (fctx->xl_array[i] == prev->this) {
			idx = i;
			break;
		}
	}

	return idx;
}

static inline void stripe_copy_xl_array(xlator_t **dst, xlator_t **src,
					int count)
{
	int i;

	for (i = 0; i < count; i++)
		dst[i] = src[i];
}

void stripe_local_wipe (stripe_local_t *local);
int32_t stripe_ctx_handle (xlator_t *this, call_frame_t *prev,
                           stripe_local_t *local, dict_t *dict);
void stripe_aggregate_xattr (dict_t *dst, dict_t *src);
int32_t stripe_xattr_request_build (xlator_t *this, dict_t *dict,
                                    uint64_t stripe_size, uint32_t stripe_count,
                                    uint32_t stripe_index,
				    uint32_t stripe_coalesce);
int32_t stripe_get_matching_bs (const char *path, stripe_private_t *priv);
int set_stripe_block_size (xlator_t *this, stripe_private_t *priv, char *data);
int32_t stripe_iatt_merge (struct iatt *from, struct iatt *to);
int32_t stripe_fill_pathinfo_xattr (xlator_t *this, stripe_local_t *local,
                                    char **xattr_serz);
int32_t stripe_free_xattr_str (stripe_local_t *local);
int32_t stripe_xattr_aggregate (char *buffer, stripe_local_t *local,
                                int32_t *total);
off_t coalesced_offset(off_t offset, uint64_t stripe_size, int stripe_count);
off_t uncoalesced_size(off_t size, uint64_t stripe_size, int stripe_count,
			int stripe_index);
int32_t
stripe_fill_lockinfo_xattr (xlator_t *this, stripe_local_t *local,
                            void **xattr_serz);

/*
 * Adjust the size attribute for files if coalesce is enabled.
 */
static inline void correct_file_size(struct iatt *buf, stripe_fd_ctx_t *fctx,
	call_frame_t *prev)
{
	int index;

	if (!IA_ISREG(buf->ia_type))
		return;

	if (!fctx || !fctx->stripe_coalesce)
		return;

	index = stripe_get_frame_index(fctx, prev);
	buf->ia_size = uncoalesced_size(buf->ia_size, fctx->stripe_size,
		fctx->stripe_count, index);
}

#endif /* _STRIPE_H_ */