glusterfs

Форк
0
339 строк · 9.4 Кб
1
/*
2
   Copyright (c) 2013 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 <sys/uio.h>
12

13
#include <glusterfs/logging.h>
14

15
#include "cdc.h"
16
#include "cdc-mem-types.h"
17

18
static void
19
cdc_cleanup_iobref(cdc_info_t *ci)
20
{
21
    assert(ci->iobref != NULL);
22
    iobref_clear(ci->iobref);
23
}
24

25
static int32_t
26
cdc_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
27
              int32_t op_errno, struct iovec *vector, int32_t count,
28
              struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
29
{
30
    int ret = -1;
31
    cdc_priv_t *priv = NULL;
32
    cdc_info_t ci = {
33
        0,
34
    };
35

36
    GF_VALIDATE_OR_GOTO("cdc", this, default_out);
37
    GF_VALIDATE_OR_GOTO(this->name, frame, default_out);
38

39
    if (op_ret <= 0)
40
        goto default_out;
41

42
    priv = this->private;
43

44
    if ((priv->min_file_size != 0) && (op_ret < priv->min_file_size))
45
        goto default_out;
46

47
    ci.count = count;
48
    ci.ibytes = op_ret;
49
    ci.vector = vector;
50
    ci.buf = NULL;
51
    ci.iobref = NULL;
52
    ci.ncount = 0;
53
    ci.crc = 0;
54
    ci.buffer_size = GF_CDC_DEF_BUFFERSIZE;
55

56
    /* A readv compresses on the server side and decompresses on the client side
57
     */
58
    if (priv->op_mode == GF_CDC_MODE_SERVER) {
59
        ret = cdc_compress(this, priv, &ci, &xdata);
60
    } else if (priv->op_mode == GF_CDC_MODE_CLIENT) {
61
        ret = cdc_decompress(this, priv, &ci, xdata);
62
    } else {
63
        gf_log(this->name, GF_LOG_ERROR, "Invalid operation mode (%d)",
64
               priv->op_mode);
65
    }
66

67
    if (ret)
68
        goto default_out;
69

70
    STACK_UNWIND_STRICT(readv, frame, ci.nbytes, op_errno, ci.vec, ci.ncount,
71
                        stbuf, iobref, xdata);
72
    cdc_cleanup_iobref(&ci);
73
    return 0;
74

75
default_out:
76
    STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, vector, count, stbuf,
77
                        iobref, xdata);
78
    return 0;
79
}
80

81
int32_t
82
cdc_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
83
          off_t offset, uint32_t flags, dict_t *xdata)
84
{
85
    STACK_WIND(frame, cdc_readv_cbk, FIRST_CHILD(this),
86
               FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata);
87
    return 0;
88
}
89

90
static int32_t
91
cdc_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
92
               int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
93
               struct iatt *postbuf, dict_t *xdata)
94
{
95
    STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf,
96
                        xdata);
97
    return 0;
98
}
99

100
int32_t
101
cdc_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
102
           int32_t count, off_t offset, uint32_t flags, struct iobref *iobref,
103
           dict_t *xdata)
