From 5eabe98861d265abf4d82a783db0568e958ecdcd 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 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 Change-Id: I55ec86ebecbb8490e557c61090f6fb8c6c449ec7 BUG: 1324058 Signed-off-by: vmallika Reviewed-on: http://review.gluster.org/13912 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System --- 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/quota') 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; -- cgit