From 7927149f71adc49cad92f28f805a8e688534156e Mon Sep 17 00:00:00 2001 From: vmallika Date: Sun, 3 Apr 2016 20:35:52 +0530 Subject: 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 Reviewed-on: http://review.gluster.org/13911 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Manikandan Selvaganesh --- xlators/features/quota/src/quota.c | 36 ++++++++++++++++++++++++++---------- xlators/features/quota/src/quota.h | 1 + 2 files changed, 27 insertions(+), 10 deletions(-) (limited to 'xlators/features') 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; -- cgit