summaryrefslogtreecommitdiffstats
path: root/xlators/features/read-only
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/read-only')
-rw-r--r--xlators/features/read-only/src/read-only-common.c2
-rw-r--r--xlators/features/read-only/src/read-only-common.h4
-rw-r--r--xlators/features/read-only/src/read-only-mem-types.h2
-rw-r--r--xlators/features/read-only/src/read-only.c14
-rw-r--r--xlators/features/read-only/src/read-only.h15
-rw-r--r--xlators/features/read-only/src/worm-helper.c24
-rw-r--r--xlators/features/read-only/src/worm.c144
7 files changed, 152 insertions, 53 deletions
diff --git a/xlators/features/read-only/src/read-only-common.c b/xlators/features/read-only/src/read-only-common.c
index 39985169991..9640e7e3eee 100644
--- a/xlators/features/read-only/src/read-only-common.c
+++ b/xlators/features/read-only/src/read-only-common.c
@@ -9,7 +9,7 @@
*/
#include "read-only.h"
#include "read-only-mem-types.h"
-#include "defaults.h"
+#include <glusterfs/defaults.h>
gf_boolean_t
is_readonly_or_worm_enabled(call_frame_t *frame, xlator_t *this)
diff --git a/xlators/features/read-only/src/read-only-common.h b/xlators/features/read-only/src/read-only-common.h
index 32719da28f1..5561961ffa2 100644
--- a/xlators/features/read-only/src/read-only-common.h
+++ b/xlators/features/read-only/src/read-only-common.h
@@ -7,8 +7,8 @@
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
-#include "xlator.h"
-#include "defaults.h"
+#include <glusterfs/xlator.h>
+#include <glusterfs/defaults.h>
gf_boolean_t
is_readonly_or_worm_enabled(call_frame_t *frame, xlator_t *this);
diff --git a/xlators/features/read-only/src/read-only-mem-types.h b/xlators/features/read-only/src/read-only-mem-types.h
index 4baaeb41216..c67d6c02cd0 100644
--- a/xlators/features/read-only/src/read-only-mem-types.h
+++ b/xlators/features/read-only/src/read-only-mem-types.h
@@ -11,7 +11,7 @@
#ifndef __READONLY_MEM_TYPES_H__
#define __READONLY_MEM_TYPES_H__
-#include "mem-types.h"
+#include <glusterfs/mem-types.h>
enum gf_read_only_mem_types_ {
gf_read_only_mt_priv_t = gf_common_mt_end + 1,
diff --git a/xlators/features/read-only/src/read-only.c b/xlators/features/read-only/src/read-only.c
index c92a9801196..48654998e63 100644
--- a/xlators/features/read-only/src/read-only.c
+++ b/xlators/features/read-only/src/read-only.c
@@ -7,7 +7,6 @@
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
-#include "defaults.h"
#include "read-only-common.h"
#include "read-only-mem-types.h"
#include "read-only.h"
@@ -130,3 +129,16 @@ struct volume_options options[] = {
"\"off\" by default."},
{.key = {NULL}},
};
+
+xlator_api_t xlator_api = {
+ .init = init,
+ .fini = fini,
+ .reconfigure = reconfigure,
+ .mem_acct_init = mem_acct_init,
+ .op_version = {1}, /* Present from the initial version */
+ .fops = &fops,
+ .cbks = &cbks,
+ .options = options,
+ .identifier = "read-only",
+ .category = GF_TECH_PREVIEW,
+};
diff --git a/xlators/features/read-only/src/read-only.h b/xlators/features/read-only/src/read-only.h
index d74053a2a8f..aced5d3c577 100644
--- a/xlators/features/read-only/src/read-only.h
+++ b/xlators/features/read-only/src/read-only.h
@@ -11,25 +11,26 @@
#ifndef __READONLY_H__
#define __READONLY_H__
-#include "read-only-mem-types.h"
-#include "xlator.h"
+#include <stdint.h> // for uint64_t, uint8_t
+#include <sys/time.h> // for time_t
+#include "glusterfs/glusterfs.h" // for gf_boolean_t
typedef struct {
uint8_t worm : 1;
uint8_t retain : 1;
uint8_t legal_hold : 1;
uint8_t ret_mode : 1;
- uint64_t ret_period;
- uint64_t auto_commit_period;
+ int64_t ret_period;
+ int64_t auto_commit_period;
} worm_reten_state_t;
typedef struct {
gf_boolean_t readonly_or_worm_enabled;
gf_boolean_t worm_file;
gf_boolean_t worm_files_deletable;
- uint64_t reten_period;
- uint64_t com_period;
- char *reten_mode;
+ int64_t reten_period;
+ int64_t com_period;
+ int reten_mode;
time_t start_time;
} read_only_priv_t;
diff --git a/xlators/features/read-only/src/worm-helper.c b/xlators/features/read-only/src/worm-helper.c
index 3f882fe08d6..df45f2a940b 100644
--- a/xlators/features/read-only/src/worm-helper.c
+++ b/xlators/features/read-only/src/worm-helper.c
@@ -9,8 +9,8 @@
*/
#include "read-only-mem-types.h"
#include "read-only.h"
-#include "xlator.h"
-#include "syncop.h"
+#include <glusterfs/xlator.h>
+#include <glusterfs/syncop.h>
#include "worm-helper.h"
/*Function to check whether file is read-only.
@@ -41,7 +41,7 @@ worm_init_state(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr)
GF_VALIDATE_OR_GOTO("worm", this, out);
GF_VALIDATE_OR_GOTO(this->name, file_ptr, out);
- start_time = time(NULL);
+ start_time = gf_time();
dict = dict_new();
if (!dict) {
gf_log(this->name, GF_LOG_ERROR, "Error creating the dict");
@@ -84,10 +84,7 @@ worm_set_state(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr,
retention_state->worm = 1;
retention_state->retain = 1;
retention_state->legal_hold = 0;
- if (strcmp(priv->reten_mode, "relax") == 0)
- retention_state->ret_mode = 0;
- else
- retention_state->ret_mode = 1;
+ retention_state->ret_mode = priv->reten_mode;
retention_state->ret_period = priv->reten_period;
retention_state->auto_commit_period = priv->com_period;
if (fop_with_fd)
@@ -97,7 +94,7 @@ worm_set_state(xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr,
if (ret)
goto out;
stbuf->ia_mtime = stpre.ia_mtime;
- stbuf->ia_atime = time(NULL) + retention_state->ret_period;
+ stbuf->ia_atime = gf_time() + retention_state->ret_period;
if (fop_with_fd)
ret = syncop_fsetattr(this, (fd_t *)file_ptr, stbuf, GF_SET_ATTR_ATIME,
@@ -289,6 +286,7 @@ gf_worm_state_transition(xlator_t *this, gf_boolean_t fop_with_fd,
{
int op_errno = EROFS;
int ret = -1;
+ time_t now = 0;
uint64_t com_period = 0;
uint64_t start_time = 0;
dict_t *dict = NULL;
@@ -340,8 +338,10 @@ gf_worm_state_transition(xlator_t *this, gf_boolean_t fop_with_fd,
goto out;
}
- if (ret == -1 && (time(NULL) - start_time) >= com_period) {
- if ((time(NULL) - stbuf.ia_mtime) >= com_period) {
+ now = gf_time();
+
+ if (ret == -1 && (now - start_time) >= com_period) {
+ if ((now - stbuf.ia_mtime) >= com_period) {
ret = worm_set_state(this, fop_with_fd, file_ptr, &reten_state,
&stbuf);
if (ret) {
@@ -355,10 +355,10 @@ gf_worm_state_transition(xlator_t *this, gf_boolean_t fop_with_fd,
op_errno = 0;
goto out;
}
- } else if (ret == -1 && (time(NULL) - start_time) < com_period) {
+ } else if (ret == -1 && (now - start_time) < com_period) {
op_errno = 0;
goto out;
- } else if (reten_state.retain && ((time(NULL) >= stbuf.ia_atime))) {
+ } else if (reten_state.retain && ((now >= stbuf.ia_atime))) {
gf_worm_state_lookup(this, fop_with_fd, file_ptr, &reten_state, &stbuf);
}
if (reten_state.worm && !reten_state.retain && priv->worm_files_deletable &&
diff --git a/xlators/features/read-only/src/worm.c b/xlators/features/read-only/src/worm.c
index db128b75196..1cc5526d5cd 100644
--- a/xlators/features/read-only/src/worm.c
+++ b/xlators/features/read-only/src/worm.c
@@ -7,12 +7,12 @@
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
-#include "xlator.h"
-#include "defaults.h"
+#include <glusterfs/xlator.h>
+#include <glusterfs/defaults.h>
#include "read-only-common.h"
#include "read-only-mem-types.h"
#include "read-only.h"
-#include "syncop.h"
+#include <glusterfs/syncop.h>
#include "worm-helper.h"
int32_t
@@ -292,6 +292,12 @@ worm_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
goto out;
}
}
+ reten_state.ret_period = reten_state.ret_period + stbuf->ia_atime -
+ stpre.ia_atime;
+ ret = gf_worm_set_xattr(this, &reten_state, _gf_false, loc);
+ if (ret) {
+ goto out;
+ }
stbuf->ia_mtime = stpre.ia_mtime;
}
}
@@ -372,6 +378,13 @@ worm_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf,
goto out;
}
}
+ reten_state.ret_period = reten_state.ret_period + stbuf->ia_atime -
+ stpre.ia_atime;
+ ret = gf_worm_set_xattr(this, &reten_state, _gf_true, fd);
+ if (ret) {
+ goto out;
+ }
+
stbuf->ia_mtime = stpre.ia_mtime;
}
}
@@ -427,29 +440,22 @@ worm_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
{
int ret = 0;
read_only_priv_t *priv = NULL;
- dict_t *dict = NULL;
+ // In case of an error exit because fd can be NULL and this would
+ // cause an segfault when performing fsetxattr . We explicitly
+ // unwind to avoid future problems
+ if (op_ret < 0) {
+ goto out;
+ }
priv = this->private;
GF_ASSERT(priv);
if (priv->worm_file) {
- dict = dict_new();
- if (!dict) {
- gf_log(this->name, GF_LOG_ERROR,
- "Error creating the "
- "dict");
- goto out;
- }
- ret = dict_set_int8(dict, "trusted.worm_file", 1);
+ ret = fd_ctx_set(fd, this, 1);
if (ret) {
gf_log(this->name, GF_LOG_ERROR,
- "Error in setting "
- "the dict");
- goto out;
- }
- ret = syncop_fsetxattr(this, fd, dict, 0, NULL, NULL);
- if (ret) {
- gf_log(this->name, GF_LOG_ERROR, "Error setting xattr");
- goto out;
+ "Failed to set the fd ctx "
+ "for gfid:%s . Worm feature may not work for the gfid",
+ uuid_utoa(inode->gfid));
}
ret = worm_init_state(this, _gf_true, fd);
if (ret) {
@@ -460,8 +466,6 @@ worm_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
out:
STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf,
preparent, postparent, xdata);
- if (dict)
- dict_unref(dict);
return ret;
}
@@ -475,11 +479,21 @@ worm_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
return 0;
}
+static void
+set_reten_mode(read_only_priv_t *priv, char *reten_mode)
+{
+ if (strcmp(reten_mode, "relax") == 0)
+ priv->reten_mode = 0;
+ else
+ priv->reten_mode = 1;
+}
+
int32_t
init(xlator_t *this)
{
int ret = -1;
read_only_priv_t *priv = NULL;
+ char *reten_mode = NULL;
if (!this->children || this->children->next) {
gf_log(this->name, GF_LOG_ERROR,
@@ -509,9 +523,10 @@ init(xlator_t *this)
GF_OPTION_INIT("worm", priv->readonly_or_worm_enabled, bool, out);
GF_OPTION_INIT("worm-file-level", priv->worm_file, bool, out);
- GF_OPTION_INIT("default-retention-period", priv->reten_period, uint64, out);
- GF_OPTION_INIT("auto-commit-period", priv->com_period, uint64, out);
- GF_OPTION_INIT("retention-mode", priv->reten_mode, str, out);
+ GF_OPTION_INIT("default-retention-period", priv->reten_period, int64, out);
+ GF_OPTION_INIT("auto-commit-period", priv->com_period, int64, out);
+ GF_OPTION_INIT("retention-mode", reten_mode, str, out);
+ set_reten_mode(priv, reten_mode);
GF_OPTION_INIT("worm-files-deletable", priv->worm_files_deletable, bool,
out);
@@ -524,6 +539,7 @@ int
reconfigure(xlator_t *this, dict_t *options)
{
read_only_priv_t *priv = NULL;
+ char *reten_mode = NULL;
int ret = -1;
priv = this->private;
@@ -533,9 +549,10 @@ reconfigure(xlator_t *this, dict_t *options)
out);
GF_OPTION_RECONF("worm-file-level", priv->worm_file, options, bool, out);
GF_OPTION_RECONF("default-retention-period", priv->reten_period, options,
- uint64, out);
- GF_OPTION_RECONF("retention-mode", priv->reten_mode, options, str, out);
- GF_OPTION_RECONF("auto-commit-period", priv->com_period, options, uint64,
+ int64, out);
+ GF_OPTION_RECONF("retention-mode", reten_mode, options, str, out);
+ set_reten_mode(priv, reten_mode);
+ GF_OPTION_RECONF("auto-commit-period", priv->com_period, options, int64,
out);
GF_OPTION_RECONF("worm-files-deletable", priv->worm_files_deletable,
options, bool, out);
@@ -556,6 +573,7 @@ fini(xlator_t *this)
mem_put(priv);
this->private = NULL;
mem_pool_destroy(this->local_pool);
+ this->local_pool = NULL;
out:
return;
}
@@ -583,7 +601,62 @@ struct xlator_fops fops = {
.lk = ro_lk,
};
-struct xlator_cbks cbks;
+int32_t
+worm_release(xlator_t *this, fd_t *fd)
+{
+ dict_t *dict = NULL;
+ int ret = -1;
+ dict = dict_new();
+ uint64_t value = 0;
+ loc_t loc = {
+ 0,
+ };
+ read_only_priv_t *priv = NULL;
+ priv = this->private;
+
+ if (priv->worm_file) {
+ if (!dict) {
+ gf_log(this->name, GF_LOG_ERROR, "Error creating the dict");
+ goto out;
+ }
+
+ ret = fd_ctx_get(fd, this, &value);
+ if (ret) {
+ gf_log(this->name, GF_LOG_DEBUG, "Failed to get the fd ctx");
+ }
+ if (!value) {
+ goto out;
+ }
+
+ ret = dict_set_int8(dict, "trusted.worm_file", 1);
+ if (ret) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "Error in setting "
+ "the dict");
+ goto out;
+ }
+
+ loc.inode = inode_ref(fd->inode);
+ gf_uuid_copy(loc.gfid, fd->inode->gfid);
+ ret = syncop_setxattr(this, &loc, dict, 0, NULL, NULL);
+ if (ret) {
+ gf_log(this->name, GF_LOG_ERROR, "Error setting xattr");
+ goto out;
+ }
+
+ gf_worm_state_transition(this, _gf_false, &loc, GF_FOP_WRITE);
+ }
+
+out:
+ loc_wipe(&loc);
+ if (dict)
+ dict_unref(dict);
+ return 0;
+}
+
+struct xlator_cbks cbks = {
+ .release = worm_release,
+};
struct volume_options options[] = {
{.key = {"worm"},
@@ -634,3 +707,16 @@ struct volume_options options[] = {
.description = "Auto commit period for the files."},
{.key = {NULL}},
};
+
+xlator_api_t xlator_api = {
+ .init = init,
+ .fini = fini,
+ .reconfigure = reconfigure,
+ .mem_acct_init = mem_acct_init,
+ .op_version = {1}, /* Present from the initial version */
+ .fops = &fops,
+ .cbks = &cbks,
+ .options = options,
+ .identifier = "worm",
+ .category = GF_TECH_PREVIEW,
+};