summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2012-05-02 12:09:12 -0700
committerSage Weil <sage@newdream.net>2012-05-02 14:55:53 -0700
commit8220ab251bb59a6b274dbd9456d129aef48a0c30 (patch)
tree5e420acbaa7010c36c05af321801b0907a535a88
parentbfa7635162566ccbf3a3ab326a71024836a146f6 (diff)
downloadceph-8220ab251bb59a6b274dbd9456d129aef48a0c30.tar.gz
crush: implement update_item()
This is similar to insert_item(), except it will succeed if the item is already there, and will move an item to the specified location if it is not. It returns 0 for no change, 1 if a chance was made. It also makes sure the weight and name match. Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r--src/crush/CrushWrapper.cc38
-rw-r--r--src/crush/CrushWrapper.h6
2 files changed, 43 insertions, 1 deletions
diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc
index 5473e60a85d..396fcfacde0 100644
--- a/src/crush/CrushWrapper.cc
+++ b/src/crush/CrushWrapper.cc
@@ -119,7 +119,7 @@ bool CrushWrapper::check_item_loc(CephContext *cct, int item, map<string,string>
}
int CrushWrapper::insert_item(CephContext *cct, int item, float weight, string name,
- map<string,string>& loc) // typename -> bucketname
+ map<string,string>& loc) // typename -> bucketname
{
ldout(cct, 5) << "insert_item item " << item << " weight " << weight
<< " name " << name << " loc " << loc << dendl;
@@ -184,6 +184,42 @@ int CrushWrapper::insert_item(CephContext *cct, int item, float weight, string n
return -EINVAL;
}
+int CrushWrapper::update_item(CephContext *cct, int item, float weight, string name,
+ map<string,string>& loc) // typename -> bucketname
+{
+ ldout(cct, 5) << "update_item item " << item << " weight " << weight
+ << " name " << name << " loc " << loc << dendl;
+ int ret = 0;
+
+ weight = quantize_weight(weight);
+
+ float old_weight;
+ if (check_item_loc(cct, item, loc, &old_weight)) {
+ ldout(cct, 5) << "update_item " << item << " already at " << loc << dendl;
+ if (old_weight != weight) {
+ ldout(cct, 5) << "update_item " << item << " adjusting weight "
+ << old_weight << " -> " << weight << dendl;
+ adjust_item_weightf(cct, item, weight);
+ ret = 1;
+ }
+ if (get_item_name(item) != name) {
+ ldout(cct, 5) << "update_item setting " << item << " name to " << name << dendl;
+ set_item_name(item, name.c_str());
+ ret = 1;
+ }
+ } else {
+ if (item_exists(item)) {
+ remove_item(cct, item);
+ }
+ ldout(cct, 5) << "update_item adding " << item << " weight " << weight
+ << " at " << loc << dendl;
+ int r = insert_item(cct, item, weight, name.c_str(), loc);
+ if (r == 0)
+ ret = 1;
+ }
+ return ret;
+}
+
int CrushWrapper::adjust_item_weight(CephContext *cct, int id, int weight)
{
ldout(cct, 5) << "adjust_item_weight " << id << " weight " << weight << dendl;
diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h
index 25ada59d12e..3db2a23c34a 100644
--- a/src/crush/CrushWrapper.h
+++ b/src/crush/CrushWrapper.h
@@ -166,6 +166,7 @@ public:
void find_roots(set<int>& roots) const;
bool check_item_loc(CephContext *cct, int item, map<string,string>& loc, float *weight);
int insert_item(CephContext *cct, int id, float weight, string name, map<string,string>& loc);
+ int update_item(CephContext *cct, int id, float weight, string name, map<string,string>& loc);
int remove_item(CephContext *cct, int id);
int adjust_item_weight(CephContext *cct, int id, int weight);
int adjust_item_weightf(CephContext *cct, int id, float weight) {
@@ -173,6 +174,11 @@ public:
}
void reweight(CephContext *cct);
+ static float quantize_weight(float weight) {
+ int w = (int)(weight * (float)0x10000);
+ return (float)w / (float)0x10000;
+ }
+
/*** devices ***/
int get_max_devices() const {