diff options
author | vmallika <vmallika@redhat.com> | 2015-03-18 23:17:23 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2015-03-18 18:24:12 -0700 |
commit | 3e18f093974c85ac92a4c48f0cd13aa9ff9c5cac (patch) | |
tree | 6bbdd814492a3e7dcf6e9a06f49a373926f970dd /libglusterfs | |
parent | fa50fcb6dddf4d7d0094c26cee802fd942f62727 (diff) |
features/quota : Introducing inode quota
==========================================================================
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 proposed mechanism will provide an easier alternative to determine =
= the count of files/objects in a directory or volume. =
= =
= 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. =
= =
= The count value can be accessed by performing a getxattr(). =
= Cluster translators like afr, dht and stripe will perform aggregation =
= of count values from various bricks when getxattr() happens on the key =
= associated with file/object count. =
A new interface is introduced:
------------------------------
limit-objects : limit the number of inodes at directory level
list-objects : list the directories where the limit is set
remove-objects : remove the limit from the directory
==========================================================================
CLI COMMAND:
gluster volume quota <volname> limit-objects <path> <number> [<percent>]
* <number> is a hard-limit for number of objects limitation for path "<path>"
If hard-limit is exceeded, creation of file/directory is no longer
permitted.
* <percent> is a soft-limit for number of objects creation for path "<path>"
If soft-limit is exceeded, a warning is issued for each creation.
CLI COMMAND:
gluster volume quota <volname> remove-objects [path]
==========================================================================
CLI COMMAND:
gluster volume quota <volname> list-objects [path] ...
Sample output:
------------------
Path Hard-limit Soft-limit Used Available
Soft-limit exceeded?
Hard-limit exceeded?
------------------------------------------------------------------------
--------------------------------------
/dir 10 80% 10 0
Yes
Yes
==========================================================================
[root@snapshot-28 dir]# ls
a b file11 file12 file13 file14 file15 file16 file17
[root@snapshot-28 dir]# touch a1
touch: cannot touch `a1': Disk quota exceeded
* Nine files are created in directory "dir" and directory is included in
* the
count too. Hence the limit "10" is reached and further file creation
fails
==========================================================================
Note: We have also done some re-factoring in cli for volume name
validation. New function cli_validate_volname is created
==========================================================================
Change-Id: I1823497de4f790a2a20ebb1770293472ea33ee2b
BUG: 1190108
Signed-off-by: Sachin Pandit <spandit@redhat.com>
Signed-off-by: vmallika <vmallika@redhat.com>
Reviewed-on: http://review.gluster.org/9769
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'libglusterfs')
-rw-r--r-- | libglusterfs/src/Makefile.am | 5 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs.h | 1 | ||||
-rw-r--r-- | libglusterfs/src/mem-types.h | 1 | ||||
-rw-r--r-- | libglusterfs/src/quota-common-utils.c | 99 | ||||
-rw-r--r-- | libglusterfs/src/quota-common-utils.h | 36 |
5 files changed, 140 insertions, 2 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index 02f4462e6b0..73ee69f8630 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -29,7 +29,8 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.c \ syncop-utils.c \ $(CONTRIBDIR)/libgen/basename_r.c $(CONTRIBDIR)/libgen/dirname_r.c \ $(CONTRIBDIR)/stdlib/gf_mkostemp.c strfd.c parse-utils.c \ - $(CONTRIBDIR)/mount/mntent.c $(CONTRIBDIR)/libexecinfo/execinfo.c + $(CONTRIBDIR)/mount/mntent.c $(CONTRIBDIR)/libexecinfo/execinfo.c\ + quota-common-utils.c nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c @@ -48,7 +49,7 @@ noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h timespec. template-component-messages.h strfd.h syncop-utils.h parse-utils.h \ $(CONTRIBDIR)/mount/mntent_compat.h lvm-defaults.h \ $(CONTRIBDIR)/libexecinfo/execinfo_compat.h \ - unittest/unittest.h + unittest/unittest.h quota-common-utils.h EXTRA_DIST = graph.l graph.y diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 791e6dc5fd8..5a82d753879 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -88,6 +88,7 @@ #define GF_XATTR_GET_REAL_FILENAME_KEY "glusterfs.get_real_filename:" #define GF_XATTR_USER_PATHINFO_KEY "glusterfs.pathinfo" #define QUOTA_LIMIT_KEY "trusted.glusterfs.quota.limit-set" +#define QUOTA_LIMIT_OBJECTS_KEY "trusted.glusterfs.quota.limit-objects" #define VIRTUAL_QUOTA_XATTR_CLEANUP_KEY "glusterfs.quota-xattr-cleanup" #define GF_INTERNAL_IGNORE_DEEM_STATFS "ignore-deem-statfs" diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h index 9ff78dd19a4..5f4e7bcd2c2 100644 --- a/libglusterfs/src/mem-types.h +++ b/libglusterfs/src/mem-types.h @@ -129,6 +129,7 @@ enum gf_common_mem_types_ { gf_common_mt_wr = 113, gf_common_mt_rdma_arena_mr = 114, gf_common_mt_parser_t = 115, + gf_common_quota_meta_t = 116, /*related to gfdb library*/ gfdb_mt_time_t, gf_mt_sql_cbk_args_t, diff --git a/libglusterfs/src/quota-common-utils.c b/libglusterfs/src/quota-common-utils.c new file mode 100644 index 00000000000..8cc09e8fff7 --- /dev/null +++ b/libglusterfs/src/quota-common-utils.c @@ -0,0 +1,99 @@ +/* + Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + + +#include "dict.h" +#include "logging.h" +#include "byte-order.h" +#include "quota-common-utils.h" + +int32_t +quota_dict_get_meta (dict_t *dict, char *key, quota_meta_t *meta) +{ + int32_t ret = -1; + data_t *data = NULL; + quota_meta_t *value = NULL; + int64_t *size = NULL; + + if (!dict || !key || !meta) + goto out; + + data = dict_get (dict, key); + if (!data || !data->data) + goto out; + + if (data->len > sizeof (int64_t)) { + value = (quota_meta_t *) data->data; + meta->size = ntoh64 (value->size); + meta->file_count = ntoh64 (value->file_count); + if (data->len > (sizeof (int64_t)) * 2) + meta->dir_count = ntoh64 (value->dir_count); + else + meta->dir_count = 0; + } else { + size = (int64_t *) data->data; + meta->size = ntoh64 (*size); + meta->file_count = 0; + meta->dir_count = 0; + /* This can happen during software upgrade. + * Older version of glusterfs will not have inode count. + * Return failure, this will be healed as part of lookup + */ + gf_log_callingfn ("quota", GF_LOG_DEBUG, "Object quota xattrs " + "missing: len = %d", data->len); + ret = -2; + goto out; + } + + ret = 0; +out: + + return ret; +} + +int32_t +quota_dict_set_meta (dict_t *dict, char *key, const quota_meta_t *meta, + ia_type_t ia_type) +{ + int32_t ret = -1; + quota_meta_t *value = NULL; + + value = GF_CALLOC (1, sizeof (quota_meta_t), gf_common_quota_meta_t); + if (value == NULL) { + gf_log_callingfn ("quota", GF_LOG_ERROR, + "Memory allocation failed"); + goto out; + } + + value->size = hton64 (meta->size); + value->file_count = hton64 (meta->file_count); + value->dir_count = hton64 (meta->dir_count); + + if (ia_type == IA_IFDIR) { + ret = dict_set_bin (dict, key, value, sizeof (*value)); + } else { + /* For a file we don't need to store dir_count in the + * quota size xattr, so we set the len of the data in the dict + * as 128bits, so when the posix xattrop reads the dict, it only + * performs operations on size and file_count + */ + ret = dict_set_bin (dict, key, value, + sizeof (*value) - sizeof (int64_t)); + } + + if (ret < 0) { + gf_log_callingfn ("quota", GF_LOG_ERROR, "dict set failed"); + GF_FREE (value); + } + +out: + return ret; +} + diff --git a/libglusterfs/src/quota-common-utils.h b/libglusterfs/src/quota-common-utils.h new file mode 100644 index 00000000000..42301724348 --- /dev/null +++ b/libglusterfs/src/quota-common-utils.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#ifndef _QUOTA_COMMON_UTILS_H +#define _QUOTA_COMMON_UTILS_H + +#include "iatt.h" + +struct _quota_limits { + int64_t hl; + int64_t sl; +} __attribute__ ((__packed__)); +typedef struct _quota_limits quota_limits_t; + +struct _quota_meta { + int64_t size; + int64_t file_count; + int64_t dir_count; +} __attribute__ ((__packed__)); +typedef struct _quota_meta quota_meta_t; + +int32_t +quota_dict_get_meta (dict_t *dict, char *key, quota_meta_t *meta); + +int32_t +quota_dict_set_meta (dict_t *dict, char *key, const quota_meta_t *meta, + ia_type_t ia_type); + +#endif /* _QUOTA_COMMON_UTILS_H */ |