diff options
-rw-r--r-- | cli/src/cli-cmd-volume.c | 36 | ||||
-rw-r--r-- | cli/src/cli-rpc-ops.c | 66 | ||||
-rw-r--r-- | cli/src/cli.c | 1 | ||||
-rw-r--r-- | cli/src/cli.h | 1 | ||||
-rw-r--r-- | libglusterfs/src/common-utils.c | 48 | ||||
-rw-r--r-- | libglusterfs/src/common-utils.h | 9 | ||||
-rw-r--r-- | libglusterfs/src/mem-types.h | 1 |
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 |