summaryrefslogtreecommitdiffstats
path: root/xlators/features
diff options
context:
space:
mode:
authorKotresh HR <khiremat@redhat.com>2014-12-31 12:47:47 +0530
committerVenky Shankar <vshankar@redhat.com>2015-01-09 01:17:28 -0800
commitbbb4b7679be26ed5460524bcf26e779f6907d299 (patch)
tree10c4d1848d06212b47be3c870708a09ffe9b4f70 /xlators/features
parent70dc47389cbe08238d8c216c51d49583154bd08a (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/features')
-rw-r--r--xlators/features/changelog/src/changelog-helpers.c72
-rw-r--r--xlators/features/changelog/src/changelog-helpers.h3
-rw-r--r--xlators/features/changelog/src/changelog.c67
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;
}