74b1de
From 90254e4ae9455fa0a126f83700978a9314eb79ea Mon Sep 17 00:00:00 2001
74b1de
From: Anuradha Talur <atalur@commvault.com>
74b1de
Date: Thu, 29 Nov 2018 12:54:21 -0800
74b1de
Subject: [PATCH 153/169] features/cloudsync : Added some new functions
74b1de
74b1de
This patch contains the following changes:
74b1de
1) Store ID info will now be stored in the inode ctx
74b1de
2) Added new readv type where read is made directly
74b1de
   from the remote store. This choice is made by
74b1de
   volume set operation.
74b1de
3) cs_forget() was missing. Added it.
74b1de
74b1de
backport of:https://review.gluster.org/#/c/glusterfs/+/21757/
74b1de
74b1de
> Change-Id: Ie3232b3d7ffb5313a03f011b0553b19793eedfa2
74b1de
> fixes: bz#1642168
74b1de
> Signed-off-by: Anuradha Talur <atalur@commvault.com>
74b1de
74b1de
Change-Id: I089e5a8c93049cf6bfabf011673796e38e78d7ee
74b1de
Signed-off-by: Susant Palai <spalai@redhat.com>
74b1de
Reviewed-on: https://code.engineering.redhat.com/gerrit/172192
74b1de
Tested-by: RHGS Build Bot <nigelb@redhat.com>
74b1de
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
74b1de
---
74b1de
 xlators/features/cloudsync/src/cloudsync-common.c  |  16 +
74b1de
 xlators/features/cloudsync/src/cloudsync-common.h  |  35 ++
74b1de
 xlators/features/cloudsync/src/cloudsync-fops-c.py |  12 +-
74b1de
 .../features/cloudsync/src/cloudsync-mem-types.h   |   1 +
74b1de
 xlators/features/cloudsync/src/cloudsync.c         | 600 ++++++++++++++++++---
74b1de
 xlators/features/cloudsync/src/cloudsync.h         |  20 +
74b1de
 xlators/mgmt/glusterd/src/glusterd-volume-set.c    |   7 +-
74b1de
 7 files changed, 597 insertions(+), 94 deletions(-)
74b1de
74b1de
diff --git a/xlators/features/cloudsync/src/cloudsync-common.c b/xlators/features/cloudsync/src/cloudsync-common.c
74b1de
index aee1f06..445a31b 100644
74b1de
--- a/xlators/features/cloudsync/src/cloudsync-common.c
74b1de
+++ b/xlators/features/cloudsync/src/cloudsync-common.c
74b1de
@@ -11,6 +11,20 @@
74b1de
 #include "cloudsync-common.h"
74b1de
 
74b1de
 void
74b1de
+cs_xattrinfo_wipe(cs_local_t *local)
74b1de
+{
74b1de
+    if (local->xattrinfo.lxattr) {
74b1de
+        if (local->xattrinfo.lxattr->file_path)
74b1de
+            GF_FREE(local->xattrinfo.lxattr->file_path);
74b1de
+
74b1de
+        if (local->xattrinfo.lxattr->volname)
74b1de
+            GF_FREE(local->xattrinfo.lxattr->volname);
74b1de
+
74b1de
+        GF_FREE(local->xattrinfo.lxattr);
74b1de
+    }
74b1de
+}
74b1de
+
74b1de
+void
74b1de
 cs_local_wipe(xlator_t *this, cs_local_t *local)
74b1de
 {
74b1de
     if (!local)
74b1de
@@ -40,5 +54,7 @@ cs_local_wipe(xlator_t *this, cs_local_t *local)
74b1de
     if (local->remotepath)
74b1de
         GF_FREE(local->remotepath);
74b1de
 
74b1de
+    cs_xattrinfo_wipe(local);
74b1de
+
74b1de
     mem_put(local);
74b1de
 }
74b1de
diff --git a/xlators/features/cloudsync/src/cloudsync-common.h b/xlators/features/cloudsync/src/cloudsync-common.h
74b1de
index 7b3520c..11d2334 100644
74b1de
--- a/xlators/features/cloudsync/src/cloudsync-common.h
74b1de
+++ b/xlators/features/cloudsync/src/cloudsync-common.h
74b1de
@@ -14,9 +14,23 @@
74b1de
 #include <glusterfs/call-stub.h>
74b1de
 #include <glusterfs/xlator.h>
74b1de
 #include <glusterfs/syncop.h>
74b1de
+#include <glusterfs/compat-errno.h>
74b1de
 #include "cloudsync-mem-types.h"
74b1de
 #include "cloudsync-messages.h"
74b1de
 
