summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/dict.c6
-rw-r--r--libglusterfs/src/dict.h4
-rw-r--r--xlators/features/index/src/index.c188
-rw-r--r--xlators/features/index/src/index.h1
4 files changed, 154 insertions, 45 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index 3d8b5d8fef1..31867588def 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -1122,8 +1122,8 @@ dict_remove_foreach_fn (dict_t *d, char *k,
return 0;
}
-static inline gf_boolean_t
-match_everything (dict_t *d, char *k, data_t *v, void *data)
+gf_boolean_t
+dict_match_everything (dict_t *d, char *k, data_t *v, void *data)
{
return _gf_true;
}
@@ -1138,7 +1138,7 @@ dict_foreach (dict_t *dict,
{
int ret = 0;
- ret = dict_foreach_match (dict, match_everything, NULL, fn, data);
+ ret = dict_foreach_match (dict, dict_match_everything, NULL, fn, data);
if (ret > 0)
ret = 0;
diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h
index 66a900131d1..a4c1815d06a 100644
--- a/libglusterfs/src/dict.h
+++ b/libglusterfs/src/dict.h
@@ -95,6 +95,8 @@ struct _dict {
gf_boolean_t free_pair_in_use;
};
+typedef gf_boolean_t (*dict_match_t) (dict_t *d, char *k, data_t *v,
+ void *data);
int32_t is_data_equal (data_t *one, data_t *two);
void data_destroy (data_t *data);
@@ -255,4 +257,6 @@ dict_dump_to_log (dict_t *dict);
int
dict_dump_to_str (dict_t *dict, char *dump, int dumpsize, char *format);
+gf_boolean_t
+dict_match_everything (dict_t *d, char *k, data_t *v, void *data);
#endif
diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c
index f7408c1308f..827a96d75b9 100644
--- a/xlators/features/index/src/index.c
+++ b/xlators/features/index/src/index.c
@@ -520,41 +520,50 @@ out:
return;
}
+static gf_boolean_t
+is_xattr_in_watchlist (dict_t *this, char *key, data_t *value, void *matchdata)
+{
+ if (dict_get (matchdata, key))
+ return _gf_true;
+
+ return _gf_false;
+}
+
void
-_xattrop_index_action (xlator_t *this, inode_t *inode, dict_t *xattr)
+xattrop_index_action (xlator_t *this, inode_t *inode, dict_t *xattr,
+ dict_match_t match, void *match_data)
{
gf_boolean_t zero_xattr = _gf_true;
int ret = 0;
- ret = dict_foreach (xattr, _check_key_is_zero_filled, NULL);
+ ret = dict_foreach_match (xattr, match, match_data,
+ _check_key_is_zero_filled, NULL);
if (ret == -1)
zero_xattr = _gf_false;
_index_action (this, inode, zero_xattr);
return;
}
-void
-fop_xattrop_index_action (xlator_t *this, inode_t *inode, dict_t *xattr)
+static inline gf_boolean_t
+index_xattrop_track (xlator_t *this, gf_xattrop_flags_t flags, dict_t *dict)
{
- _xattrop_index_action (this, inode, xattr);
-}
+ index_priv_t *priv = this->private;
-void
-fop_fxattrop_index_action (xlator_t *this, inode_t *inode, dict_t *xattr)
-{
- _xattrop_index_action (this, inode, xattr);
-}
+ if (flags == GF_XATTROP_ADD_ARRAY)
+ return _gf_true;
-static inline gf_boolean_t
-index_xattrop_track (loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict)
-{
- return (flags == GF_XATTROP_ADD_ARRAY);
-}
+ if (flags != GF_XATTROP_ADD_ARRAY64)
+ return _gf_false;
-static inline gf_boolean_t
-index_fxattrop_track (fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict)
-{
- return (flags == GF_XATTROP_ADD_ARRAY);
+ if (!priv->xattrop64_watchlist)
+ return _gf_false;
+
+ if (dict_foreach_match (dict, is_xattr_in_watchlist,
+ priv->xattrop64_watchlist, dict_null_foreach_fn,
+ NULL) > 0)
+ return _gf_true;
+
+ return _gf_false;
}
int
@@ -671,16 +680,18 @@ unlock:
return;
}
-int32_t
-index_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata)
+static int
+xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xattr,
+ dict_t *xdata, dict_match_t match, dict_t *matchdata)
{
inode_t *inode = NULL;
inode = inode_ref (frame->local);
if (op_ret < 0)
goto out;
- fop_xattrop_index_action (this, frame->local, xattr);
+
+ xattrop_index_action (this, frame->local, xattr, match, matchdata);
out:
INDEX_STACK_UNWIND (xattrop, frame, op_ret, op_errno, xattr, xdata);
index_queue_process (this, inode, NULL);
@@ -690,35 +701,41 @@ out:
}
int32_t
-index_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr,
- dict_t *xdata)
+index_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xattr,
+ dict_t *xdata)
{
- inode_t *inode = NULL;
-
- inode = inode_ref (frame->local);
- if (op_ret < 0)
- goto out;
+ return xattrop_cbk (frame, cookie, this, op_ret, op_errno, xattr, xdata,
+ dict_match_everything, NULL);
+}
- fop_fxattrop_index_action (this, frame->local, xattr);
-out:
- INDEX_STACK_UNWIND (fxattrop, frame, op_ret, op_errno, xattr, xdata);
- index_queue_process (this, inode, NULL);
- inode_unref (inode);
+int32_t
+index_xattrop64_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xattr,
+ dict_t *xdata)
+{
+ index_priv_t *priv = this->private;
- return 0;
+ return xattrop_cbk (frame, cookie, this, op_ret, op_errno, xattr, xdata,
+ is_xattr_in_watchlist, priv->xattrop64_watchlist);
}
int
index_xattrop_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
{
+ fop_xattrop_cbk_t cbk = NULL;
//In wind phase bring the gfid into index. This way if the brick crashes
//just after posix performs xattrop before _cbk reaches index xlator
//we will still have the gfid in index.
_index_action (this, frame->local, _gf_false);
- STACK_WIND (frame, index_xattrop_cbk, FIRST_CHILD (this),
+ if (optype == GF_XATTROP_ADD_ARRAY)
+ cbk = index_xattrop_cbk;
+ else
+ cbk = index_xattrop64_cbk;
+
+ STACK_WIND (frame, cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->xattrop, loc, optype, xattr,
xdata);
return 0;
@@ -728,11 +745,18 @@ int
index_fxattrop_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
{
+ fop_fxattrop_cbk_t cbk = NULL;
//In wind phase bring the gfid into index. This way if the brick crashes
//just after posix performs xattrop before _cbk reaches index xlator
//we will still have the gfid in index.
_index_action (this, frame->local, _gf_false);
- STACK_WIND (frame, index_fxattrop_cbk, FIRST_CHILD (this),
+
+ if (optype == GF_XATTROP_ADD_ARRAY)
+ cbk = index_xattrop_cbk;
+ else
+ cbk = index_xattrop64_cbk;
+
+ STACK_WIND (frame, cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->fxattrop, fd, optype, xattr,
xdata);
return 0;
@@ -744,7 +768,7 @@ index_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
{
call_stub_t *stub = NULL;
- if (!index_xattrop_track (loc, flags, dict))
+ if (!index_xattrop_track (this, flags, dict))
goto out;
frame->local = inode_ref (loc->inode);
@@ -769,7 +793,7 @@ index_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
{
call_stub_t *stub = NULL;
- if (!index_fxattrop_track (fd, flags, dict))
+ if (!index_xattrop_track (this, flags, dict))
goto out;
frame->local = inode_ref (fd->inode);
@@ -1148,6 +1172,70 @@ out:
return 0;
}
+int
+index_make_xattrop64_watchlist (xlator_t *this, index_priv_t *priv,
+ char *watchlist)
+{
+ char *delim = NULL;
+ char *dup_watchlist = NULL;
+ char *key = NULL;
+ char *saveptr = NULL;
+ dict_t *xattrs = NULL;
+ data_t *dummy = NULL;
+ int ret = 0;
+
+ if (!watchlist)
+ return 0;
+
+ dup_watchlist = gf_strdup (watchlist);
+ if (!dup_watchlist)
+ return -1;
+
+ xattrs = dict_new ();
+ if (!xattrs) {
+ ret = -1;
+ goto out;
+ }
+
+ dummy = int_to_data (1);
+ if (!dummy) {
+ ret = -1;
+ goto out;
+ }
+
+ data_ref (dummy);
+
+ delim = ",";
+ key = strtok_r (dup_watchlist, delim, &saveptr);
+ while (key) {
+ if (strlen (key) == 0) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set (xattrs, key, dummy);
+ if (ret)
+ goto out;
+
+ key = strtok_r (NULL, delim, &saveptr);
+ }
+
+ priv->xattrop64_watchlist = xattrs;
+ xattrs = NULL;
+
+ ret = 0;
+out:
+ if (xattrs)
+ dict_unref (xattrs);
+
+ GF_FREE (dup_watchlist);
+
+ if (dummy)
+ data_unref (dummy);
+
+ return ret;
+}
+
int32_t
mem_acct_init (xlator_t *this)
{
@@ -1168,6 +1256,7 @@ init (xlator_t *this)
gf_boolean_t mutex_inited = _gf_false;
gf_boolean_t cond_inited = _gf_false;
gf_boolean_t attr_inited = _gf_false;
+ char *watchlist = NULL;
if (!this->children || this->children->next) {
gf_log (this->name, GF_LOG_ERROR,
@@ -1211,7 +1300,14 @@ init (xlator_t *this)
gf_log (this->name, GF_LOG_WARNING,
"Using default thread stack size");
}
+
GF_OPTION_INIT ("index-base", priv->index_basepath, path, out);
+
+ GF_OPTION_INIT ("xattrop64-watchlist", watchlist, str, out);
+ ret = index_make_xattrop64_watchlist (this, priv, watchlist);
+ if (ret)
+ goto out;
+
uuid_generate (priv->index);
uuid_generate (priv->xattrop_vgfid);
INIT_LIST_HEAD (&priv->callstubs);
@@ -1236,6 +1332,8 @@ out:
pthread_cond_destroy (&priv->cond);
if (mutex_inited)
pthread_mutex_destroy (&priv->mutex);
+ if (priv && priv->xattrop64_watchlist)
+ dict_unref (priv->xattrop64_watchlist);
if (priv)
GF_FREE (priv);
this->private = NULL;
@@ -1257,6 +1355,8 @@ fini (xlator_t *this)
LOCK_DESTROY (&priv->lock);
pthread_cond_destroy (&priv->cond);
pthread_mutex_destroy (&priv->mutex);
+ if (priv->xattrop64_watchlist)
+ dict_unref (priv->xattrop64_watchlist);
GF_FREE (priv);
out:
return;
@@ -1345,5 +1445,9 @@ struct volume_options options[] = {
.type = GF_OPTION_TYPE_PATH,
.description = "path where the index files need to be stored",
},
+ { .key = {"xattrop64-watchlist" },
+ .type = GF_OPTION_TYPE_STR,
+ .description = "Comma separated list of xattrs that are watched",
+ },
{ .key = {NULL} },
};
diff --git a/xlators/features/index/src/index.h b/xlators/features/index/src/index.h
index 206d280e519..a8dfe067ae1 100644
--- a/xlators/features/index/src/index.h
+++ b/xlators/features/index/src/index.h
@@ -45,6 +45,7 @@ typedef struct index_priv {
struct list_head callstubs;
pthread_mutex_t mutex;
pthread_cond_t cond;
+ dict_t *xattrop64_watchlist;
} index_priv_t;
#define INDEX_STACK_UNWIND(fop, frame, params ...) \