104
{
105
    int ret = -1;
106
    cdc_priv_t *priv = NULL;
107
    cdc_info_t ci = {
108
        0,
109
    };
110
    size_t isize = 0;
111

112
    GF_VALIDATE_OR_GOTO("cdc", this, err);
113
    GF_VALIDATE_OR_GOTO(this->name, frame, err);
114

115
    isize = iov_length(vector, count);
116

117
    if (isize <= 0)
118
        goto default_out;
119

120
    priv = this->private;
121

122
    if ((priv->min_file_size != 0) && (isize < priv->min_file_size))
123
        goto default_out;
124

125
    ci.count = count;
126
    ci.ibytes = isize;
127
    ci.vector = vector;
128
    ci.buf = NULL;
129
    ci.iobref = NULL;
130
    ci.ncount = 0;
131
    ci.crc = 0;
132
    ci.buffer_size = GF_CDC_DEF_BUFFERSIZE;
133

134
    /* A writev compresses on the client side and decompresses on the server
135
     * side
136
     */
137
    if (priv->op_mode == GF_CDC_MODE_CLIENT) {
138
        ret = cdc_compress(this, priv, &ci, &xdata);
139
    } else if (priv->op_mode == GF_CDC_MODE_SERVER) {
140
        ret = cdc_decompress(this, priv, &ci, xdata);
141
    } else {
142
        gf_log(this->name, GF_LOG_ERROR, "Invalid operation mode (%d) ",
143
               priv->op_mode);
144
    }
145

146
    if (ret)
147
        goto default_out;
148

149
    STACK_WIND(frame, cdc_writev_cbk, FIRST_CHILD(this),
150
               FIRST_CHILD(this)->fops->writev, fd, ci.vec, ci.ncount, offset,
151
               flags, iobref, xdata);
152

153
    cdc_cleanup_iobref(&ci);
154
    return 0;
155

156
default_out:
157
    STACK_WIND(frame, cdc_writev_cbk, FIRST_CHILD(this),
158
               FIRST_CHILD(this)->fops->writev, fd, vector, count, offset,
159
               flags, iobref, xdata);
160
    return 0;
161
err:
162
    STACK_UNWIND_STRICT(writev, frame, -1, EINVAL, NULL, NULL, NULL);
163
    return 0;
164
}
165

166
int32_t
167
mem_acct_init(xlator_t *this)
168
{
169
    int ret = -1;
170

171
    if (!this)
172
        return ret;
173

174
    ret = xlator_mem_acct_init(this, gf_cdc_mt_end);
175

176
    if (ret != 0) {
177
        gf_log(this->name, GF_LOG_ERROR,
178
               "Memory accounting init"
179
               "failed");
180
        return ret;
181
    }
182

183
    return ret;
184
}
185

186
int32_t
187
init(xlator_t *this)
188
{
189
    int ret = -1;
190
    char *temp_str = NULL;
191
    cdc_priv_t *priv = NULL;
192

193
    GF_VALIDATE_OR_GOTO("cdc", this, err);
194

195
    if (!this->children || this->children->next) {
196
        gf_log(this->name, GF_LOG_ERROR, "Need subvolume == 1");
197
        goto err;
198
    }
199

200
    if (!this->parents) {
201
        gf_log(this->name, GF_LOG_WARNING, "Dangling volume. Check volfile");
202
    }
203

204
    priv = GF_CALLOC(1, sizeof(*priv), gf_cdc_mt_priv_t);
205
    if (!priv) {
206
        goto err;
207
    }
208

209
    /* Check if debug mode is turned on */
210
    GF_OPTION_INIT("debug", priv->debug, bool, err);
211
    if (priv->debug) {
212
        gf_log(this->name, GF_LOG_DEBUG, "CDC debug option turned on");
213
    }
214

215
    /* Set Gzip Window Size */
216
    GF_OPTION_INIT("window-size", priv->window_size, int32, err);
217
    if ((priv->window_size > GF_CDC_MAX_WINDOWSIZE) ||
218
        (priv->window_size < GF_CDC_DEF_WINDOWSIZE)) {
219
        gf_log(this->name, GF_LOG_WARNING,
220
               "Invalid gzip window size (%d), using default",
221
               priv->window_size);
222
        priv->window_size = GF_CDC_DEF_WINDOWSIZE;
223
    }
224

225
    /* Set Gzip (De)Compression Level */
226
    GF_OPTION_INIT("compression-level", priv->cdc_level, int32, err);
227
    if (((priv->cdc_level < 1) || (priv->cdc_level > 9)) &&
228
        (priv->cdc_level != Z_DEFAULT_COMPRESSION)) {
229
        gf_log(this->name, GF_LOG_WARNING,
230
               "Invalid gzip (de)compression level (%d),"
231
               " using default",
232
               priv->cdc_level);
233
        priv->cdc_level = Z_DEFAULT_COMPRESSION;
234
    }
235

236
    /* Set Gzip Memory Level */
237
    GF_OPTION_INIT("mem-level", priv->mem_level, int32, err);
238
    if ((priv->mem_level < 1) || (priv->mem_level > 9)) {
239
        gf_log(this->name, GF_LOG_WARNING,
240
               "Invalid gzip memory level, using the default");
241
        priv->mem_level = GF_CDC_DEF_MEMLEVEL;
242
    }
243

244
    /* Set min file size to enable compression */
245
    GF_OPTION_INIT("min-size", priv->min_file_size, int32, err);
246

247
    /* Mode of operation - Server/Client */
248
    ret = dict_get_str(this->options, "mode", &temp_str);
249
    if (ret) {
250
        gf_log(this->name, GF_LOG_CRITICAL, "Operation mode not specified !!");
251
        goto err;
252
    }
253

254
    if (GF_CDC_MODE_IS_CLIENT(temp_str)) {
255
        priv->op_mode = GF_CDC_MODE_CLIENT;
256
    } else if (GF_CDC_MODE_IS_SERVER(temp_str)) {
257
        priv->op_mode = GF_CDC_MODE_SERVER;
258
    } else {
259
        gf_log(this->name, GF_LOG_CRITICAL,
260
               "Bogus operation mode (%s) specified", temp_str);
261
        goto err;
262
    }
263

264
    this->private = priv;
265
    gf_log(this->name, GF_LOG_DEBUG, "CDC xlator loaded in (%s) mode",
266
           temp_str);
267
    return 0;
268

269
err:
270
    if (priv)
271
        GF_FREE(priv);
272

273
    return -1;
274
}
275