74b1de
+typedef struct cs_loc_xattr {
74b1de
+    char *file_path;
74b1de
+    uuid_t uuid;
74b1de
+    uuid_t gfid;
74b1de
+    char *volname;
74b1de
+} cs_loc_xattr_t;
74b1de
+
74b1de
+typedef struct cs_size_xattr {
74b1de
+    uint64_t size;
74b1de
+    uint64_t blksize;
74b1de
+    uint64_t blocks;
74b1de
+} cs_size_xattr_t;
74b1de
+
74b1de
 typedef struct cs_local {
74b1de
     loc_t loc;
74b1de
     fd_t *fd;
74b1de
@@ -34,10 +48,25 @@ typedef struct cs_local {
74b1de
     int call_cnt;
74b1de
     inode_t *inode;
74b1de
     char *remotepath;
74b1de
+
74b1de
+    struct {
74b1de
+        /* offset, flags and size are the information needed
74b1de
+         * by read fop for remote read operation. These will be
74b1de
+         * populated in cloudsync read fop, before being passed
74b1de
+         * on to the plugin performing remote read.
74b1de
+         */
74b1de
+        off_t offset;
74b1de
+        uint32_t flags;
74b1de
+        size_t size;
74b1de
+        cs_loc_xattr_t *lxattr;
74b1de
+    } xattrinfo;
74b1de
+
74b1de
 } cs_local_t;
74b1de
 
74b1de
 typedef int (*fop_download_t)(call_frame_t *frame, void *config);
74b1de
 
74b1de
+typedef int (*fop_remote_read_t)(call_frame_t *, void *);
74b1de
+
74b1de
 typedef void *(*store_init)(xlator_t *this);
74b1de
 
74b1de
 typedef int (*store_reconfigure)(xlator_t *this, dict_t *options);
74b1de
@@ -48,6 +77,7 @@ struct cs_remote_stores {
74b1de
     char *name;                    /* store name */
74b1de
     void *config;                  /* store related information */
74b1de
     fop_download_t dlfop;          /* store specific download function */
74b1de
+    fop_remote_read_t rdfop;       /* store specific read function */
74b1de
     store_init init;               /* store init to initialize store config */
74b1de
     store_reconfigure reconfigure; /* reconfigure store config */
74b1de
     store_fini fini;
74b1de
@@ -59,11 +89,15 @@ typedef struct cs_private {
74b1de
     struct cs_remote_stores *stores;
74b1de
     gf_boolean_t abortdl;
74b1de
     pthread_spinlock_t lock;
74b1de
+    gf_boolean_t remote_read;
74b1de
 } cs_private_t;
74b1de
 
74b1de
 void
74b1de
 cs_local_wipe(xlator_t *this, cs_local_t *local);
74b1de
 
74b1de
+void
74b1de
+cs_xattrinfo_wipe(cs_local_t *local);
74b1de
+
74b1de
 #define CS_STACK_UNWIND(fop, frame, params...)                                 \
74b1de
     do {                                                                       \
74b1de
         cs_local_t *__local = NULL;                                            \
74b1de
@@ -90,6 +124,7 @@ cs_local_wipe(xlator_t *this, cs_local_t *local);
74b1de
 
74b1de
 typedef struct store_methods {
74b1de
     int (*fop_download)(call_frame_t *frame, void *config);
74b1de
+    int (*fop_remote_read)(call_frame_t *, void *);
74b1de
     /* return type should be the store config */
74b1de
     void *(*fop_init)(xlator_t *this);
74b1de
     int (*fop_reconfigure)(xlator_t *this, dict_t *options);
74b1de
diff --git a/xlators/features/cloudsync/src/cloudsync-fops-c.py b/xlators/features/cloudsync/src/cloudsync-fops-c.py
74b1de
index 3122bd3..a7a2201 100755
74b1de
--- a/xlators/features/cloudsync/src/cloudsync-fops-c.py
74b1de
+++ b/xlators/features/cloudsync/src/cloudsync-fops-c.py
74b1de
@@ -137,15 +137,15 @@ cs_@NAME@_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
74b1de
                         } else {
74b1de
                                 __cs_inode_ctx_update (this, fd->inode, val);
74b1de
                                 gf_msg (this->name, GF_LOG_INFO, 0, 0,
74b1de
-                                        " state = %ld", val);
74b1de
+                                        " state = %" PRIu64, val);
74b1de
 
74b1de
                                 if (local->call_cnt == 1 &&
74b1de
                                     (val == GF_CS_REMOTE ||
74b1de
                                      val == GF_CS_DOWNLOADING))  {
74b1de
                                         gf_msg (this->name, GF_LOG_INFO, 0,
74b1de
                                                 0, " will repair and download "
74b1de
-                                                "the file, current state : %ld",
74b1de
-                                                val);
74b1de
+                                                "the file, current state : %"
74b1de
+                                                PRIu64, val);
74b1de
                                         goto repair;
74b1de
                                 } else {
74b1de
                                         gf_msg (this->name, GF_LOG_ERROR, 0, 0,
74b1de
@@ -274,7 +274,7 @@ fd_ops = ['readv', 'writev', 'flush', 'fsync', 'fsyncdir', 'ftruncate',
74b1de
 # These are the current actual lists used to generate the code
74b1de
 
74b1de
 # The following list contains fops which are fd based that modifies data
74b1de
-fd_data_modify_op_fop_template = ['readv', 'writev', 'flush', 'fsync',
74b1de
+fd_data_modify_op_fop_template = ['writev', 'flush', 'fsync',
74b1de
                                   'ftruncate', 'rchecksum', 'fallocate',
74b1de
                                   'discard', 'zerofill', 'seek']
74b1de
 
74b1de
@@ -284,8 +284,8 @@ loc_stat_op_fop_template = ['lookup', 'stat', 'discover', 'access', 'setattr',
74b1de
                             'getattr']
74b1de
 
74b1de
 # These fops need a separate implementation
74b1de
-special_fops = ['readdirp', 'statfs', 'setxattr', 'unlink', 'getxattr',
74b1de
-                'truncate', 'fstat']
74b1de
+special_fops = ['statfs', 'setxattr', 'unlink', 'getxattr',
74b1de
+                'truncate', 'fstat', 'readv']
74b1de
 
74b1de
 def gen_defaults():
74b1de
     for name in ops:
74b1de
diff --git a/xlators/features/cloudsync/src/cloudsync-mem-types.h b/xlators/features/cloudsync/src/cloudsync-mem-types.h
74b1de
index 9e6837a..2203464 100644
74b1de
--- a/xlators/features/cloudsync/src/cloudsync-mem-types.h
74b1de
+++ b/xlators/features/cloudsync/src/cloudsync-mem-types.h
74b1de
@@ -16,6 +16,7 @@ enum cs_mem_types_ {
74b1de
     gf_cs_mt_cs_private_t = gf_common_mt_end + 1,
74b1de
     gf_cs_mt_cs_remote_stores_t,
74b1de
     gf_cs_mt_cs_inode_ctx_t,
74b1de
+    gf_cs_mt_cs_lxattr_t,
74b1de
     gf_cs_mt_end
74b1de
 };
74b1de
 #endif /* __CLOUDSYNC_MEM_TYPES_H__ */
74b1de
diff --git a/xlators/features/cloudsync/src/cloudsync.c b/xlators/features/cloudsync/src/cloudsync.c
74b1de
index fbdcdf7..2240fc3 100644
74b1de
--- a/xlators/features/cloudsync/src/cloudsync.c
74b1de
+++ b/xlators/features/cloudsync/src/cloudsync.c
74b1de
@@ -16,6 +16,7 @@
74b1de
 #include <glusterfs/call-stub.h>
74b1de
 #include "cloudsync-autogen-fops.h"
74b1de
 
74b1de
+#include <string.h>
74b1de
 #include <dlfcn.h>
74b1de
 
74b1de
 void
74b1de
@@ -72,6 +73,8 @@ cs_init(xlator_t *this)
74b1de
 
74b1de
     this->private = priv;
74b1de
 
74b1de
+    GF_OPTION_INIT("cloudsync-remote-read", priv->remote_read, bool, out);
74b1de
+
74b1de
     /* temp workaround. Should be configurable through glusterd*/
74b1de
     per_vol = _gf_true;
74b1de
 
74b1de
@@ -135,6 +138,18 @@ cs_init(xlator_t *this)
74b1de
 
74b1de
         (void)dlerror();
74b1de
 
74b1de
+        if (priv->remote_read) {
74b1de
+            priv->stores->rdfop = store_methods->fop_remote_read;
74b1de
+            if (!priv->stores->rdfop) {
74b1de
+                gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
+                       "failed to get"
74b1de
+                       " read fop %s",
74b1de
+                       dlerror());
74b1de
+                ret = -1;
74b1de
+                goto out;
74b1de
+            }
74b1de
+        }
74b1de
+
74b1de
         priv->stores->dlfop = store_methods->fop_download;
74b1de
         if (!priv->stores->dlfop) {
74b1de
             gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
@@ -196,6 +211,22 @@ out:
74b1de
     return ret;
74b1de
 }
74b1de
 
74b1de
+int
74b1de
+cs_forget(xlator_t *this, inode_t *inode)
74b1de
+{
74b1de
+    uint64_t ctx_int = 0;
74b1de
+    cs_inode_ctx_t *ctx = NULL;
74b1de
+
74b1de
+    inode_ctx_del(inode, this, &ctx_int);
74b1de
+    if (!ctx_int)
74b1de
+        return 0;
74b1de
+
74b1de
+    ctx = (cs_inode_ctx_t *)(uintptr_t)ctx_int;
74b1de
+
74b1de
+    GF_FREE(ctx);
74b1de
+    return 0;
74b1de
+}
74b1de
+
74b1de
 void
74b1de
 cs_fini(xlator_t *this)
74b1de
 {
74b1de
@@ -217,6 +248,9 @@ cs_reconfigure(xlator_t *this, dict_t *options)
74b1de
         goto out;
74b1de
     }
74b1de
 
74b1de
+    GF_OPTION_RECONF("cloudsync-remote-read", priv->remote_read, options, bool,
74b1de
+                     out);
74b1de
+
74b1de
     /* needed only for per volume configuration*/
74b1de
     ret = priv->stores->reconfigure(this, options);
74b1de
 
74b1de
@@ -242,59 +276,6 @@ out:
74b1de
 }
74b1de
 
74b1de
 int32_t
74b1de
-cs_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
74b1de
-                int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
74b1de
-                dict_t *xdata)
74b1de
-{
74b1de
-    gf_dirent_t *tmp = NULL;
74b1de
-    char *sxattr = NULL;
74b1de
-    uint64_t ia_size = 0;
74b1de
-    int ret = 0;
74b1de
-
74b1de
-    list_for_each_entry(tmp, &entries->list, list)
74b1de
-    {
74b1de
-        ret = dict_get_str(tmp->dict, GF_CS_OBJECT_SIZE, &sxattr);
74b1de
-        if (ret) {
74b1de
-            gf_msg_trace(this->name, 0, "size xattr found");
74b1de
-            continue;
74b1de
-        }
74b1de
-
74b1de
-        ia_size = atoll(sxattr);
74b1de
-        tmp->d_stat.ia_size = ia_size;
74b1de
-    }
74b1de
-
74b1de
-    STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, xdata);
74b1de
-    return 0;
74b1de
-}
74b1de
-
74b1de
-int32_t
74b1de
-cs_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
74b1de
-            off_t off, dict_t *xdata)
74b1de
-{
74b1de
-    int ret = 0;
74b1de
-    int op_errno = ENOMEM;
74b1de
-
74b1de
-    if (!xdata) {
74b1de
-        xdata = dict_new();
74b1de
-        if (!xdata) {
74b1de
-            goto err;
74b1de
-        }
74b1de
-    }
74b1de
-
74b1de
-    ret = dict_set_int32(xdata, GF_CS_OBJECT_SIZE, 1);
74b1de
-    if (ret) {
74b1de
-        goto err;
74b1de
-    }
74b1de
-
74b1de
-    STACK_WIND(frame, cs_readdirp_cbk, FIRST_CHILD(this),
74b1de
-               FIRST_CHILD(this)->fops->readdirp, fd, size, off, xdata);
74b1de
-    return 0;
74b1de
-err:
74b1de
-    STACK_UNWIND_STRICT(readdirp, frame, -1, op_errno, NULL, NULL);
74b1de
-    return 0;
74b1de
-}
74b1de
-
74b1de
-int32_t
74b1de
 cs_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
74b1de
                 int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
74b1de
                 struct iatt *postbuf, dict_t *xdata)
