summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-cmd-volume.c36
-rw-r--r--cli/src/cli-rpc-ops.c66
-rw-r--r--cli/src/cli.c1
-rw-r--r--cli/src/cli.h1
-rw-r--r--libglusterfs/src/common-utils.c48
-rw-r--r--libglusterfs/src/common-utils.h9
-rw-r--r--libglusterfs/src/mem-types.h1
7 files changed, 157 insertions, 5 deletions
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index 5a153c68f6b..f5ee1b14544 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -1226,6 +1226,7 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options)
int32_t type = 0;
char gfid_type = 0;
float version = 0.0f;
+ int32_t max_count = 0;
xdata = dict_new ();
if (!xdata) {
@@ -1321,6 +1322,41 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options)
ret = -1;
goto out;
}
+
+ for (count = 0;; count++) {
+ ret = quota_conf_read_gfid (fd, buf, &gfid_type, version);
+ if (ret == 0) {
+ break;
+ } else if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_CRITICAL, "Quota "
+ "configuration store may be corrupt.");
+ goto out;
+ }
+
+ if ((type == GF_QUOTA_OPTION_TYPE_LIST &&
+ gfid_type == GF_QUOTA_CONF_TYPE_OBJECTS) ||
+ (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS &&
+ gfid_type == GF_QUOTA_CONF_TYPE_USAGE))
+ continue;
+
+ max_count++;
+ }
+ ret = dict_set_int32 (xdata, "max_count", max_count);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set max_count");
+ goto out;
+ }
+
+ ret = sys_lseek (fd, 0L, SEEK_SET);
+ if (ret < 0) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to move offset to "
+ "the beginning: %s", strerror (errno));
+ goto out;
+ }
+ ret = quota_conf_read_version (fd, &version);
+ if (ret)
+ goto out;
+
for (count = 0;; count++) {
ret = quota_conf_read_gfid (fd, buf, &gfid_type, version);
if (ret == 0) {
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 223ec4260aa..67d61d44071 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -3533,6 +3533,35 @@ cli_cmd_broadcast_response_detached (void *opaque)
return NULL;
}
+int32_t
+cli_quota_compare_path (struct list_head *list1,
+ struct list_head *list2)
+{
+ struct list_node *node1 = NULL;
+ struct list_node *node2 = NULL;
+ dict_t *dict1 = NULL;
+ dict_t *dict2 = NULL;
+ char *path1 = NULL;
+ char *path2 = NULL;
+ int ret = 0;
+
+ node1 = list_entry (list1, struct list_node, list);
+ node2 = list_entry (list2, struct list_node, list);
+
+ dict1 = node1->ptr;
+ dict2 = node2->ptr;
+
+ ret = dict_get_str (dict1, GET_ANCESTRY_PATH_KEY, &path1);
+ if (ret < 0)
+ return 0;
+
+ ret = dict_get_str (dict2, GET_ANCESTRY_PATH_KEY, &path2);
+ if (ret < 0)
+ return 0;
+
+ return strcmp (path1, path2);
+}
+
int
cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
@@ -3541,10 +3570,13 @@ cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov,
gf_cli_rsp rsp = {0,};
int ret = -1;
dict_t *dict = NULL;
+ struct list_node *node = NULL;
+ struct list_node *tmpnode = NULL;
call_frame_t *frame = NULL;
cli_local_t *local = NULL;
int32_t list_count = 0;
pthread_t th_id = {0, };
+ int32_t max_count = 0;
GF_ASSERT (myframe);
@@ -3560,8 +3592,10 @@ cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov,
&list_count);
if (ret)
list_count = 0;
+
+ list_count++;
ret = dict_set_int32 (local->dict, "quota-list-count",
- list_count + 1);
+ list_count);
}
UNLOCK (&local->lock);
@@ -3609,7 +3643,32 @@ cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- print_quota_list_from_quotad (frame, dict);
+ ret = dict_get_int32 (local->dict, "max_count",
+ &max_count);
+ if (ret < 0) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "failed to get max_count");
+ goto out;
+ }
+
+ node = list_node_add_order (dict, &local->dict_list,
+ cli_quota_compare_path);
+ if (node == NULL) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "failed to add node to the list");
+ dict_unref (dict);
+ goto out;
+ }
+
+ if (list_count == max_count) {
+ list_for_each_entry_safe (node, tmpnode,
+ &local->dict_list, list) {
+ dict = node->ptr;
+ print_quota_list_from_quotad (frame, dict);
+ list_node_del (node);
+ dict_unref (dict);
+ }
+ }
}
out:
@@ -3639,9 +3698,6 @@ out:
cli_cmd_broadcast_response (ret);
}
- if (dict)
- dict_unref (dict);
-
free (rsp.dict.dict_val);
return ret;
}
diff --git a/cli/src/cli.c b/cli/src/cli.c
index dfacd4bee0c..923748b4594 100644
--- a/cli/src/cli.c
+++ b/cli/src/cli.c
@@ -663,6 +663,7 @@ cli_local_get ()
local = GF_CALLOC (1, sizeof (*local), cli_mt_cli_local_t);
LOCK_INIT (&local->lock);
+ INIT_LIST_HEAD (&local->dict_list);
return local;
}
diff --git a/cli/src/cli.h b/cli/src/cli.h
index 0776383fc9f..73fb67289f7 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -156,6 +156,7 @@ struct cli_local {
int vol_count;
#endif
gf_lock_t lock;
+ struct list_head dict_list;
};
struct cli_volume_status {
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index ef48aca056b..21fe3841be9 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -4214,6 +4214,54 @@ _unmask_cancellation (void)
(void) pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
}
+/* This is a wrapper function to add a pointer to a list,
+ * which doesn't contain list member
+ */
+struct list_node*
+_list_node_add (void *ptr, struct list_head *list,
+ int (*compare)(struct list_head *, struct list_head *))
+{
+ struct list_node *node = NULL;
+
+ if (ptr == NULL || list == NULL)
+ goto out;
+
+ node = GF_CALLOC (1, sizeof (struct list_node), gf_common_list_node);
+
+ if (node == NULL)
+ goto out;
+
+ node->ptr = ptr;
+ if (compare)
+ list_add_order (&node->list, list, compare);
+ else
+ list_add_tail (&node->list, list);
+out:
+ return node;
+}
+
+struct list_node*
+list_node_add (void *ptr, struct list_head *list)
+{
+ return _list_node_add (ptr, list, NULL);
+}
+
+struct list_node*
+list_node_add_order (void *ptr, struct list_head *list,
+ int (*compare)(struct list_head *, struct list_head *))
+{
+ return _list_node_add (ptr, list, compare);
+}
+
+void
+list_node_del (struct list_node *node)
+{
+ if (node == NULL)
+ return;
+
+ list_del_init (&node->list);
+ GF_FREE (node);
+}
const char *
fop_enum_to_pri_string (glusterfs_fop_t fop)
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index acd5cb5303e..58889ca9a5c 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -188,7 +188,16 @@ struct dnscache6 {
struct addrinfo *next;
};
+struct list_node {
+ void *ptr;
+ struct list_head list;
+};
+struct list_node *list_node_add (void *ptr, struct list_head *list);
+struct list_node *list_node_add_order (void *ptr, struct list_head *list,
+ int (*compare)(struct list_head *,
+ struct list_head *));
+void list_node_del (struct list_node *node);
struct dnscache *gf_dnscache_init (time_t ttl);
struct dnscache_entry *gf_dnscache_entry_init ();
diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h
index 63fffeeafab..639ba3721f1 100644
--- a/libglusterfs/src/mem-types.h
+++ b/libglusterfs/src/mem-types.h
@@ -158,6 +158,7 @@ enum gf_common_mem_types_ {
gf_common_mt_syncstack,
gf_common_mt_syncenv,
gf_common_mt_scan_data,
+ gf_common_list_node,
gf_common_mt_end
};
#endif