2
Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
3
This file is part of GlusterFS.
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.
13
#include <glusterfs/logging.h>
16
#include "cdc-mem-types.h"
19
cdc_cleanup_iobref(cdc_info_t *ci)
21
assert(ci->iobref != NULL);
22
iobref_clear(ci->iobref);
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)
31
cdc_priv_t *priv = NULL;
36
GF_VALIDATE_OR_GOTO("cdc", this, default_out);
37
GF_VALIDATE_OR_GOTO(this->name, frame, default_out);
44
if ((priv->min_file_size != 0) && (op_ret < priv->min_file_size))
54
ci.buffer_size = GF_CDC_DEF_BUFFERSIZE;
56
/* A readv compresses on the server side and decompresses on the client side
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);
63
gf_log(this->name, GF_LOG_ERROR, "Invalid operation mode (%d)",
70
STACK_UNWIND_STRICT(readv, frame, ci.nbytes, op_errno, ci.vec, ci.ncount,
71
stbuf, iobref, xdata);
72
cdc_cleanup_iobref(&ci);
76
STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, vector, count, stbuf,
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)
85
STACK_WIND(frame, cdc_readv_cbk, FIRST_CHILD(this),
86
FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata);
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)
95
STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf,
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,
106
cdc_priv_t *priv = NULL;
112
GF_VALIDATE_OR_GOTO("cdc", this, err);
113
GF_VALIDATE_OR_GOTO(this->name, frame, err);
115
isize = iov_length(vector, count);
120
priv = this->private;
122
if ((priv->min_file_size != 0) && (isize < priv->min_file_size))
132
ci.buffer_size = GF_CDC_DEF_BUFFERSIZE;
134
/* A writev compresses on the client side and decompresses on the server
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);
142
gf_log(this->name, GF_LOG_ERROR, "Invalid operation mode (%d) ",
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);
153
cdc_cleanup_iobref(&ci);
157
STACK_WIND(frame, cdc_writev_cbk, FIRST_CHILD(this),
158
FIRST_CHILD(this)->fops->writev, fd, vector, count, offset,
159
flags, iobref, xdata);
162
STACK_UNWIND_STRICT(writev, frame, -1, EINVAL, NULL, NULL, NULL);
167
mem_acct_init(xlator_t *this)
174
ret = xlator_mem_acct_init(this, gf_cdc_mt_end);
177
gf_log(this->name, GF_LOG_ERROR,
178
"Memory accounting init"
190
char *temp_str = NULL;
191
cdc_priv_t *priv = NULL;
193
GF_VALIDATE_OR_GOTO("cdc", this, err);
195
if (!this->children || this->children->next) {
196
gf_log(this->name, GF_LOG_ERROR, "Need subvolume == 1");
200
if (!this->parents) {
201
gf_log(this->name, GF_LOG_WARNING, "Dangling volume. Check volfile");
204
priv = GF_CALLOC(1, sizeof(*priv), gf_cdc_mt_priv_t);
209
/* Check if debug mode is turned on */
210
GF_OPTION_INIT("debug", priv->debug, bool, err);
212
gf_log(this->name, GF_LOG_DEBUG, "CDC debug option turned on");
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",
222
priv->window_size = GF_CDC_DEF_WINDOWSIZE;
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),"
233
priv->cdc_level = Z_DEFAULT_COMPRESSION;
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;
244
/* Set min file size to enable compression */
245
GF_OPTION_INIT("min-size", priv->min_file_size, int32, err);
247
/* Mode of operation - Server/Client */
248
ret = dict_get_str(this->options, "mode", &temp_str);
250
gf_log(this->name, GF_LOG_CRITICAL, "Operation mode not specified !!");
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;
259
gf_log(this->name, GF_LOG_CRITICAL,
260
"Bogus operation mode (%s) specified", temp_str);
264
this->private = priv;
265
gf_log(this->name, GF_LOG_DEBUG, "CDC xlator loaded in (%s) mode",
279
cdc_priv_t *priv = this->private;
283
this->private = NULL;
287
struct xlator_fops fops = {
289
.writev = cdc_writev,
292
struct xlator_cbks cbks = {};
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."},
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."},
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."},
329
xlator_api_t xlator_api = {
332
.mem_acct_init = mem_acct_init,
333
.op_version = {GD_OP_VERSION_3_9_0},
338
.category = GF_TECH_PREVIEW,