summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
Diffstat (limited to 'xlators')
-rw-r--r--xlators/features/upcall/src/upcall-internal.c12
-rw-r--r--xlators/features/upcall/src/upcall.c117
-rw-r--r--xlators/features/upcall/src/upcall.h6
-rw-r--r--xlators/performance/md-cache/src/md-cache-mem-types.h1
-rw-r--r--xlators/performance/md-cache/src/md-cache-messages.h27
-rw-r--r--xlators/performance/md-cache/src/md-cache.c148
6 files changed, 295 insertions, 16 deletions
diff --git a/xlators/features/upcall/src/upcall-internal.c b/xlators/features/upcall/src/upcall-internal.c
index 3cde56a7ce8..0f07ae8df03 100644
--- a/xlators/features/upcall/src/upcall-internal.c
+++ b/xlators/features/upcall/src/upcall-internal.c
@@ -435,10 +435,16 @@ upcall_reaper_thread_init (xlator_t *this)
}
int
-up_filter_virtual_xattr (dict_t *d, char *k, data_t *v, void *tmp)
+up_filter_unregd_xattr (dict_t *xattrs, char *xattr, data_t *v,
+ void *regd_xattrs)
{
- if (is_virtual_xattr (k) == _gf_true) {
- dict_del (d, k);
+ int ret = 0;
+
+ if (dict_get ((dict_t *)regd_xattrs, xattr) == NULL) {
+ /* xattr was not found in the registered xattr, hence do not
+ * send notification for its change
+ */
+ dict_del (xattrs, xattr);
}
return 0;
diff --git a/xlators/features/upcall/src/upcall.c b/xlators/features/upcall/src/upcall.c
index c49a3fd8796..c7b74ed3c29 100644
--- a/xlators/features/upcall/src/upcall.c
+++ b/xlators/features/upcall/src/upcall.c
@@ -1596,9 +1596,13 @@ up_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
upcall_local_t *local = NULL;
int ret = 0;
struct iatt stbuf = {0, };
+ upcall_private_t *priv = NULL;
EXIT_IF_UPCALL_OFF (this, out);
+ priv = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, priv, out);
+
client = frame->root->client;
local = frame->local;
@@ -1607,13 +1611,21 @@ up_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
flags = UP_XATTR;
- /* Remove the virtual xattrs from the dict */
- ret = dict_foreach (local->xattr, up_filter_virtual_xattr, NULL);
+ /* Remove the xattrs from the dict, if they are not registered for
+ * cache invalidation */
+ ret = dict_foreach (local->xattr, up_filter_unregd_xattr, priv->xattrs);
if (ret < 0) {
op_ret = ret;
goto out;
}
+ if (dict_key_count(local->xattr) == 0) {
+ gf_msg_trace (this->name, 0, "None of xattrs requested for"
+ " invalidation, were changed. Nothing to "
+ "invalidate");
+ goto out; /* nothing to invalidate */
+ }
+
ret = syncop_stat (FIRST_CHILD(frame->this), &local->loc, &stbuf,
NULL, NULL);
if (ret == 0)
@@ -1677,9 +1689,13 @@ up_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
upcall_local_t *local = NULL;
int ret = 0;
struct iatt stbuf = {0,};
+ upcall_private_t *priv = NULL;
EXIT_IF_UPCALL_OFF (this, out);
+ priv = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, priv, out);
+
client = frame->root->client;
local = frame->local;
@@ -1688,13 +1704,21 @@ up_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
flags = UP_XATTR;
- /* Remove the virtual xattrs from the dict */
- ret = dict_foreach (local->xattr, up_filter_virtual_xattr, NULL);
+ /* Remove the xattrs from the dict, if they are not registered for
+ * cache invalidation */
+ ret = dict_foreach (local->xattr, up_filter_unregd_xattr, priv->xattrs);
if (ret < 0) {
op_ret = ret;
goto out;
}
+ if (dict_key_count(local->xattr) == 0) {
+ gf_msg_trace (this->name, 0, "None of xattrs requested for"
+ " invalidation, were changed. Nothing to "
+ "invalidate");
+ goto out; /* nothing to invalidate */
+ }
+
ret = syncop_fstat (FIRST_CHILD(frame->this), local->fd, &stbuf, NULL,
NULL);
if (ret == 0)
@@ -1758,9 +1782,13 @@ up_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
upcall_local_t *local = NULL;
struct iatt stbuf = {0,};
int ret = 0;
+ upcall_private_t *priv = NULL;
EXIT_IF_UPCALL_OFF (this, out);
+ priv = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, priv, out);
+
client = frame->root->client;
local = frame->local;
@@ -1769,6 +1797,21 @@ up_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
flags = UP_XATTR_RM;
+ /* Remove the xattrs from the dict, if they are not registered for
+ * cache invalidation */
+ ret = dict_foreach (local->xattr, up_filter_unregd_xattr, priv->xattrs);
+ if (ret < 0) {
+ op_ret = ret;
+ goto out;
+ }
+
+ if (dict_key_count(local->xattr) == 0) {
+ gf_msg_trace (this->name, 0, "None of xattrs requested for"
+ " invalidation, were changed. Nothing to "
+ "invalidate");
+ goto out; /* nothing to invalidate */
+ }
+
ret = syncop_fstat (FIRST_CHILD(frame->this), local->fd, &stbuf, NULL,
NULL);
if (ret == 0)
@@ -1828,9 +1871,13 @@ up_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
upcall_local_t *local = NULL;
struct iatt stbuf = {0,};
int ret = 0;
+ upcall_private_t *priv = NULL;
EXIT_IF_UPCALL_OFF (this, out);
+ priv = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, priv, out);
+
client = frame->root->client;
local = frame->local;
@@ -1839,6 +1886,21 @@ up_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
flags = UP_XATTR_RM;
+ /* Remove the xattrs from the dict, if they are not registered for
+ * cache invalidation */
+ ret = dict_foreach (local->xattr, up_filter_unregd_xattr, priv->xattrs);
+ if (ret < 0) {
+ op_ret = ret;
+ goto out;
+ }
+
+ if (dict_key_count(local->xattr) == 0) {
+ gf_msg_trace (this->name, 0, "None of xattrs requested for"
+ " invalidation, were changed. Nothing to "
+ "invalidate");
+ goto out; /* nothing to invalidate */
+ }
+
ret = syncop_stat (FIRST_CHILD(frame->this), &local->loc, &stbuf, NULL,
NULL);
if (ret == 0)
@@ -2064,6 +2126,47 @@ out:
return local;
}
+static int32_t
+update_xattrs (dict_t *dict, char *key, data_t *value, void *data)
+{
+ dict_t *xattrs = data;
+ int ret = 0;
+
+ ret = dict_set_int8 (xattrs, key, 0);
+ return ret;
+}
+
+int32_t
+up_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata)
+{
+ upcall_private_t *priv = NULL;
+ int ret = 0;
+
+ priv = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, priv, out);
+
+ if (op != GF_IPC_TARGET_UPCALL)
+ goto wind;
+
+ /* TODO: Bz-1371622 Along with the xattrs also store list of clients
+ * that are interested in notifications, so that the notification
+ * can be sent to the clients that have registered.
+ * Once this implemented there can be unregister of xattrs for
+ * notifications. Until then there is no unregister of xattrs*/
+ if (xdata && priv->xattrs) {
+ ret = dict_foreach (xdata, update_xattrs, priv->xattrs);
+ }
+
+out:
+ STACK_UNWIND_STRICT (ipc, frame, ret, 0, NULL);
+ return 0;
+
+wind:
+ STACK_WIND (frame, default_ipc_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->ipc, op, xdata);
+ return 0;
+}
+
int
reconfigure (xlator_t *this, dict_t *options)
{
@@ -2071,7 +2174,7 @@ reconfigure (xlator_t *this, dict_t *options)
int ret = -1;
priv = this->private;
- GF_ASSERT (priv);
+ GF_VALIDATE_OR_GOTO (this->name, priv, out);
GF_OPTION_RECONF ("cache-invalidation", priv->cache_invalidation_enabled,
options, bool, out);
@@ -2120,6 +2223,7 @@ init (xlator_t *this)
LOCK_INIT (&priv->inode_ctx_lk);
INIT_LIST_HEAD (&priv->inode_ctx_list);
+ priv->xattrs = dict_new ();
this->private = priv;
priv->fini = 0;
@@ -2142,6 +2246,7 @@ init (xlator_t *this)
}
out:
if (ret) {
+ dict_unref (priv->xattrs);
GF_FREE (priv);
}
@@ -2164,6 +2269,7 @@ fini (xlator_t *this)
if (priv->reaper_init_done)
pthread_join (priv->reaper_thr, NULL);
+ dict_unref (priv->xattrs);
LOCK_DESTROY (&priv->inode_ctx_lk);
/* Do we need to cleanup the inode_ctxs? IMO not required
@@ -2226,6 +2332,7 @@ out:
}
struct xlator_fops fops = {
+ .ipc = up_ipc,
/* fops which change only "ATIME" do not result
* in any cache invalidation. Hence upcall
* notifications are not sent in this case.
diff --git a/xlators/features/upcall/src/upcall.h b/xlators/features/upcall/src/upcall.h
index f86849341ec..852f5511726 100644
--- a/xlators/features/upcall/src/upcall.h
+++ b/xlators/features/upcall/src/upcall.h
@@ -52,6 +52,8 @@ struct _upcall_private_t {
gf_boolean_t reaper_init_done;
pthread_t reaper_thr;
int32_t fini;
+ dict_t *xattrs; /* list of xattrs registered by clients
+ for receiving invalidation */
};
typedef struct _upcall_private_t upcall_private_t;
@@ -130,6 +132,6 @@ void upcall_client_cache_invalidate (xlator_t *xl, uuid_t gfid,
struct iatt *p_stbuf,
struct iatt *oldp_stbuf, dict_t *xattr);
-int up_filter_virtual_xattr (dict_t *d, char *k, data_t *v, void *tmp);
-
+int up_filter_unregd_xattr (dict_t *xattrs, char *xattr, data_t *v,
+ void *regd_xattrs);
#endif /* __UPCALL_H__ */
diff --git a/xlators/performance/md-cache/src/md-cache-mem-types.h b/xlators/performance/md-cache/src/md-cache-mem-types.h
index 6634cf962a5..5cfc68e13c1 100644
--- a/xlators/performance/md-cache/src/md-cache-mem-types.h
+++ b/xlators/performance/md-cache/src/md-cache-mem-types.h
@@ -18,6 +18,7 @@ enum gf_mdc_mem_types_ {
gf_mdc_mt_mdc_local_t = gf_common_mt_end + 1,
gf_mdc_mt_md_cache_t,
gf_mdc_mt_mdc_conf_t,
+ gf_mdc_mt_mdc_ipc,
gf_mdc_mt_end
};
#endif
diff --git a/xlators/performance/md-cache/src/md-cache-messages.h b/xlators/performance/md-cache/src/md-cache-messages.h
index 1fe26ccc8b2..4aea7cd0a9d 100644
--- a/xlators/performance/md-cache/src/md-cache-messages.h
+++ b/xlators/performance/md-cache/src/md-cache-messages.h
@@ -40,7 +40,7 @@
*/
#define GLFS_MD_CACHE_BASE GLFS_MSGID_COMP_MD_CACHE
-#define GLFS_MD_CACHE_NUM_MESSAGES 3
+#define GLFS_MD_CACHE_NUM_MESSAGES 5
#define GLFS_MSGID_END (GLFS_MD_CACHE_BASE + GLFS_MD_CACHE_NUM_MESSAGES + 1)
/* Messages with message IDs */
@@ -67,8 +67,33 @@
#define MD_CACHE_MSG_DISCARD_UPDATE (GLFS_MD_CACHE_BASE + 2)
+/*!
+ * @messageid
+ * @diagnosis
+ * @recommendedaction None
+ *
+ */
+
#define MD_CACHE_MSG_CACHE_UPDATE (GLFS_MD_CACHE_BASE + 3)
+/*!
+ * @messageid
+ * @diagnosis
+ * @recommendedaction None
+ *
+ */
+
+#define MD_CACHE_MSG_IPC_UPCALL_FAILED (GLFS_MD_CACHE_BASE + 4)
+
+/*!
+ * @messageid
+ * @diagnosis
+ * @recommendedaction None
+ *
+ */
+
+#define MD_CACHE_MSG_NO_XATTR_CACHE (GLFS_MD_CACHE_BASE + 5)
+
/*------------*/
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c
index bb2310e8c82..e0e7ee68e3b 100644
--- a/xlators/performance/md-cache/src/md-cache.c
+++ b/xlators/performance/md-cache/src/md-cache.c
@@ -13,6 +13,7 @@
#include "logging.h"
#include "dict.h"
#include "xlator.h"
+#include "syncop.h"
#include "md-cache-mem-types.h"
#include "compat-errno.h"
#include "glusterfs-acl.h"
@@ -2455,6 +2456,18 @@ is_strpfx (const char *str1, const char *str2)
}
+static int
+mdc_key_unload_all (struct mdc_key *keys)
+{
+ struct mdc_key *key = NULL;
+
+ for (key = keys; key->name; key++) {
+ key->load = 0;
+ }
+
+ return 0;
+}
+
int
mdc_key_load_set (struct mdc_key *keys, char *pattern, gf_boolean_t val)
{
@@ -2545,12 +2558,129 @@ out:
return ret;
}
+struct mdc_ipc {
+ xlator_t *this;
+ dict_t *xattr;
+};
+
+static int
+mdc_send_xattrs_cbk (int ret, call_frame_t *frame, void *data)
+{
+ struct mdc_ipc *tmp = data;
+
+ if (ret < 0) {
+ mdc_key_unload_all (mdc_keys);
+ gf_msg ("md-cache", GF_LOG_INFO, 0, MD_CACHE_MSG_NO_XATTR_CACHE,
+ "Disabled cache for all xattrs, as registering for "
+ "xattr cache invalidation failed");
+ }
+ STACK_DESTROY (frame->root);
+ dict_unref (tmp->xattr);
+ GF_FREE (tmp);
+
+ return 0;
+}
+
+static int
+mdc_send_xattrs (void *data)
+{
+ int ret = 0;
+ struct mdc_ipc *tmp = data;
+
+ ret = syncop_ipc (FIRST_CHILD (tmp->this), GF_IPC_TARGET_UPCALL,
+ tmp->xattr, NULL);
+ DECODE_SYNCOP_ERR (ret);
+ if (ret < 0) {
+ gf_msg (tmp->this->name, GF_LOG_WARNING, errno,
+ MD_CACHE_MSG_IPC_UPCALL_FAILED, "Registering the list "
+ "of xattrs that needs invalidaton, with upcall, failed");
+ }
+
+ return ret;
+}
+
+
+static int
+mdc_register_xattr_inval (xlator_t *this)
+{
+ dict_t *xattr = NULL;
+ int ret = 0;
+ struct mdc_conf *conf = NULL;
+ call_frame_t *frame = NULL;
+ struct mdc_ipc *data = NULL;
+
+ conf = this->private;
+
+ LOCK (&conf->lock);
+ {
+ if (!conf->mdc_invalidation) {
+ UNLOCK (&conf->lock);
+ goto out;
+ }
+ }
+ UNLOCK (&conf->lock);
+
+ xattr = dict_new ();
+ if (!xattr) {
+ gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
+ MD_CACHE_MSG_NO_MEMORY, "dict_new failed");
+ ret = -1;
+ goto out;
+ }
+
+ mdc_load_reqs (this, xattr);
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
+ MD_CACHE_MSG_NO_MEMORY,
+ "failed to create the frame");
+ ret = -1;
+ goto out;
+ }
+
+ data = GF_CALLOC (1, sizeof (struct mdc_ipc), gf_mdc_mt_mdc_ipc);
+ if (!data) {
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
+ MD_CACHE_MSG_NO_MEMORY,
+ "failed to allocate memory");
+ ret = -1;
+ goto out;
+ }
+
+ data->this = this;
+ data->xattr = xattr;
+ ret = synctask_new (this->ctx->env, mdc_send_xattrs, mdc_send_xattrs_cbk,
+ frame, data);
+ if (ret < 0) {
+ gf_msg (this->name, GF_LOG_WARNING, errno,
+ MD_CACHE_MSG_IPC_UPCALL_FAILED, "Registering the list "
+ "of xattrs that needs invalidaton, with upcall, failed");
+ }
+
+out:
+ if (ret < 0) {
+ mdc_key_unload_all (mdc_keys);
+ if (xattr)
+ dict_unref (xattr);
+ if (frame)
+ STACK_DESTROY (frame->root);
+ GF_FREE (data);
+ gf_msg (this->name, GF_LOG_INFO, 0, MD_CACHE_MSG_NO_XATTR_CACHE,
+ "Disabled cache for all xattrs, as registering for "
+ "xattr cache invalidation failed");
+ }
+
+ return ret;
+}
+
int
reconfigure (xlator_t *this, dict_t *options)
{
struct mdc_conf *conf = NULL;
int timeout = 0;
+ int ret = 0;
conf = this->private;
@@ -2589,6 +2719,8 @@ reconfigure (xlator_t *this, dict_t *options)
goto out;
}
conf->timeout = timeout;
+
+ ret = mdc_register_xattr_inval (this);
out:
return 0;
}
@@ -2686,22 +2818,28 @@ notify (xlator_t *this, int event, void *data, ...)
switch (event) {
case GF_EVENT_CHILD_DOWN:
case GF_EVENT_SOME_CHILD_DOWN:
- case GF_EVENT_CHILD_MODIFIED:
time (&now);
mdc_update_child_down_time (this, &now);
- ret = default_notify (this, event, data);
break;
case GF_EVENT_UPCALL:
if (conf->mdc_invalidation)
ret = mdc_invalidate (this, data);
- if (default_notify (this, event, data) != 0)
- ret = -1;
+ break;
+ case GF_EVENT_CHILD_MODIFIED:
+ time (&now);
+ mdc_update_child_down_time (this, &now);
+ ret = mdc_register_xattr_inval (this);
+ break;
+ case GF_EVENT_CHILD_UP:
+ ret = mdc_register_xattr_inval (this);
break;
default:
- ret = default_notify (this, event, data);
break;
}
+ if (default_notify (this, event, data) != 0)
+ ret = -1;
+
return ret;
}