Skip to content

Commit

Permalink
Merge pull request #10832: jewel: rgw - default quota fixes
Browse files Browse the repository at this point in the history
Reviewed-by: Loic Dachary <ldachary@redhat.com>
  • Loading branch information
Loic Dachary committed Oct 10, 2016
2 parents 95543ee + 11328d7 commit 8374f17
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 44 deletions.
10 changes: 10 additions & 0 deletions doc/radosgw/admin.rst
Expand Up @@ -400,6 +400,15 @@ To see how much of the quota a user has consumed, execute the following::
.. note:: You should execute ``radosgw-admin user stats`` with the
``--sync-stats`` option to receive the latest data.

Default Quotas
--------------

You can set default quotas in the config. These defaults are used when
creating a new user and have no effect on existing users. If the
relevant default quota is set in config, then that quota is set on the
new user, and that quota is enabled. See ``rgw bucket default quota max objects``,
``rgw bucket default quota max size``, ``rgw user default quota max objects``, and
``rgw user default quota max size`` in `Ceph Object Gateway Config Reference`_

Reading / Writing Global Quotas
-------------------------------
Expand Down Expand Up @@ -468,3 +477,4 @@ ranges for trim operations. ::

.. _radosgw-admin: ../../man/8/radosgw-admin/
.. _Pool Configuration: ../../rados/configuration/pool-pg-config-ref/
.. _Ceph Object Gateway Config Reference: ../config-ref/
34 changes: 34 additions & 0 deletions doc/radosgw/config-ref.rst
Expand Up @@ -346,6 +346,40 @@ Ceph configuration file, the default value will be set automatically.
:Type: Boolean
:Default: ``false``


``rgw bucket default quota max objects``

:Description: Default max number of objects per bucket. Set on new users,
if no other quota is specified. Has no effect on existing users.
:Type: Integer
:Default: ``-1``


``rgw bucket default quota max size``

:Description: Default max capacity per bucket, in kB. Set on new users,
if no other quota is specified. Has no effect on existing users.
:Type: Integer
:Default: ``-1``


``rgw user default quota max objects``

:Description: Default max number of objects for a user. This includes all
objects in all buckets owned by the user. Set on new users,
if no other quota is specified. Has no effect on existing users.
:Type: Integer
:Default: ``-1``


``rgw user default quota max size``

:Description: The value for user max size quota in kB set on new users,
if no other quota is specified. Has no effect on existing users.
:Type: Integer
:Default: ``-1``


Regions
=======

Expand Down
56 changes: 14 additions & 42 deletions src/rgw/rgw_quota.cc
Expand Up @@ -694,73 +694,45 @@ class RGWQuotaHandlerImpl : public RGWQuotaHandler {
return 0;
}
public:
RGWQuotaHandlerImpl(RGWRados *_store, bool quota_threads) : store(_store), bucket_stats_cache(_store), user_stats_cache(_store, quota_threads) {
if (store->ctx()->_conf->rgw_bucket_default_quota_max_objects >= 0) {
def_bucket_quota.max_objects = store->ctx()->_conf->rgw_bucket_default_quota_max_objects;
def_bucket_quota.enabled = true;
}
if (store->ctx()->_conf->rgw_bucket_default_quota_max_size >= 0) {
def_bucket_quota.max_size_kb = store->ctx()->_conf->rgw_bucket_default_quota_max_size;
def_bucket_quota.enabled = true;
}
if (store->ctx()->_conf->rgw_user_default_quota_max_objects >= 0) {
def_user_quota.max_objects = store->ctx()->_conf->rgw_user_default_quota_max_objects;
def_user_quota.enabled = true;
}
if (store->ctx()->_conf->rgw_user_default_quota_max_size >= 0) {
def_user_quota.max_size_kb = store->ctx()->_conf->rgw_user_default_quota_max_size;
def_user_quota.enabled = true;
}
}
RGWQuotaHandlerImpl(RGWRados *_store, bool quota_threads) : store(_store),
bucket_stats_cache(_store),
user_stats_cache(_store, quota_threads) {}