74b1de
@@ -305,7 +286,6 @@ cs_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
74b1de
 
74b1de
     local = frame->local;
74b1de
 
74b1de
-    /* Do we need lock here? */
74b1de
     local->call_cnt++;
74b1de
 
74b1de
     if (op_ret == -1) {
74b1de
@@ -320,13 +300,13 @@ cs_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
74b1de
                 goto unwind;
74b1de
             } else {
74b1de
                 __cs_inode_ctx_update(this, local->loc.inode, val);
74b1de
-                gf_msg(this->name, GF_LOG_INFO, 0, 0, " state = %ld", val);
74b1de
+                gf_msg(this->name, GF_LOG_INFO, 0, 0, " state = %" PRIu64, val);
74b1de
 
74b1de
                 if (local->call_cnt == 1 &&
74b1de
                     (val == GF_CS_REMOTE || val == GF_CS_DOWNLOADING)) {
74b1de
                     gf_msg(this->name, GF_LOG_WARNING, 0, 0,
74b1de
                            "will repair and download "
74b1de
-                           "the file, current state : %ld",
74b1de
+                           "the file, current state : %" PRIu64,
74b1de
                            val);
74b1de
                     goto repair;
74b1de
                 } else {
74b1de
@@ -665,7 +645,7 @@ cs_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
74b1de
     if (op_ret == 0) {
74b1de
         ret = dict_get_uint64(xdata, GF_CS_OBJECT_STATUS, &val;;
74b1de
         if (!ret) {
74b1de
-            gf_msg_debug(this->name, 0, "state %ld", val);
74b1de
+            gf_msg_debug(this->name, 0, "state %" PRIu64, val);
74b1de
             ret = __cs_inode_ctx_update(this, fd->inode, val);
74b1de
             if (ret) {
74b1de
                 gf_msg(this->name, GF_LOG_ERROR, 0, 0, "ctx update failed");
74b1de
@@ -831,7 +811,7 @@ out:
74b1de
     return 0;
74b1de
 }
74b1de
 
74b1de
-void *
74b1de
+int
74b1de
 cs_download_task(void *arg)
74b1de
 {
74b1de
     call_frame_t *frame = NULL;
74b1de
@@ -842,7 +822,6 @@ cs_download_task(void *arg)
74b1de
     fd_t *fd = NULL;
74b1de
     cs_local_t *local = NULL;
74b1de
     dict_t *dict = NULL;
74b1de
-    int *retval = NULL;
74b1de
 
74b1de
     frame = (call_frame_t *)arg;
74b1de
 
74b1de
@@ -850,13 +829,6 @@ cs_download_task(void *arg)
74b1de
 
74b1de
     priv = this->private;
74b1de
 
74b1de
-    retval = GF_CALLOC(1, sizeof(int), gf_common_mt_int);
74b1de
-    if (!retval) {
74b1de
-        gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
74b1de
-        ret = -1;
74b1de
-        goto out;
74b1de
-    }
74b1de
-
74b1de
     if (!priv->stores) {
74b1de
         gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
                "No remote store "
74b1de
@@ -972,20 +944,13 @@ out:
74b1de
         local->dlfd = NULL;
74b1de
     }
74b1de
 
74b1de
-    if (retval) {
74b1de
-        *retval = ret;
74b1de
-        pthread_exit(retval);
74b1de
-    } else {
74b1de
-        pthread_exit(&ret;;
74b1de
-    }
74b1de
+    return ret;
74b1de
 }
74b1de
 
74b1de
 int
74b1de
 cs_download(call_frame_t *frame)
74b1de
 {
74b1de
-    int *retval = NULL;
74b1de
     int ret = 0;
74b1de
-    pthread_t dthread;
74b1de
     cs_local_t *local = NULL;
74b1de
     xlator_t *this = NULL;
74b1de
 
74b1de
@@ -1000,16 +965,406 @@ cs_download(call_frame_t *frame)
74b1de
         goto out;
74b1de
     }
74b1de
 
74b1de
-    ret = gf_thread_create(&dthread, NULL, &cs_download_task, (void *)frame,
74b1de
-                           "downloadthread");
74b1de
+    ret = cs_download_task((void *)frame);
74b1de
+out:
74b1de
+    return ret;
74b1de
+}
74b1de
 
74b1de
-    pthread_join(dthread, (void **)&retval);
74b1de
+int
74b1de
+cs_set_xattr_req(call_frame_t *frame)
74b1de
+{
74b1de
+    cs_local_t *local = NULL;
74b1de
+    GF_UNUSED int ret = 0;
74b1de
+
74b1de
+    local = frame->local;
74b1de
+
74b1de
+    /* When remote reads are performed (i.e. reads on remote store),
74b1de
+     * there needs to be a way to associate a file on gluster volume
74b1de
+     * with its correspnding file on the remote store. In order to do
74b1de
+     * that, a unique key can be maintained as an xattr
74b1de
+     * (GF_CS_XATTR_ARCHIVE_UUID)on the stub file on gluster bricks.
74b1de
+     * This xattr should be provided to the plugin to
74b1de
+     * perform the read fop on the correct file. This assumes that the file
74b1de
+     * hierarchy and name need not be the same on remote store as that of
74b1de
+     * the gluster volume.
74b1de
+     */
74b1de
+    ret = dict_set_str(local->xattr_req, GF_CS_XATTR_ARCHIVE_UUID, "1");
74b1de
+
74b1de
+    return 0;
74b1de
+}
74b1de
 
74b1de
-    ret = *retval;
74b1de
+int
74b1de
+cs_update_xattrs(call_frame_t *frame, dict_t *xdata)
74b1de
+{
74b1de
+    cs_local_t *local = NULL;
74b1de
+    xlator_t *this = NULL;
74b1de
+    int size = -1;
74b1de
+    GF_UNUSED int ret = 0;
74b1de
+
74b1de
+    local = frame->local;
74b1de
+    this = frame->this;
74b1de
+
74b1de
+    local->xattrinfo.lxattr = GF_CALLOC(1, sizeof(cs_loc_xattr_t),
74b1de
+                                        gf_cs_mt_cs_lxattr_t);
74b1de
+    if (!local->xattrinfo.lxattr) {
74b1de
+        local->op_ret = -1;
74b1de
+        local->op_errno = ENOMEM;
74b1de
+        goto err;
74b1de
+    }
74b1de
+
74b1de
+    gf_uuid_copy(local->xattrinfo.lxattr->gfid, local->loc.gfid);
74b1de
+
74b1de
+    if (local->remotepath) {
74b1de
+        local->xattrinfo.lxattr->file_path = gf_strdup(local->remotepath);
74b1de
+        if (!local->xattrinfo.lxattr->file_path) {
74b1de
+            local->op_ret = -1;
74b1de
+            local->op_errno = ENOMEM;
74b1de
+            goto err;
74b1de
+        }
74b1de
+    }
74b1de
+
74b1de
+    ret = dict_get_gfuuid(xdata, GF_CS_XATTR_ARCHIVE_UUID,
74b1de
+                          &(local->xattrinfo.lxattr->uuid));
74b1de
+
74b1de
+    if (ret) {
74b1de
+        gf_uuid_clear(local->xattrinfo.lxattr->uuid);
74b1de
+    }
74b1de
+    size = strlen(this->name) - strlen("-cloudsync") + 1;
74b1de
+    local->xattrinfo.lxattr->volname = GF_CALLOC(1, size, gf_common_mt_char);
74b1de
+    if (!local->xattrinfo.lxattr->volname) {
74b1de
+        local->op_ret = -1;
74b1de
+        local->op_errno = ENOMEM;
74b1de
+        goto err;
74b1de
+    }
74b1de
+    strncpy(local->xattrinfo.lxattr->volname, this->name, size - 1);
74b1de
+    local->xattrinfo.lxattr->volname[size - 1] = '\0';
74b1de
+
74b1de
+    return 0;
74b1de
+err:
74b1de
+    cs_xattrinfo_wipe(local);
74b1de
+    return -1;
74b1de
+}
74b1de
+
74b1de
+int
74b1de
+cs_serve_readv(call_frame_t *frame, off_t offset, size_t size, uint32_t flags)
74b1de
+{
74b1de
+    xlator_t *this = NULL;
74b1de
+    cs_private_t *priv = NULL;
74b1de
+    int ret = -1;
74b1de
+    fd_t *fd = NULL;
74b1de
+    cs_local_t *local = NULL;
74b1de
+
74b1de
+    local = frame->local;
74b1de
+    this = frame->this;
74b1de
+    priv = this->private;
74b1de
+
74b1de
+    if (!local->remotepath) {
74b1de
+        ret = -1;
74b1de
+        gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
+               "remote path not"
74b1de
+               " available. Check posix logs to resolve");
74b1de
+        goto out;
74b1de
+    }
74b1de
+
74b1de
+    if (!priv->stores) {
74b1de
+        gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
+               "No remote store "
74b1de
+               "plugins found");
74b1de
+        ret = -1;
74b1de
+        goto out;
74b1de
+    }
74b1de
+
74b1de
+    if (local->fd) {
74b1de
+        fd = fd_anonymous(local->fd->inode);
74b1de
+    } else {
74b1de
+        fd = fd_anonymous(local->loc.inode);
74b1de
+    }
74b1de
+
74b1de
+    local->xattrinfo.size = size;
74b1de
+    local->xattrinfo.offset = offset;
74b1de
+    local->xattrinfo.flags = flags;
74b1de
+
74b1de
+    if (!fd) {
74b1de
+        gf_msg("CS", GF_LOG_ERROR, 0, 0, "fd creation failed");
74b1de
+        ret = -1;
74b1de
+        goto out;
74b1de
+    }
74b1de
+
74b1de
+    local->dlfd = fd;
74b1de
+    local->dloffset = offset;
74b1de
+
74b1de
+    /*this calling method is for per volume setting */
74b1de
+    ret = priv->stores->rdfop(frame, priv->stores->config);
74b1de
+    if (ret) {
74b1de
+        gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
+               "read failed"
74b1de
+               ", remotepath: %s",
74b1de
+               local->remotepath);
74b1de
+        ret = -1;
74b1de
+        goto out;
74b1de
+    } else {
74b1de
+        gf_msg(this->name, GF_LOG_INFO, 0, 0,
74b1de
+               "read success, path"
74b1de
+               " : %s",
74b1de
+               local->remotepath);
74b1de
+    }
74b1de
 
74b1de
 out:
74b1de
-    if (retval)
74b1de
-        GF_FREE(retval);
74b1de
+    if (fd) {
74b1de
+        fd_unref(fd);
74b1de
+        local->dlfd = NULL;
74b1de
+    }
74b1de
+    return ret;
74b1de
+}
74b1de
+
74b1de
+int32_t
74b1de
+cs_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
74b1de
+             int32_t op_errno, struct iovec *vector, int32_t count,
74b1de
+             struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
74b1de
+{
74b1de
+    cs_local_t *local = NULL;
74b1de
+    int ret = 0;
74b1de
+    uint64_t val = 0;
74b1de
+    fd_t *fd = NULL;
74b1de
+
74b1de
+    local = frame->local;
74b1de
+    fd = local->fd;
74b1de
+
74b1de
+    local->call_cnt++;
74b1de
+
74b1de
+    if (op_ret == -1) {
74b1de
+        ret = dict_get_uint64(xdata, GF_CS_OBJECT_STATUS, &val;;
74b1de
+        if (ret == 0) {
74b1de
+            if (val == GF_CS_ERROR) {
74b1de
+                gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
+                       "could not get file state, unwinding");
74b1de
+                op_ret = -1;
74b1de
+                op_errno = EIO;
74b1de
+                goto unwind;
74b1de
+            } else {
74b1de
+                __cs_inode_ctx_update(this, fd->inode, val);
74b1de
+                gf_msg(this->name, GF_LOG_INFO, 0, 0, " state = %" PRIu64, val);
74b1de
+
74b1de
+                if (local->call_cnt == 1 &&
74b1de
+                    (val == GF_CS_REMOTE || val == GF_CS_DOWNLOADING)) {
74b1de
+                    gf_msg(this->name, GF_LOG_INFO, 0, 0,
74b1de
+                           " will read from remote : %" PRIu64, val);
74b1de
+                    goto repair;
74b1de
+                } else {
74b1de
+                    gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
+                           "second readv, Unwinding");
74b1de
+                    goto unwind;
74b1de
+                }
74b1de
+            }
74b1de
+        } else {
74b1de
+            gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
+                   "file state "
74b1de
+                   "could not be figured, unwinding");
74b1de
+            goto unwind;
74b1de
+        }
74b1de
+    } else {
74b1de
+        /* successful readv => file is local */
74b1de
+        __cs_inode_ctx_update(this, fd->inode, GF_CS_LOCAL);
74b1de
+        gf_msg(this->name, GF_LOG_INFO, 0, 0,
74b1de
+               "state : GF_CS_LOCAL"
74b1de
+               ", readv successful");
74b1de
+
74b1de
+        goto unwind;
74b1de
+    }
74b1de
+
74b1de
+repair:
74b1de
+    ret = locate_and_execute(frame);
74b1de
+    if (ret) {
74b1de
+        goto unwind;
74b1de
+    }
74b1de
+
74b1de
+    return 0;
74b1de
+
74b1de
+unwind:
74b1de
+    CS_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, stbuf,
74b1de
+                    iobref, xdata);
74b1de
+
74b1de
+    return 0;
74b1de
+}
74b1de
+
74b1de
+int32_t
74b1de
+cs_resume_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
74b1de
+                off_t offset, uint32_t flags, dict_t *xdata)
74b1de
+{
74b1de
+    int ret = 0;
74b1de
+
74b1de
+    ret = cs_resume_postprocess(this, frame, fd->inode);
74b1de
+    if (ret) {
74b1de
+        goto unwind;
74b1de
+    }
74b1de
+
74b1de
+    cs_inodelk_unlock(frame);
74b1de
+
74b1de
+    STACK_WIND(frame, cs_readv_cbk, FIRST_CHILD(this),
74b1de
+               FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata);
74b1de
+
74b1de
+    return 0;
74b1de
+
74b1de
+unwind:
74b1de
+    cs_inodelk_unlock(frame);
74b1de
+
74b1de
+    cs_common_cbk(frame);
74b1de
+
74b1de
+    return 0;
74b1de
+}
74b1de
+
74b1de
+int32_t
74b1de
+cs_resume_remote_readv(call_frame_t *frame, xlator_t *this, fd_t *fd,
74b1de
+                       size_t size, off_t offset, uint32_t flags, dict_t *xdata)
74b1de
+{
74b1de
+    int ret = 0;
74b1de
+    cs_local_t *local = NULL;
74b1de
+    gf_cs_obj_state state = -1;
74b1de
+    cs_inode_ctx_t *ctx = NULL;
74b1de
+
74b1de
+    cs_inodelk_unlock(frame);
74b1de
+
74b1de
+    local = frame->local;
74b1de
+    if (!local) {
74b1de
+        ret = -1;
74b1de
+        goto unwind;
74b1de
+    }
74b1de
+
74b1de
+    __cs_inode_ctx_get(this, fd->inode, &ctx;;
74b1de
+
74b1de
+    state = __cs_get_file_state(this, fd->inode, ctx);
74b1de
+    if (state == GF_CS_ERROR) {
74b1de
+        gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
+               "status is GF_CS_ERROR."
74b1de
+               " Aborting readv");
74b1de
+        local->op_ret = -1;
74b1de
+        local->op_errno = EREMOTE;
74b1de
+        ret = -1;
74b1de
+        goto unwind;
74b1de
+    }
74b1de
+
74b1de
+    /* Serve readv from remote store only if it is remote. */
74b1de
+    gf_msg_debug(this->name, 0, "status of file %s is %d",
74b1de
+                 local->remotepath ? local->remotepath : "", state);
74b1de
+
74b1de
+    /* We will reach this condition if local inode ctx had REMOTE
74b1de
+     * state when the control was in cs_readv but after stat
74b1de
+     * we got an updated state saying that the file is LOCAL.
74b1de
+     */
74b1de
+    if (state == GF_CS_LOCAL) {
74b1de
+        STACK_WIND(frame, cs_readv_cbk, FIRST_CHILD(this),
74b1de
+                   FIRST_CHILD(this)->fops->readv, fd, size, offset, flags,
74b1de
+                   xdata);
74b1de
+    } else if (state == GF_CS_REMOTE) {
74b1de
+        ret = cs_resume_remote_readv_postprocess(this, frame, fd->inode, offset,
74b1de
+                                                 size, flags);
74b1de
+        /* Failed to submit the remote readv fop to plugin */
74b1de
+        if (ret) {
74b1de
+            local->op_ret = -1;
74b1de
+            local->op_errno = EREMOTE;
74b1de
+            goto unwind;
74b1de
+        }
74b1de
+        /* When the file is in any other intermediate state,
74b1de
+         * we should not perform remote reads.
74b1de
+         */
74b1de
+    } else {
74b1de
+        local->op_ret = -1;
74b1de
+        local->op_errno = EINVAL;
74b1de
+        goto unwind;
74b1de
+    }
74b1de
+
74b1de
+    return 0;
74b1de
+
74b1de
+unwind:
74b1de
+    cs_common_cbk(frame);
74b1de
+
74b1de
+    return 0;
74b1de
+}
74b1de
+
74b1de
+int32_t
74b1de
+cs_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
74b1de
+         off_t offset, uint32_t flags, dict_t *xdata)
74b1de
+{
74b1de
+    int op_errno = -1;
74b1de
+    cs_local_t *local = NULL;
74b1de
+    int ret = 0;
74b1de
+    cs_inode_ctx_t *ctx = NULL;
74b1de
+    gf_cs_obj_state state = -1;
74b1de
+    cs_private_t *priv = NULL;
74b1de
+
74b1de
+    VALIDATE_OR_GOTO(frame, err);
74b1de
+    VALIDATE_OR_GOTO(this, err);
74b1de
+    VALIDATE_OR_GOTO(fd, err);
74b1de
+
74b1de
+    priv = this->private;
74b1de
+
74b1de
+    local = cs_local_init(this, frame, NULL, fd, GF_FOP_READ);
74b1de
+    if (!local) {
74b1de
+        gf_msg(this->name, GF_LOG_ERROR, 0, 0, "local init failed");
74b1de
+        op_errno = ENOMEM;
74b1de
+        goto err;
74b1de
+    }
74b1de
+
74b1de
+    __cs_inode_ctx_get(this, fd->inode, &ctx;;
74b1de
+
74b1de
+    if (ctx)
74b1de
+        state = __cs_get_file_state(this, fd->inode, ctx);
74b1de
+    else
74b1de
+        state = GF_CS_LOCAL;
74b1de
+
74b1de
+    local->xattr_req = xdata ? dict_ref(xdata) : (xdata = dict_new());
74b1de
+
74b1de
+    ret = dict_set_uint32(local->xattr_req, GF_CS_OBJECT_STATUS, 1);
74b1de
+    if (ret) {
74b1de
+        gf_msg(this->name, GF_LOG_ERROR, 0, 0,
74b1de
+               "dict_set failed key:"
74b1de
+               " %s",
74b1de
+               GF_CS_OBJECT_STATUS);
74b1de
+        goto err;
74b1de
+    }
74b1de
+
74b1de
+    if (priv->remote_read) {
74b1de
+        local->stub = fop_readv_stub(frame, cs_resume_remote_readv, fd, size,
74b1de
+                                     offset, flags, xdata);
74b1de
+    } else {
74b1de
+        local->stub = fop_readv_stub(frame, cs_resume_readv, fd, size, offset,
74b1de
+                                     flags, xdata);
74b1de
+    }
74b1de
+    if (!local->stub) {
74b1de
+        gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
74b1de
+        op_errno = ENOMEM;
74b1de
+        goto err;
74b1de
+    }
74b1de
+
74b1de
+    if (state == GF_CS_LOCAL) {
74b1de
+        STACK_WIND(frame, cs_readv_cbk, FIRST_CHILD(this),
74b1de
+                   FIRST_CHILD(this)->fops->readv, fd, size, offset, flags,
74b1de
+                   xdata);
74b1de
+    } else {
74b1de
+        local->call_cnt++;
74b1de
+        ret = locate_and_execute(frame);
74b1de
+        if (ret) {
74b1de
+            op_errno = ENOMEM;
74b1de
+            goto err;
74b1de
+        }
74b1de
+    }
74b1de
+
74b1de
+    return 0;
74b1de
+
74b1de
+err:
74b1de
+    CS_STACK_UNWIND(readv, frame, -1, op_errno, NULL, -1, NULL, NULL, NULL);
74b1de
+
74b1de
+    return 0;
74b1de
+}
74b1de
+
74b1de
+int
74b1de
+cs_resume_remote_readv_postprocess(xlator_t *this, call_frame_t *frame,
74b1de
+                                   inode_t *inode, off_t offset, size_t size,
74b1de
+                                   uint32_t flags)
74b1de
+{
74b1de
+    int ret = 0;
74b1de
+
74b1de
+    ret = cs_serve_readv(frame, offset, size, flags);
74b1de
 
74b1de
     return ret;
74b1de
 }
74b1de
@@ -1059,7 +1414,7 @@ cs_stat_check_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
74b1de
                 goto err;
74b1de
             } else {
74b1de
                 ret = __cs_inode_ctx_update(this, inode, val);
74b1de
-                gf_msg_debug(this->name, 0, "status : %lu", val);
74b1de
+                gf_msg_debug(this->name, 0, "status : %" PRIu64, val);
74b1de
                 if (ret) {
74b1de
                     gf_msg(this->name, GF_LOG_ERROR, 0, 0, "ctx update failed");
74b1de
                     local->op_ret = -1;
74b1de
@@ -1087,6 +1442,10 @@ cs_stat_check_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
74b1de
             gf_msg_debug(this->name, 0, "NULL filepath");
74b1de
         }
74b1de
 
74b1de
+        ret = cs_update_xattrs(frame, xdata);
74b1de
+        if (ret)
74b1de
+            goto err;
74b1de
+
74b1de
         local->op_ret = 0;
74b1de
         local->xattr_rsp = dict_ref(xdata);
74b1de
         memcpy(&local->stbuf, stbuf, sizeof(struct iatt));
74b1de
@@ -1121,6 +1480,8 @@ cs_do_stat_check(call_frame_t *main_frame)
74b1de
         goto err;
74b1de
     }
