summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2012-04-08 11:40:48 +0530
committerVijay Bellur <vijay@gluster.com>2012-04-12 22:18:57 -0700
commite46a57fda716c00b7c490be74485863c80d6f7b4 (patch)
tree961e9a30282f40db469d481b4b036912ab4de512
parentea8378299e4d9ae5a8d296feb1d16950d07173de (diff)
features/quota: don't adjust statfs buffer if size used is already
greater than available limit. members f_bfree and f_bavail of struct statfs are unsigned types. A negative value assigned to them is interpreted as some positive number and resulting in incorrect output of df output. Signed-off-by: Raghavendra G <raghavendra@gluster.com> Change-Id: I4d3d38b9bb6f675958ee38ad4d6c71ebcf4bb9a1 BUG: 773530 Reviewed-on: http://review.gluster.com/3102 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Amar Tumballi <amarts@redhat.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
-rw-r--r--xlators/features/quota/src/quota.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c
index 77218bc4eb4..f6c4e0099b9 100644
--- a/xlators/features/quota/src/quota.c
+++ b/xlators/features/quota/src/quota.c
@@ -2805,18 +2805,20 @@ quota_fremovexattr (call_frame_t *frame, xlator_t *this,
return 0;
}
+
int32_t
quota_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct statvfs *buf,
dict_t *xdata)
{
- inode_t *root_inode = NULL;
- quota_priv_t *priv = NULL;
- uint64_t value = 0;
- quota_inode_ctx_t *ctx = NULL;
- limits_t *limit_node = NULL;
- int64_t usage = -1;
- int64_t avail = -1;
+ inode_t *root_inode = NULL;
+ quota_priv_t *priv = NULL;
+ uint64_t value = 0;
+ quota_inode_ctx_t *ctx = NULL;
+ limits_t *limit_node = NULL;
+ int64_t usage = -1;
+ int64_t avail = -1;
+ int64_t blocks = 0;
root_inode = cookie;
@@ -2851,7 +2853,12 @@ quota_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
list_for_each_entry (limit_node, &priv->limit_head, limit_list) {
/* Notice that this only works for volume-level quota. */
if (strcmp (limit_node->path, "/") == 0) {
- buf->f_blocks = limit_node->value / buf->f_bsize;
+ blocks = limit_node->value / buf->f_bsize;
+ if (usage > blocks) {
+ break;
+ }
+
+ buf->f_blocks = blocks;
avail = buf->f_blocks - usage;
if (buf->f_bfree > avail) {
buf->f_bfree = avail;