diff options
author | Raghavendra G <rgowdapp@redhat.com> | 2013-08-22 23:05:34 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2013-09-03 10:28:04 +0530 |
commit | 3f4490b3e4b0b912d6eba026e44f8b446018a806 (patch) | |
tree | 0c97aa4493e9c496023db5ebd78ce32d72726749 | |
parent | 19c728d4162c16a12363fc9ad2cda1aa835b6b31 (diff) |
features/quota: Pass correct delta during quota_updation
We used to calculate delta as,
delta = (postbuf->ia_blocks - prebuf->ia_blocks) * 512;
However this can result in some blocks getting accounted twice in a
multithreaded environment. This is because at storage/posix, we dont
do,
* stat (file, &prebuf)
* write ()
* stat (file, &postbuf)
as a single atomic operation. So, stat in step 3, can account for some
blocks which are allocated as part of a parallel write.
One of the possible fixes is to make these three operations by holding
a lock. However, this is too costly operation and hence quota relies
on size of the vector being written (with the check that if post and
pre block count are same, entire write was accomodated in existing
blocks). This seems to be acceptable since we don't solely rely on
size_updation by quota-enforcer (we do fetch aggregated size from
quotad after a timeout).
Change-Id: Ifdc8174c77058322aca8f589f7558641b73f0bc1
BUG: 969461
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/11829
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Tested-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r-- | xlators/features/quota/src/quota.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index 2170e646..114febff 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -1008,8 +1008,10 @@ quota_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } UNLOCK (&ctx->lock); + if (postbuf->ia_blocks != prebuf->ia_blocks) + delta = local->delta; + list_for_each_entry (dentry, &ctx->parents, next) { - delta = (postbuf->ia_blocks - prebuf->ia_blocks) * 512; quota_update_size (this, local->loc.inode, dentry->name, dentry->par, delta); } @@ -1114,6 +1116,7 @@ quota_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, UNLOCK (&ctx->lock); local->delta = size; + local->link_count = parents; local->stub = stub; |