74b1de
 
74b1de
+    cs_set_xattr_req(main_frame);
74b1de
+
74b1de
     if (local->fd) {
74b1de
         STACK_WIND(main_frame, cs_stat_check_cbk, FIRST_CHILD(this),
74b1de
                    FIRST_CHILD(this)->fops->fstat, local->fd, local->xattr_req);
74b1de
@@ -1177,6 +1538,10 @@ cs_common_cbk(call_frame_t *frame)
74b1de
                             NULL, NULL, NULL);
74b1de
             break;
74b1de
 
74b1de
+        case GF_FOP_TRUNCATE:
74b1de
+            CS_STACK_UNWIND(truncate, frame, local->op_ret, local->op_errno,
74b1de
+                            NULL, NULL, NULL);
74b1de
+            break;
74b1de
         default:
74b1de
             break;
74b1de
     }
74b1de
@@ -1427,7 +1792,7 @@ __cs_inode_ctx_get(xlator_t *this, inode_t *inode, cs_inode_ctx_t **ctx)
74b1de
     if (ret)
74b1de
         *ctx = NULL;
74b1de
     else
74b1de
-        *ctx = (cs_inode_ctx_t *)ctxint;
74b1de
+        *ctx = (cs_inode_ctx_t *)(uintptr_t)ctxint;
74b1de
 
