diff options
author | David Spisla <david.spisla@iternity.com> | 2020-02-25 10:57:36 +0100 |
---|---|---|
committer | Amar Tumballi <amar@kadalu.io> | 2020-03-17 04:24:14 +0000 |
commit | 476139c962c298b2d00a3d42b90632fc25401526 (patch) | |
tree | bf4ee55352605542e1d9a646844e90945bc01ab6 /xlators/features | |
parent | b30f76980fc5d01b569d9409b68d24d809444ff8 (diff) |
WORM-Xlator: Initial write of a file succeeds if auto-commit-period 0
If worm-file-level enabled and auto-commit-period 0 an initial write
of a file (e.g. $ echo test >> file1.txt) would lead to an zero byte
file because the WORM xlator immediately WORMed the file when it was
created.
To avoid this we move the setting of trusted.worm_file from
worm_create_cbk to worm_release . This means that this xattr will set
when the filehandle is closed and all initial WRITE FOPs succeed.
Finally we also perform gf_worm_state_transition in worm_release to
ensure that the file will be immediately WORMed after the file handle
was closed.
Change-Id: I5d02e18975b646ca1a27ed41d836e9d0dc333204
Fixes: bz#1808421
Signed-off-by: David Spisla <david.spisla@iternity.com>
Diffstat (limited to 'xlators/features')
-rw-r--r-- | xlators/features/read-only/src/worm.c | 77 |
1 files changed, 60 insertions, 17 deletions
diff --git a/xlators/features/read-only/src/worm.c b/xlators/features/read-only/src/worm.c index 46078c1a96e..056e429dd62 100644 --- a/xlators/features/read-only/src/worm.c +++ b/xlators/features/read-only/src/worm.c @@ -452,24 +452,12 @@ worm_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, 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) { @@ -617,7 +605,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"}, |