276
void
277
fini(xlator_t *this)
278
{
279
    cdc_priv_t *priv = this->private;
280

281
    if (priv)
282
        GF_FREE(priv);
283
    this->private = NULL;
284
    return;
285
}
286

287
struct xlator_fops fops = {
288
    .readv = cdc_readv,
289
    .writev = cdc_writev,
290
};
291

292
struct xlator_cbks cbks = {};
293

294
struct volume_options options[] = {
295
    {.key = {"window-size"},
296
     .default_value = "-15",
297
     .type = GF_OPTION_TYPE_INT,
298
     .description = "Size of the zlib history buffer."},
299
    {.key = {"mem-level"},
300
     .default_value = "8",
301
     .type = GF_OPTION_TYPE_INT,
302
     .description = "Memory allocated for internal compression state. "
303
                    "1 uses minimum memory but is slow and reduces "
304
                    "compression ratio; memLevel=9 uses maximum memory "
305
                    "for optimal speed. The default value is 8."},
306
    {.key = {"compression-level"},
307
     .default_value = "1",
308
     .type = GF_OPTION_TYPE_INT,
309
     .description = "Compression levels \n"
310
                    "0 : no compression, 1 : best speed, \n"
311
                    "9 : best compression, -1 : default compression "},
312
    {.key = {"min-size"},
313
     .default_value = "1024",
314
     .type = GF_OPTION_TYPE_INT,
315
     .description = "Data is compressed only when its size exceeds this."},
316
    {.key = {"mode"},
317
     .value = {"server", "client"},
318
     .type = GF_OPTION_TYPE_STR,
319
     .description = "Set on the basis of where the xlator is loaded. "
320
                    "This option should NOT be configured by user."},
321
    {.key = {"debug"},
322
     .default_value = "false",
323
     .type = GF_OPTION_TYPE_BOOL,
324
     .description = "This is used in testing. Will dump compressed data "
325
                    "to disk as a gzip file."},
326
    {.key = {NULL}},
327
};
328

329
xlator_api_t xlator_api = {
330
    .init = init,
331
    .fini = fini,
332
    .mem_acct_init = mem_acct_init,
333
    .op_version = {GD_OP_VERSION_3_9_0},
334
    .fops = &fops,
335
    .cbks = &cbks,
336
    .options = options,
337
    .identifier = "cdc",
338
    .category = GF_TECH_PREVIEW,
339
};
340

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.