virtual int check_quota(const rgw_user& user, rgw_bucket& bucket,
RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota,
uint64_t num_objs, uint64_t size) {

if (!bucket_quota.enabled && !user_quota.enabled && !def_bucket_quota.enabled && !def_user_quota.enabled)
if (!bucket_quota.enabled && !user_quota.enabled)
return 0;

uint64_t size_kb = rgw_rounded_objsize_kb(size);

RGWStorageStats bucket_stats;

/*
* we need to fetch bucket stats if the user quota is enabled, because the whole system relies
* on us periodically updating the user's bucket stats in the user's header, this happens in
* get_stats() if we actually fetch that info and not rely on cached data
*/

int ret = bucket_stats_cache.get_stats(user, bucket, bucket_stats, bucket_quota);
if (ret < 0)
return ret;

if (bucket_quota.enabled) {
ret = check_quota("bucket", bucket_quota, bucket_stats, num_objs, size_kb);
RGWStorageStats bucket_stats;
int ret = bucket_stats_cache.get_stats(user, bucket, bucket_stats, bucket_quota);
if (ret < 0)
return ret;
}

if (def_bucket_quota.enabled) {
ret = check_quota("def_bucket", def_bucket_quota, bucket_stats, num_objs, size_kb);
ret = check_quota("bucket", bucket_quota, bucket_stats, num_objs, size_kb);
if (ret < 0)
return ret;
return ret;
}

if (user_quota.enabled || def_user_quota.enabled) {
if (user_quota.enabled) {
RGWStorageStats user_stats;

ret = user_stats_cache.get_stats(user, bucket, user_stats, user_quota);
int ret = user_stats_cache.get_stats(user, bucket, user_stats, user_quota);
if (ret < 0)
return ret;

if (user_quota.enabled) {
ret = check_quota("user", user_quota, user_stats, num_objs, size_kb);
if (ret < 0)
return ret;
} else if (def_user_quota.enabled) {
ret = check_quota("def_user", def_user_quota, user_stats, num_objs, size_kb);
if (ret < 0)
return ret;
}
ret = check_quota("user", user_quota, user_stats, num_objs, size_kb);
if (ret < 0)
return ret;
}

return 0;
Expand Down
31 changes: 31 additions & 0 deletions src/rgw/rgw_rest_user.cc
Expand Up @@ -143,6 +143,37 @@ void RGWOp_User_Create::execute()
if (gen_key)
op_state.set_generate_key();

RGWQuotaInfo bucket_quota;
RGWQuotaInfo user_quota;

if (s->cct->_conf->rgw_bucket_default_quota_max_objects >= 0) {
bucket_quota.max_objects = s->cct->_conf->rgw_bucket_default_quota_max_objects;
bucket_quota.enabled = true;
}

if (s->cct->_conf->rgw_bucket_default_quota_max_size >= 0) {
bucket_quota.max_size_kb = s->cct->_conf->rgw_bucket_default_quota_max_size;
bucket_quota.enabled = true;
}

if (s->cct->_conf->rgw_user_default_quota_max_objects >= 0) {
user_quota.max_objects = s->cct->_conf->rgw_user_default_quota_max_objects;
user_quota.enabled = true;
}

if (s->cct->_conf->rgw_user_default_quota_max_size >= 0) {
user_quota.max_size_kb = s->cct->_conf->rgw_user_default_quota_max_size;
user_quota.enabled = true;
}

if (bucket_quota.enabled) {
op_state.set_bucket_quota(bucket_quota);
}

if (user_quota.enabled) {
op_state.set_user_quota(user_quota);
}

http_ret = RGWUserAdminOp_User::create(store, op_state, flusher);
}

Expand Down
24 changes: 22 additions & 2 deletions src/rgw/rgw_user.cc
Expand Up @@ -1932,8 +1932,18 @@ int RGWUser::execute_add(RGWUserAdminOpState& op_state, std::string *err_msg)
if (op_state.op_mask_specified)
user_info.op_mask = op_state.get_op_mask();

if (op_state.has_bucket_quota())
if (op_state.has_bucket_quota()) {
user_info.bucket_quota = op_state.get_bucket_quota();
} else {
if (cct->_conf->rgw_bucket_default_quota_max_objects >= 0) {
user_info.bucket_quota.max_objects = cct->_conf->rgw_bucket_default_quota_max_objects;
user_info.bucket_quota.enabled = true;
}
if (cct->_conf->rgw_bucket_default_quota_max_size >= 0) {
user_info.bucket_quota.max_size_kb = cct->_conf->rgw_bucket_default_quota_max_size;
user_info.bucket_quota.enabled = true;
}
}

if (op_state.temp_url_key_specified) {
map<int, string>::iterator iter;
Expand All @@ -1943,8 +1953,18 @@ int RGWUser::execute_add(RGWUserAdminOpState& op_state, std::string *err_msg)
}
}

if (op_state.has_user_quota())
if (op_state.has_user_quota()) {
user_info.user_quota = op_state.get_user_quota();
} else {
if (cct->_conf->rgw_user_default_quota_max_objects >= 0) {
user_info.user_quota.max_objects = cct->_conf->rgw_user_default_quota_max_objects;
user_info.user_quota.enabled = true;
}
if (cct->_conf->rgw_user_default_quota_max_size >= 0) {
user_info.user_quota.max_size_kb = cct->_conf->rgw_user_default_quota_max_size;
user_info.user_quota.enabled = true;
}
}

// update the request
op_state.set_user_info(user_info);
Expand Down

0 comments on commit 8374f17

Please sign in to comment.