74b1de
     return;
74b1de
 }
74b1de
@@ -1452,7 +1817,7 @@ __cs_inode_ctx_update(xlator_t *this, inode_t *inode, uint64_t val)
74b1de
 
74b1de
             ctx->state = val;
74b1de
 
74b1de
-            ctxint = (uint64_t)ctx;
74b1de
+            ctxint = (uint64_t)(uintptr_t)ctx;
74b1de
 
74b1de
             ret = __inode_ctx_set(inode, this, &ctxint);
74b1de
             if (ret) {
74b1de
@@ -1460,7 +1825,7 @@ __cs_inode_ctx_update(xlator_t *this, inode_t *inode, uint64_t val)
74b1de
                 goto out;
74b1de
             }
74b1de
         } else {
74b1de
-            ctx = (cs_inode_ctx_t *)ctxint;
74b1de
+            ctx = (cs_inode_ctx_t *)(uintptr_t)ctxint;
74b1de
 
74b1de
             ctx->state = val;
74b1de
         }
74b1de
@@ -1483,7 +1848,7 @@ cs_inode_ctx_reset(xlator_t *this, inode_t *inode)
74b1de
         return 0;
74b1de
     }
74b1de
 
74b1de
-    ctx = (cs_inode_ctx_t *)ctxint;
74b1de
+    ctx = (cs_inode_ctx_t *)(uintptr_t)ctxint;
74b1de
 
