diff options
author | vmallika <vmallika@redhat.com> | 2015-04-15 17:35:07 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2015-05-04 03:46:08 -0700 |
commit | 821b1fdc893c0dd603d4c43a0b31f1ea495a46c9 (patch) | |
tree | a8593c6bc0b1ecbd58350b071b7ae4b5658ea57d /xlators/mgmt | |
parent | 40df2ed4d098d4cd2c6abbed23e497ac3e2e5804 (diff) |
quota: support for inode quota in quota.conf
Currently when quota limit is set, corresponding gfid
is set in quota.conf. This patch supports storing
inode-quota limits in quota.conf and also stores
additional byte for each gfid to differentiate
between usage quota limit and inode quota limit.
Change-Id: I444d7399407594edd280e640681679a784d4c46a
BUG: 1202244
Signed-off-by: vmallika <vmallika@redhat.com>
Signed-off-by: Sachin Pandit <spandit@redhat.com>
Reviewed-on: http://review.gluster.org/10069
Tested-by: NetBSD Build System
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators/mgmt')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-quota.c | 167 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 118 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 6 |
3 files changed, 180 insertions, 111 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 97fa4380656..9f2aa8ec9de 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -578,28 +578,33 @@ glusterd_update_quota_conf_version (glusterd_volinfo_t *volinfo) * and continue the search. */ static gf_boolean_t -glusterd_find_gfid_match (uuid_t gfid, unsigned char *buf, size_t bytes_read, - int opcode, size_t *write_byte_count) +glusterd_find_gfid_match (uuid_t gfid, char gfid_type, unsigned char *buf, + size_t bytes_read, int opcode, + size_t *write_byte_count) { int gfid_index = 0; int shift_count = 0; unsigned char tmp_buf[17] = {0,}; + char type = 0; while (gfid_index != bytes_read) { memcpy ((void *)tmp_buf, (void *)&buf[gfid_index], 16); - if (!gf_uuid_compare (gfid, tmp_buf)) { - if (opcode == GF_QUOTA_OPTION_TYPE_REMOVE) { - shift_count = bytes_read - (gfid_index + 16); + type = buf[gfid_index + 16]; + + if (!gf_uuid_compare (gfid, tmp_buf) && type == gfid_type) { + if (opcode == GF_QUOTA_OPTION_TYPE_REMOVE || + opcode == GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS) { + shift_count = bytes_read - (gfid_index + 17); memmove ((void *)&buf[gfid_index], - (void *)&buf[gfid_index+16], + (void *)&buf[gfid_index + 17], shift_count); - *write_byte_count = bytes_read - 16; + *write_byte_count = bytes_read - 17; } else { *write_byte_count = bytes_read; } return _gf_true; } else { - gfid_index+=16; + gfid_index += 17; } } if (gfid_index == bytes_read) @@ -647,15 +652,91 @@ out: } int +glusterd_store_quota_conf_upgrade (glusterd_volinfo_t *volinfo) +{ + int ret = -1; + int fd = -1; + int conf_fd = -1; + unsigned char gfid[17] = {0,}; + xlator_t *this = NULL; + char type = 0; + + this = THIS; + GF_ASSERT (this); + + fd = gf_store_mkstemp (volinfo->quota_conf_shandle); + if (fd < 0) { + ret = -1; + goto out; + } + + conf_fd = open (volinfo->quota_conf_shandle->path, O_RDONLY); + if (conf_fd == -1) { + ret = -1; + goto out; + } + + ret = quota_conf_skip_header (conf_fd); + if (ret) + goto out; + + ret = quota_conf_write_header (fd); + if (ret) + goto out; + + while (1) { + ret = quota_conf_read_gfid (conf_fd, gfid, &type, 1.1); + if (ret == 0) + break; + else if (ret < 0) + goto out; + + ret = quota_conf_write_gfid (fd, gfid, + GF_QUOTA_CONF_TYPE_USAGE); + if (ret < 0) + goto out; + } + +out: + if (conf_fd != -1) + close (conf_fd); + + if (ret && (fd > 0)) { + gf_store_unlink_tmppath (volinfo->quota_conf_shandle); + } else if (!ret) { + ret = gf_store_rename_tmppath (volinfo->quota_conf_shandle); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to rename " + "quota conf file"); + return ret; + } + + ret = glusterd_compute_cksum (volinfo, _gf_true); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "compute cksum for quota conf file"); + return ret; + } + + ret = glusterd_store_save_quota_version_and_cksum (volinfo); + if (ret) + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "store quota version and cksum"); + } + + return ret; +} + +int glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, char *gfid_str, int opcode, char **op_errstr) { int ret = -1; int fd = -1; int conf_fd = -1; - size_t entry_sz = 131072; + size_t entry_sz = 139264; ssize_t bytes_read = 0; - size_t bytes_to_write = 0; + size_t bytes_to_write = 0; unsigned char buf[131072] = {0,}; uuid_t gfid = {0,}; xlator_t *this = NULL; @@ -664,6 +745,8 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, gf_boolean_t is_file_empty = _gf_false; gf_boolean_t is_first_read = _gf_true; glusterd_conf_t *conf = NULL; + float version = 0.0f; + char type = 0; this = THIS; GF_ASSERT (this); @@ -672,30 +755,43 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, glusterd_store_create_quota_conf_sh_on_absence (volinfo); - fd = gf_store_mkstemp (volinfo->quota_conf_shandle); - if (fd < 0) { - ret = -1; - goto out; - } - conf_fd = open (volinfo->quota_conf_shandle->path, O_RDONLY); if (conf_fd == -1) { ret = -1; goto out; } - ret = glusterd_store_quota_conf_skip_header (this, conf_fd); - if (ret) { + ret = quota_conf_read_version (conf_fd, &version); + if (ret) goto out; + + if (version < 1.2f) { + close (conf_fd); + ret = glusterd_store_quota_conf_upgrade(volinfo); + if (ret) + goto out; + + conf_fd = open (volinfo->quota_conf_shandle->path, O_RDONLY); + if (conf_fd == -1) { + ret = -1; + goto out; + } + + ret = quota_conf_skip_header (conf_fd); + if (ret) + goto out; } - ret = glusterd_store_quota_conf_stamp_header (this, fd); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Failed to add header to tmp " - "file."); + fd = gf_store_mkstemp (volinfo->quota_conf_shandle); + if (fd < 0) { + ret = -1; goto out; } + ret = quota_conf_write_header (fd); + if (ret) + goto out; + /* Just create empty quota.conf file if create */ if (GF_QUOTA_OPTION_TYPE_ENABLE == opcode) { modified = _gf_true; @@ -709,6 +805,11 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, } gf_uuid_parse (gfid_str, gfid); + if (opcode > GF_QUOTA_OPTION_TYPE_VERSION_OBJECTS) + type = GF_QUOTA_CONF_TYPE_OBJECTS; + else + type = GF_QUOTA_CONF_TYPE_USAGE; + for (;;) { bytes_read = read (conf_fd, (void*)&buf, entry_sz); if (bytes_read <= 0) { @@ -724,14 +825,14 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, is_file_empty = _gf_true; break; } - if ((bytes_read % 16) != 0) { + if ((bytes_read % 17) != 0) { gf_log (this->name, GF_LOG_ERROR, "quota.conf " "corrupted"); ret = -1; goto out; } - found = glusterd_find_gfid_match (gfid, buf, bytes_read, opcode, - &bytes_to_write); + found = glusterd_find_gfid_match (gfid, type, buf, bytes_read, + opcode, &bytes_to_write); ret = write (fd, (void *) buf, bytes_to_write); if (ret == -1) { @@ -756,9 +857,23 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, switch (opcode) { case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE: + if (!found) { + ret = quota_conf_write_gfid (fd, gfid, + GF_QUOTA_CONF_TYPE_USAGE); + if (ret == -1) { + gf_log (this->name, GF_LOG_ERROR, + "write into quota.conf failed. " + "Reason : %s", + strerror (errno)); + goto out; + } + modified = _gf_true; + } + break; case GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS: if (!found) { - ret = write (fd, gfid, 16); + ret = quota_conf_write_gfid (fd, gfid, + GF_QUOTA_CONF_TYPE_OBJECTS); if (ret == -1) { gf_log (this->name, GF_LOG_ERROR, "write into quota.conf failed. " diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index c72c7266f16..31aabaf41d0 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -61,6 +61,7 @@ #include "glusterd-quotad-svc.h" #include "glusterd-snapd-svc.h" #include "glusterd-bitd-svc.h" +#include "quota-common-utils.h" #include "xdr-generic.h" #include <sys/resource.h> @@ -2396,13 +2397,14 @@ int glusterd_vol_add_quota_conf_to_dict (glusterd_volinfo_t *volinfo, dict_t* load, int vol_idx, char *prefix) { - int fd = -1; - char *gfid_str = NULL; - unsigned char buf[16] = {0}; - char key[PATH_MAX] = {0}; - int gfid_idx = 0; - int ret = -1; - xlator_t *this = NULL; + int fd = -1; + unsigned char buf[16] = {0}; + char key[PATH_MAX] = {0}; + int gfid_idx = 0; + int ret = -1; + xlator_t *this = NULL; + char type = 0; + float version = 0.0f; this = THIS; GF_ASSERT (this); @@ -2418,40 +2420,31 @@ glusterd_vol_add_quota_conf_to_dict (glusterd_volinfo_t *volinfo, dict_t* load, goto out; } - ret = glusterd_store_quota_conf_skip_header (this, fd); + ret = quota_conf_read_version (fd, &version); if (ret) goto out; for (gfid_idx=0; ; gfid_idx++) { - - ret = read (fd, (void*)&buf, 16) ; - if (ret <= 0) { - //Finished reading all entries in the conf file + ret = quota_conf_read_gfid (fd, buf, &type, version); + if (ret == 0) { break; - } - if (ret != 16) { - //This should never happen. We must have a multiple of - //entry_sz bytes in our configuration file. + } else if (ret < 0) { gf_log (this->name, GF_LOG_CRITICAL, "Quota " "configuration store may be corrupt."); goto out; } - gfid_str = gf_strdup (uuid_utoa (buf)); - if (!gfid_str) { - ret = -1; - goto out; - } - snprintf (key, sizeof(key)-1, "%s%d.gfid%d", prefix, vol_idx, gfid_idx); - key[sizeof(key)-1] = '\0'; - ret = dict_set_dynstr (load, key, gfid_str); - if (ret) { + ret = dict_set_dynstr_with_alloc (load, key, uuid_utoa (buf)); + if (ret) goto out; - } - gfid_str = NULL; + snprintf (key, sizeof(key)-1, "%s%d.gfid-type%d", prefix, + vol_idx, gfid_idx); + ret = dict_set_int8 (load, key, type); + if (ret) + goto out; } snprintf (key, sizeof(key)-1, "%s%d.gfid-count", prefix, vol_idx); @@ -2476,7 +2469,6 @@ glusterd_vol_add_quota_conf_to_dict (glusterd_volinfo_t *volinfo, dict_t* load, out: if (fd != -1) close (fd); - GF_FREE (gfid_str); return ret; } @@ -2935,14 +2927,15 @@ glusterd_import_quota_conf (dict_t *peer_data, int vol_idx, glusterd_volinfo_t *new_volinfo, char *prefix) { - int gfid_idx = 0; - int gfid_count = 0; - int ret = -1; - int fd = -1; - char key[PATH_MAX] = {0}; - char *gfid_str = NULL; - uuid_t gfid = {0,}; - xlator_t *this = NULL; + int gfid_idx = 0; + int gfid_count = 0; + int ret = -1; + int fd = -1; + char key[PATH_MAX] = {0}; + char *gfid_str = NULL; + uuid_t gfid = {0,}; + xlator_t *this = NULL; + int8_t gfid_type = 0; this = THIS; GF_ASSERT (this); @@ -2984,33 +2977,34 @@ glusterd_import_quota_conf (dict_t *peer_data, int vol_idx, if (ret) goto out; - ret = glusterd_store_quota_conf_stamp_header (this, fd); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Failed to add header to tmp " - "file"); + ret = quota_conf_write_header (fd); + if (ret) goto out; - } gfid_idx = 0; for (gfid_idx = 0; gfid_idx < gfid_count; gfid_idx++) { snprintf (key, sizeof (key)-1, "%s%d.gfid%d", prefix, vol_idx, gfid_idx); - key[sizeof(key)-1] = '\0'; ret = dict_get_str (peer_data, key, &gfid_str); if (ret) goto out; + snprintf (key, sizeof (key)-1, "%s%d.gfid-type%d", + prefix, vol_idx, gfid_idx); + ret = dict_get_int8 (peer_data, key, &gfid_type); + if (ret) + gfid_type = GF_QUOTA_CONF_TYPE_USAGE; + gf_uuid_parse (gfid_str, gfid); - ret = write (fd, (void*)gfid, 16); - if (ret != 16) { + ret = quota_conf_write_gfid (fd, gfid, (char)gfid_type); + if (ret < 0) { gf_log (this->name, GF_LOG_CRITICAL, "Unable to write " "gfid %s into quota.conf for %s", gfid_str, new_volinfo->volname); ret = -1; goto out; } - } ret = gf_store_rename_tmppath (new_volinfo->quota_conf_shandle); @@ -8952,40 +8946,6 @@ glusterd_clean_up_quota_store (glusterd_volinfo_t *volinfo) } -#define QUOTA_CONF_HEADER \ - "GlusterFS Quota conf | version: v%d.%d\n" - -int -glusterd_store_quota_conf_skip_header (xlator_t *this, int fd) -{ - char buf[PATH_MAX] = {0,}; - - snprintf (buf, sizeof(buf)-1, QUOTA_CONF_HEADER, 1, 1); - return gf_skip_header_section (fd, strlen (buf)); -} - -int -glusterd_store_quota_conf_stamp_header (xlator_t *this, int fd) -{ - char buf[PATH_MAX] = {0,}; - int buf_len = 0; - ssize_t ret = -1; - ssize_t written = 0; - - snprintf (buf, sizeof(buf)-1, QUOTA_CONF_HEADER, 1, 1); - buf_len = strlen (buf); - for (written = 0; written != buf_len; written += ret) { - ret = write (fd, buf + written, buf_len - written); - if (ret == -1) { - goto out; - } - } - - ret = 0; -out: - return ret; -} - int glusterd_remove_auxiliary_mount (char *volname) { diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 59a07bacc1c..39c4442b72b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -536,12 +536,6 @@ void glusterd_clean_up_quota_store (glusterd_volinfo_t *volinfo); int -glusterd_store_quota_conf_skip_header (xlator_t *this, int fd); - -int -glusterd_store_quota_conf_stamp_header (xlator_t *this, int fd); - -int glusterd_remove_auxiliary_mount (char *volname); gf_boolean_t |