summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/dht
diff options
context:
space:
mode:
authorVarun Shastry <vshastry@redhat.com>2013-12-26 15:30:49 +0530
committerRaghavendra G <rgowdapp@redhat.com>2014-06-18 09:50:32 -0700
commitb54764ba860c3baba4b441ae7fcf043ab7eb46db (patch)
tree5255300a883af00f8c112719a7bbc046d42f1e4a /xlators/cluster/dht
parent2b87e157a50953b542d5fc49fac84813ee116ce5 (diff)
features/quota: Make dht_statfs_cbk more fool proof from quota_deem_statfs
Problem: The function depends on the fact that if quota-deem-statfs option is enabled, all of the subvolumes send their xdata with quota-deem-statfs flag ON. But, this may not be true in case of errors in some of the subvolumes. There is a decision/policy made which assumes quota-deem-statfs to be ON if at least ONE of the subvolumes sends the flag ON. By this, df reports quota modified statfs values if *at least ONE* of the bricks sends the quota-deem-statfs flag ON. This can be visualized with the below "Transition Diagram/State Machine". Event: Each Quota deem statfs status from the individual bricks Action: Decision taken on the calculation of the statvfs received State: Whether quota deem statfs is ON or OFF (0: OFF, 1: ON) Input: Event from individual bricks ___ ___ / \ OFF* / \ (OFF|ON)* | | | | \ / ON \ / -----> 0 ----------------> 1 The below Transition Function depicts the relation between the statfs calculation based on the events received. State Event action ------------------------------------- OFF OFF OFF OFF ON REPLACE ON OFF NEGLECT ON ON COMPARE Change-Id: I0e8fb7d3945a3ca3dde0bb99de6cd397e27a3162 BUG: 1048786 Signed-off-by: Varun Shastry <vshastry@redhat.com> Reviewed-on: http://review.gluster.org/6652 Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Raghavendra G <rgowdapp@redhat.com> Tested-by: Raghavendra G <rgowdapp@redhat.com>
Diffstat (limited to 'xlators/cluster/dht')
-rw-r--r--xlators/cluster/dht/src/dht-common.c76
-rw-r--r--xlators/cluster/dht/src/dht-common.h12
2 files changed, 72 insertions, 16 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 7eb40faa9a3..73d58d853b2 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -2984,20 +2984,26 @@ dht_normalize_stats (struct statvfs *buf, unsigned long bsize,
int
dht_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct statvfs *statvfs, dict_t *xdata)
+ int op_ret, int op_errno, struct statvfs *statvfs,
+ dict_t *xdata)
{
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- int bsize = 0;
- int frsize = 0;
- int8_t quota_deem_statfs = 0;
- GF_UNUSED int ret = 0;
- unsigned long new_usage = 0;
- unsigned long cur_usage = 0;
- ret = dict_get_int8 (xdata, "quota-deem-statfs", &quota_deem_statfs);
+ gf_boolean_t event = _gf_false;
+ qdstatfs_action_t action = qdstatfs_action_OFF;
+ dht_local_t * local = NULL;
+ int this_call_cnt = 0;
+ int bsize = 0;
+ int frsize = 0;
+ GF_UNUSED int ret = 0;
+ unsigned long new_usage = 0;
+ unsigned long cur_usage = 0;
local = frame->local;
+ GF_ASSERT (local);
+
+ if (xdata)
+ ret = dict_get_int8 (xdata, "quota-deem-statfs",
+ (int8_t *)&event);
LOCK (&frame->lock);
{
@@ -3012,13 +3018,51 @@ dht_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
local->op_ret = 0;
- if (quota_deem_statfs) {
- new_usage = statvfs->f_blocks - statvfs->f_bfree;
- cur_usage = local->statvfs.f_blocks - local->statvfs.f_bfree;
- /* We take the maximux of the usage from the subvols */
- if (new_usage >= cur_usage)
+ switch (local->quota_deem_statfs) {
+ case _gf_true:
+ if (event == _gf_true)
+ action = qdstatfs_action_COMPARE;
+ else
+ action = qdstatfs_action_NEGLECT;
+ break;
+
+ case _gf_false:
+ if (event == _gf_true) {
+ action = qdstatfs_action_REPLACE;
+ local->quota_deem_statfs = _gf_true;
+ }
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_ERROR, "Encountered third "
+ "value for boolean variable %d",
+ local->quota_deem_statfs);
+ break;
+ }
+
+ if (local->quota_deem_statfs) {
+ switch (action) {
+ case qdstatfs_action_NEGLECT:
+ goto unlock;
+
+ case qdstatfs_action_REPLACE:
local->statvfs = *statvfs;
- goto unlock;
+ goto unlock;
+
+ case qdstatfs_action_COMPARE:
+ new_usage = statvfs->f_blocks -
+ statvfs->f_bfree;
+ cur_usage = local->statvfs.f_blocks -
+ local->statvfs.f_bfree;
+
+ /* Take the max of the usage from subvols */
+ if (new_usage >= cur_usage)
+ local->statvfs = *statvfs;
+ goto unlock;
+
+ default:
+ break;
+ }
}
if (local->statvfs.f_bsize != 0) {
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index ba66306dd13..e45418a73f6 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -100,6 +100,17 @@ struct dht_rebalance_ {
dict_t *xdata;
};
+/**
+ * Enum to store decided action based on the qdstatfs (quota-deem-statfs)
+ * events
+ **/
+typedef enum {
+ qdstatfs_action_OFF = 0,
+ qdstatfs_action_REPLACE,
+ qdstatfs_action_NEGLECT,
+ qdstatfs_action_COMPARE,
+} qdstatfs_action_t;
+
struct dht_local {
int call_cnt;
loc_t loc;
@@ -187,6 +198,7 @@ struct dht_local {
struct dht_rebalance_ rebalance;
xlator_t *first_up_subvol;
+ gf_boolean_t quota_deem_statfs;
};
typedef struct dht_local dht_local_t;