74b1de
     GF_FREE(ctx);
74b1de
     return 0;
74b1de
@@ -1532,6 +1897,57 @@ cs_resume_postprocess(xlator_t *this, call_frame_t *frame, inode_t *inode)
74b1de
 out:
74b1de
     return ret;
74b1de
 }
74b1de
+
74b1de
+int32_t
74b1de
+__cs_get_dict_str(char **str, dict_t *xattr, const char *name, int *errnum)
74b1de
+{
74b1de
+    data_t *data = NULL;
74b1de
+    int ret = -1;
74b1de
+
74b1de
+    assert(str != NULL);
74b1de
+
74b1de
+    data = dict_get(xattr, (char *)name);
74b1de
+    if (!data) {
74b1de
+        *errnum = ENODATA;
74b1de
+        goto out;
74b1de
+    }
74b1de
+
74b1de
+    *str = GF_CALLOC(data->len + 1, sizeof(char), gf_common_mt_char);
74b1de
+    if (!(*str)) {
74b1de
+        *errnum = ENOMEM;
74b1de
+        goto out;
74b1de
+    }
74b1de
+
74b1de
+    memcpy(*str, data->data, sizeof(char) * (data->len));
74b1de
+    return 0;
74b1de
+
74b1de
+out:
74b1de
+    return ret;
74b1de
+}
74b1de
+
74b1de
+int32_t
74b1de
+__cs_get_dict_uuid(uuid_t uuid, dict_t *xattr, const char *name, int *errnum)
74b1de
+{
74b1de
+    data_t *data = NULL;
74b1de
+    int ret = -1;
74b1de
+
74b1de
+    assert(uuid != NULL);
74b1de
+
74b1de
+    data = dict_get(xattr, (char *)name);
74b1de
+    if (!data) {
74b1de
+        *errnum = ENODATA;
74b1de
+        goto out;
74b1de
+    }
74b1de
+
74b1de
+    assert(data->len == sizeof(uuid_t));
74b1de
+
74b1de
+    gf_uuid_copy(uuid, (unsigned char *)data->data);
74b1de
+    return 0;
74b1de
+
74b1de
+out:
74b1de
+    return ret;
74b1de
+}
74b1de
+
74b1de
 int32_t
