summaryrefslogtreecommitdiffstats
path: root/xlators/features/upcall/src/upcall.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/upcall/src/upcall.c')
-rw-r--r--xlators/features/upcall/src/upcall.c117
1 files changed, 112 insertions, 5 deletions
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.