summaryrefslogtreecommitdiffstats
path: root/xlators/features/cloudsync/src/cloudsync.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/cloudsync/src/cloudsync.c')
-rw-r--r--xlators/features/cloudsync/src/cloudsync.c582
1 files changed, 497 insertions, 85 deletions
diff --git a/xlators/features/cloudsync/src/cloudsync.c b/xlators/features/cloudsync/src/cloudsync.c
index cb2cefa4d01..7f0b9e563b8 100644
--- a/xlators/features/cloudsync/src/cloudsync.c
+++ b/xlators/features/cloudsync/src/cloudsync.c
@@ -8,17 +8,18 @@
* cases as published by the Free Software Foundation.
*/
-#include "glusterfs.h"
-#include "xlator.h"
-#include "defaults.h"
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/xlator.h>
+#include <glusterfs/defaults.h>
#include "cloudsync.h"
#include "cloudsync-common.h"
-#include "call-stub.h"
+#include <glusterfs/call-stub.h>
#include "cloudsync-autogen-fops.h"
+#include <string.h>
#include <dlfcn.h>
-void
+static void
cs_cleanup_private(cs_private_t *priv)
{
if (priv) {
@@ -34,11 +35,15 @@ cs_cleanup_private(cs_private_t *priv)
return;
}
-struct cs_plugin plugins[] = {
+static struct cs_plugin plugins[] = {
{.name = "cloudsyncs3",
.library = "cloudsyncs3.so",
.description = "cloudsync s3 store."},
-
+#if defined(__linux__)
+ {.name = "cvlt",
+ .library = "cloudsynccvlt.so",
+ .description = "Commvault content store."},
+#endif
{.name = NULL},
};
@@ -72,12 +77,14 @@ cs_init(xlator_t *this)
this->private = priv;
+ GF_OPTION_INIT("cloudsync-remote-read", priv->remote_read, bool, out);
+
/* temp workaround. Should be configurable through glusterd*/
per_vol = _gf_true;
if (per_vol) {
- if (dict_get_str(this->options, "cloudsync-storetype", &temp_str) ==
- 0) {
+ if (dict_get_str_sizen(this->options, "cloudsync-storetype",
+ &temp_str) == 0) {
for (index = 0; plugins[index].name; index++) {
if (!strcmp(temp_str, plugins[index].name)) {
libname = plugins[index].library;
@@ -135,6 +142,18 @@ cs_init(xlator_t *this)
(void)dlerror();
+ if (priv->remote_read) {
+ priv->stores->rdfop = store_methods->fop_remote_read;
+ if (!priv->stores->rdfop) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0,
+ "failed to get"
+ " read fop %s",
+ dlerror());
+ ret = -1;
+ goto out;
+ }
+ }
+
priv->stores->dlfop = store_methods->fop_download;
if (!priv->stores->dlfop) {
gf_msg(this->name, GF_LOG_ERROR, 0, 0,
@@ -181,8 +200,10 @@ cs_init(xlator_t *this)
out:
if (ret == -1) {
- if (this->local_pool)
+ if (this->local_pool) {
mem_pool_destroy(this->local_pool);
+ this->local_pool = NULL;
+ }
cs_cleanup_private(priv);
@@ -196,6 +217,22 @@ out:
return ret;
}
+int
+cs_forget(xlator_t *this, inode_t *inode)
+{
+ uint64_t ctx_int = 0;
+ cs_inode_ctx_t *ctx = NULL;
+
+ inode_ctx_del(inode, this, &ctx_int);
+ if (!ctx_int)
+ return 0;
+
+ ctx = (cs_inode_ctx_t *)(uintptr_t)ctx_int;
+
+ GF_FREE(ctx);
+ return 0;
+}
+
void
cs_fini(xlator_t *this)
{
@@ -217,6 +254,9 @@ cs_reconfigure(xlator_t *this, dict_t *options)
goto out;
}
+ GF_OPTION_RECONF("cloudsync-remote-read", priv->remote_read, options, bool,
+ out);
+
/* needed only for per volume configuration*/
ret = priv->stores->reconfigure(this, options);
@@ -242,32 +282,6 @@ out:
}
int32_t
-cs_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
-{
- gf_dirent_t *tmp = NULL;
- char *sxattr = NULL;
- uint64_t ia_size = 0;
- int ret = 0;
-
- list_for_each_entry(tmp, &entries->list, list)
- {
- ret = dict_get_str(tmp->dict, GF_CS_OBJECT_SIZE, &sxattr);
- if (ret) {
- gf_msg_trace(this->name, 0, "size xattr found");
- continue;
- }
-
- ia_size = atoll(sxattr);
- tmp->d_stat.ia_size = ia_size;
- }
-
- STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, xdata);
- return 0;
-}
-
-int32_t
cs_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t off, dict_t *xdata)
{
@@ -277,16 +291,23 @@ cs_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
if (!xdata) {
xdata = dict_new();
if (!xdata) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, ENOMEM,
+ "failed to create "
+ "dict");
goto err;
}
}
- ret = dict_set_int32(xdata, GF_CS_OBJECT_SIZE, 1);
+ ret = dict_set_uint32(xdata, GF_CS_OBJECT_STATUS, 1);
if (ret) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0,
+ "dict_set failed key:"
+ " %s",
+ GF_CS_OBJECT_STATUS);
goto err;
}
- STACK_WIND(frame, cs_readdirp_cbk, FIRST_CHILD(this),
+ STACK_WIND(frame, default_readdirp_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdirp, fd, size, off, xdata);
return 0;
err:
@@ -305,7 +326,6 @@ cs_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
- /* Do we need lock here? */
local->call_cnt++;
if (op_ret == -1) {
@@ -320,13 +340,13 @@ cs_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
goto unwind;
} else {
__cs_inode_ctx_update(this, local->loc.inode, val);
- gf_msg(this->name, GF_LOG_INFO, 0, 0, " state = %ld", val);
+ gf_msg(this->name, GF_LOG_INFO, 0, 0, " state = %" PRIu64, val);
if (local->call_cnt == 1 &&
(val == GF_CS_REMOTE || val == GF_CS_DOWNLOADING)) {
gf_msg(this->name, GF_LOG_WARNING, 0, 0,
"will repair and download "
- "the file, current state : %ld",
+ "the file, current state : %" PRIu64,
val);
goto repair;
} else {
@@ -368,7 +388,6 @@ int32_t
cs_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
dict_t *xdata)
{
- int op_errno = -1;
cs_local_t *local = NULL;
int ret = 0;
cs_inode_ctx_t *ctx = NULL;
@@ -381,14 +400,13 @@ cs_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
local = cs_local_init(this, frame, loc, NULL, GF_FOP_TRUNCATE);
if (!local) {
gf_msg(this->name, GF_LOG_ERROR, 0, 0, "local init failed");
- op_errno = ENOMEM;
goto err;
}
__cs_inode_ctx_get(this, loc->inode, &ctx);
if (ctx)
- state = __cs_get_file_state(this, loc->inode, ctx);
+ state = __cs_get_file_state(loc->inode, ctx);
else
state = GF_CS_LOCAL;
@@ -407,7 +425,6 @@ cs_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
xdata);
if (!local->stub) {
gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
- op_errno = ENOMEM;
goto err;
}
@@ -419,14 +436,13 @@ cs_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
local->call_cnt++;
ret = locate_and_execute(frame);
if (ret) {
- op_errno = ENOMEM;
goto err;
}
}
return 0;
err:
- CS_STACK_UNWIND(truncate, frame, -1, op_errno, NULL, NULL, NULL);
+ CS_STACK_UNWIND(truncate, frame, -1, ENOMEM, NULL, NULL, NULL);
return 0;
}
@@ -498,7 +514,7 @@ cs_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
local->xattr_req = xdata ? dict_ref(xdata) : (xdata = dict_new());
- tmp = dict_get(dict, GF_CS_OBJECT_UPLOAD_COMPLETE);
+ tmp = dict_get_sizen(dict, GF_CS_OBJECT_UPLOAD_COMPLETE);
if (tmp) {
/* Value of key should be the atime */
local->stub = fop_setxattr_stub(frame, cs_resume_setxattr, loc, dict,
@@ -665,7 +681,7 @@ cs_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
if (op_ret == 0) {
ret = dict_get_uint64(xdata, GF_CS_OBJECT_STATUS, &val);
if (!ret) {
- gf_msg_debug(this->name, 0, "state %ld", val);
+ gf_msg_debug(this->name, 0, "state %" PRIu64, val);
ret = __cs_inode_ctx_update(this, fd->inode, val);
if (ret) {
gf_msg(this->name, GF_LOG_ERROR, 0, 0, "ctx update failed");
@@ -831,7 +847,7 @@ out:
return 0;
}
-void *
+int
cs_download_task(void *arg)
{
call_frame_t *frame = NULL;
@@ -842,7 +858,6 @@ cs_download_task(void *arg)
fd_t *fd = NULL;
cs_local_t *local = NULL;
dict_t *dict = NULL;
- int *retval = NULL;
frame = (call_frame_t *)arg;
@@ -850,13 +865,6 @@ cs_download_task(void *arg)
priv = this->private;
- retval = GF_CALLOC(1, sizeof(int), gf_common_mt_int);
- if (!retval) {
- gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
- ret = -1;
- goto out;
- }
-
if (!priv->stores) {
gf_msg(this->name, GF_LOG_ERROR, 0, 0,
"No remote store "
@@ -915,7 +923,8 @@ cs_download_task(void *arg)
local->remotepath);
/*using dlfd as it is anonymous and have RDWR flag*/
- ret = syncop_ftruncate(FIRST_CHILD(this), local->dlfd, 0, NULL, NULL);
+ ret = syncop_ftruncate(FIRST_CHILD(this), local->dlfd, 0, NULL, NULL,
+ NULL, NULL);
if (ret) {
gf_msg(this->name, GF_LOG_ERROR, 0, -ret, "ftruncate failed");
} else {
@@ -971,20 +980,13 @@ out:
local->dlfd = NULL;
}
- if (retval) {
- *retval = ret;
- pthread_exit(retval);
- } else {
- pthread_exit(&ret);
- }
+ return ret;
}
int
cs_download(call_frame_t *frame)
{
- int *retval = NULL;
int ret = 0;
- pthread_t dthread;
cs_local_t *local = NULL;
xlator_t *this = NULL;
@@ -999,16 +1001,404 @@ cs_download(call_frame_t *frame)
goto out;
}
- ret = gf_thread_create(&dthread, NULL, &cs_download_task, (void *)frame,
- "downloadthread");
+ ret = cs_download_task((void *)frame);
+out:
+ return ret;
+}
+
+int
+cs_set_xattr_req(call_frame_t *frame)
+{
+ cs_local_t *local = NULL;
+ GF_UNUSED int ret = 0;
+
+ local = frame->local;
+
+ /* When remote reads are performed (i.e. reads on remote store),
+ * there needs to be a way to associate a file on gluster volume
+ * with its correspnding file on the remote store. In order to do
+ * that, a unique key can be maintained as an xattr
+ * (GF_CS_XATTR_ARCHIVE_UUID)on the stub file on gluster bricks.
+ * This xattr should be provided to the plugin to
+ * perform the read fop on the correct file. This assumes that the file
+ * hierarchy and name need not be the same on remote store as that of
+ * the gluster volume.
+ */
+ ret = dict_set_sizen_str_sizen(local->xattr_req, GF_CS_XATTR_ARCHIVE_UUID,
+ "1");
+
+ return 0;
+}
+
+int
+cs_update_xattrs(call_frame_t *frame, dict_t *xdata)
+{
+ cs_local_t *local = NULL;
+ xlator_t *this = NULL;
+ int size = -1;
+ GF_UNUSED int ret = 0;
+
+ local = frame->local;
+ this = frame->this;
+
+ local->xattrinfo.lxattr = GF_CALLOC(1, sizeof(cs_loc_xattr_t),
+ gf_cs_mt_cs_lxattr_t);
+ if (!local->xattrinfo.lxattr) {
+ local->op_ret = -1;
+ local->op_errno = ENOMEM;
+ goto err;
+ }
+
+ gf_uuid_copy(local->xattrinfo.lxattr->gfid, local->loc.gfid);
+
+ if (local->remotepath) {
+ local->xattrinfo.lxattr->file_path = gf_strdup(local->remotepath);
+ if (!local->xattrinfo.lxattr->file_path) {
+ local->op_ret = -1;
+ local->op_errno = ENOMEM;
+ goto err;
+ }
+ }
- pthread_join(dthread, (void **)&retval);
+ ret = dict_get_gfuuid(xdata, GF_CS_XATTR_ARCHIVE_UUID,
+ &(local->xattrinfo.lxattr->uuid));
- ret = *retval;
+ if (ret) {
+ gf_uuid_clear(local->xattrinfo.lxattr->uuid);
+ }
+ size = strlen(this->name) - strlen("-cloudsync") + 1;
+ local->xattrinfo.lxattr->volname = GF_CALLOC(1, size, gf_common_mt_char);
+ if (!local->xattrinfo.lxattr->volname) {
+ local->op_ret = -1;
+ local->op_errno = ENOMEM;
+ goto err;
+ }
+ strncpy(local->xattrinfo.lxattr->volname, this->name, size - 1);
+ local->xattrinfo.lxattr->volname[size - 1] = '\0';
+
+ return 0;
+err:
+ cs_xattrinfo_wipe(local);
+ return -1;
+}
+
+int
+cs_serve_readv(call_frame_t *frame, off_t offset, size_t size, uint32_t flags)
+{
+ xlator_t *this = NULL;
+ cs_private_t *priv = NULL;
+ int ret = -1;
+ fd_t *fd = NULL;
+ cs_local_t *local = NULL;
+
+ local = frame->local;
+ this = frame->this;
+ priv = this->private;
+
+ if (!local->remotepath) {
+ ret = -1;
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0,
+ "remote path not"
+ " available. Check posix logs to resolve");
+ goto out;
+ }
+
+ if (!priv->stores) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0,
+ "No remote store "
+ "plugins found");
+ ret = -1;
+ goto out;
+ }
+
+ if (local->fd) {
+ fd = fd_anonymous(local->fd->inode);
+ } else {
+ fd = fd_anonymous(local->loc.inode);
+ }
+
+ local->xattrinfo.size = size;
+ local->xattrinfo.offset = offset;
+ local->xattrinfo.flags = flags;
+
+ if (!fd) {
+ gf_msg("CS", GF_LOG_ERROR, 0, 0, "fd creation failed");
+ ret = -1;
+ goto out;
+ }
+
+ local->dlfd = fd;
+ local->dloffset = offset;
+
+ /*this calling method is for per volume setting */
+ ret = priv->stores->rdfop(frame, priv->stores->config);
+ if (ret) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0,
+ "read failed"
+ ", remotepath: %s",
+ local->remotepath);
+ ret = -1;
+ goto out;
+ } else {
+ gf_msg(this->name, GF_LOG_INFO, 0, 0,
+ "read success, path"
+ " : %s",
+ local->remotepath);
+ }
out:
- if (retval)
- GF_FREE(retval);
+ if (fd) {
+ fd_unref(fd);
+ local->dlfd = NULL;
+ }
+ return ret;
+}
+
+int32_t
+cs_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iovec *vector, int32_t count,
+ struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+{
+ cs_local_t *local = NULL;
+ int ret = 0;
+ uint64_t val = 0;
+ fd_t *fd = NULL;
+
+ local = frame->local;
+ fd = local->fd;
+
+ local->call_cnt++;
+
+ if (op_ret == -1) {
+ ret = dict_get_uint64(xdata, GF_CS_OBJECT_STATUS, &val);
+ if (ret == 0) {
+ if (val == GF_CS_ERROR) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0,
+ "could not get file state, unwinding");
+ op_ret = -1;
+ op_errno = EIO;
+ goto unwind;
+ } else {
+ __cs_inode_ctx_update(this, fd->inode, val);
+ gf_msg(this->name, GF_LOG_INFO, 0, 0, " state = %" PRIu64, val);
+
+ if (local->call_cnt == 1 &&
+ (val == GF_CS_REMOTE || val == GF_CS_DOWNLOADING)) {
+ gf_msg(this->name, GF_LOG_INFO, 0, 0,
+ " will read from remote : %" PRIu64, val);
+ goto repair;
+ } else {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0,
+ "second readv, Unwinding");
+ goto unwind;
+ }
+ }
+ } else {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0,
+ "file state "
+ "could not be figured, unwinding");
+ goto unwind;
+ }
+ } else {
+ /* successful readv => file is local */
+ __cs_inode_ctx_update(this, fd->inode, GF_CS_LOCAL);
+ gf_msg(this->name, GF_LOG_INFO, 0, 0,
+ "state : GF_CS_LOCAL"
+ ", readv successful");
+
+ goto unwind;
+ }
+
+repair:
+ ret = locate_and_execute(frame);
+ if (ret) {
+ goto unwind;
+ }
+
+ return 0;
+
+unwind:
+ CS_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, stbuf,
+ iobref, xdata);
+
+ return 0;
+}
+
+int32_t
+cs_resume_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, uint32_t flags, dict_t *xdata)
+{
+ int ret = 0;
+
+ ret = cs_resume_postprocess(this, frame, fd->inode);
+ if (ret) {
+ goto unwind;
+ }
+
+ cs_inodelk_unlock(frame);
+
+ STACK_WIND(frame, cs_readv_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata);
+
+ return 0;
+
+unwind:
+ cs_inodelk_unlock(frame);
+
+ cs_common_cbk(frame);
+
+ return 0;
+}
+
+int32_t
+cs_resume_remote_readv(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t offset, uint32_t flags, dict_t *xdata)
+{
+ int ret = 0;
+ cs_local_t *local = NULL;
+ gf_cs_obj_state state = -1;
+ cs_inode_ctx_t *ctx = NULL;
+
+ cs_inodelk_unlock(frame);
+
+ local = frame->local;
+ if (!local) {
+ ret = -1;
+ goto unwind;
+ }
+
+ __cs_inode_ctx_get(this, fd->inode, &ctx);
+
+ state = __cs_get_file_state(fd->inode, ctx);
+ if (state == GF_CS_ERROR) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0,
+ "status is GF_CS_ERROR."
+ " Aborting readv");
+ local->op_ret = -1;
+ local->op_errno = EREMOTE;
+ ret = -1;
+ goto unwind;
+ }
+
+ /* Serve readv from remote store only if it is remote. */
+ gf_msg_debug(this->name, 0, "status of file %s is %d",
+ local->remotepath ? local->remotepath : "", state);
+
+ /* We will reach this condition if local inode ctx had REMOTE
+ * state when the control was in cs_readv but after stat
+ * we got an updated state saying that the file is LOCAL.
+ */
+ if (state == GF_CS_LOCAL) {
+ STACK_WIND(frame, cs_readv_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readv, fd, size, offset, flags,
+ xdata);
+ } else if (state == GF_CS_REMOTE) {
+ ret = cs_resume_remote_readv_postprocess(this, frame, fd->inode, offset,
+ size, flags);
+ /* Failed to submit the remote readv fop to plugin */
+ if (ret) {
+ local->op_ret = -1;
+ local->op_errno = EREMOTE;
+ goto unwind;
+ }
+ /* When the file is in any other intermediate state,
+ * we should not perform remote reads.
+ */
+ } else {
+ local->op_ret = -1;
+ local->op_errno = EINVAL;
+ goto unwind;
+ }
+
+ return 0;
+
+unwind:
+ cs_common_cbk(frame);
+
+ return 0;
+}
+
+int32_t
+cs_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, uint32_t flags, dict_t *xdata)
+{
+ int op_errno = ENOMEM;
+ cs_local_t *local = NULL;
+ int ret = 0;
+ cs_inode_ctx_t *ctx = NULL;
+ gf_cs_obj_state state = -1;
+ cs_private_t *priv = NULL;
+
+ VALIDATE_OR_GOTO(frame, err);
+ VALIDATE_OR_GOTO(this, err);
+ VALIDATE_OR_GOTO(fd, err);
+
+ priv = this->private;
+
+ local = cs_local_init(this, frame, NULL, fd, GF_FOP_READ);
+ if (!local) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0, "local init failed");
+ goto err;
+ }
+
+ __cs_inode_ctx_get(this, fd->inode, &ctx);
+
+ if (ctx)
+ state = __cs_get_file_state(fd->inode, ctx);
+ else
+ state = GF_CS_LOCAL;
+
+ local->xattr_req = xdata ? dict_ref(xdata) : (xdata = dict_new());
+
+ ret = dict_set_uint32(local->xattr_req, GF_CS_OBJECT_STATUS, 1);
+ if (ret) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0,
+ "dict_set failed key:"
+ " %s",
+ GF_CS_OBJECT_STATUS);
+ goto err;
+ }
+
+ if (priv->remote_read) {
+ local->stub = fop_readv_stub(frame, cs_resume_remote_readv, fd, size,
+ offset, flags, xdata);
+ } else {
+ local->stub = fop_readv_stub(frame, cs_resume_readv, fd, size, offset,
+ flags, xdata);
+ }
+ if (!local->stub) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insufficient memory");
+ goto err;
+ }
+
+ if (state == GF_CS_LOCAL) {
+ STACK_WIND(frame, cs_readv_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readv, fd, size, offset, flags,
+ xdata);
+ } else {
+ local->call_cnt++;
+ ret = locate_and_execute(frame);
+ if (ret) {
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
+ CS_STACK_UNWIND(readv, frame, -1, op_errno, NULL, -1, NULL, NULL, NULL);
+
+ return 0;
+}
+
+int
+cs_resume_remote_readv_postprocess(xlator_t *this, call_frame_t *frame,
+ inode_t *inode, off_t offset, size_t size,
+ uint32_t flags)
+{
+ int ret = 0;
+
+ ret = cs_serve_readv(frame, offset, size, flags);
return ret;
}
@@ -1058,7 +1448,7 @@ cs_stat_check_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
goto err;
} else {
ret = __cs_inode_ctx_update(this, inode, val);
- gf_msg_debug(this->name, 0, "status : %lu", val);
+ gf_msg_debug(this->name, 0, "status : %" PRIu64, val);
if (ret) {
gf_msg(this->name, GF_LOG_ERROR, 0, 0, "ctx update failed");
local->op_ret = -1;
@@ -1073,7 +1463,7 @@ cs_stat_check_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
goto err;
}
- ret = dict_get_str(xdata, GF_CS_OBJECT_REMOTE, &filepath);
+ ret = dict_get_str_sizen(xdata, GF_CS_OBJECT_REMOTE, &filepath);
if (filepath) {
gf_msg_debug(this->name, 0, "filepath returned %s", filepath);
local->remotepath = gf_strdup(filepath);
@@ -1086,6 +1476,10 @@ cs_stat_check_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
gf_msg_debug(this->name, 0, "NULL filepath");
}
+ ret = cs_update_xattrs(frame, xdata);
+ if (ret)
+ goto err;
+
local->op_ret = 0;
local->xattr_rsp = dict_ref(xdata);
memcpy(&local->stbuf, stbuf, sizeof(struct iatt));
@@ -1120,6 +1514,8 @@ cs_do_stat_check(call_frame_t *main_frame)
goto err;
}
+ cs_set_xattr_req(main_frame);
+
if (local->fd) {
STACK_WIND(main_frame, cs_stat_check_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fstat, local->fd, local->xattr_req);
@@ -1176,6 +1572,10 @@ cs_common_cbk(call_frame_t *frame)
NULL, NULL, NULL);
break;
+ case GF_FOP_TRUNCATE:
+ CS_STACK_UNWIND(truncate, frame, local->op_ret, local->op_errno,
+ NULL, NULL, NULL);
+ break;
default:
break;
}
@@ -1262,14 +1662,14 @@ cs_blocking_inodelk(call_frame_t *parent_frame)
};
int ret = 0;
+ this = parent_frame->this;
+
lock_frame = cs_lock_frame(parent_frame);
if (!lock_frame) {
gf_msg(this->name, GF_LOG_ERROR, 0, 0, "insuffcient memory");
goto err;
}
- this = parent_frame->this;
-
lock_local = cs_local_init(this, lock_frame, NULL, NULL, 0);
if (!lock_local) {
gf_msg(this->name, GF_LOG_ERROR, 0, 0, "local init failed");
@@ -1353,7 +1753,7 @@ cs_resume_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
__cs_inode_ctx_get(this, loc->inode, &ctx);
- state = __cs_get_file_state(this, loc->inode, ctx);
+ state = __cs_get_file_state(loc->inode, ctx);
if (state == GF_CS_ERROR) {
/* file is already remote */
@@ -1395,7 +1795,7 @@ unwind:
}
gf_cs_obj_state
-__cs_get_file_state(xlator_t *this, inode_t *inode, cs_inode_ctx_t *ctx)
+__cs_get_file_state(inode_t *inode, cs_inode_ctx_t *ctx)
{
gf_cs_obj_state state = -1;
@@ -1426,7 +1826,7 @@ __cs_inode_ctx_get(xlator_t *this, inode_t *inode, cs_inode_ctx_t **ctx)
if (ret)
*ctx = NULL;
else
- *ctx = (cs_inode_ctx_t *)ctxint;
+ *ctx = (cs_inode_ctx_t *)(uintptr_t)ctxint;
return;
}
@@ -1451,7 +1851,7 @@ __cs_inode_ctx_update(xlator_t *this, inode_t *inode, uint64_t val)
ctx->state = val;
- ctxint = (uint64_t)ctx;
+ ctxint = (uint64_t)(uintptr_t)ctx;
ret = __inode_ctx_set(inode, this, &ctxint);
if (ret) {
@@ -1459,7 +1859,7 @@ __cs_inode_ctx_update(xlator_t *this, inode_t *inode, uint64_t val)
goto out;
}
} else {
- ctx = (cs_inode_ctx_t *)ctxint;
+ ctx = (cs_inode_ctx_t *)(uintptr_t)ctxint;
ctx->state = val;
}
@@ -1482,7 +1882,7 @@ cs_inode_ctx_reset(xlator_t *this, inode_t *inode)
return 0;
}
- ctx = (cs_inode_ctx_t *)ctxint;
+ ctx = (cs_inode_ctx_t *)(uintptr_t)ctxint;
GF_FREE(ctx);
return 0;
@@ -1504,7 +1904,7 @@ cs_resume_postprocess(xlator_t *this, call_frame_t *frame, inode_t *inode)
__cs_inode_ctx_get(this, inode, &ctx);
- state = __cs_get_file_state(this, inode, ctx);
+ state = __cs_get_file_state(inode, ctx);
if (state == GF_CS_ERROR) {
gf_msg(this->name, GF_LOG_ERROR, 0, 0,
"status is GF_CS_ERROR."
@@ -1531,6 +1931,7 @@ cs_resume_postprocess(xlator_t *this, call_frame_t *frame, inode_t *inode)
out:
return ret;
}
+
int32_t
cs_fdctx_to_dict(xlator_t *this, fd_t *fd, dict_t *dict)
{
@@ -1626,7 +2027,9 @@ struct xlator_fops cs_fops = {
.zerofill = cs_zerofill,
};
-struct xlator_cbks cs_cbks = {};
+struct xlator_cbks cs_cbks = {
+ .forget = cs_forget,
+};
struct xlator_dumpops cs_dumpops = {
.fdctx_to_dict = cs_fdctx_to_dict,
@@ -1646,6 +2049,15 @@ struct volume_options cs_options[] = {
{.key = {"cloudsync-storetype"},
.type = GF_OPTION_TYPE_STR,
.description = "Defines which remote store is enabled"},
+ {.key = {"cloudsync-remote-read"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .description = "Defines a remote read fop when on"},
+ {.key = {"cloudsync-store-id"},
+ .type = GF_OPTION_TYPE_STR,
+ .description = "Defines a volume wide store id"},
+ {.key = {"cloudsync-product-id"},
+ .type = GF_OPTION_TYPE_STR,
+ .description = "Defines a volume wide product id"},
{.key = {NULL}},
};