74b1de
 cs_fdctx_to_dict(xlator_t *this, fd_t *fd, dict_t *dict)
74b1de
 {
74b1de
@@ -1606,7 +2022,6 @@ cs_notify(xlator_t *this, int event, void *data, ...)
74b1de
 
74b1de
 struct xlator_fops cs_fops = {
74b1de
     .stat = cs_stat,
74b1de
-    .readdirp = cs_readdirp,
74b1de
     .truncate = cs_truncate,
74b1de
     .seek = cs_seek,
74b1de
     .statfs = cs_statfs,
74b1de
@@ -1627,7 +2042,9 @@ struct xlator_fops cs_fops = {
74b1de
     .zerofill = cs_zerofill,
74b1de
 };
74b1de
 
74b1de
-struct xlator_cbks cs_cbks = {};
74b1de
+struct xlator_cbks cs_cbks = {
74b1de
+    .forget = cs_forget,
74b1de
+};
74b1de
 
74b1de
 struct xlator_dumpops cs_dumpops = {
74b1de
     .fdctx_to_dict = cs_fdctx_to_dict,
74b1de
@@ -1647,6 +2064,15 @@ struct volume_options cs_options[] = {
74b1de
     {.key = {"cloudsync-storetype"},
74b1de
      .type = GF_OPTION_TYPE_STR,
74b1de
      .description = "Defines which remote store is enabled"},
74b1de
+    {.key = {"cloudsync-remote-read"},
74b1de
+     .type = GF_OPTION_TYPE_BOOL,
74b1de
+     .description = "Defines a remote read fop when on"},
74b1de
+    {.key = {"cloudsync-store-id"},
74b1de
+     .type = GF_OPTION_TYPE_STR,
74b1de
+     .description = "Defines a volume wide store id"},
74b1de
+    {.key = {"cloudsync-product-id"},
74b1de
+     .type = GF_OPTION_TYPE_STR,
74b1de
+     .description = "Defines a volume wide product id"},
74b1de
     {.key = {NULL}},
74b1de
 };
74b1de
 
74b1de
diff --git a/xlators/features/cloudsync/src/cloudsync.h b/xlators/features/cloudsync/src/cloudsync.h
74b1de
index dbdb207..0cb800a 100644
74b1de
--- a/xlators/features/cloudsync/src/cloudsync.h
74b1de
+++ b/xlators/features/cloudsync/src/cloudsync.h
74b1de
@@ -19,6 +19,7 @@
74b1de
 #include "cloudsync-common.h"
74b1de
 #include "cloudsync-autogen-fops.h"
74b1de
 
74b1de
+#define ALIGN_SIZE 4096
74b1de
 #define CS_LOCK_DOMAIN "cs.protect.file.stat"
74b1de
 typedef struct cs_dlstore {
74b1de
     off_t off;
74b1de
@@ -29,6 +30,7 @@ typedef struct cs_dlstore {
74b1de
 } cs_dlstore;
74b1de
 
74b1de
 typedef struct cs_inode_ctx {
74b1de
+    cs_loc_xattr_t locxattr;
74b1de
     gf_cs_obj_state state;
74b1de
 } cs_inode_ctx_t;
74b1de
 
74b1de
@@ -100,4 +102,22 @@ cs_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
74b1de
 int32_t
74b1de
 cs_resume_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc,
74b1de
                    off_t offset, dict_t *xattr_req);
74b1de
+
74b1de
+int32_t
74b1de
+cs_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
74b1de
+             int32_t op_errno, struct iovec *vector, int32_t count,
74b1de
+             struct iatt *stbuf, struct iobref *iobref, dict_t *xdata);
74b1de
+int32_t
74b1de
+cs_resume_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
74b1de
+                off_t offset, uint32_t flags, dict_t *xdata);
74b1de
+int32_t
74b1de
+cs_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
74b1de
+         off_t offset, uint32_t flags, dict_t *xdata);
74b1de
+
74b1de
+int
74b1de
+cs_resume_remote_readv_postprocess(xlator_t *this, call_frame_t *frame,
74b1de
+                                   inode_t *inode, off_t offset, size_t size,
74b1de
+                                   uint32_t flags);
74b1de
+int
74b1de
+cs_serve_readv(call_frame_t *frame, off_t offset, size_t size, uint32_t flags);
74b1de
 #endif /* __CLOUDSYNC_H__ */
