summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvmallika <vmallika@redhat.com>2016-04-03 20:35:52 +0530
committerVijaikumar Mallikarjuna <vmallika@redhat.com>2016-04-06 02:26:28 -0700
commit5eabe98861d265abf4d82a783db0568e958ecdcd (patch)
treed741568b3f41e9af7667f25254be68b82428886b
parent45ea3bce3068fa2c846e8c11e069fff9eacf8532 (diff)
quota: check inode limits only when new file/dir is created
This is a backport of http://review.gluster.org/#/c/13911/ 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> Change-Id: I55ec86ebecbb8490e557c61090f6fb8c6c449ec7 BUG: 1324058 Signed-off-by: vmallika <vmallika@redhat.com> Reviewed-on: http://review.gluster.org/13912 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>
-rw-r--r--tests/basic/inode-quota-enforcing.t45
-rw-r--r--tests/basic/inode-quota.t40
-rw-r--r--xlators/features/quota/src/quota.c36
-rw-r--r--xlators/features/quota/src/quota.h1
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 3dcb021685c..41ad2f04d5c 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);
@@ -1325,6 +1330,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);
@@ -1863,6 +1869,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;
}
@@ -2001,6 +2008,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);
@@ -2151,6 +2159,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);
@@ -2427,6 +2436,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);
@@ -2703,6 +2713,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;
@@ -2760,20 +2771,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)) {
@@ -3002,6 +3015,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);
@@ -3945,6 +3959,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);
@@ -4889,6 +4904,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 db27e1e1773..6ec6b8bdbdb 100644
--- a/xlators/features/quota/src/quota.h
+++ b/xlators/features/quota/src/quota.h
@@ -199,6 +199,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;