diff options
author | Varun Shastry <vshastry@redhat.com> | 2013-12-26 15:30:49 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2014-06-18 09:50:32 -0700 |
commit | b54764ba860c3baba4b441ae7fcf043ab7eb46db (patch) | |
tree | 5255300a883af00f8c112719a7bbc046d42f1e4a | |
parent | 2b87e157a50953b542d5fc49fac84813ee116ce5 (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>
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 76 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 12 |
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", "a_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; |