diff options
author | Kotresh HR <khiremat@redhat.com> | 2014-12-31 12:47:47 +0530 |
---|---|---|
committer | Venky Shankar <vshankar@redhat.com> | 2015-01-09 01:17:28 -0800 |
commit | bbb4b7679be26ed5460524bcf26e779f6907d299 (patch) | |
tree | 10c4d1848d06212b47be3c870708a09ffe9b4f70 /xlators | |
parent | 70dc47389cbe08238d8c216c51d49583154bd08a (diff) |
feature/changelog: Logging entry as well for explicit sync virtual xattr.
This is an improvement over the patch 'http://review.gluster.org/9337'
to trigger explicit geo-rep sync on regular files even if entry is not
present on the slave. An attempt is made to find the pargfid and
if available captures CREATE along with DATA in changelog.
CREATE is captured with default file permissions. Setting this virtual
setxattr on directories captures MKDIR in changelog. The value of
setxattr can be as follows.
If value = "1" : Both CREATE and DATA is captured in changelog if
pargfid is available, else on DATA is captured.
value = "any other: ENOTSUP is returned.
Usage:
setfattr -n glusterfs.geo-rep.trigger-sync -v "1" <file-path>
NOTE: This patch supports explicit record of entries only for
directories and regular files.
Change-Id: Iedde8b2c8bc3b78db524050d8c866ff664811d01
BUG: 1176934
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Reviewed-on: http://review.gluster.org/9370
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Venky Shankar <vshankar@redhat.com>
Tested-by: Venky Shankar <vshankar@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/features/changelog/src/changelog-helpers.c | 72 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog-helpers.h | 3 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog.c | 67 |
3 files changed, 135 insertions, 7 deletions
diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c index 9dccf45187c..3af2938190d 100644 --- a/xlators/features/changelog/src/changelog-helpers.c +++ b/xlators/features/changelog/src/changelog-helpers.c @@ -20,6 +20,7 @@ #include "syscall.h" #include "changelog-helpers.h" +#include "changelog-encoders.h" #include "changelog-mem-types.h" #include "changelog-encoders.h" @@ -1337,3 +1338,74 @@ changelog_barrier_cleanup (xlator_t *this, changelog_priv_t *priv, return; } /* End: Geo-Rep snapshot dependency changes */ + +int32_t +changelog_fill_entry_buf (call_frame_t *frame, xlator_t *this, + loc_t *loc, changelog_local_t **local) +{ + changelog_opt_t *co = NULL; + size_t xtra_len = 0; + char *dup_path = NULL; + char *bname = NULL; + inode_t *parent = NULL; + + GF_ASSERT (this); + + parent = inode_parent (loc->inode, 0, 0); + if (!parent) { + gf_log (this->name, GF_LOG_ERROR, "Parent inode not found" + " for gfid: %s", uuid_utoa (loc->inode->gfid)); + goto err; + } + + CHANGELOG_INIT_NOCHECK (this, *local, loc->inode, loc->inode->gfid, 5); + if (!(*local)) { + gf_log (this->name, GF_LOG_ERROR, "changelog local" + " initiatilization failed"); + goto err; + } + + co = changelog_get_usable_buffer (*local); + if (!co) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get buffer"); + goto err; + } + + if (loc->inode->ia_type == IA_IFDIR) { + CHANGLOG_FILL_FOP_NUMBER (co, GF_FOP_MKDIR, fop_fn, xtra_len); + co++; + CHANGELOG_FILL_UINT32 (co, S_IFDIR|0755, number_fn, xtra_len); + co++; + } else { + CHANGLOG_FILL_FOP_NUMBER (co, GF_FOP_CREATE, fop_fn, xtra_len); + co++; + CHANGELOG_FILL_UINT32 (co, S_IFREG|0644, number_fn, xtra_len); + co++; + } + + CHANGELOG_FILL_UINT32 (co, frame->root->uid, number_fn, xtra_len); + co++; + + CHANGELOG_FILL_UINT32 (co, frame->root->gid, number_fn, xtra_len); + co++; + + dup_path = gf_strdup (loc->path); + bname = basename (dup_path); + + CHANGELOG_FILL_ENTRY (co, parent->gfid, bname, entry_fn, entry_free_fn, + xtra_len, err); + changelog_set_usable_record_and_length (*local, xtra_len, 5); + + if (dup_path) + GF_FREE (dup_path); + if (parent) + inode_unref (parent); + return 0; + +err: + if (dup_path) + GF_FREE (dup_path); + if (parent) + inode_unref (parent); + return -1; +} diff --git a/xlators/features/changelog/src/changelog-helpers.h b/xlators/features/changelog/src/changelog-helpers.h index d8f80465922..03a795369d1 100644 --- a/xlators/features/changelog/src/changelog-helpers.h +++ b/xlators/features/changelog/src/changelog-helpers.h @@ -456,6 +456,9 @@ void chlog_barrier_dequeue_all (xlator_t *this, struct list_head *queue); call_stub_t *__chlog_barrier_dequeue (xlator_t *this, struct list_head *queue); int __chlog_barrier_enable (xlator_t *this, changelog_priv_t *priv); +int32_t +changelog_fill_entry_buf (call_frame_t *frame, xlator_t *this, + loc_t *loc, changelog_local_t **local); /* macros */ diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c index e047288d43d..4263a462ad7 100644 --- a/xlators/features/changelog/src/changelog.c +++ b/xlators/features/changelog/src/changelog.c @@ -1309,6 +1309,61 @@ changelog_setxattr_cbk (call_frame_t *frame, return 0; } +/* changelog_handle_virtual_xattr: + * Handles virtual setxattr 'glusterfs.geo-rep.trigger-sync' on files. + * Following is the behaviour based on the value of xattr. + * 1: Captures only DATA entry in changelog. + * 2: Tries to captures both ENTRY and DATA entry in + * changelog. If failed to get pargfid, only DATA + * entry is captured. + * any other value: ENOTSUP is returned. + */ +static void +changelog_handle_virtual_xattr (call_frame_t *frame, xlator_t *this, + loc_t *loc, dict_t *dict) +{ + changelog_priv_t *priv = NULL; + changelog_local_t *local = NULL; + int32_t value = 0; + int ret = 0; + int dict_ret = 0; + gf_boolean_t valid = _gf_false; + + priv = this->private; + GF_ASSERT (priv); + + dict_ret = dict_get_int32 (dict, GF_XATTR_TRIGGER_SYNC, &value); + + if ((dict_ret == 0 && value == 1) && ((loc->inode->ia_type == IA_IFDIR) + || (loc->inode->ia_type == IA_IFREG))) + valid = _gf_true; + + if (valid) { + ret = changelog_fill_entry_buf (frame, this, loc, &local); + if (ret) { + gf_log (this->name, GF_LOG_INFO, "Entry cannot be" + " captured for gfid: %s. Capturing DATA" + " entry.", uuid_utoa (loc->inode->gfid)); + goto unwind; + } + changelog_update (this, priv, local, CHANGELOG_TYPE_ENTRY); + + unwind: + /* Capture DATA only if it's a file. */ + if (loc->inode->ia_type != IA_IFDIR) + changelog_update (this, priv, frame->local, + CHANGELOG_TYPE_DATA); + /* Assign local to prev_entry, so unwind will take + * care of cleanup. */ + ((changelog_local_t *)(frame->local))->prev_entry = local; + CHANGELOG_STACK_UNWIND (setxattr, frame, 0, 0, NULL); + return; + } else { + CHANGELOG_STACK_UNWIND (setxattr, frame, -1, ENOTSUP, NULL); + return; + } +} + int32_t changelog_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, @@ -1327,13 +1382,11 @@ changelog_setxattr (call_frame_t *frame, loc->inode, loc->inode->gfid, 1); /* On setting this virtual xattr on a file, an explicit data - sync is triggered from geo-rep as DATA entry is recorded - in changelog. */ - if (dict_get (dict, GF_XATTR_TRIGGER_SYNC) - && loc->inode->ia_type != IA_IFDIR) { - changelog_update (this, priv, frame->local, - CHANGELOG_TYPE_DATA); - CHANGELOG_STACK_UNWIND (setxattr, frame, 0, 0, xdata); + * sync is triggered from geo-rep as CREATE|DATA entry is + * recorded in changelog based on xattr value. + */ + if (dict_get (dict, GF_XATTR_TRIGGER_SYNC)) { + changelog_handle_virtual_xattr (frame, this, loc, dict); return 0; } |