74b1de
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
74b1de
index 4b32fb6..73abf37 100644
74b1de
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
74b1de
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
74b1de
@@ -3693,7 +3693,7 @@ struct volopt_map_entry glusterd_volopt_map[] = {
74b1de
      .op_version = GD_OP_VERSION_5_0,
74b1de
      .description = "enable/disable noatime option with ctime enabled.",
74b1de
      .flags = VOLOPT_FLAG_CLIENT_OPT | VOLOPT_FLAG_XLATOR_OPT},
74b1de
-    {.key = "feature.cloudsync-storetype",
74b1de
+    {.key = "features.cloudsync-storetype",
74b1de
      .voltype = "features/cloudsync",
74b1de
      .op_version = GD_OP_VERSION_5_0,
74b1de
      .flags = VOLOPT_FLAG_CLIENT_OPT},
74b1de
@@ -3721,4 +3721,9 @@ struct volopt_map_entry glusterd_volopt_map[] = {
74b1de
      .validate_fn = validate_boolean,
74b1de
      .description = "option to enforce mandatory lock on a file",
74b1de
      .flags = VOLOPT_FLAG_XLATOR_OPT},
74b1de
+    {.key = "features.cloudsync-remote-read",
74b1de
+     .voltype = "features/cloudsync",
74b1de
+     .value = "off",
74b1de
+     .op_version = GD_OP_VERSION_6_0,
74b1de
+     .flags = VOLOPT_FLAG_CLIENT_OPT},
74b1de
     {.key = NULL}};
74b1de
-- 
74b1de
1.8.3.1
74b1de