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