2
Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3
This file is part of GlusterFS.
5
This file is licensed to you under your choice of the GNU Lesser
6
General Public License, version 3 or any later version (LGPLv3 or
7
later), or the GNU General Public License, version 2 (GPLv2), in all
8
cases as published by the Free Software Foundation.
12
#include <glusterfs/statedump.h>
13
#include "quota-messages.h"
14
#include <glusterfs/events.h>
16
struct volume_options options[];
19
__quota_init_inode_ctx(inode_t *inode, xlator_t *this,
20
quota_inode_ctx_t **context)
23
quota_inode_ctx_t *ctx = NULL;
29
QUOTA_ALLOC_OR_GOTO(ctx, quota_inode_ctx_t, out);
31
LOCK_INIT(&ctx->lock);
33
if (context != NULL) {
37
INIT_LIST_HEAD(&ctx->parents);
39
ret = __inode_ctx_put(inode, this, (uint64_t)(long)ctx);
41
gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_SET_FAILED,
42
"cannot set quota context "
44
uuid_utoa(inode->gfid));
52
quota_inode_ctx_get(inode_t *inode, xlator_t *this, quota_inode_ctx_t **ctx,
53
char create_if_absent)
60
ret = __inode_ctx_get(inode, this, &ctx_int);
62
if ((ret == 0) && (ctx != NULL)) {
63
*ctx = (quota_inode_ctx_t *)(unsigned long)ctx_int;
64
} else if (create_if_absent) {
65
ret = __quota_init_inode_ctx(inode, this, ctx);
74
quota_loc_fill(loc_t *loc, inode_t *inode, inode_t *parent, char *path)
78
if (!loc || (inode == NULL))
82
loc->inode = inode_ref(inode);
83
gf_uuid_copy(loc->gfid, inode->gfid);
87
loc->parent = inode_ref(parent);
91
loc->path = gf_strdup(path);
93
loc->name = strrchr(loc->path, '/');
105
quota_inode_loc_fill(inode_t *inode, loc_t *loc)
107
char *resolvedpath = NULL;
108
inode_t *parent = NULL;
110
xlator_t *this = NULL;
112
if ((!inode) || (!loc)) {
118
if ((inode) && __is_root_gfid(inode->gfid)) {
123
parent = inode_parent(inode, 0, NULL);
125
gf_msg_debug(this->name, 0,
126
"cannot find parent for "
128
uuid_utoa(inode->gfid));
132
ret = inode_path(inode, NULL, &resolvedpath);
134
gf_msg_debug(this->name, 0,
135
"cannot construct path for "
137
uuid_utoa(inode->gfid));
140
ret = quota_loc_fill(loc, inode, parent, resolvedpath);
142
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
152
GF_FREE(resolvedpath);
158
quota_local_cleanup(quota_local_t *local)
164
loc_wipe(&local->loc);
165
loc_wipe(&local->newloc);
166
loc_wipe(&local->oldloc);
167
loc_wipe(&local->validate_loc);
169
inode_unref(local->inode);
172
dict_unref(local->xdata);
174
if (local->validate_xdata)
175
dict_unref(local->validate_xdata);
178
call_stub_destroy(local->stub);
180
LOCK_DESTROY(&local->lock);
187
static quota_local_t *
190
quota_local_t *local = NULL;
191
local = mem_get0(THIS->local_pool);
195
LOCK_INIT(&local->lock);
196
local->space_available = -1;
203
__quota_dentry_new(quota_inode_ctx_t *ctx, char *name, uuid_t par)
205
quota_dentry_t *dentry = NULL;
206
GF_UNUSED int32_t ret = 0;
208
QUOTA_ALLOC_OR_GOTO(dentry, quota_dentry_t, err);
210
INIT_LIST_HEAD(&dentry->next);
212
dentry->name = gf_strdup(name);
213
if (dentry->name == NULL) {
219
gf_uuid_copy(dentry->par, par);
222
list_add_tail(&dentry->next, &ctx->parents);
229
__quota_dentry_free(quota_dentry_t *dentry)
231
if (dentry == NULL) {
235
list_del_init(&dentry->next);
237
GF_FREE(dentry->name);
244
__quota_dentry_del(quota_inode_ctx_t *ctx, const char *name, uuid_t par)
246
quota_dentry_t *dentry = NULL;
247
quota_dentry_t *tmp = NULL;
249
list_for_each_entry_safe(dentry, tmp, &ctx->parents, next)
251
if ((strcmp(dentry->name, name) == 0) &&
252
(gf_uuid_compare(dentry->par, par) == 0)) {
253
__quota_dentry_free(dentry);
260
quota_dentry_del(quota_inode_ctx_t *ctx, const char *name, uuid_t par)
264
__quota_dentry_del(ctx, name, par);
270
__quota_inode_parent(inode_t *inode, uuid_t pargfid, const char *name)
272
inode_t *parent = NULL;
274
parent = inode_parent(inode, pargfid, name);
280
quota_inode_parent(inode_t *inode, uuid_t pargfid, const char *name)
282
inode_t *parent = NULL;
284
parent = __quota_inode_parent(inode, pargfid, name);
286
gf_msg_callingfn(THIS->name, GF_LOG_ERROR, 0, Q_MSG_PARENT_NULL,
288
"ancestor for inode (%s)",
289
uuid_utoa(inode->gfid));
295
quota_inode_depth(inode_t *inode)
298
inode_t *cur_inode = NULL;
300
cur_inode = inode_ref(inode);
301
while (cur_inode && !__is_root_gfid(cur_inode->gfid)) {
303
cur_inode = quota_inode_parent(cur_inode, 0, NULL);
309
inode_unref(cur_inode);
315
quota_find_common_ancestor(inode_t *inode1, inode_t *inode2,
316
uuid_t *common_ancestor)
321
inode_t *cur_inode1 = NULL;
322
inode_t *cur_inode2 = NULL;
324
depth1 = quota_inode_depth(inode1);
328
depth2 = quota_inode_depth(inode2);
332
cur_inode1 = inode_ref(inode1);
333
cur_inode2 = inode_ref(inode2);
335
while (cur_inode1 && depth1 > depth2) {
336
cur_inode1 = quota_inode_parent(cur_inode1, 0, NULL);
340
while (cur_inode2 && depth2 > depth1) {
341
cur_inode2 = quota_inode_parent(cur_inode2, 0, NULL);
345
while (depth1 && cur_inode1 && cur_inode2 && cur_inode1 != cur_inode2) {
346
cur_inode1 = quota_inode_parent(cur_inode1, 0, NULL);
347
cur_inode2 = quota_inode_parent(cur_inode2, 0, NULL);
351
if (cur_inode1 && cur_inode2) {
352
gf_uuid_copy(*common_ancestor, cur_inode1->gfid);
357
inode_unref(cur_inode1);
360
inode_unref(cur_inode2);
366
check_ancestory_continue(struct list_head *parents, inode_t *inode,
367
int32_t op_ret, int32_t op_errno, void *data)
369
call_frame_t *frame = NULL;
370
quota_local_t *local = NULL;
371
uint32_t link_count = 0;
374
local = frame->local;
376
if (parents && list_empty(parents)) {
377
gf_msg(THIS->name, GF_LOG_WARNING, EIO, Q_MSG_ANCESTRY_BUILD_FAILED,
378
"Couldn't build ancestry for inode (gfid:%s). "
379
"Without knowing ancestors till root, quota "
380
"cannot be enforced. "
381
"Hence, failing fop with EIO",
382
uuid_utoa(inode->gfid));
389
link_count = --local->link_count;
391
local->op_ret = op_ret;
392
local->op_errno = op_errno;
395
UNLOCK(&local->lock);
398
local->fop_continue_cbk(frame);
402
check_ancestory(call_frame_t *frame, inode_t *inode)
404
inode_t *cur_inode = NULL;
405
inode_t *parent = NULL;
407
cur_inode = inode_ref(inode);
408
while (cur_inode && !__is_root_gfid(cur_inode->gfid)) {
409
parent = inode_parent(cur_inode, 0, NULL);
411
quota_build_ancestry(cur_inode, check_ancestory_continue, frame);
412
inode_unref(cur_inode);
415
inode_unref(cur_inode);
420
inode_unref(cur_inode);
421
check_ancestory_continue(NULL, NULL, 0, 0, frame);
423
check_ancestory_continue(NULL, NULL, -1, ESTALE, frame);
428
check_ancestory_2_cbk(struct list_head *parents, inode_t *inode, int32_t op_ret,
429
int32_t op_errno, void *data)
431
inode_t *this_inode = NULL;
432
quota_inode_ctx_t *ctx = NULL;
439
if (parents == NULL || list_empty(parents)) {
440
gf_msg(THIS->name, GF_LOG_WARNING, 0, Q_MSG_ENFORCEMENT_FAILED,
441
"Couldn't build ancestry for inode (gfid:%s). "
442
"Without knowing ancestors till root, quota "
443
"cannot be enforced.",
444
uuid_utoa(this_inode->gfid));
448
quota_inode_ctx_get(this_inode, THIS, &ctx, 0);
450
ctx->ancestry_built = _gf_true;
453
inode_unref(this_inode);
457
check_ancestory_2(xlator_t *this, quota_local_t *local, inode_t *inode)
459
inode_t *cur_inode = NULL;
460
inode_t *parent = NULL;
461
quota_inode_ctx_t *ctx = NULL;
465
name = (char *)local->loc.name;
466
if (local->loc.parent) {
467
gf_uuid_copy(pgfid, local->loc.parent->gfid);
470
cur_inode = inode_ref(inode);
471
while (cur_inode && !__is_root_gfid(cur_inode->gfid)) {
472
quota_inode_ctx_get(cur_inode, this, &ctx, 0);
473
/* build ancestry is required only on the first lookup,
474
* so stop crawling when the inode_ctx is set for an inode
476
if (ctx && ctx->ancestry_built)
479
parent = inode_parent(cur_inode, pgfid, name);
481
quota_build_ancestry(cur_inode, check_ancestory_2_cbk,
488
gf_uuid_clear(pgfid);
491
inode_unref(cur_inode);
496
if (cur_inode && cur_inode != inode) {
497
quota_inode_ctx_get(inode, this, &ctx, 0);
499
ctx->ancestry_built = _gf_true;
503
inode_unref(cur_inode);
507
quota_link_count_decrement(call_frame_t *frame)
509
call_frame_t *tmpframe = NULL;
510
quota_local_t *local = NULL;
511
call_stub_t *stub = NULL;
514
local = frame->local;
515
if (local && local->par_frame) {
516
local = local->par_frame->local;
525
link_count = --local->link_count;
526
if (link_count == 0) {
531
UNLOCK(&local->lock);
539
local = tmpframe->local;
540
tmpframe->local = NULL;
542
STACK_DESTROY(frame->root);
544
quota_local_cleanup(local);
551
quota_handle_validate_error(call_frame_t *frame, int32_t op_ret,
554
quota_local_t *local;
556
local = frame->local;
557
if (local && local->par_frame)
558
local = local->par_frame->local;
566
local->op_ret = op_ret;
567
local->op_errno = op_errno;
569
UNLOCK(&local->lock);
571
/* we abort checking limits on this path to root */
572
quota_link_count_decrement(frame);
578
quota_validate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
579
int32_t op_ret, int32_t op_errno, inode_t *inode,
580
struct iatt *buf, dict_t *xdata, struct iatt *postparent)
582
quota_local_t *local = NULL;
584
quota_inode_ctx_t *ctx = NULL;
586
quota_meta_t size = {
590
local = frame->local;
598
GF_VALIDATE_OR_GOTO_WITH_ERROR("quota", this, unwind, op_errno, EINVAL);
599
GF_VALIDATE_OR_GOTO_WITH_ERROR(this->name, xdata, unwind, op_errno, EINVAL);
601
ret = inode_ctx_get(local->validate_loc.inode, this, &value);
603
ctx = (quota_inode_ctx_t *)(unsigned long)value;
604
if ((ret == -1) || (ctx == NULL)) {
605
gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_INODE_CTX_GET_FAILED,
607
" not present in inode (gfid:%s)",
608
uuid_utoa(local->validate_loc.inode->gfid));
613
ret = quota_dict_get_meta(xdata, QUOTA_SIZE_KEY, SLEN(QUOTA_SIZE_KEY),
616
gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_SIZE_KEY_MISSING,
617
"quota size key not present "
622
local->just_validated = 1; /* so that we don't go into infinite
623
* loop of validation and checking
624
* limit when timeout is zero.
628
ctx->size = size.size;
629
ctx->validate_time = gf_time();
630
ctx->file_count = size.file_count;
631
ctx->dir_count = size.dir_count;
635
quota_check_limit(frame, local->validate_loc.inode, this);
639
quota_handle_validate_error(frame, op_ret, op_errno);
643
static inline gf_boolean_t
644
quota_timeout(time_t t, time_t timeout)
646
return (gf_time() - t) >= timeout;
649
/* Return: 1 if new entry added
654
quota_add_parent(struct list_head *list, char *name, uuid_t pgfid)
656
quota_dentry_t *entry = NULL;
657
gf_boolean_t found = _gf_false;
660
if (!list_empty(list)) {
661
list_for_each_entry(entry, list, next)
663
if (gf_uuid_compare(pgfid, entry->par) == 0) {
670
entry = __quota_dentry_new(NULL, name, pgfid);
672
list_add_tail(&entry->next, list);
685
/* This function iterates the parent list in inode
686
* context and add unique parent to the list
687
* Returns number of dentry added to the list, or -1 on errors
690
quota_add_parents_from_ctx(quota_inode_ctx_t *ctx, struct list_head *list)
693
quota_dentry_t *dentry = NULL;
696
if (ctx == NULL || list == NULL)
701
list_for_each_entry(dentry, &ctx->parents, next)
703
ret = quota_add_parent(list, dentry->name, dentry->par);
713
return (ret == -1) ? -1 : count;
717
quota_build_ancestry_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
718
int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
721
inode_t *parent = NULL;
722
inode_t *tmp_parent = NULL;
723
inode_t *linked_inode = NULL;
724
inode_t *tmp_inode = NULL;
725
gf_dirent_t *entry = NULL;
729
quota_dentry_t *dentry = NULL;
730
quota_dentry_t *tmp = NULL;
731
quota_inode_ctx_t *ctx = NULL;
732
struct list_head parents;
733
quota_local_t *local = NULL;
736
INIT_LIST_HEAD(&parents);
738
local = frame->local;
744
if ((op_ret > 0) && (entries != NULL)) {
745
list_for_each_entry(entry, &entries->list, list)
747
if (__is_root_gfid(entry->inode->gfid)) {
748
/* The list contains a sub-list for each
749
* possible path to the target inode. Each
750
* sub-list starts with the root entry of the
751
* tree and is followed by the child entries
752
* for a particular path to the target entry.
753
* The root entry is an implied sub-list
754
* delimiter, as it denotes we have started
755
* processing a new path. Reset the parent
756
* pointer and continue
761
/* For a non-root entry, link this inode */
762
linked_inode = inode_link(entry->inode, tmp_parent,
763
entry->d_name, &entry->d_stat);
765
tmp_inode = entry->inode;
766
entry->inode = linked_inode;
767
inode_unref(tmp_inode);
769
gf_msg(this->name, GF_LOG_WARNING, EINVAL,
770
Q_MSG_PARENT_NULL, "inode link failed");
776
gf_uuid_copy(loc.gfid, entry->d_stat.ia_gfid);
778
loc.inode = inode_ref(entry->inode);
779
loc.parent = inode_ref(tmp_parent);
780
loc.name = entry->d_name;
782
quota_fill_inodectx(this, entry->inode, entry->dict, &loc,
783
&entry->d_stat, &op_errno);
785
/* For non-directory, posix_get_ancestry_non_directory
786
* returns all hard-links that are represented by nodes
787
* adjacent to each other in the dentry-list.
788
* (Unlike the directory case where adjacent nodes
789
* either have a parent/child relationship or belong to
792
if (entry->inode->ia_type == IA_IFDIR)
793
tmp_parent = entry->inode;
799
parent = inode_parent(local->loc.inode, 0, NULL);
800
if (parent == NULL) {
801
gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_PARENT_NULL,
807
quota_inode_ctx_get(local->loc.inode, this, &ctx, 0);
809
ret = quota_add_parents_from_ctx(ctx, &parents);
815
if (list_empty(&parents)) {
816
/* we built ancestry for a directory */
817
list_for_each_entry(entry, &entries->list, list)
819
if (entry->inode == local->loc.inode)
823
/* Getting assertion here, need to investigate
825
GF_ASSERT (&entry->list != &entries->list);
828
ret = quota_add_parent(&parents, entry->d_name, parent->gfid);
835
local->ancestry_cbk(&parents, local->loc.inode, 0, 0, local->ancestry_data);
839
local->ancestry_cbk(NULL, NULL, -1, op_errno, local->ancestry_data);
842
STACK_DESTROY(frame->root);
843
quota_local_cleanup(local);
845
if (parent != NULL) {
850
if (!list_empty(&parents)) {
851
list_for_each_entry_safe(dentry, tmp, &parents, next)
853
__quota_dentry_free(dentry);
861
quota_build_ancestry(inode_t *inode, quota_ancestry_built_t ancestry_cbk,
865
quota_local_t *local = NULL;
866
call_frame_t *new_frame = NULL;
867
int op_errno = ENOMEM;
869
xlator_t *this = NULL;
870
dict_t *xdata_req = NULL;
874
xdata_req = dict_new();
875
if (xdata_req == NULL)
878
fd = fd_anonymous(inode);
882
new_frame = create_frame(this, this->ctx->pool);
883
if (new_frame == NULL)
886
local = quota_local_new();
890
new_frame->root->uid = new_frame->root->gid = 0;
891
new_frame->local = local;
892
local->ancestry_cbk = ancestry_cbk;
893
local->ancestry_data = data;
894
local->loc.inode = inode_ref(inode);
896
op_ret = dict_set_int8(xdata_req, QUOTA_LIMIT_KEY, 1);
902
op_ret = dict_set_int8(xdata_req, QUOTA_LIMIT_OBJECTS_KEY, 1);
908
op_ret = dict_set_int8(xdata_req, GET_ANCESTRY_DENTRY_KEY, 1);
914
/* This would ask posix layer to construct dentry chain till root
915
* We don't need to do a opendir, we can use the anonymous fd
916
* here for the readidrp.
917
* avoiding opendir also reduces the window size where another FOP
918
* can be executed before completion of build ancestry
920
STACK_WIND(new_frame, quota_build_ancestry_cbk, FIRST_CHILD(this),
921
FIRST_CHILD(this)->fops->readdirp, fd, 0, 0, xdata_req);
930
dict_unref(xdata_req);
933
ancestry_cbk(NULL, NULL, -1, op_errno, data);
936
local = new_frame->local;
937
new_frame->local = NULL;
938
STACK_DESTROY(new_frame->root);
942
quota_local_cleanup(local);
949
quota_validate(call_frame_t *frame, inode_t *inode, xlator_t *this,
950
fop_lookup_cbk_t cbk_fn)
952
quota_local_t *local = NULL;
954
dict_t *xdata = NULL;
955
quota_priv_t *priv = NULL;
957
local = frame->local;
958
priv = this->private;
962
loc_wipe(&local->validate_loc);
964
ret = quota_inode_loc_fill(inode, &local->validate_loc);
966
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENFORCEMENT_FAILED,
967
"cannot fill loc for inode (gfid:%s), hence "
968
"aborting quota-checks and continuing with fop",
969
uuid_utoa(inode->gfid));
972
UNLOCK(&local->lock);
985
ret = dict_set_int8(xdata, QUOTA_SIZE_KEY, 1);
987
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
993
ret = dict_set_str(xdata, "volume-uuid", priv->volume_uuid);
995
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
1001
ret = quota_enforcer_lookup(frame, this, xdata, cbk_fn);
1016
quota_check_limit_continuation(struct list_head *parents, inode_t *inode,
1017
int32_t op_ret, int32_t op_errno, void *data)
1019
call_frame_t *frame = NULL;
1020
xlator_t *this = NULL;
1021
quota_local_t *local = NULL;
1022
quota_local_t *par_local = NULL;
1023
quota_dentry_t *entry = NULL;
1024
inode_t *parent = NULL;
1025
int parent_count = 0;
1028
local = frame->local;
1031
if (local->par_frame)
1032
par_local = local->par_frame->local;
1036
if ((op_ret < 0) || list_empty(parents)) {
1038
gf_msg(this->name, GF_LOG_WARNING, EIO, Q_MSG_ANCESTRY_BUILD_FAILED,
1039
"Couldn't build ancestry for inode (gfid:%s). "
1040
"Without knowing ancestors till root, quota"
1041
"cannot be enforced. "
1042
"Hence, failing fop with EIO",
1043
uuid_utoa(inode->gfid));
1047
quota_handle_validate_error(frame, -1, op_errno);
1051
list_for_each_entry(entry, parents, next)
1056
LOCK(&par_local->lock);
1058
par_local->link_count += (parent_count - 1);
1060
UNLOCK(&par_local->lock);
1062
if (local->par_frame) {
1063
list_for_each_entry(entry, parents, next)
1065
parent = inode_find(inode->table, entry->par);
1066
quota_check_limit(frame, parent, this);
1067
inode_unref(parent);
1070
list_for_each_entry(entry, parents, next)
1072
parent = do_quota_check_limit(frame, inode, this, entry, _gf_true);
1074
inode_unref(parent);
1076
quota_link_count_decrement(frame);
1085
quota_check_object_limit(call_frame_t *frame, quota_inode_ctx_t *ctx,
1086
quota_priv_t *priv, inode_t *_inode, xlator_t *this,
1087
int32_t *op_errno, int just_validated,
1088
quota_local_t *local, gf_boolean_t *skip_check)
1091
uint64_t timeout = 0;
1092
char need_validate = 0;
1093
gf_boolean_t hard_limit_exceeded = 0;
1094
int64_t object_aggr_count = 0;
1102
if (ctx != NULL && (ctx->object_hard_lim > 0 || ctx->object_soft_lim)) {
1105
timeout = priv->soft_timeout;
1107
object_aggr_count = ctx->file_count + ctx->dir_count + 1;
1108
if (((ctx->object_soft_lim >= 0) &&
1109
(object_aggr_count) > ctx->object_soft_lim)) {
1110
timeout = priv->hard_timeout;
1113
if (!just_validated && quota_timeout(ctx->validate_time, timeout)) {
1115
} else if ((object_aggr_count) > ctx->object_hard_lim) {
1116
hard_limit_exceeded = 1;
1121
if (need_validate && *skip_check != _gf_true) {
1122
*skip_check = _gf_true;
1123
ret = quota_validate(frame, _inode, this, quota_validate_cbk);
1126
*skip_check = _gf_false;
1131
if (hard_limit_exceeded) {
1133
local->op_errno = EDQUOT;
1138
/*We log usage only if quota limit is configured on
1141
quota_log_usage(this, ctx, _inode, 0);
1151
quota_check_size_limit(call_frame_t *frame, quota_inode_ctx_t *ctx,
1152
quota_priv_t *priv, inode_t *_inode, xlator_t *this,
1153
int32_t *op_errno, int just_validated, int64_t delta,
1154
quota_local_t *local, gf_boolean_t *skip_check)
1157
uint64_t timeout = 0;
1158
char need_validate = 0;
1159
gf_boolean_t hard_limit_exceeded = 0;
1160
int64_t space_available = 0;
1161
int64_t wouldbe_size = 0;
1169
if (ctx != NULL && (ctx->hard_lim > 0 || ctx->soft_lim > 0)) {
1170
wouldbe_size = ctx->size + delta;
1174
timeout = priv->soft_timeout;
1176
if ((ctx->soft_lim >= 0) && (wouldbe_size > ctx->soft_lim)) {
1177
timeout = priv->hard_timeout;
1180
if (!just_validated && quota_timeout(ctx->validate_time, timeout)) {
1182
} else if (wouldbe_size >= ctx->hard_lim) {
1183
hard_limit_exceeded = 1;
1188
if (need_validate && *skip_check != _gf_true) {
1189
*skip_check = _gf_true;
1190
ret = quota_validate(frame, _inode, this, quota_validate_cbk);
1193
*skip_check = _gf_false;
1198
if (hard_limit_exceeded) {
1200
local->op_errno = EDQUOT;
1202
space_available = ctx->hard_lim - ctx->size;
1204
if (space_available < 0)
1205
space_available = 0;
1207
if ((local->space_available < 0) ||
1208
(local->space_available > space_available)) {
1209
local->space_available = space_available;
1212
if (space_available == 0) {
1218
/* We log usage only if quota limit is configured on
1220
quota_log_usage(this, ctx, _inode, delta);
1229
quota_check_limit(call_frame_t *frame, inode_t *inode, xlator_t *this)
1231
int32_t ret = -1, op_errno = EINVAL;
1232
inode_t *_inode = NULL, *parent = NULL;
1233
quota_inode_ctx_t *ctx = NULL;
1234
quota_priv_t *priv = NULL;
1235
quota_local_t *local = NULL;
1236
quota_local_t *par_local = NULL;
1237
char just_validated = 0;
1239
int8_t object_delta = 0;
1241
gf_boolean_t skip_check = _gf_false;
1243
GF_VALIDATE_OR_GOTO("quota", this, err);
1244
GF_VALIDATE_OR_GOTO(this->name, frame, err);
1245
GF_VALIDATE_OR_GOTO(this->name, inode, err);
1247
local = frame->local;
1248
GF_VALIDATE_OR_GOTO(this->name, local, err);
1250
if (local->par_frame) {
1251
par_local = local->par_frame->local;
1252
GF_VALIDATE_OR_GOTO(this->name, par_local, err);
1257
delta = par_local->delta;
1258
object_delta = par_local->object_delta;
1260
GF_VALIDATE_OR_GOTO(this->name, par_local->stub, err);
1261
/* Allow all the trusted clients
1262
* Don't block the gluster internal processes like rebalance, gsyncd,
1263
* self heal etc from the disk quotas.
1265
* Method: Allow all the clients with PID negative. This is by the
1266
* assumption that any kernel assigned pid doesn't have the negative
1269
if (0 > frame->root->pid) {
1271
quota_link_count_decrement(frame);
1275
priv = this->private;
1277
inode_ctx_get(inode, this, &value);
1278
ctx = (quota_inode_ctx_t *)(unsigned long)value;
1280
_inode = inode_ref(inode);
1284
just_validated = local->just_validated;
1285
local->just_validated = 0;
1287
UNLOCK(&local->lock);
1290
/* In a rename operation, enforce should be stopped at common
1292
if (!gf_uuid_is_null(par_local->common_ancestor) &&
1293
!gf_uuid_compare(_inode->gfid, par_local->common_ancestor)) {
1294
quota_link_count_decrement(frame);
1298
if (object_delta <= 0)
1299
goto skip_check_object_limit;
1301
ret = quota_check_object_limit(frame, ctx, priv, _inode, this,
1302
&op_errno, just_validated, par_local,
1304
if (skip_check == _gf_true)
1308
if (op_errno != EDQUOT)
1309
gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_ENFORCEMENT_FAILED,
1311
"check quota object limit");
1315
skip_check_object_limit:
1316
ret = quota_check_size_limit(frame, ctx, priv, _inode, this, &op_errno,
1317
just_validated, delta, par_local,
1319
if (skip_check == _gf_true)
1323
if (op_errno != EDQUOT)
1324
gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_ENFORCEMENT_FAILED,
1326
"check quota size limit");
1330
if (__is_root_gfid(_inode->gfid)) {
1331
quota_link_count_decrement(frame);
1335
parent = inode_parent(_inode, 0, NULL);
1336
if (parent == NULL) {
1337
ret = quota_build_ancestry(_inode, quota_check_limit_continuation,
1347
inode_unref(_inode);
1352
inode_ctx_get(_inode, this, &value);
1353
ctx = (quota_inode_ctx_t *)(unsigned long)value;
1357
if (_inode != NULL) {
1358
inode_unref(_inode);
1364
quota_handle_validate_error(frame, -1, op_errno);
1366
inode_unref(_inode);
1371
do_quota_check_limit(call_frame_t *frame, inode_t *inode, xlator_t *this,
1372
quota_dentry_t *dentry, gf_boolean_t force)
1375
inode_t *parent = NULL;
1376
call_frame_t *new_frame = NULL;
1377
quota_local_t *new_local = NULL;
1379
parent = inode_parent(inode, dentry->par, dentry->name);
1380
if (parent == NULL) {
1382
parent = inode_find(inode->table, dentry->par);
1389
new_frame = copy_frame(frame);
1390
if (new_frame == NULL)
1393
new_local = quota_local_new();
1394
if (new_local == NULL)
1397
new_frame->local = new_local;
1398
new_local->par_frame = frame;
1400
quota_check_limit(new_frame, parent, this);
1406
/* Caller should decrement link_count, in case parent is
1409
quota_handle_validate_error(frame, -1, ENOMEM);
1413
new_frame->local = NULL;
1414
STACK_DESTROY(new_frame->root);
1422
quota_get_limits(xlator_t *this, dict_t *dict, int64_t *hard_lim,
1423
int64_t *soft_lim, int64_t *object_hard_limit,
1424
int64_t *object_soft_limit)
1426
quota_limits_t *limit = NULL;
1427
quota_limits_t *object_limit = NULL;
1428
quota_priv_t *priv = NULL;
1429
int64_t soft_lim_percent = 0;
1430
int64_t *ptr = NULL;
1433
if ((this == NULL) || (dict == NULL) || (hard_lim == NULL) ||
1437
priv = this->private;
1439
ret = dict_get_bin(dict, QUOTA_LIMIT_KEY, (void **)&ptr);
1440
limit = (quota_limits_t *)ptr;
1443
*hard_lim = be64toh(limit->hl);
1444
soft_lim_percent = be64toh(limit->sl);
1447
if (soft_lim_percent < 0) {
1448
soft_lim_percent = priv->default_soft_lim;
1451
if ((*hard_lim > 0) && (soft_lim_percent > 0)) {
1452
*soft_lim = (soft_lim_percent * (*hard_lim)) / 100;
1455
ret = dict_get_bin(dict, QUOTA_LIMIT_OBJECTS_KEY, (void **)&ptr);
1458
object_limit = (quota_limits_t *)ptr;
1461
*object_hard_limit = be64toh(object_limit->hl);
1462
soft_lim_percent = be64toh(object_limit->sl);
1465
if (soft_lim_percent < 0) {
1466
soft_lim_percent = priv->default_soft_lim;
1469
if ((*object_hard_limit > 0) && (soft_lim_percent > 0)) {
1470
*object_soft_limit = (soft_lim_percent * (*object_hard_limit)) / 100;
1478
quota_fill_inodectx(xlator_t *this, inode_t *inode, dict_t *dict, loc_t *loc,
1479
struct iatt *buf, int32_t *op_errno)
1483
quota_inode_ctx_t *ctx = NULL;
1484
quota_dentry_t *dentry = NULL;
1486
int64_t hard_lim = 0;
1487
int64_t soft_lim = 0;
1488
int64_t object_hard_limit = 0;
1489
int64_t object_soft_limit = 0;
1491
quota_get_limits(this, dict, &hard_lim, &soft_lim, &object_hard_limit,
1492
&object_soft_limit);
1494
inode_ctx_get(inode, this, &value);
1495
ctx = (quota_inode_ctx_t *)(unsigned long)value;
1497
if ((((ctx == NULL) || (ctx->hard_lim == hard_lim)) && (hard_lim < 0) &&
1498
!QUOTA_REG_OR_LNK_FILE(buf->ia_type))) {
1503
ret = quota_inode_ctx_get(inode, this, &ctx, 1);
1504
if ((ret == -1) || (ctx == NULL)) {
1505
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_INODE_CTX_GET_FAILED,
1506
"cannot create quota "
1507
"context in inode(gfid:%s)",
1508
uuid_utoa(inode->gfid));
1516
ctx->hard_lim = hard_lim;
1517
ctx->soft_lim = soft_lim;
1518
ctx->object_hard_lim = object_hard_limit;
1519
ctx->object_soft_lim = object_soft_limit;
1523
if (!QUOTA_REG_OR_LNK_FILE(buf->ia_type)) {
1527
/* do nothing if it is a nameless lookup */
1528
if (loc->name == NULL || !loc->parent)
1531
list_for_each_entry(dentry, &ctx->parents, next)
1533
if ((strcmp(dentry->name, loc->name) == 0) &&
1534
(gf_uuid_compare(loc->parent->gfid, dentry->par) == 0)) {
1541
dentry = __quota_dentry_new(ctx, (char *)loc->name,
1543
if (dentry == NULL) {
1545
gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
1547
"cannot create a new dentry (par:%"
1548
- PRId64", name:%s) for inode(ino:%"
1549
- PRId64", gfid:%s)",
1550
- uuid_utoa (local->loc.inode->gfid));
1566
* return _gf_true if enforcement is needed and _gf_false otherwise
1569
should_quota_enforce(xlator_t *this, dict_t *dict, glusterfs_fop_t fop)
1573
ret = dict_check_flag(dict, GF_INTERNAL_CTX_KEY, GF_DHT_HEAL_DIR);
1575
if (fop == GF_FOP_MKDIR && ret == DICT_FLAG_SET) {
1577
} else if (ret == -ENOENT) {
1578
gf_msg(this->name, GF_LOG_DEBUG, EINVAL, Q_MSG_INTERNAL_FOP_KEY_MISSING,
1579
"No internal fop context present");
1587
quota_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
1588
int32_t op_ret, int32_t op_errno, inode_t *inode,
1589
struct iatt *buf, dict_t *dict, struct iatt *postparent)
1591
quota_local_t *local = NULL;
1592
inode_t *this_inode = NULL;
1594
local = frame->local;
1595
frame->local = NULL;
1597
if (op_ret >= 0 && inode) {
1598
this_inode = inode_ref(inode);
1600
op_ret = quota_fill_inodectx(this, inode, dict, &local->loc, buf,
1606
QUOTA_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, buf, dict,
1609
if (op_ret < 0 || this_inode == NULL || gf_uuid_is_null(this_inode->gfid))
1612
check_ancestory_2(this, local, this_inode);
1616
inode_unref(this_inode);
1618
quota_local_cleanup(local);
1624
quota_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
1626
quota_priv_t *priv = NULL;
1628
quota_local_t *local = NULL;
1630
priv = this->private;
1632
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
1634
xattr_req = xattr_req ? dict_ref(xattr_req) : dict_new();
1638
local = quota_local_new();
1639
if (local == NULL) {
1643
frame->local = local;
1644
loc_copy(&local->loc, loc);
1646
ret = dict_set_int8(xattr_req, QUOTA_LIMIT_KEY, 1);
1648
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
1649
"dict set of key for "
1650
"hard-limit failed");
1654
ret = dict_set_int8(xattr_req, QUOTA_LIMIT_OBJECTS_KEY, 1);
1656
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
1657
"dict set of key for quota object limit failed");
1661
STACK_WIND(frame, quota_lookup_cbk, FIRST_CHILD(this),
1662
FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
1668
dict_unref(xattr_req);
1671
QUOTA_STACK_UNWIND(lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL);
1677
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup,
1683
quota_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
1684
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
1685
struct iatt *postbuf, dict_t *xdata)
1688
uint64_t ctx_int = 0;
1689
quota_inode_ctx_t *ctx = NULL;
1690
quota_local_t *local = NULL;
1692
local = frame->local;
1694
if ((op_ret < 0) || (local == NULL) || (postbuf == NULL)) {
1698
ret = inode_ctx_get(local->loc.inode, this, &ctx_int);
1700
gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED,
1701
"%s: failed to get the "
1707
ctx = (quota_inode_ctx_t *)(unsigned long)ctx_int;
1710
gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED,
1711
"quota context not set in %s (gfid:%s)", local->loc.path,
1712
uuid_utoa(local->loc.inode->gfid));
1718
ctx->buf = *postbuf;
1723
QUOTA_STACK_UNWIND(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
1728
static int gf_quota_enforcer_log;
1731
quota_writev_helper(call_frame_t *frame, xlator_t *this, fd_t *fd,
1732
struct iovec *vector, int32_t count, off_t off,
1733
uint32_t flags, struct iobref *iobref, dict_t *xdata)
1735
quota_local_t *local = NULL;
1736
int32_t op_errno = EINVAL;
1737
struct iovec *new_vector = NULL;
1738
int32_t new_count = 0;
1740
local = frame->local;
1742
GF_VALIDATE_OR_GOTO("quota", local, unwind);
1744
if (local->op_ret == -1) {
1745
op_errno = local->op_errno;
1747
if ((op_errno == EDQUOT) && (local->space_available > 0)) {
1748
new_count = iov_subset(vector, count, 0, local->space_available,
1750
if (new_count < 0) {
1752
local->op_errno = ENOMEM;
1756
vector = new_vector;
1758
} else if (op_errno == ENOENT || op_errno == ESTALE) {
1759
/* We may get ENOENT/ESTALE in case of below scenario
1760
* fd = open file.txt
1763
* Here build_ancestry can fail as the file is removed.
1764
* For now ignore ENOENT/ESTALE with writes on active fd
1765
* We need to re-visit this code once we understand
1766
* how other file-system behave in this scenario
1768
gf_msg_debug(this->name, 0,
1769
"quota enforcer failed "
1770
"with ENOENT/ESTALE on %s, cannot check "
1771
"quota limits and allowing writes",
1772
uuid_utoa(fd->inode->gfid));
1773
} else if ((op_errno == EINVAL) &&
1774
!inode_parent(local->loc.inode, 0, NULL)) {
1775
/* We may get INVAL with parent == NULL,
1776
* in case of below scenario
1778
* 2. glusterfsd stop/start
1779
* 3. nameless lookup
1781
* Here build_ancestry can fail as the file's pgfid
1783
* For now ignore EINVAL with writes on active fd
1784
* untils the pgfid is created at name lookup
1786
GF_LOG_OCCASIONALLY(gf_quota_enforcer_log, this->name,
1788
"Quota cannot be enforced as "
1789
"parent is not available and writes are being "
1790
"allowed without checking whether they are "
1791
"within quota limits. This can happen if Quota "
1792
"crawl is not complete. If crawl has been "
1793
"completed, please file a bug.");
1799
STACK_WIND(frame, quota_writev_cbk, FIRST_CHILD(this),
1800
FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags,
1803
if (new_vector != NULL)
1804
GF_FREE(new_vector);
1809
QUOTA_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL);
1814
quota_writev(call_frame_t *frame, xlator_t *this, fd_t *fd,
1815
struct iovec *vector, int32_t count, off_t off, uint32_t flags,
1816
struct iobref *iobref, dict_t *xdata)
1818
quota_priv_t *priv = NULL;
1819
int32_t op_errno = EINVAL;
1820
int32_t parents = 0;
1821
int32_t fail_count = 0;
1823
quota_local_t *local = NULL;
1824
quota_inode_ctx_t *ctx = NULL;
1825
quota_dentry_t *dentry = NULL, *tmp = NULL;
1826
call_stub_t *stub = NULL;
1827
struct list_head head;
1828
inode_t *par_inode = NULL;
1830
priv = this->private;
1832
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
1834
INIT_LIST_HEAD(&head);
1837
GF_VALIDATE_OR_GOTO("quota", this, unwind);
1838
GF_VALIDATE_OR_GOTO(this->name, fd, unwind);
1840
local = quota_local_new();
1841
if (local == NULL) {
1845
frame->local = local;
1846
local->loc.inode = inode_ref(fd->inode);
1848
(void)quota_inode_ctx_get(fd->inode, this, &ctx, 0);
1850
gf_msg_debug(this->name, 0,
1851
"quota context is NULL on inode"
1852
" (%s). If quota is not enabled recently and "
1853
"crawler has finished crawling, its an error",
1854
uuid_utoa(fd->inode->gfid));
1857
stub = fop_writev_stub(frame, quota_writev_helper, fd, vector, count, off,
1858
flags, iobref, xdata);
1864
priv = this->private;
1865
GF_VALIDATE_OR_GOTO(this->name, priv, unwind);
1867
parents = quota_add_parents_from_ctx(ctx, &head);
1868
if (parents == -1) {
1873
size = iov_length(vector, count);
1877
local->delta = size;
1878
local->object_delta = 0;
1879
local->link_count = (parents != 0) ? parents : 1;
1882
UNLOCK(&local->lock);
1885
/* nameless lookup on this inode, allow quota to reconstruct
1886
* ancestry as part of check_limit.
1888
quota_check_limit(frame, fd->inode, this);
1890
list_for_each_entry_safe(dentry, tmp, &head, next)
1892
par_inode = do_quota_check_limit(frame, fd->inode, this, dentry,
1894
if (par_inode == NULL) {
1896
/* remove stale entry from inode ctx */
1897
quota_dentry_del(ctx, dentry->name, dentry->par);
1902
inode_unref(par_inode);
1904
__quota_dentry_free(dentry);
1910
local->link_count++;
1912
UNLOCK(&local->lock);
1913
quota_check_limit(frame, fd->inode, this);
1916
while (fail_count != 0) {
1917
quota_link_count_decrement(frame);
1925
QUOTA_STACK_UNWIND(writev, frame, -1, op_errno, NULL, NULL, NULL);
1929
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev,
1930
fd, vector, count, off, flags, iobref, xdata);
1935
quota_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
1936
int32_t op_ret, int32_t op_errno, inode_t *inode,
1937
struct iatt *buf, struct iatt *preparent,
1938
struct iatt *postparent, dict_t *xdata)
1940
QUOTA_STACK_UNWIND(mkdir, frame, op_ret, op_errno, inode, buf, preparent,
1946
quota_mkdir_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
1947
mode_t umask, dict_t *xdata)
1949
quota_local_t *local = NULL;
1950
int32_t op_errno = EINVAL;
1952
local = frame->local;
1954
GF_VALIDATE_OR_GOTO("quota", local, unwind);
1956
op_errno = local->op_errno;
1958
if (local->op_ret == -1) {
1962
STACK_WIND(frame, quota_mkdir_cbk, FIRST_CHILD(this),
1963
FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata);
1968
QUOTA_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL,
1974
quota_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
1975
mode_t umask, dict_t *xdata)
1977
quota_priv_t *priv = NULL;
1978
int32_t ret = 0, op_errno = 0;
1979
quota_local_t *local = NULL;
1980
call_stub_t *stub = NULL;
1982
priv = this->private;
1983
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
1985
if (!should_quota_enforce(this, xdata, GF_FOP_MKDIR)) {
1986
gf_msg(this->name, GF_LOG_DEBUG, 0, Q_MSG_ENFORCEMENT_SKIPPED,
1987
"Enforcement has been skipped(internal fop).");
1991
local = quota_local_new();
1992
if (local == NULL) {
1997
frame->local = local;
1999
ret = loc_copy(&local->loc, loc);
2002
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2007
stub = fop_mkdir_stub(frame, quota_mkdir_helper, loc, mode, umask, xdata);
2017
local->object_delta = 1;
2018
local->link_count = 1;
2020
UNLOCK(&local->lock);
2022
quota_check_limit(frame, loc->parent, this);
2026
QUOTA_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL,
2032
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir,
2033
loc, mode, umask, xdata);
2039
quota_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
2040
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
2041
struct iatt *buf, struct iatt *preparent,
2042
struct iatt *postparent, dict_t *xdata)
2045
quota_local_t *local = NULL;
2046
quota_inode_ctx_t *ctx = NULL;
2047
quota_dentry_t *dentry = NULL;
2049
local = frame->local;
2054
ret = quota_inode_ctx_get(inode, this, &ctx, 1);
2055
if ((ret == -1) || (ctx == NULL)) {
2056
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_INODE_CTX_GET_FAILED,
2057
"cannot create quota "
2058
"context in inode(gfid:%s)",
2059
uuid_utoa(inode->gfid));
2069
dentry = __quota_dentry_new(ctx, (char *)local->loc.name,
2070
local->loc.parent->gfid);
2071
if (dentry == NULL) {
2072
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2073
"cannot create a new dentry "
2074
"(name:%s) for inode(gfid:%s)",
2075
local->loc.name, uuid_utoa(local->loc.inode->gfid));
2085
QUOTA_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, buf,
2086
preparent, postparent, xdata);
2091
quota_create_helper(call_frame_t *frame, xlator_t *this, loc_t *loc,
2092
int32_t flags, mode_t mode, mode_t umask, fd_t *fd,
2095
quota_local_t *local = NULL;
2096
int32_t op_errno = EINVAL;
2098
local = frame->local;
2100
GF_VALIDATE_OR_GOTO("quota", local, unwind);
2102
if (local->op_ret == -1) {
2103
op_errno = local->op_errno;
2107
STACK_WIND(frame, quota_create_cbk, FIRST_CHILD(this),
2108
FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd,
2113
QUOTA_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL,
2119
quota_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
2120
mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
2122
quota_priv_t *priv = NULL;
2124
quota_local_t *local = NULL;
2125
int32_t op_errno = 0;
2126
call_stub_t *stub = NULL;
2128
priv = this->private;
2130
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
2131
QUOTA_WIND_FOR_INTERNAL_FOP(xdata, off);
2133
local = quota_local_new();
2134
if (local == NULL) {
2139
frame->local = local;
2141
ret = loc_copy(&local->loc, loc);
2143
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2149
stub = fop_create_stub(frame, quota_create_helper, loc, flags, mode, umask,
2157
local->link_count = 1;
2160
local->object_delta = 1;
2162
UNLOCK(&local->lock);
2164
quota_check_limit(frame, loc->parent, this);
2167
QUOTA_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL,
2173
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create,
2174
loc, flags, mode, umask, fd, xdata);
2179
quota_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
2180
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
2181
struct iatt *postparent, dict_t *xdata)
2183
quota_local_t *local = NULL;
2184
quota_inode_ctx_t *ctx = NULL;
2191
local = (quota_local_t *)frame->local;
2193
inode_ctx_get(local->loc.inode, this, &value);
2194
ctx = (quota_inode_ctx_t *)(unsigned long)value;
2197
gf_msg(this->name, GF_LOG_INFO, EINVAL, Q_MSG_INODE_CTX_GET_FAILED,
2198
"quota context not set inode (gfid:%s)",
2199
uuid_utoa(local->loc.gfid));
2203
quota_dentry_del(ctx, local->loc.name, local->loc.parent->gfid);
2206
QUOTA_STACK_UNWIND(unlink, frame, op_ret, op_errno, preparent, postparent,
2212
quota_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
2215
quota_priv_t *priv = NULL;
2217
quota_local_t *local = NULL;
2219
priv = this->private;
2221
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
2223
local = quota_local_new();
2224
if (local == NULL) {
2228
frame->local = local;
2230
ret = loc_copy(&local->loc, loc);
2232
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2237
STACK_WIND(frame, quota_unlink_cbk, FIRST_CHILD(this),
2238
FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
2244
QUOTA_STACK_UNWIND(unlink, frame, -1, 0, NULL, NULL, NULL);
2250
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink,
2256
quota_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
2257
int32_t op_ret, int32_t op_errno, inode_t *inode,
2258
struct iatt *buf, struct iatt *preparent,
2259
struct iatt *postparent, dict_t *xdata)
2262
quota_local_t *local = NULL;
2263
quota_inode_ctx_t *ctx = NULL;
2264
quota_dentry_t *dentry = NULL;
2271
local = (quota_local_t *)frame->local;
2273
ret = quota_inode_ctx_get(inode, this, &ctx, 0);
2274
if ((ret == -1) || (ctx == NULL)) {
2275
gf_msg_debug(this->name, 0,
2276
"quota context is NULL on inode"
2277
" (%s). If quota is not enabled recently and "
2278
"crawler has finished crawling, its an error",
2279
uuid_utoa(inode->gfid));
2285
list_for_each_entry(dentry, &ctx->parents, next)
2287
if ((strcmp(dentry->name, local->loc.name) == 0) &&
2288
(gf_uuid_compare(local->loc.parent->gfid, dentry->par) == 0)) {
2291
gf_msg_debug(this->name, 0,
2293
" linked (name:%s) for inode "
2294
"(gfid:%s) is already present "
2295
"in inode-dentry-list",
2296
dentry->name, uuid_utoa(local->loc.inode->gfid));
2302
dentry = __quota_dentry_new(ctx, (char *)local->loc.name,
2303
local->loc.parent->gfid);
2304
if (dentry == NULL) {
2305
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2306
"cannot create a new dentry (name:%s)"
2307
"for inode(gfid:%s)",
2308
local->loc.name, uuid_utoa(local->loc.inode->gfid));
2321
QUOTA_STACK_UNWIND(link, frame, op_ret, op_errno, inode, buf, preparent,
2328
quota_link_helper(call_frame_t *frame, xlator_t *this, loc_t *oldloc,
2329
loc_t *newloc, dict_t *xdata)
2331
quota_local_t *local = NULL;
2332
int32_t op_errno = EINVAL;
2334
local = frame->local;
2336
GF_VALIDATE_OR_GOTO("quota", local, unwind);
2338
op_errno = local->op_errno;
2340
if (local->op_ret == -1) {
2344
STACK_WIND(frame, quota_link_cbk, FIRST_CHILD(this),
2345
FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
2349
QUOTA_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
2354
quota_link_continue(call_frame_t *frame)
2357
int32_t op_errno = EIO;
2358
quota_local_t *local = NULL;
2359
uuid_t common_ancestor = {0};
2360
xlator_t *this = NULL;
2361
quota_inode_ctx_t *ctx = NULL;
2362
inode_t *src_parent = NULL;
2363
inode_t *dst_parent = NULL;
2365
local = frame->local;
2368
if (local->op_ret < 0) {
2369
op_errno = local->op_errno;
2373
if (local->xdata && dict_get(local->xdata, GLUSTERFS_INTERNAL_FOP_KEY)) {
2374
/* Treat link as rename, crawl upwards only till common ancestor
2376
ret = quota_find_common_ancestor(
2377
local->oldloc.inode, local->newloc.parent, &common_ancestor);
2378
if (ret < 0 || gf_uuid_is_null(common_ancestor)) {
2379
gf_msg(this->name, GF_LOG_ERROR, ESTALE,
2380
Q_MSG_ANCESTRY_BUILD_FAILED,
2382
"common_ancestor for %s and %s",
2383
local->oldloc.path, local->newloc.path);
2388
/* Treat link as a new file.
2389
* TODO: Currently marker accounts twice for the links created
2390
* across directories.
2391
* This needs re-visit if marker accounts only once
2392
* for the links created across directories
2394
if (local->oldloc.parent)
2395
src_parent = inode_ref(local->oldloc.parent);
2397
src_parent = inode_parent(local->oldloc.inode, 0, NULL);
2398
dst_parent = local->newloc.parent;
2400
/* No need to check quota limit if src and dst parents are same
2402
if (src_parent == dst_parent ||
2403
gf_uuid_compare(src_parent->gfid, dst_parent->gfid) == 0) {
2404
inode_unref(src_parent);
2408
inode_unref(src_parent);
2411
quota_inode_ctx_get(local->oldloc.inode, this, &ctx, 0);
2413
gf_msg_debug(this->name, 0,
2414
"quota context is NULL on inode"
2415
" (%s). If quota is not enabled recently and "
2416
"crawler has finished crawling, its an error",
2417
uuid_utoa(local->oldloc.inode->gfid));
2422
local->link_count = 1;
2423
local->delta = (ctx != NULL) ? ctx->buf.ia_blocks * 512 : 0;
2424
local->object_delta = 1;
2425
gf_uuid_copy(local->common_ancestor, common_ancestor);
2427
UNLOCK(&local->lock);
2429
quota_check_limit(frame, local->newloc.parent, this);
2433
QUOTA_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
2437
STACK_WIND(frame, quota_link_cbk, FIRST_CHILD(this),
2438
FIRST_CHILD(this)->fops->link, &(local->oldloc),
2439
&(local->newloc), local->xdata);
2444
quota_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
2447
quota_priv_t *priv = NULL;
2449
int32_t op_errno = ENOMEM;
2450
quota_local_t *local = NULL;
2451
call_stub_t *stub = NULL;
2453
priv = this->private;
2455
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
2457
local = quota_local_new();
2458
if (local == NULL) {
2462
frame->local = (void *)local;
2465
local->xdata = dict_ref(xdata);
2467
ret = loc_copy(&local->loc, newloc);
2469
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2474
ret = loc_copy(&local->oldloc, oldloc);
2476
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2481
ret = loc_copy(&local->newloc, newloc);
2483
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2488
/* No need to check quota limit if src and dst parents are same */
2489
if (oldloc->parent && newloc->parent &&
2490
!gf_uuid_compare(oldloc->parent->gfid, newloc->parent->gfid)) {
2491
gf_msg_debug(this->name, GF_LOG_DEBUG,
2492
"link %s -> %s are "
2493
"in the same directory, so skip check limit",
2494
oldloc->path, newloc->path);
2498
stub = fop_link_stub(frame, quota_link_helper, oldloc, newloc, xdata);
2505
local->link_count = 2;
2506
local->fop_continue_cbk = quota_link_continue;
2509
UNLOCK(&local->lock);
2511
check_ancestory(frame, newloc->parent);
2513
/* source parent can be NULL, so do check_ancestry on a file */
2515
check_ancestory(frame, oldloc->parent);
2517
check_ancestory(frame, oldloc->inode);
2522
QUOTA_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
2526
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link,
2527
oldloc, newloc, xdata);
2531
STACK_WIND(frame, quota_link_cbk, FIRST_CHILD(this),
2532
FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
2537
quota_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
2538
int32_t op_ret, int32_t op_errno, struct iatt *buf,
2539
struct iatt *preoldparent, struct iatt *postoldparent,
2540
struct iatt *prenewparent, struct iatt *postnewparent,
2544
quota_local_t *local = NULL;
2545
quota_inode_ctx_t *ctx = NULL;
2546
quota_dentry_t *old_dentry = NULL, *dentry = NULL;
2547
char new_dentry_found = 0;
2553
local = frame->local;
2555
GF_VALIDATE_OR_GOTO("quota", local, out);
2557
if (!QUOTA_REG_OR_LNK_FILE(local->oldloc.inode->ia_type))
2560
ret = quota_inode_ctx_get(local->oldloc.inode, this, &ctx, 0);
2561
if ((ret == -1) || (ctx == NULL)) {
2562
gf_msg_debug(this->name, 0,
2563
"quota context is NULL on inode"
2564
" (%s). If quota is not enabled recently and "
2565
"crawler has finished crawling, its an error",
2566
uuid_utoa(local->oldloc.inode->gfid));
2573
list_for_each_entry(dentry, &ctx->parents, next)
2575
if ((strcmp(dentry->name, local->oldloc.name) == 0) &&
2576
(gf_uuid_compare(local->oldloc.parent->gfid, dentry->par) ==
2578
old_dentry = dentry;
2579
} else if ((strcmp(dentry->name, local->newloc.name) == 0) &&
2580
(gf_uuid_compare(local->newloc.parent->gfid,
2581
dentry->par) == 0)) {
2582
new_dentry_found = 1;
2583
gf_msg_debug(this->name, 0,
2585
"linked (name:%s) for inode (gfid:%s) "
2586
"is in inode-dentry-list",
2588
uuid_utoa(local->oldloc.inode->gfid));
2591
if (old_dentry && new_dentry_found)
2595
if (old_dentry != NULL) {
2596
__quota_dentry_free(old_dentry);
2598
gf_msg_debug(this->name, 0,
2599
"dentry corresponding"
2600
"the path just renamed (name:%s) is not"
2602
local->oldloc.name);
2605
if (!new_dentry_found) {
2606
dentry = __quota_dentry_new(ctx, (char *)local->newloc.name,
2607
local->newloc.parent->gfid);
2608
if (dentry == NULL) {
2609
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2610
"cannot create a new dentry (name:%s) "
2611
"for inode(gfid:%s)",
2613
uuid_utoa(local->newloc.inode->gfid));
2626
QUOTA_STACK_UNWIND(rename, frame, op_ret, op_errno, buf, preoldparent,
2627
postoldparent, prenewparent, postnewparent, xdata);
2633
quota_rename_helper(call_frame_t *frame, xlator_t *this, loc_t *oldloc,
2634
loc_t *newloc, dict_t *xdata)
2636
quota_local_t *local = NULL;
2637
int32_t op_errno = EINVAL;
2639
local = frame->local;
2641
GF_VALIDATE_OR_GOTO("quota", local, unwind);
2643
op_errno = local->op_errno;
2645
if (local->op_ret == -1) {
2649
STACK_WIND(frame, quota_rename_cbk, FIRST_CHILD(this),
2650
FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata);
2655
QUOTA_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL,
2661
quota_rename_get_size_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
2662
int32_t op_ret, int32_t op_errno, inode_t *inode,
2663
struct iatt *buf, dict_t *xdata,
2664
struct iatt *postparent)
2666
quota_local_t *local = NULL;
2671
GF_VALIDATE_OR_GOTO_WITH_ERROR("quota", this, out, op_errno, EINVAL);
2672
GF_VALIDATE_OR_GOTO_WITH_ERROR(this->name, xdata, out, op_errno, EINVAL);
2673
local = frame->local;
2675
local->link_count = 1;
2680
ret = dict_get_bin(xdata, QUOTA_SIZE_KEY, (void **)&size);
2682
gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_SIZE_KEY_MISSING,
2683
"size key not present in dict");
2687
local->delta = be64toh(*size);
2688
local->object_delta = 1;
2689
quota_check_limit(frame, local->newloc.parent, this);
2693
quota_handle_validate_error(frame, -1, op_errno);
2698
quota_rename_continue(call_frame_t *frame)
2701
int32_t op_errno = EIO;
2702
quota_local_t *local = NULL;
2703
uuid_t common_ancestor = {0};
2704
xlator_t *this = NULL;
2705
quota_inode_ctx_t *ctx = NULL;
2707
local = frame->local;
2710
if (local->op_ret < 0) {
2711
op_errno = local->op_errno;
2715
ret = quota_find_common_ancestor(local->oldloc.parent, local->newloc.parent,
2717
if (ret < 0 || gf_uuid_is_null(common_ancestor)) {
2718
gf_msg(this->name, GF_LOG_ERROR, ESTALE, Q_MSG_ANCESTRY_BUILD_FAILED,
2720
"common_ancestor for %s and %s",
2721
local->oldloc.path, local->newloc.path);
2728
local->link_count = 1;
2729
gf_uuid_copy(local->common_ancestor, common_ancestor);
2731
UNLOCK(&local->lock);
2733
if (QUOTA_REG_OR_LNK_FILE(local->oldloc.inode->ia_type)) {
2734
ret = quota_inode_ctx_get(local->oldloc.inode, this, &ctx, 0);
2736
gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED,
2737
"quota context not set in inode (gfid:%s), "
2738
"considering file size as zero while enforcing "
2739
"quota on new ancestry",
2740
uuid_utoa(local->oldloc.inode->gfid));
2743
local->object_delta = 1;
2745
/* FIXME: We need to account for the size occupied by
2746
* this inode on the target directory. To avoid double
2747
* accounting, we need to modify enforcer to perform
2748
* quota_check_limit only up till the least common
2749
* ancestor directory inode*/
2751
/* FIXME: The following code assumes that regular files
2752
* and link files are present, in their entirety, in a
2753
* single brick. This *assumption is invalid in the
2756
local->delta = ctx->buf.ia_blocks * 512;
2757
local->object_delta = 1;
2760
} else if (IA_ISDIR(local->oldloc.inode->ia_type)) {
2761
ret = quota_validate(frame, local->oldloc.inode, this,
2762
quota_rename_get_size_cbk);
2771
quota_check_limit(frame, local->newloc.parent, this);
2775
QUOTA_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL,
2781
quota_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
2784
quota_priv_t *priv = NULL;
2786
int32_t op_errno = ENOMEM;
2787
quota_local_t *local = NULL;
2788
call_stub_t *stub = NULL;
2790
priv = this->private;
2792
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
2794
local = quota_local_new();
2795
if (local == NULL) {
2799
frame->local = local;
2801
ret = loc_copy(&local->oldloc, oldloc);
2803
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2808
ret = loc_copy(&local->newloc, newloc);
2810
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2815
/* No need to check quota limit if src and dst parents are same */
2816
if (oldloc->parent && newloc->parent &&
2817
!gf_uuid_compare(oldloc->parent->gfid, newloc->parent->gfid)) {
2818
gf_msg_debug(this->name, 0,
2819
"rename %s -> %s are "
2820
"in the same directory, so skip check limit",
2821
oldloc->path, newloc->path);
2825
stub = fop_rename_stub(frame, quota_rename_helper, oldloc, newloc, xdata);
2832
/* link_count here tell how many check_ancestry should be done
2833
* before continuing the FOP
2835
local->link_count = 2;
2837
local->fop_continue_cbk = quota_rename_continue;
2839
UNLOCK(&local->lock);
2841
check_ancestory(frame, newloc->parent);
2842
check_ancestory(frame, oldloc->parent);
2846
QUOTA_STACK_UNWIND(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL,
2851
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename,
2852
oldloc, newloc, xdata);
2856
STACK_WIND(frame, quota_rename_cbk, FIRST_CHILD(this),
2857
FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata);
2862
quota_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
2863
int32_t op_ret, int32_t op_errno, inode_t *inode,
2864
struct iatt *buf, struct iatt *preparent,
2865
struct iatt *postparent, dict_t *xdata)
2867
quota_local_t *local = NULL;
2868
quota_inode_ctx_t *ctx = NULL;
2869
quota_dentry_t *dentry = NULL;
2876
local = frame->local;
2878
ret = quota_inode_ctx_get(local->loc.inode, this, &ctx, 1);
2879
if ((ret == -1) || (ctx == NULL)) {
2880
gf_msg_debug(this->name, 0,
2881
"quota context is NULL on inode"
2882
" (%s). If quota is not enabled recently and "
2883
"crawler has finished crawling, its an error",
2884
uuid_utoa(local->loc.inode->gfid));
2893
dentry = __quota_dentry_new(ctx, (char *)local->loc.name,
2894
local->loc.parent->gfid);
2895
if (dentry == NULL) {
2896
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2898
"a new dentry (name:%s) for inode(gfid:%s)",
2899
local->loc.name, uuid_utoa(local->loc.inode->gfid));
2907
QUOTA_STACK_UNWIND(symlink, frame, op_ret, op_errno, inode, buf, preparent,
2914
quota_symlink_helper(call_frame_t *frame, xlator_t *this, const char *linkpath,
2915
loc_t *loc, mode_t umask, dict_t *xdata)
2917
quota_local_t *local = NULL;
2918
int32_t op_errno = EINVAL;
2920
local = frame->local;
2922
GF_VALIDATE_OR_GOTO("quota", local, unwind);
2924
if (local->op_ret == -1) {
2925
op_errno = local->op_errno;
2929
STACK_WIND(frame, quota_symlink_cbk, FIRST_CHILD(this),
2930
FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata);
2934
QUOTA_STACK_UNWIND(symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL,
2940
quota_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath,
2941
loc_t *loc, mode_t umask, dict_t *xdata)
2943
quota_priv_t *priv = NULL;
2945
int32_t op_errno = ENOMEM;
2946
quota_local_t *local = NULL;
2947
call_stub_t *stub = NULL;
2949
priv = this->private;
2951
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
2953
local = quota_local_new();
2954
if (local == NULL) {
2958
frame->local = local;
2960
ret = loc_copy(&local->loc, loc);
2962
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
2967
stub = fop_symlink_stub(frame, quota_symlink_helper, linkpath, loc, umask,
2976
local->delta = strlen(linkpath);
2977
local->object_delta = 1;
2978
local->link_count = 1;
2980
UNLOCK(&local->lock);
2982
quota_check_limit(frame, loc->parent, this);
2986
QUOTA_STACK_UNWIND(symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL,
2992
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink,
2993
linkpath, loc, umask, xdata);
2998
quota_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
2999
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
3000
struct iatt *postbuf, dict_t *xdata)
3002
quota_local_t *local = NULL;
3003
quota_inode_ctx_t *ctx = NULL;
3009
local = frame->local;
3011
GF_VALIDATE_OR_GOTO("quota", local, out);
3013
quota_inode_ctx_get(local->loc.inode, this, &ctx, 0);
3015
gf_msg_debug(this->name, 0,
3016
"quota context is NULL on inode"
3017
" (%s). If quota is not enabled recently and "
3018
"crawler has finished crawling, its an error",
3019
uuid_utoa(local->loc.inode->gfid));
3025
ctx->buf = *postbuf;
3030
QUOTA_STACK_UNWIND(truncate, frame, op_ret, op_errno, prebuf, postbuf,
3036
quota_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
3039
quota_priv_t *priv = NULL;
3041
quota_local_t *local = NULL;
3043
priv = this->private;
3045
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3047
local = quota_local_new();
3048
if (local == NULL) {
3052
frame->local = local;
3054
ret = loc_copy(&local->loc, loc);
3056
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
3061
STACK_WIND(frame, quota_truncate_cbk, FIRST_CHILD(this),
3062
FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
3067
QUOTA_STACK_UNWIND(truncate, frame, -1, ENOMEM, NULL, NULL, NULL);
3071
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate,
3072
loc, offset, xdata);
3077
quota_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
3078
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
3079
struct iatt *postbuf, dict_t *xdata)
3081
quota_local_t *local = NULL;
3082
quota_inode_ctx_t *ctx = NULL;
3088
local = frame->local;
3090
GF_VALIDATE_OR_GOTO("quota", local, out);
3092
quota_inode_ctx_get(local->loc.inode, this, &ctx, 0);
3094
gf_msg_debug(this->name, 0,
3095
"quota context is NULL on inode"
3096
" (%s). If quota is not enabled recently and "
3097
"crawler has finished crawling, its an error",
3098
uuid_utoa(local->loc.inode->gfid));
3104
ctx->buf = *postbuf;
3109
QUOTA_STACK_UNWIND(ftruncate, frame, op_ret, op_errno, prebuf, postbuf,
3115
quota_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
3118
quota_priv_t *priv = NULL;
3119
quota_local_t *local = NULL;
3121
priv = this->private;
3123
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3125
local = quota_local_new();
3129
frame->local = local;
3131
local->loc.inode = inode_ref(fd->inode);
3133
STACK_WIND(frame, quota_ftruncate_cbk, FIRST_CHILD(this),
3134
FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
3138
QUOTA_STACK_UNWIND(ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL);
3143
STACK_WIND_TAIL(frame, FIRST_CHILD(this),
3144
FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
3149
quota_send_dir_limit_to_cli(call_frame_t *frame, xlator_t *this, inode_t *inode,
3150
const char *name, const int namelen)
3153
int dir_limit_len = 0;
3154
char dir_limit[64] = {
3157
dict_t *dict = NULL;
3158
quota_inode_ctx_t *ctx = NULL;
3160
quota_priv_t *priv = NULL;
3162
priv = this->private;
3163
if (!priv->is_quota_on) {
3164
dir_limit_len = snprintf(dir_limit, sizeof(dir_limit),
3165
"Quota is disabled please turn on");
3169
ret = inode_ctx_get(inode, this, &value);
3173
ctx = (quota_inode_ctx_t *)(unsigned long)value;
3174
dir_limit_len = snprintf(dir_limit, sizeof(dir_limit),
3175
"%" PRId64 ",%" PRId64, ctx->size, ctx->hard_lim);
3184
ret = dict_set_nstrn(dict, (char *)name, namelen, dir_limit, dir_limit_len);
3188
gf_msg_debug(this->name, 0, "str = %s", dir_limit);
3190
QUOTA_STACK_UNWIND(getxattr, frame, 0, 0, dict, NULL);
3201
quota_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
3206
if (name && strcasecmp(name, "trusted.limit.list") == 0) {
3207
ret = quota_send_dir_limit_to_cli(frame, this, fd->inode,
3208
"trusted.limit.list",
3209
SLEN("trusted.limit.list"));
3215
STACK_WIND(frame, default_fgetxattr_cbk, FIRST_CHILD(this),
3216
FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata);
3221
quota_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
3222
const char *name, dict_t *xdata)
3226
if ((name != NULL) && strcasecmp(name, "trusted.limit.list") == 0) {
3227
ret = quota_send_dir_limit_to_cli(frame, this, loc->inode,
3228
"trusted.limit.list",
3229
SLEN("trusted.limit.list"));
3234
STACK_WIND(frame, default_getxattr_cbk, FIRST_CHILD(this),
3235
FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
3240
quota_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
3241
int32_t op_ret, int32_t op_errno, struct iatt *buf,
3244
quota_local_t *local = NULL;
3245
quota_inode_ctx_t *ctx = NULL;
3251
local = frame->local;
3253
GF_VALIDATE_OR_GOTO("quota", local, out);
3255
quota_inode_ctx_get(local->loc.inode, this, &ctx, 0);
3257
if (!IA_ISDIR(buf->ia_type)) {
3258
gf_msg_debug(this->name, 0,
3259
"quota context is NULL on inode"
3260
" (%s). If quota is not enabled recently and "
3261
"crawler has finished crawling, its an error",
3262
uuid_utoa(local->loc.inode->gfid));
3275
QUOTA_STACK_UNWIND(stat, frame, op_ret, op_errno, buf, xdata);
3280
quota_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
3282
quota_priv_t *priv = NULL;
3283
quota_local_t *local = NULL;
3286
priv = this->private;
3288
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3290
local = quota_local_new();
3291
if (local == NULL) {
3295
frame->local = local;
3296
ret = loc_copy(&local->loc, loc);
3298
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
3303
STACK_WIND(frame, quota_stat_cbk, FIRST_CHILD(this),
3304
FIRST_CHILD(this)->fops->stat, loc, xdata);
3308
QUOTA_STACK_UNWIND(stat, frame, -1, ENOMEM, NULL, NULL);
3312
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat,
3318
quota_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
3319
int32_t op_ret, int32_t op_errno, struct iatt *buf,
3322
quota_local_t *local = NULL;
3323
quota_inode_ctx_t *ctx = NULL;
3329
local = frame->local;
3331
GF_VALIDATE_OR_GOTO("quota", local, out);
3333
quota_inode_ctx_get(local->loc.inode, this, &ctx, 0);
3335
if (!IA_ISDIR(buf->ia_type)) {
3336
gf_msg_debug(this->name, 0,
3337
"quota context is NULL on inode"
3338
" (%s). If quota is not enabled recently and "
3339
"crawler has finished crawling, its an error",
3340
uuid_utoa(local->loc.inode->gfid));
3353
QUOTA_STACK_UNWIND(fstat, frame, op_ret, op_errno, buf, xdata);
3358
quota_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
3360
quota_priv_t *priv = NULL;
3361
quota_local_t *local = NULL;
3363
priv = this->private;
3365
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3367
local = quota_local_new();
3368
if (local == NULL) {
3372
frame->local = local;
3374
local->loc.inode = inode_ref(fd->inode);
3376
STACK_WIND(frame, quota_fstat_cbk, FIRST_CHILD(this),
3377
FIRST_CHILD(this)->fops->fstat, fd, xdata);
3381
QUOTA_STACK_UNWIND(fstat, frame, -1, ENOMEM, NULL, NULL);
3385
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat,
3391
quota_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
3392
int32_t op_ret, int32_t op_errno, const char *path,
3393
struct iatt *buf, dict_t *xdata)
3395
quota_local_t *local = NULL;
3396
quota_inode_ctx_t *ctx = NULL;
3402
local = frame->local;
3404
GF_VALIDATE_OR_GOTO("quota", local, out);
3406
quota_inode_ctx_get(local->loc.inode, this, &ctx, 0);
3408
gf_msg_debug(this->name, 0,
3409
"quota context is NULL on inode"
3410
" (%s). If quota is not enabled recently and "
3411
"crawler has finished crawling, its an error",
3412
uuid_utoa(local->loc.inode->gfid));
3423
QUOTA_STACK_UNWIND(readlink, frame, op_ret, op_errno, path, buf, xdata);
3428
quota_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
3431
quota_priv_t *priv = NULL;
3432
quota_local_t *local = NULL;
3435
priv = this->private;
3437
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3439
local = quota_local_new();
3440
if (local == NULL) {
3444
frame->local = local;
3446
ret = loc_copy(&local->loc, loc);
3448
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
3453
STACK_WIND(frame, quota_readlink_cbk, FIRST_CHILD(this),
3454
FIRST_CHILD(this)->fops->readlink, loc, size, xdata);
3458
QUOTA_STACK_UNWIND(readlink, frame, -1, ENOMEM, NULL, NULL, NULL);
3462
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readlink,
3468
quota_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
3469
int32_t op_ret, int32_t op_errno, struct iovec *vector,
3470
int32_t count, struct iatt *buf, struct iobref *iobref,
3473
quota_local_t *local = NULL;
3474
quota_inode_ctx_t *ctx = NULL;
3480
local = frame->local;
3482
GF_VALIDATE_OR_GOTO("quota", local, out);
3484
quota_inode_ctx_get(local->loc.inode, this, &ctx, 0);
3486
gf_msg_debug(this->name, 0,
3487
"quota context is NULL on inode"
3488
" (%s). If quota is not enabled recently and "
3489
"crawler has finished crawling, its an error",
3490
uuid_utoa(local->loc.inode->gfid));
3501
QUOTA_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, buf,
3507
quota_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
3508
off_t offset, uint32_t flags, dict_t *xdata)
3510
quota_priv_t *priv = NULL;
3511
quota_local_t *local = NULL;
3513
priv = this->private;
3515
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3517
local = quota_local_new();
3518
if (local == NULL) {
3522
frame->local = local;
3524
local->loc.inode = inode_ref(fd->inode);
3526
STACK_WIND(frame, quota_readv_cbk, FIRST_CHILD(this),
3527
FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata);
3531
QUOTA_STACK_UNWIND(readv, frame, -1, ENOMEM, NULL, -1, NULL, NULL, NULL);
3535
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv,
3536
fd, size, offset, flags, xdata);
3541
quota_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
3542
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
3543
struct iatt *postbuf, dict_t *xdata)
3545
quota_local_t *local = NULL;
3546
quota_inode_ctx_t *ctx = NULL;
3552
local = frame->local;
3554
GF_VALIDATE_OR_GOTO("quota", local, out);
3556
quota_inode_ctx_get(local->loc.inode, this, &ctx, 0);
3558
gf_msg_debug(this->name, 0,
3559
"quota context is NULL on inode"
3560
" (%s). If quota is not enabled recently and "
3561
"crawler has finished crawling, its an error",
3562
uuid_utoa(local->loc.inode->gfid));
3568
ctx->buf = *postbuf;
3573
QUOTA_STACK_UNWIND(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata);
3578
quota_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
3581
quota_priv_t *priv = NULL;
3582
quota_local_t *local = NULL;
3584
priv = this->private;
3586
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3588
local = quota_local_new();
3589
if (local == NULL) {
3593
local->loc.inode = inode_ref(fd->inode);
3595
frame->local = local;
3597
STACK_WIND(frame, quota_fsync_cbk, FIRST_CHILD(this),
3598
FIRST_CHILD(this)->fops->fsync, fd, flags, xdata);
3602
QUOTA_STACK_UNWIND(fsync, frame, -1, ENOMEM, NULL, NULL, NULL);
3606
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync,
3612
quota_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
3613
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
3614
struct iatt *statpost, dict_t *xdata)
3616
quota_local_t *local = NULL;
3617
quota_inode_ctx_t *ctx = NULL;
3623
local = frame->local;
3625
GF_VALIDATE_OR_GOTO("quota", local, out);
3627
quota_inode_ctx_get(local->loc.inode, this, &ctx, 0);
3629
if (!IA_ISDIR(statpost->ia_type)) {
3630
gf_msg_debug(this->name, 0,
3631
"quota context is NULL on inode"
3632
" (%s). If quota is not enabled recently and "
3633
"crawler has finished crawling, its an error",
3634
uuid_utoa(local->loc.inode->gfid));
3642
ctx->buf = *statpost;
3647
QUOTA_STACK_UNWIND(setattr, frame, op_ret, op_errno, statpre, statpost,
3653
quota_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
3654
struct iatt *stbuf, int32_t valid, dict_t *xdata)
3656
quota_priv_t *priv = NULL;
3657
quota_local_t *local = NULL;
3660
priv = this->private;
3662
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3664
local = quota_local_new();
3665
if (local == NULL) {
3669
frame->local = local;
3671
ret = loc_copy(&local->loc, loc);
3673
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
3678
STACK_WIND(frame, quota_setattr_cbk, FIRST_CHILD(this),
3679
FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata);
3683
QUOTA_STACK_UNWIND(setattr, frame, -1, ENOMEM, NULL, NULL, NULL);
3687
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr,
3688
loc, stbuf, valid, xdata);
3693
quota_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
3694
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
3695
struct iatt *statpost, dict_t *xdata)
3697
quota_local_t *local = NULL;
3698
quota_inode_ctx_t *ctx = NULL;
3704
local = frame->local;
3706
GF_VALIDATE_OR_GOTO("quota", local, out);
3708
quota_inode_ctx_get(local->loc.inode, this, &ctx, 0);
3710
if (!IA_ISDIR(statpost->ia_type)) {
3711
gf_msg_debug(this->name, 0,
3712
"quota context is NULL on inode"
3713
" (%s). If quota is not enabled recently and "
3714
"crawler has finished crawling, its an error",
3715
uuid_utoa(local->loc.inode->gfid));
3723
ctx->buf = *statpost;
3728
QUOTA_STACK_UNWIND(fsetattr, frame, op_ret, op_errno, statpre, statpost,
3734
quota_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd,
3735
struct iatt *stbuf, int32_t valid, dict_t *xdata)
3737
quota_priv_t *priv = NULL;
3738
quota_local_t *local = NULL;
3740
priv = this->private;
3742
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3744
local = quota_local_new();
3745
if (local == NULL) {
3749
frame->local = local;
3751
local->loc.inode = inode_ref(fd->inode);
3753
STACK_WIND(frame, quota_fsetattr_cbk, FIRST_CHILD(this),
3754
FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata);
3758
QUOTA_STACK_UNWIND(fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL);
3762
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr,
3763
fd, stbuf, valid, xdata);
3768
quota_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
3769
int32_t op_ret, int32_t op_errno, inode_t *inode,
3770
struct iatt *buf, struct iatt *preparent,
3771
struct iatt *postparent, dict_t *xdata)
3774
quota_local_t *local = NULL;
3775
quota_inode_ctx_t *ctx = NULL;
3776
quota_dentry_t *dentry = NULL;
3778
local = frame->local;
3783
ret = quota_inode_ctx_get(inode, this, &ctx, 1);
3784
if ((ret == -1) || (ctx == NULL)) {
3785
gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED,
3786
"cannot create quota context in "
3788
uuid_utoa(inode->gfid));
3798
dentry = __quota_dentry_new(ctx, (char *)local->loc.name,
3799
local->loc.parent->gfid);
3800
if (dentry == NULL) {
3801
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
3802
"cannot create a new dentry "
3803
"(name:%s) for inode(gfid:%s)",
3804
local->loc.name, uuid_utoa(local->loc.inode->gfid));
3814
QUOTA_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, buf, preparent,
3820
quota_mknod_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
3821
dev_t rdev, mode_t umask, dict_t *xdata)
3823
quota_local_t *local = NULL;
3824
int32_t op_errno = EINVAL;
3826
local = frame->local;
3828
GF_VALIDATE_OR_GOTO("quota", local, unwind);
3830
if (local->op_ret == -1) {
3831
op_errno = local->op_errno;
3835
STACK_WIND(frame, quota_mknod_cbk, FIRST_CHILD(this),
3836
FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata);
3841
QUOTA_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL,
3847
quota_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
3848
dev_t rdev, mode_t umask, dict_t *xdata)
3850
quota_priv_t *priv = NULL;
3852
quota_local_t *local = NULL;
3853
call_stub_t *stub = NULL;
3855
priv = this->private;
3857
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3858
QUOTA_WIND_FOR_INTERNAL_FOP(xdata, off);
3860
local = quota_local_new();
3861
if (local == NULL) {
3865
frame->local = local;
3867
ret = loc_copy(&local->loc, loc);
3869
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
3874
stub = fop_mknod_stub(frame, quota_mknod_helper, loc, mode, rdev, umask,
3882
local->link_count = 1;
3885
local->object_delta = 1;
3887
UNLOCK(&local->lock);
3889
quota_check_limit(frame, loc->parent, this);
3893
QUOTA_STACK_UNWIND(mknod, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL);
3897
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod,
3898
loc, mode, rdev, umask, xdata);
3903
quota_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
3904
int op_ret, int op_errno, dict_t *xdata)
3906
quota_local_t *local = NULL;
3907
quota_inode_ctx_t *ctx = NULL;
3914
local = frame->local;
3918
ret = quota_inode_ctx_get(local->loc.inode, this, &ctx, 1);
3919
if ((ret < 0) || (ctx == NULL)) {
3926
ctx->hard_lim = local->limit.hl;
3927
ctx->soft_lim = local->limit.sl;
3928
ctx->object_hard_lim = local->object_limit.hl;
3929
ctx->object_soft_lim = local->object_limit.sl;
3934
QUOTA_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata);
3939
quota_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
3940
int flags, dict_t *xdata)
3942
quota_priv_t *priv = NULL;
3943
int op_errno = EINVAL;
3945
int64_t hard_lim = -1;
3946
int64_t soft_lim = -1;
3947
int64_t object_hard_limit = -1;
3948
int64_t object_soft_limit = -1;
3949
quota_local_t *local = NULL;
3950
gf_boolean_t internal_fop = _gf_false;
3952
priv = this->private;
3954
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
3956
VALIDATE_OR_GOTO(frame, err);
3957
VALIDATE_OR_GOTO(this, err);
3958
VALIDATE_OR_GOTO(loc, err);
3960
if (xdata && dict_get_sizen(xdata, GLUSTERFS_INTERNAL_FOP_KEY))
3961
internal_fop = _gf_true;
3963
if (frame->root->pid >= 0 && internal_fop == _gf_false) {
3964
GF_IF_INTERNAL_XATTR_GOTO("trusted.glusterfs.quota*", dict, op_errno,
3966
GF_IF_INTERNAL_XATTR_GOTO("trusted.pgfid*", dict, op_errno, err);
3969
quota_get_limits(this, dict, &hard_lim, &soft_lim, &object_hard_limit,
3970
&object_soft_limit);
3972
if (hard_lim > 0 || object_hard_limit > 0) {
3973
local = quota_local_new();
3974
if (local == NULL) {
3978
frame->local = local;
3979
loc_copy(&local->loc, loc);
3983
local->limit.hl = hard_lim;
3984
local->limit.sl = soft_lim;
3987
if (object_hard_limit > 0) {
3988
local->object_limit.hl = object_hard_limit;
3989
local->object_limit.sl = object_soft_limit;
3992
STACK_WIND(frame, quota_setxattr_cbk, FIRST_CHILD(this),
3993
FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata);
3996
QUOTA_STACK_UNWIND(setxattr, frame, op_ret, op_errno, NULL);
4000
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr,
4001
loc, dict, flags, xdata);
4006
quota_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
4007
int op_ret, int op_errno, dict_t *xdata)
4009
quota_inode_ctx_t *ctx = NULL;
4010
quota_local_t *local = NULL;
4015
local = frame->local;
4019
op_ret = quota_inode_ctx_get(local->loc.inode, this, &ctx, 1);
4020
if ((op_ret < 0) || (ctx == NULL)) {
4027
ctx->hard_lim = local->limit.hl;
4028
ctx->soft_lim = local->limit.sl;
4029
ctx->object_hard_lim = local->object_limit.hl;
4030
ctx->object_soft_lim = local->object_limit.sl;
4035
QUOTA_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, xdata);
4040
quota_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
4041
int flags, dict_t *xdata)
4043
quota_priv_t *priv = NULL;
4044
int32_t op_ret = -1;
4045
int32_t op_errno = EINVAL;
4046
quota_local_t *local = NULL;
4047
int64_t hard_lim = -1;
4048
int64_t soft_lim = -1;
4049
int64_t object_hard_limit = -1;
4050
int64_t object_soft_limit = -1;
4052
priv = this->private;
4054
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
4056
VALIDATE_OR_GOTO(frame, err);
4057
VALIDATE_OR_GOTO(this, err);
4058
VALIDATE_OR_GOTO(fd, err);
4060
if (0 <= frame->root->pid) {
4061
GF_IF_INTERNAL_XATTR_GOTO("trusted.glusterfs.quota*", dict, op_errno,
4063
GF_IF_INTERNAL_XATTR_GOTO("trusted.pgfid*", dict, op_errno, err);
4066
quota_get_limits(this, dict, &hard_lim, &soft_lim, &object_hard_limit,
4067
&object_soft_limit);
4069
if (hard_lim > 0 || object_hard_limit > 0) {
4070
local = quota_local_new();
4071
if (local == NULL) {
4075
frame->local = local;
4076
local->loc.inode = inode_ref(fd->inode);
4080
local->limit.hl = hard_lim;
4081
local->limit.sl = soft_lim;
4084
if (object_hard_limit > 0) {
4085
local->object_limit.hl = object_hard_limit;
4086
local->object_limit.sl = object_soft_limit;
4089
STACK_WIND(frame, quota_fsetxattr_cbk, FIRST_CHILD(this),
4090
FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
4093
QUOTA_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, NULL);
4097
STACK_WIND_TAIL(frame, FIRST_CHILD(this),
4098
FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
4103
quota_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
4104
int32_t op_ret, int32_t op_errno, dict_t *xdata)
4106
QUOTA_STACK_UNWIND(removexattr, frame, op_ret, op_errno, xdata);
4111
quota_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
4112
const char *name, dict_t *xdata)
4114
quota_priv_t *priv = NULL;
4115
int32_t op_errno = EINVAL;
4117
priv = this->private;
4119
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
4121
VALIDATE_OR_GOTO(this, err);
4123
/* all quota xattrs can be cleaned up by doing setxattr on special key.
4124
* Hence its ok that we don't allow removexattr on quota keys here.
4126
if (frame->root->pid >= 0) {
4127
GF_IF_NATIVE_XATTR_GOTO("trusted.glusterfs.quota*", name, op_errno,
4129
GF_IF_NATIVE_XATTR_GOTO("trusted.pgfid*", name, op_errno, err);
4132
VALIDATE_OR_GOTO(frame, err);
4133
VALIDATE_OR_GOTO(loc, err);
4135
STACK_WIND(frame, quota_removexattr_cbk, FIRST_CHILD(this),
4136
FIRST_CHILD(this)->fops->removexattr, loc, name, xdata);
4140
QUOTA_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL);
4144
STACK_WIND_TAIL(frame, FIRST_CHILD(this),
4145
FIRST_CHILD(this)->fops->removexattr, loc, name, xdata);
4150
quota_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
4151
int32_t op_ret, int32_t op_errno, dict_t *xdata)
4153
QUOTA_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, xdata);
4158
quota_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd,
4159
const char *name, dict_t *xdata)
4161
quota_priv_t *priv = NULL;
4162
int32_t op_ret = -1;
4163
int32_t op_errno = EINVAL;
4165
priv = this->private;
4167
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
4169
VALIDATE_OR_GOTO(frame, err);
4170
VALIDATE_OR_GOTO(this, err);
4171
VALIDATE_OR_GOTO(fd, err);
4173
if (frame->root->pid >= 0) {
4174
GF_IF_NATIVE_XATTR_GOTO("trusted.glusterfs.quota*", name, op_errno,
4176
GF_IF_NATIVE_XATTR_GOTO("trusted.pgfid*", name, op_errno, err);
4178
STACK_WIND(frame, quota_fremovexattr_cbk, FIRST_CHILD(this),
4179
FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata);
4182
QUOTA_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, NULL);
4186
STACK_WIND_TAIL(frame, FIRST_CHILD(this),
4187
FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata);
4192
quota_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
4193
int32_t op_ret, int32_t op_errno, struct statvfs *buf,
4196
inode_t *inode = NULL;
4201
quota_inode_ctx_t *ctx = NULL;
4206
/* This fop will fail mostly in case of client disconnect,
4207
* which is already logged. Hence, not logging here */
4211
* We should never get here unless quota_statfs (below) sent us a
4212
* cookie, and it would only do so if the value was non-NULL. This
4213
* check is therefore just routine defensive coding.
4216
GF_VALIDATE_OR_GOTO("quota", inode, unwind);
4218
inode_ctx_get(inode, this, &value);
4219
ctx = (quota_inode_ctx_t *)(unsigned long)value;
4220
if (!ctx || ctx->hard_lim <= 0)
4223
{ /* statfs is adjusted in this code block */
4224
usage = (ctx->size) / buf->f_bsize;
4226
blocks = ctx->hard_lim / buf->f_bsize;
4227
buf->f_blocks = blocks;
4229
avail = buf->f_blocks - usage;
4230
avail = max(avail, 0);
4232
buf->f_bfree = avail;
4234
* We have to assume that the total assigned quota
4235
* won't cause us to dip into the reserved space,
4236
* because dealing with the overcommitted cases is
4237
* just too hairy (especially when different bricks
4238
* might be using different reserved percentages and
4241
buf->f_bavail = buf->f_bfree;
4244
xdata = xdata ? dict_ref(xdata) : dict_new();
4248
ret = dict_set_int8(xdata, "quota-deem-statfs", 1);
4250
gf_msg(this->name, GF_LOG_ERROR, ENOMEM, Q_MSG_ENOMEM,
4251
"Dict set failed, deem-statfs option may "
4255
QUOTA_STACK_UNWIND(statfs, frame, op_ret, op_errno, buf, xdata);
4264
quota_statfs_helper(call_frame_t *frame, xlator_t *this, loc_t *loc,
4267
quota_local_t *local = frame->local;
4268
int op_errno = EINVAL;
4270
GF_VALIDATE_OR_GOTO("quota", local, err);
4272
if (-1 == local->op_ret) {
4273
op_errno = local->op_errno;
4277
STACK_WIND_COOKIE(frame, quota_statfs_cbk, local->inode, FIRST_CHILD(this),
4278
FIRST_CHILD(this)->fops->statfs, loc, xdata);
4281
QUOTA_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL);
4287
quota_statfs_validate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
4288
int32_t op_ret, int32_t op_errno, inode_t *inode,
4289
struct iatt *buf, dict_t *xdata,
4290
struct iatt *postparent)
4292
quota_local_t *local = NULL;
4294
quota_inode_ctx_t *ctx = NULL;
4296
quota_meta_t size = {
4300
local = frame->local;
4307
GF_VALIDATE_OR_GOTO_WITH_ERROR("quota", this, resume, op_errno, EINVAL);
4308
GF_VALIDATE_OR_GOTO_WITH_ERROR(this->name, xdata, resume, op_errno, EINVAL);
4310
ret = inode_ctx_get(local->validate_loc.inode, this, &value);
4312
ctx = (quota_inode_ctx_t *)(unsigned long)value;
4313
if ((ret == -1) || (ctx == NULL)) {
4314
gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_INODE_CTX_GET_FAILED,
4315
"quota context is not present in inode (gfid:%s)",
4316
uuid_utoa(local->validate_loc.inode->gfid));
4321
ret = quota_dict_get_meta(xdata, QUOTA_SIZE_KEY, SLEN(QUOTA_SIZE_KEY),
4324
gf_msg(this->name, GF_LOG_WARNING, EINVAL, Q_MSG_SIZE_KEY_MISSING,
4325
"size key not present in "
4332
ctx->size = size.size;
4333
ctx->validate_time = gf_time();
4334
ctx->file_count = size.file_count;
4335
ctx->dir_count = size.dir_count;
4340
local->op_errno = op_errno;
4341
quota_link_count_decrement(frame);
4346
quota_get_limit_dir_continuation(struct list_head *parents, inode_t *inode,
4347
int32_t op_ret, int32_t op_errno, void *data)
4349
call_frame_t *frame = NULL;
4350
xlator_t *this = NULL;
4351
quota_dentry_t *entry = NULL;
4352
inode_t *parent = NULL;
4357
if ((op_ret < 0) || list_empty(parents)) {
4359
gf_msg(this->name, GF_LOG_WARNING, EIO, Q_MSG_ANCESTRY_BUILD_FAILED,
4360
"Couldn't build ancestry for inode (gfid:%s). "
4361
"Without knowing ancestors till root, quota "
4362
"cannot be enforced. "
4363
"Hence, failing fop with EIO",
4364
uuid_utoa(inode->gfid));
4368
quota_handle_validate_error(frame, -1, op_errno);
4372
entry = list_first_entry(parents, quota_dentry_t, next);
4373
parent = inode_find(inode->table, entry->par);
4375
quota_get_limit_dir(frame, parent, this);
4377
inode_unref(parent);
4383
quota_statfs_continue(call_frame_t *frame, xlator_t *this, inode_t *inode)
4385
quota_local_t *local = frame->local;
4390
local->inode = inode_ref(inode);
4392
UNLOCK(&local->lock);
4394
ret = quota_validate(frame, local->inode, this, quota_statfs_validate_cbk);
4396
quota_handle_validate_error(frame, -1, -ret);
4400
quota_get_limit_dir(call_frame_t *frame, inode_t *cur_inode, xlator_t *this)
4402
inode_t *inode = NULL;
4403
inode_t *parent = NULL;
4405
quota_inode_ctx_t *ctx = NULL;
4406
quota_local_t *local = frame->local;
4411
inode = inode_ref(cur_inode);
4414
inode_ctx_get(inode, this, &value);
4417
ctx = (quota_inode_ctx_t *)(unsigned long)value;
4418
if (ctx->hard_lim > 0)
4422
if (__is_root_gfid(inode->gfid))
4425
parent = inode_parent(inode, 0, NULL);
4427
(void)quota_build_ancestry(inode, quota_get_limit_dir_continuation,
4436
quota_statfs_continue(frame, this, inode);
4441
gf_msg_debug(this->name, 0, "No limit set on the inode or it's parents.");
4443
QUOTA_STACK_WIND_TAIL(frame, FIRST_CHILD(this),
4444
FIRST_CHILD(this)->fops->statfs, &local->loc,
4453
quota_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
4457
int8_t ignore_deem_statfs = 0;
4458
quota_priv_t *priv = NULL;
4459
quota_local_t *local = NULL;
4460
call_stub_t *stub = NULL;
4462
priv = this->private;
4465
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
4467
ret = dict_get_int8(xdata, GF_INTERNAL_IGNORE_DEEM_STATFS,
4468
&ignore_deem_statfs);
4471
if (ignore_deem_statfs)
4474
if (priv->consider_statfs && loc->inode) {
4475
local = quota_local_new();
4480
frame->local = local;
4482
ret = loc_copy(&local->loc, loc);
4489
local->xdata = dict_ref(xdata);
4491
stub = fop_statfs_stub(frame, quota_statfs_helper, &local->loc,
4500
local->link_count = 1;
4503
UNLOCK(&local->lock);
4505
quota_get_limit_dir(frame, loc->inode, this);
4511
* We have to make sure that we never get to quota_statfs_cbk
4512
* with a cookie that points to something other than an inode,
4513
* which is exactly what would happen with STACK_UNWIND using
4514
* that as a callback. Therefore, use default_statfs_cbk in
4515
* this case instead.
4517
* Also if the option deem-statfs is not set to "on" don't
4518
* bother calculating quota limit on / in statfs_cbk.
4520
if (priv->consider_statfs)
4521
gf_log(this->name, GF_LOG_ERROR,
4522
"Missing inode, can't adjust for quota");
4525
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs,
4530
QUOTA_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL);
4536
quota_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
4537
int op_ret, int op_errno, gf_dirent_t *entries,
4540
gf_dirent_t *entry = NULL;
4541
quota_local_t *local = NULL;
4549
local = frame->local;
4551
list_for_each_entry(entry, &entries->list, list)
4554
if (entry->inode == NULL || inode_dir_or_parentdir(entry))
4557
gf_uuid_copy(loc.gfid, entry->d_stat.ia_gfid);
4558
loc.inode = inode_ref(entry->inode);
4559
loc.parent = inode_ref(local->loc.inode);
4560
gf_uuid_copy(loc.pargfid, loc.parent->gfid);
4561
loc.name = entry->d_name;
4563
quota_fill_inodectx(this, entry->inode, entry->dict, &loc,
4564
&entry->d_stat, &op_errno);
4570
QUOTA_STACK_UNWIND(readdirp, frame, op_ret, op_errno, entries, xdata);
4576
quota_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
4577
off_t offset, dict_t *dict)
4579
quota_priv_t *priv = NULL;
4581
gf_boolean_t new_dict = _gf_false;
4582
quota_local_t *local = NULL;
4584
priv = this->private;
4586
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
4588
local = quota_local_new();
4590
if (local == NULL) {
4594
frame->local = local;
4596
local->loc.inode = inode_ref(fd->inode);
4600
new_dict = _gf_true;
4604
ret = dict_set_int8(dict, QUOTA_LIMIT_KEY, 1);
4606
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
4607
"dict set of key for hard-limit");
4613
ret = dict_set_int8(dict, QUOTA_LIMIT_OBJECTS_KEY, 1);
4615
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
4616
"dict set of key for hard-limit "
4622
STACK_WIND(frame, quota_readdirp_cbk, FIRST_CHILD(this),
4623
FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict);
4631
STACK_UNWIND_STRICT(readdirp, frame, -1, EINVAL, NULL, NULL);
4640
STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp,
4641
fd, size, offset, dict);
4646
quota_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
4647
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
4648
struct iatt *postbuf, dict_t *xdata)
4651
uint64_t ctx_int = 0;
4652
quota_inode_ctx_t *ctx = NULL;
4653
quota_local_t *local = NULL;
4655
local = frame->local;
4657
if ((op_ret < 0) || (local == NULL)) {
4661
ret = inode_ctx_get(local->loc.inode, this, &ctx_int);
4663
gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED,
4664
"%s: failed to get the context", local->loc.path);
4668
ctx = (quota_inode_ctx_t *)(unsigned long)ctx_int;
4671
gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INODE_CTX_GET_FAILED,
4672
"quota context not set in %s (gfid:%s)", local->loc.path,
4673
uuid_utoa(local->loc.inode->gfid));
4679
ctx->buf = *postbuf;
4684
QUOTA_STACK_UNWIND(fallocate, frame, op_ret, op_errno, prebuf, postbuf,
4691
quota_fallocate_helper(call_frame_t *frame, xlator_t *this, fd_t *fd,
4692
int32_t mode, off_t offset, size_t len, dict_t *xdata)
4694
quota_local_t *local = NULL;
4695
int32_t op_errno = EINVAL;
4697
local = frame->local;
4699
GF_VALIDATE_OR_GOTO("quota", local, unwind);
4701
if (local->op_ret == -1) {
4702
op_errno = local->op_errno;
4703
if (op_errno == ENOENT || op_errno == ESTALE) {
4704
/* We may get ENOENT/ESTALE in case of below scenario
4705
* fd = open file.txt
4708
* Here build_ancestry can fail as the file is removed.
4709
* For now ignore ENOENT/ESTALE on active fd
4710
* We need to re-visit this code once we understand
4711
* how other file-system behave in this scenario
4713
gf_msg_debug(this->name, 0,
4714
"quota enforcer failed "
4715
"with ENOENT/ESTALE on %s, cannot check "
4716
"quota limits and allowing fallocate",
4717
uuid_utoa(fd->inode->gfid));
4723
STACK_WIND(frame, quota_fallocate_cbk, FIRST_CHILD(this),
4724
FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len,
4729
QUOTA_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL);
4734
quota_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
4735
off_t offset, size_t len, dict_t *xdata)
4737
int32_t op_errno = EINVAL;
4738
int32_t parents = 0;
4739
int32_t fail_count = 0;
4740
quota_local_t *local = NULL;
4741
quota_inode_ctx_t *ctx = NULL;
4742
quota_priv_t *priv = NULL;
4743
quota_dentry_t *dentry = NULL;
4744
quota_dentry_t *tmp = NULL;
4745
call_stub_t *stub = NULL;
4746
struct list_head head = {
4749
inode_t *par_inode = NULL;
4751
priv = this->private;
4752
GF_VALIDATE_OR_GOTO(this->name, priv, unwind);
4754
WIND_IF_QUOTAOFF(priv->is_quota_on, off);
4756
INIT_LIST_HEAD(&head);
4759
GF_VALIDATE_OR_GOTO("quota", this, unwind);
4760
GF_VALIDATE_OR_GOTO(this->name, fd, unwind);
4762
local = quota_local_new();
4763
if (local == NULL) {
4767
frame->local = local;
4768
local->loc.inode = inode_ref(fd->inode);
4770
(void)quota_inode_ctx_get(fd->inode, this, &ctx, 0);
4772
gf_msg_debug(this->name, 0,
4773
"quota context is NULL on inode"
4774
" (%s). If quota is not enabled recently and "
4775
"crawler has finished crawling, its an error",
4776
uuid_utoa(local->loc.inode->gfid));
4779
stub = fop_fallocate_stub(frame, quota_fallocate_helper, fd, mode, offset,
4786
priv = this->private;
4787
GF_VALIDATE_OR_GOTO(this->name, priv, unwind);
4789
parents = quota_add_parents_from_ctx(ctx, &head);
4790
if (parents == -1) {
4796
* Note that by using len as the delta we're assuming the range from
4797
* offset to offset+len has not already been allocated. This can result
4798
* in ENOSPC errors attempting to allocate an already allocated range.
4801
local->object_delta = 0;
4803
local->link_count = parents;
4806
local->link_count = 1;
4807
quota_check_limit(frame, fd->inode, this);
4809
list_for_each_entry_safe(dentry, tmp, &head, next)
4811
par_inode = do_quota_check_limit(frame, fd->inode, this, dentry,
4813
if (par_inode == NULL) {
4814
/* remove stale entry from inode_ctx */
4815
quota_dentry_del(ctx, dentry->name, dentry->par);
4819
inode_unref(par_inode);
4821
__quota_dentry_free(dentry);
4827
local->link_count++;
4829
UNLOCK(&local->lock);
4830
quota_check_limit(frame, fd->inode, this);
4833
while (fail_count != 0) {
4834
quota_link_count_decrement(frame);
4842
QUOTA_STACK_UNWIND(fallocate, frame, -1, op_errno, NULL, NULL, NULL);
4846
STACK_WIND_TAIL(frame, FIRST_CHILD(this),
4847
FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len,
4853
quota_log_helper(char **usage_str, int64_t cur_size, inode_t *inode,
4854
char **path, time_t *cur_time)
4856
xlator_t *this = THIS;
4858
if (!usage_str || !inode || !path || !cur_time) {
4859
gf_log(this->name, GF_LOG_ERROR, "Received null argument");
4863
*usage_str = gf_uint64_2human_readable(cur_size);
4865
gf_msg(this->name, GF_LOG_ERROR, ENOMEM, Q_MSG_ENOMEM,
4866
"integer to string conversion failed Reason"
4867
":\"Cannot allocate memory\"");
4869
inode_path(inode, NULL, path);
4871
*path = uuid_utoa(inode->gfid);
4873
*cur_time = gf_time();
4877
* i. Usage crossed soft limit
4878
* ii. Usage above soft limit and alert-time elapsed
4881
quota_log_usage(xlator_t *this, quota_inode_ctx_t *ctx, inode_t *inode,
4884
time_t cur_time = 0;
4885
char *usage_str = NULL;
4887
int64_t cur_size = 0;
4888
quota_priv_t *priv = NULL;
4890
priv = this->private;
4891
cur_size = ctx->size + delta;
4893
if ((ctx->soft_lim <= 0) || cur_size < ctx->soft_lim)
4896
/* Usage crossed/reached soft limit */
4897
if (DID_REACH_LIMIT(ctx->soft_lim, ctx->size, cur_size)) {
4898
quota_log_helper(&usage_str, cur_size, inode, &path, &cur_time);
4900
gf_msg(this->name, GF_LOG_ALERT, 0, Q_MSG_CROSSED_SOFT_LIMIT,
4901
"Usage crossed soft limit: "
4905
gf_event(EVENT_QUOTA_CROSSED_SOFT_LIMIT,
4906
"Usage=%s;volume=%s;"
4908
usage_str, priv->volume_uuid, path);
4910
ctx->prev_log_time = cur_time;
4913
/* Usage is above soft limit */
4914
else if (cur_size > ctx->soft_lim &&
4915
quota_timeout(ctx->prev_log_time, priv->log_timeout)) {
4916
quota_log_helper(&usage_str, cur_size, inode, &path, &cur_time);
4918
gf_msg(this->name, GF_LOG_ALERT, 0, Q_MSG_CROSSED_SOFT_LIMIT,
4919
"Usage is above soft limit: %s used by %s", usage_str, path);
4921
gf_event(EVENT_QUOTA_CROSSED_SOFT_LIMIT,
4922
"Usage=%s;volume=%s;"
4924
usage_str, priv->volume_uuid, path);
4926
ctx->prev_log_time = cur_time;
4937
mem_acct_init(xlator_t *this)
4944
ret = xlator_mem_acct_init(this, gf_quota_mt_end);
4947
gf_msg(this->name, GF_LOG_WARNING, ENOMEM, Q_MSG_ENOMEM,
4948
"Memory accounting init failed");
4956
quota_forget(xlator_t *this, inode_t *inode)
4959
uint64_t ctx_int = 0;
4960
quota_inode_ctx_t *ctx = NULL;
4961
quota_dentry_t *dentry = NULL, *tmp;
4963
ret = inode_ctx_del(inode, this, &ctx_int);
4969
ctx = (quota_inode_ctx_t *)(long)ctx_int;
4973
list_for_each_entry_safe(dentry, tmp, &ctx->parents, next)
4975
__quota_dentry_free(dentry);
4980
LOCK_DESTROY(&ctx->lock);
4988
notify(xlator_t *this, int event, void *data, ...)
4990
quota_priv_t *priv = NULL;
4992
rpc_clnt_t *rpc = NULL;
4993
gf_boolean_t conn_status = _gf_true;
4994
xlator_t *victim = data;
4996
priv = this->private;
4997
if (!priv || !priv->is_quota_on)
5000
if (event == GF_EVENT_PARENT_DOWN) {
5001
rpc = priv->rpc_clnt;
5003
rpc_clnt_disable(rpc);
5004
pthread_mutex_lock(&priv->conn_mutex);
5006
conn_status = priv->conn_status;
5007
while (conn_status) {
5008
(void)pthread_cond_wait(&priv->conn_cond,
5010
conn_status = priv->conn_status;
5013
pthread_mutex_unlock(&priv->conn_mutex);
5014
gf_log(this->name, GF_LOG_INFO,
5015
"Notify GF_EVENT_PARENT_DOWN for brick %s", victim->name);
5020
ret = default_notify(this, event, data);
5028
quota_priv_t *priv = NULL;
5029
rpc_clnt_t *rpc = NULL;
5031
if ((this->children == NULL) || this->children->next) {
5032
gf_msg(this->name, GF_LOG_ERROR, 0, Q_MSG_INVALID_VOLFILE,
5033
"FATAL: quota (%s) not configured with "
5034
"exactly one child",
5039
if (this->parents == NULL) {
5040
gf_msg(this->name, GF_LOG_WARNING, 0, Q_MSG_INVALID_VOLFILE,
5041
"dangling volume. check volfile");
5044
QUOTA_ALLOC_OR_GOTO(priv, quota_priv_t, err);
5046
LOCK_INIT(&priv->lock);
5048
this->private = priv;
5050
GF_OPTION_INIT("deem-statfs", priv->consider_statfs, bool, err);
5051
GF_OPTION_INIT("server-quota", priv->is_quota_on, bool, err);
5052
GF_OPTION_INIT("default-soft-limit", priv->default_soft_lim, percent, err);
5053
GF_OPTION_INIT("soft-timeout", priv->soft_timeout, time, err);
5054
GF_OPTION_INIT("hard-timeout", priv->hard_timeout, time, err);
5055
GF_OPTION_INIT("alert-time", priv->log_timeout, time, err);
5056
GF_OPTION_INIT("volume-uuid", priv->volume_uuid, str, err);
5058
this->local_pool = mem_pool_new(quota_local_t, 64);
5059
if (!this->local_pool) {
5061
gf_msg(this->name, GF_LOG_ERROR, ENOMEM, Q_MSG_ENOMEM,
5062
"failed to create local_t's memory pool");
5066
pthread_mutex_init(&priv->conn_mutex, NULL);
5067
pthread_cond_init(&priv->conn_cond, NULL);
5068
priv->conn_status = _gf_false;
5070
if (priv->is_quota_on) {
5071
rpc = quota_enforcer_init(this, this->options);
5074
gf_msg(this->name, GF_LOG_WARNING, 0,
5075
Q_MSG_QUOTA_ENFORCER_RPC_INIT_FAILED,
5076
"quota enforcer rpc init failed");
5082
priv->rpc_clnt = rpc;
5084
UNLOCK(&priv->lock);
5093
reconfigure(xlator_t *this, dict_t *options)
5096
quota_priv_t *priv = NULL;
5097
gf_boolean_t quota_on = _gf_false;
5098
rpc_clnt_t *rpc = NULL;
5100
priv = this->private;
5102
GF_OPTION_RECONF("deem-statfs", priv->consider_statfs, options, bool, out);
5103
GF_OPTION_RECONF("server-quota", quota_on, options, bool, out);
5104
GF_OPTION_RECONF("default-soft-limit", priv->default_soft_lim, options,
5106
GF_OPTION_RECONF("alert-time", priv->log_timeout, options, time, out);
5107
GF_OPTION_RECONF("soft-timeout", priv->soft_timeout, options, time, out);
5108
GF_OPTION_RECONF("hard-timeout", priv->hard_timeout, options, time, out);
5111
priv->rpc_clnt = quota_enforcer_init(this, this->options);
5112
if (priv->rpc_clnt == NULL) {
5114
gf_msg(this->name, GF_LOG_WARNING, 0,
5115
Q_MSG_QUOTA_ENFORCER_RPC_INIT_FAILED,
5116
"quota enforcer rpc init failed");
5123
rpc = priv->rpc_clnt;
5124
priv->rpc_clnt = NULL;
5126
UNLOCK(&priv->lock);
5129
// Quotad is shutdown when there is no started volume
5130
// which has quota enabled. So, we should disable the
5131
// enforcer client when quota is disabled on a volume,
5132
// to avoid spurious reconnect attempts to a service
5133
// (quotad), that is known to be down.
5134
rpc_clnt_unref(rpc);
5138
priv->is_quota_on = quota_on;
5146
quota_priv_dump(xlator_t *this)
5148
quota_priv_t *priv = NULL;
5153
priv = this->private;
5157
gf_proc_dump_add_section("xlators.features.quota.priv");
5159
ret = TRY_LOCK(&priv->lock);
5163
gf_proc_dump_write("soft-timeout", "%ld", priv->soft_timeout);
5164
gf_proc_dump_write("hard-timeout", "%ld", priv->hard_timeout);
5165
gf_proc_dump_write("alert-time", "%ld", priv->log_timeout);
5166
gf_proc_dump_write("quota-on", "%d", priv->is_quota_on);
5167
gf_proc_dump_write("statfs", "%d", priv->consider_statfs);
5168
gf_proc_dump_write("volume-uuid", "%s", priv->volume_uuid);
5169
gf_proc_dump_write("validation-count", "%" PRIu64,
5170
priv->validation_count);
5172
UNLOCK(&priv->lock);
5181
quota_priv_t *priv = NULL;
5182
rpc_clnt_t *rpc = NULL;
5184
priv = this->private;
5187
rpc = priv->rpc_clnt;
5188
priv->rpc_clnt = NULL;
5190
rpc_clnt_connection_cleanup(&rpc->conn);
5191
rpc_clnt_unref(rpc);
5194
this->private = NULL;
5195
LOCK_DESTROY(&priv->lock);
5196
pthread_mutex_destroy(&priv->conn_mutex);
5197
pthread_cond_destroy(&priv->conn_cond);
5200
if (this->local_pool) {
5201
mem_pool_destroy(this->local_pool);
5202
this->local_pool = NULL;
5207
struct xlator_fops fops = {
5208
.statfs = quota_statfs,
5209
.lookup = quota_lookup,
5210
.writev = quota_writev,
5211
.create = quota_create,
5212
.mkdir = quota_mkdir,
5213
.truncate = quota_truncate,
5214
.ftruncate = quota_ftruncate,
5215
.unlink = quota_unlink,
5216
.symlink = quota_symlink,
5218
.rename = quota_rename,
5219
.getxattr = quota_getxattr,
5220
.fgetxattr = quota_fgetxattr,
5222
.fstat = quota_fstat,
5223
.readlink = quota_readlink,
5224
.readv = quota_readv,
5225
.fsync = quota_fsync,
5226
.setattr = quota_setattr,
5227
.fsetattr = quota_fsetattr,
5228
.mknod = quota_mknod,
5229
.setxattr = quota_setxattr,
5230
.fsetxattr = quota_fsetxattr,
5231
.removexattr = quota_removexattr,
5232
.fremovexattr = quota_fremovexattr,
5233
.readdirp = quota_readdirp,
5234
.fallocate = quota_fallocate,
5237
struct xlator_cbks cbks = {.forget = quota_forget};
5239
struct xlator_dumpops dumpops = {
5240
.priv = quota_priv_dump,
5242
struct volume_options options[] = {
5245
.type = GF_OPTION_TYPE_BOOL,
5246
.default_value = "off",
5247
.description = "enable is the volume option that can be used "
5248
"to turn on quota.",
5250
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
5251
.level = OPT_STATUS_BASIC,
5255
.key = {"deem-statfs"},
5256
.type = GF_OPTION_TYPE_BOOL,
5257
.default_value = "on",
5258
.description = "If set to on, it takes quota limits into"
5259
" consideration while estimating fs size. (df command)"
5260
" (Default is on).",
5262
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
5266
.key = {"server-quota"},
5267
.type = GF_OPTION_TYPE_BOOL,
5268
.default_value = "off",
5269
.description = "Skip the quota enforcement if the feature is"
5270
" not turned on. This is not a user exposed option.",
5271
.flags = OPT_FLAG_NONE,
5274
.key = {"default-soft-limit"},
5275
.type = GF_OPTION_TYPE_PERCENT,
5276
.default_value = "80%",
5278
.description = "Soft limit is expressed as a proportion of hard limit."
5279
" Default-soft-limit is the proportion used when the "
5280
" user does not supply any soft limit value.",
5281
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
5285
.key = {"soft-timeout"},
5286
.type = GF_OPTION_TYPE_TIME,
5289
.default_value = "60",
5290
.description = "quota caches the directory sizes on client. "
5291
"soft-timeout indicates the timeout for the validity of"
5292
" cache before soft-limit has been crossed.",
5294
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
5298
.key = {"hard-timeout"},
5299
.type = GF_OPTION_TYPE_TIME,
5302
.default_value = "5",
5303
.description = "quota caches the directory sizes on client. "
5304
"hard-timeout indicates the timeout for the validity of"
5305
" cache after soft-limit has been crossed.",
5307
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
5310
{.key = {"volume-uuid"},
5311
.type = GF_OPTION_TYPE_STR,
5312
.default_value = "{{ volume.id }}",
5313
.description = "uuid of the volume this brick is part of."},
5315
.key = {"alert-time"},
5316
.type = GF_OPTION_TYPE_TIME,
5319
.default_value = "86400",
5321
.flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC,
5322
.description = "Frequency of limit breach messages in log.",
5327
xlator_api_t xlator_api = {
5331
.reconfigure = reconfigure,
5332
.mem_acct_init = mem_acct_init,
5333
.op_version = {1}, /* Present from the initial version */
5337
.identifier = "quota",
5338
.category = GF_MAINTAINED,