diff options
author | vmallika <vmallika@redhat.com> | 2016-04-03 20:35:52 +0530 |
---|---|---|
committer | Vijaikumar Mallikarjuna <vmallika@redhat.com> | 2016-04-06 02:25:23 -0700 |
commit | 7927149f71adc49cad92f28f805a8e688534156e (patch) | |
tree | c8fffd7e9880d2f542a00e0dbb37c3efdbbee18a | |
parent | 81955d8aaee8a2c7bf6370970926bc7b403a6efa (diff) |
quota: check inode limits only when new file/dir is created
When a inode limit is full, writes to any existing file
fails with disk quota exceed even if usage limit is
not set or usage limit is not full.
BUG: 1323486
Change-Id: I9679fe26a2839ade0b1541fa7f0a2b71ac6dcc31
Signed-off-by: vmallika <vmallika@redhat.com>
Reviewed-on: http://review.gluster.org/13911
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Manikandan Selvaganesh <mselvaga@redhat.com>
-rw-r--r-- | tests/basic/inode-quota-enforcing.t | 45 | ||||
-rw-r--r-- | tests/basic/inode-quota.t | 40 | ||||
-rw-r--r-- | xlators/features/quota/src/quota.c | 36 | ||||
-rw-r--r-- | xlators/features/quota/src/quota.h | 1 |
4 files changed, 57 insertions, 65 deletions
diff --git a/tests/basic/inode-quota-enforcing.t b/tests/basic/inode-quota-enforcing.t index 44b6c52a1ed..0cc92dd3963 100644 --- a/tests/basic/inode-quota-enforcing.t +++ b/tests/basic/inode-quota-enforcing.t @@ -6,6 +6,10 @@ cleanup; +QDD=$(dirname $0)/quota +# compile the test write program and run it +build_tester $(dirname $0)/quota.c -o $QDD + TESTS_EXPECTED_IN_LOOP=9 TEST glusterd @@ -14,7 +18,7 @@ TEST glusterd # Create, start and mount a volume with single brick # -------------------------------------------------- -TEST $CLI volume create $V0 $H0:$B0/{V0} +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2}; TEST $CLI volume start $V0 @@ -32,24 +36,17 @@ EXPECT '0' volinfo_field $V0 'features.soft-timeout' TEST $CLI volume quota $V0 hard-timeout 0 EXPECT '0' volinfo_field $V0 'features.hard-timeout' - #------------------------------------------------------- -# Set and remove quota limits on the directory and +# Set quota limits on the directory and # verify if the limits are being reflected properly #------------------------------------------------------ -TEST $CLI volume quota $V0 limit-objects /test_dir 100 -EXPECT "100" quota_object_list_field "/test_dir" 2 - -# Need to verify this once -TEST $CLI volume quota $V0 remove-objects /test_dir -EXPECT "" quota_object_list_field "/test_dir" 2 - -# Set back the limits - TEST $CLI volume quota $V0 limit-objects /test_dir 10 EXPECT "10" quota_object_list_field "/test_dir" 2 +TEST $CLI volume quota $V0 limit-usage /test_dir 100MB +EXPECT "100.0MB" quota_list_field "/test_dir" 2 + #------------------------------------------------------ # Check the quota enforcement mechanism for object count #------------------------------------------------------- @@ -59,12 +56,15 @@ EXPECT "10" quota_object_list_field "/test_dir" 2 # as well. for i in {1..9}; do - TEST_IN_LOOP touch $M0/test_dir/test$i.txt + #TEST_IN_LOOP touch $M0/test_dir/test$i.txt + TEST_IN_LOOP $QDD $M0/test_dir/test$i.txt 256 4 done EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "9" quota_object_list_field "/test_dir" 4 +EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "9.0MB" quotausage "/test_dir" # Check available limit EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "0" quota_object_list_field "/test_dir" 6 +EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "91.0MB" quota_list_field "/test_dir" 5 # Check if hard-limit exceeded EXPECT "Yes" quota_object_list_field "/test_dir" 8 @@ -75,10 +75,25 @@ EXPECT "Yes" quota_object_list_field "/test_dir" 7 # Creation of 11th file should throw out an error TEST ! touch $M0/test_dir/test11.txt +#------------------------------------------------------- +# remove quota limits on the directory and +# verify if the limit show 'N/A' and displayes only the usage +#------------------------------------------------------ +TEST $CLI volume quota $V0 remove-objects /test_dir +EXPECT "N/A" quota_object_list_field "/test_dir" 2 +EXPECT "9" quota_object_list_field "/test_dir" 4 + +TEST $CLI volume quota $V0 remove /test_dir +EXPECT "N/A" quota_list_field "/test_dir" 2 +EXPECT "9.0MB" quotausage "/test_dir" 4 + +# Set back the limits +TEST $CLI volume quota $V0 limit-objects /test_dir 10 +EXPECT "10" quota_object_list_field "/test_dir" 2 + +# Remove all files and verify the file count TEST rm -rf $M0/test_dir/test* EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "0" quota_object_list_field "/test_dir" 4 -TEST $CLI volume quota $V0 remove-objects /test_dir - rm -f $QDD cleanup; diff --git a/tests/basic/inode-quota.t b/tests/basic/inode-quota.t deleted file mode 100644 index 4b5ac44ee19..00000000000 --- a/tests/basic/inode-quota.t +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -. $(dirname $0)/../include.rc -. $(dirname $0)/../volume.rc - -function get_quota_value() -{ - local LIST_TYPE=$1 - local LIMIT_PATH=$2; - $CLI volume quota $V0 $LIST_TYPE $LIMIT_PATH | grep "$LIMIT_PATH"\ - | awk '{print $2}' -} - -cleanup; - -TEST glusterd; - -TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2}; -TEST $CLI volume start $V0; -TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 $M0; - -TEST $CLI volume quota $V0 enable; -EXPECT "on" volinfo_field $V0 'features.quota' -EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" quotad_up_status; - -TEST mkdir $M0/dir; - -TEST $CLI volume quota $V0 limit-usage /dir 10MB; -EXPECT "10.0MB" get_quota_value "list" "/dir" - -TEST $CLI volume quota $V0 limit-objects /dir 10; -EXPECT "10" get_quota_value "list-objects" "/dir" - -TEST $CLI volume quota $V0 remove /dir; -EXPECT "" get_quota_value "list" "/dir" - -TEST $CLI volume quota $V0 remove-objects /dir; -EXPECT "" get_quota_value "list-objects" "/dir" - -cleanup; diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index 81691f1ca0f..622227912da 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -1252,6 +1252,7 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this) char just_validated = 0; gf_boolean_t hard_limit_exceeded = 0; int64_t delta = 0; + int8_t object_delta = 0; uint64_t value = 0; gf_boolean_t skip_check = _gf_false; @@ -1270,6 +1271,7 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this) } delta = par_local->delta; + object_delta = par_local->object_delta; GF_VALIDATE_OR_GOTO (this->name, par_local->stub, err); /* Allow all the trusted clients @@ -1310,6 +1312,9 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this) break; } + if (object_delta <= 0) + goto skip_check_object_limit; + ret = quota_check_object_limit (frame, ctx, priv, _inode, this, &op_errno, just_validated, par_local, &skip_check); @@ -1324,6 +1329,7 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this) goto err; } +skip_check_object_limit: ret = quota_check_size_limit (frame, ctx, priv, _inode, this, &op_errno, just_validated, delta, par_local, &skip_check); @@ -1861,6 +1867,7 @@ quota_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, LOCK (&local->lock); { local->delta = size; + local->object_delta = 0; local->link_count = (parents != 0) ? parents : 1; local->stub = stub; } @@ -1999,6 +2006,7 @@ quota_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, { local->stub = stub; local->delta = 0; + local->object_delta = 1; local->link_count = 1; } UNLOCK (&local->lock); @@ -2149,6 +2157,7 @@ quota_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, local->link_count = 1; local->stub = stub; local->delta = 0; + local->object_delta = 1; } UNLOCK (&local->lock); @@ -2425,6 +2434,7 @@ quota_link_continue (call_frame_t *frame) { local->link_count = 1; local->delta = (ctx != NULL) ? ctx->buf.ia_blocks * 512 : 0; + local->object_delta = 1; gf_uuid_copy (local->common_ancestor, common_ancestor); } UNLOCK (&local->lock); @@ -2701,6 +2711,7 @@ quota_rename_get_size_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto out; } local->delta = ntoh64 (*size); + local->object_delta = 1; quota_check_limit (frame, local->newloc.parent, this); return 0; @@ -2758,20 +2769,22 @@ quota_rename_continue (call_frame_t *frame) local->delta = 0; + local->object_delta = 1; } else { - /* FIXME: We need to account for the size occupied by this - * inode on the target directory. To avoid double - * accounting, we need to modify enforcer to perform - * quota_check_limit only uptil the least common ancestor - * directory inode*/ + /* FIXME: We need to account for the size occupied by + * this inode on the target directory. To avoid double + * accounting, we need to modify enforcer to perform + * quota_check_limit only uptil the least common + * ancestor directory inode*/ - /* FIXME: The following code assumes that regular files and - * linkfiles are present, in their entirety, in a single - * brick. This *assumption is invalid in the case of - * stripe.*/ + /* FIXME: The following code assumes that regular files + * and linkfiles are present, in their entirety, in a + * single brick. This *assumption is invalid in the + * case of stripe.*/ - local->delta = ctx->buf.ia_blocks * 512; + local->delta = ctx->buf.ia_blocks * 512; + local->object_delta = 1; } } else if (IA_ISDIR (local->oldloc.inode->ia_type)) { @@ -3000,6 +3013,7 @@ quota_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath, { local->stub = stub; local->delta = strlen (linkpath); + local->object_delta = 1; local->link_count = 1; } UNLOCK (&local->lock); @@ -3943,6 +3957,7 @@ quota_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, local->link_count = 1; local->stub = stub; local->delta = 0; + local->object_delta = 1; } UNLOCK (&local->lock); @@ -4887,6 +4902,7 @@ quota_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, * in ENOSPC errors attempting to allocate an already allocated range. */ local->delta = len; + local->object_delta = 0; local->stub = stub; local->link_count = parents; diff --git a/xlators/features/quota/src/quota.h b/xlators/features/quota/src/quota.h index 1d9d88adad4..6f74da789b6 100644 --- a/xlators/features/quota/src/quota.h +++ b/xlators/features/quota/src/quota.h @@ -194,6 +194,7 @@ struct quota_local { loc_t newloc; loc_t validate_loc; int64_t delta; + int8_t object_delta; int32_t op_ret; int32_t op_errno; int64_t size; |