diff options
| -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;          }  | 
