From 7970183f4c730d4aca3cfaa106fde015a0fbc415 Mon Sep 17 00:00:00 2001 From: vmallika Date: Tue, 17 Mar 2015 20:05:19 +0530 Subject: Quota/marker : Support for inode quota Currently, the only way to retrieve the number of files/objects in a directory or volume is to do a crawl of the entire directory/volume. This is expensive and is not scalable. The new mechanism proposes to store count of objects/files as part of an extended attribute of a directory. Each directory's extended attribute value will indicate the number of files/objects present in a tree with the directory being considered as the root of the tree. Currently file usage is accounted in marker by doing multiple FOPs like setting and getting xattrs. Doing this with STACK WIND and UNWIND can be harder to debug as involves multiple callbacks. In this code we are replacing current mechanism with syncop approach as syncop code is much simpler to follow and help us implement inode quota in an organized way. Change-Id: Ibf366fbe07037284e89a241ddaff7750fc8771b4 BUG: 1188636 Signed-off-by: vmallika Signed-off-by: Sachin Pandit Reviewed-on: http://review.gluster.org/9567 Reviewed-by: Vijay Bellur Tested-by: Vijay Bellur --- cli/src/cli-rpc-ops.c | 65 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 20 deletions(-) (limited to 'cli/src/cli-rpc-ops.c') diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index b2964b68ff6..8ea43f824bc 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -2413,23 +2413,29 @@ static int print_quota_list_output (cli_local_t *local, char *mountdir, char *default_sl, char *path) { - int64_t used_space = 0; - int64_t avail = 0; - char *used_str = NULL; - char *avail_str = NULL; - int ret = -1; - char *sl_final = NULL; - char *hl_str = NULL; - double sl_num = 0; - gf_boolean_t sl = _gf_false; - gf_boolean_t hl = _gf_false; - char percent_str[20] = {0}; + int64_t avail = 0; + char *used_str = NULL; + char *avail_str = NULL; + int ret = -1; + char *sl_final = NULL; + char *hl_str = NULL; + double sl_num = 0; + gf_boolean_t sl = _gf_false; + gf_boolean_t hl = _gf_false; + char percent_str[20] = {0}; + ssize_t xattr_size = 0; struct quota_limit { int64_t hl; int64_t sl; } __attribute__ ((__packed__)) existing_limits; + struct quota_meta { + int64_t size; + int64_t file_count; + int64_t dir_count; + } __attribute__ ((__packed__)) used_space; + ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.limit-set", (void *)&existing_limits, sizeof (existing_limits)); @@ -2490,10 +2496,26 @@ print_quota_list_output (cli_local_t *local, char *mountdir, sl_final = percent_str; } - ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size", - &used_space, sizeof (used_space)); + used_space.size = used_space.file_count = used_space.dir_count = 0; + xattr_size = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size", + NULL, 0); + if (xattr_size > sizeof (int64_t)) { + ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size", + &used_space, sizeof (used_space)); + } else if (xattr_size > 0) { + /* This is for compatibility. + * Older version had only file usage + */ + ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size", + &(used_space.size), sizeof (used_space.size)); + } else { + ret = -1; + } if (ret < 0) { + gf_log ("cli", GF_LOG_ERROR, "Failed to get quota size " + "on path %s: %s", mountdir, strerror (errno)); + if (global_state->mode & GLUSTER_MODE_XML) { ret = cli_quota_xml_output (local, path, hl_str, sl_final, "N/A", @@ -2510,14 +2532,16 @@ print_quota_list_output (cli_local_t *local, char *mountdir, "N/A", "N/A", "N/A", "N/A"); } } else { - used_space = ntoh64 (used_space); + used_space.size = ntoh64 (used_space.size); + used_space.file_count = ntoh64 (used_space.file_count); + used_space.dir_count = ntoh64 (used_space.dir_count); - used_str = gf_uint64_2human_readable (used_space); + used_str = gf_uint64_2human_readable (used_space.size); - if (existing_limits.hl > used_space) { - avail = existing_limits.hl - used_space; + if (existing_limits.hl > used_space.size) { + avail = existing_limits.hl - used_space.size; hl = _gf_false; - if (used_space > sl_num) + if (used_space.size > sl_num) sl = _gf_true; else sl = _gf_false; @@ -2544,8 +2568,9 @@ print_quota_list_output (cli_local_t *local, char *mountdir, if (used_str == NULL) { cli_out ("%-40s %7s %9s %11"PRIu64 "%9"PRIu64" %15s %18s", path, hl_str, - sl_final, used_space, avail, sl? "Yes" : "No", - hl? "Yes" : "No"); + sl_final, used_space.size, avail, + sl ? "Yes" : "No", + hl ? "Yes" : "No"); } else { cli_out ("%-40s %7s %9s %11s %7s %15s %20s", path, hl_str, sl_final, used_str, avail_str, sl? "Yes" : "No", -- cgit