From: Radoslaw Zarzynski Date: Tue, 10 May 2016 11:31:48 +0000 (+0200) Subject: rgw: support setting the account quota of Swift API through POST. X-Git-Tag: v11.0.0~349^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5dc7f30ad05cd0ec1038aa008915ddaab697c838;p=ceph.git rgw: support setting the account quota of Swift API through POST. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 7e44d3ae8231..6b2bbba50444 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1914,8 +1914,11 @@ static void populate_with_generic_attrs(const req_state * const s, static int filter_out_quota_info(std::map& add_attrs, const std::set& rmattr_names, - RGWQuotaInfo& quota) + RGWQuotaInfo& quota, + bool * quota_extracted = nullptr) { + bool extracted = false; + /* Put new limit on max objects. */ auto iter = add_attrs.find(RGW_ATTR_QUOTA_NOBJS); std::string err; @@ -1926,6 +1929,7 @@ static int filter_out_quota_info(std::map& add_attrs, return -EINVAL; } add_attrs.erase(iter); + extracted = true; } /* Put new limit on bucket (container) size. */ @@ -1937,23 +1941,31 @@ static int filter_out_quota_info(std::map& add_attrs, return -EINVAL; } add_attrs.erase(iter); + extracted = true; } for (const auto& name : rmattr_names) { /* Remove limit on max objects. */ if (name.compare(RGW_ATTR_QUOTA_NOBJS) == 0) { quota.max_objects = -1; + extracted = true; } /* Remove limit on max bucket size. */ if (name.compare(RGW_ATTR_QUOTA_MSIZE) == 0) { quota.max_size = -1; + extracted = true; } } /* Swift requries checking on raw usage instead of the 4 KiB rounded one. */ quota.check_on_raw = true; quota.enabled = quota.max_size > 0 || quota.max_objects > 0; + + if (quota_extracted) { + *quota_extracted = extracted; + } + return 0; } @@ -2856,6 +2868,13 @@ int RGWPutMetadataAccount::init_processing() * evaluate whether we need FULL_CONTROL or not. */ filter_out_temp_url(attrs, rmattr_names, temp_url_keys); + /* The same with quota except a client needs to be reseller admin. */ + op_ret = filter_out_quota_info(attrs, rmattr_names, new_quota, + &new_quota_extracted); + if (op_ret < 0) { + return op_ret; + } + return 0; } @@ -2874,6 +2893,13 @@ int RGWPutMetadataAccount::verify_permission() return -EPERM; } + /* We are failing this intensionally to allow system user/reseller admin + * override in rgw_process.cc. This is the way to specify a given RGWOp + * expect extra privileges. */ + if (new_quota_extracted) { + return -EPERM; + } + return 0; } @@ -2894,6 +2920,11 @@ void RGWPutMetadataAccount::execute() } } + /* Handle the quota extracted at the verify_permission step. */ + if (new_quota_extracted) { + new_uinfo.user_quota = std::move(new_quota); + } + /* We are passing here the current (old) user info to allow the function * optimize-out some operations. */ op_ret = rgw_store_user_info(store, new_uinfo, s->user, diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index abed5a556de6..7bc6f84a2148 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -748,13 +748,17 @@ protected: std::set rmattr_names; std::map attrs, orig_attrs; std::map temp_url_keys; + RGWQuotaInfo new_quota; + bool new_quota_extracted; RGWObjVersionTracker acct_op_tracker; RGWAccessControlPolicy policy; public: - RGWPutMetadataAccount() {} + RGWPutMetadataAccount() + : new_quota_extracted(false) { + } virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) { RGWOp::init(store, s, h);