diff options
| author | vmallika <vmallika@redhat.com> | 2015-03-19 07:32:33 +0530 | 
|---|---|---|
| committer | Raghavendra Bhat <raghavendra@redhat.com> | 2015-03-25 01:54:43 -0700 | 
| commit | 0799f5f6091c09361fe0bc394fe614ee55d67296 (patch) | |
| tree | be4e6accd113ec08b067a4769535a73f329ee2f4 /xlators | |
| parent | 54a725694c47ce59f700c57424e77f9c13244460 (diff) | |
Quota: Build ancestry in the lookup
This is a backport of http://review.gluster.org/#/c/9478/
> Marker can fail or can account incorrect numbers when it doesn't find a
> ancestry for a inode.
>
> Solution:
> Current build_ancestry is done only on demand in the write/create FOPs
> in quota enforcer.
> It is good to do this in the quota_lookup as well.
>
> Change-Id: I8aaf5b3e05a3ca51e7ab1eaa1b636a90f659a872
> BUG: 1184885
> Signed-off-by: vmallika <vmallika@redhat.com>
> Reviewed-on: http://review.gluster.org/9478
> Tested-by: Gluster Build System <jenkins@build.gluster.com>
> Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Change-Id: I57d3f801996da7194f5290067ff367888994786d
BUG: 1203648
Signed-off-by: vmallika <vmallika@redhat.com>
Reviewed-on: http://review.gluster.org/9943
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/features/marker/src/marker-quota-helper.c | 10 | ||||
| -rw-r--r-- | xlators/features/quota/src/quota.c | 112 | ||||
| -rw-r--r-- | xlators/features/quota/src/quota.h | 1 | 
3 files changed, 113 insertions, 10 deletions
diff --git a/xlators/features/marker/src/marker-quota-helper.c b/xlators/features/marker/src/marker-quota-helper.c index ec0d83316c7..0ad9bf00409 100644 --- a/xlators/features/marker/src/marker-quota-helper.c +++ b/xlators/features/marker/src/marker-quota-helper.c @@ -79,13 +79,19 @@ mq_inode_loc_fill (const char *parent_gfid, inode_t *inode, loc_t *loc)                  parent = inode_find (inode->table,                                       (unsigned char *) parent_gfid); -        if (parent == NULL) +        if (parent == NULL) { +                gf_log ("marker", GF_LOG_ERROR, "parent is NULL for %s", +                        uuid_utoa(inode->gfid));                  goto err; +        }  ignore_parent:          ret = inode_path (inode, NULL, &resolvedpath); -        if (ret < 0) +        if (ret < 0) { +                gf_log ("marker", GF_LOG_ERROR, "failed to resolve path for %s", +                        uuid_utoa(inode->gfid));                  goto err; +        }          ret = mq_loc_fill (loc, inode, parent, resolvedpath);          if (ret < 0) diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index 5aee09d0d59..b4ea013fbcd 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -251,6 +251,86 @@ out:          return;  } +void +check_ancestory_2_cbk (struct list_head *parents, inode_t *inode, +                       int32_t op_ret, int32_t op_errno, void *data) +{ +        inode_t            *this_inode  = NULL; +        quota_inode_ctx_t  *ctx         = NULL; + +        this_inode = data; + +        if (op_ret < 0) +                goto out; + +        if (parents == NULL || list_empty (parents)) { +                gf_log (THIS->name, GF_LOG_WARNING, +                        "Couldn't build ancestry for inode (gfid:%s). " +                        "Without knowing ancestors till root, quota " +                        "cannot be enforced.", +                        uuid_utoa (this_inode->gfid)); +                goto out; +        } + +        quota_inode_ctx_get (this_inode, THIS, &ctx, 0); +        if (ctx) +                ctx->ancestry_built = _gf_true; + +out: +        inode_unref (this_inode); +} + +void +check_ancestory_2 (xlator_t *this, quota_local_t *local, inode_t *inode) +{ +        inode_t            *cur_inode    = NULL; +        inode_t            *parent       = NULL; +        quota_inode_ctx_t  *ctx          = NULL; +        char               *name         = NULL; +        uuid_t              pgfid        = {0}; + +        name = (char *) local->loc.name; +        if (local->loc.parent) { +                uuid_copy (pgfid, local->loc.parent->gfid); +                parent = local->loc.parent; +        } + +        cur_inode = inode_ref (inode); +        while (cur_inode && !__is_root_gfid (cur_inode->gfid)) { +                quota_inode_ctx_get (cur_inode, this, &ctx, 0); +                /* build ancestry is required only on the first lookup, +                 * so stop crawling when the inode_ctx is set for an inode +                 */ +                if (ctx && ctx->ancestry_built) +                        goto setctx; + +                parent = inode_parent (cur_inode, pgfid, name); +                if (!parent) { +                        quota_build_ancestry (cur_inode, check_ancestory_2_cbk, +                                              inode_ref (inode)); +                        goto out; +                } + +                if (name != NULL) { +                        name = NULL; +                        uuid_clear (pgfid); +                } + +                inode_unref (cur_inode); +                cur_inode = parent; +        } + +setctx: +        if (cur_inode && cur_inode != inode) { +                quota_inode_ctx_get (inode, this, &ctx, 0); +                if (ctx) +                        ctx->ancestry_built = _gf_true; +        } +out: +        if (cur_inode) +                inode_unref (cur_inode); +} +  static inline void  quota_link_count_decrement (quota_local_t *local)  { @@ -1059,23 +1139,39 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                    int32_t op_ret, int32_t op_errno, inode_t *inode,                    struct iatt *buf, dict_t *dict, struct iatt *postparent)  { -        quota_local_t *local = NULL; - -        if (op_ret < 0) -                goto unwind; +        quota_local_t      *local        = NULL; +        int32_t             ret          = 0; +        inode_t            *this_inode   = NULL;          local = frame->local; +        frame->local = NULL; -        op_ret = quota_fill_inodectx (this, inode, dict, &local->loc, buf, -                                      &op_errno); +        if (op_ret >= 0 && inode) { +                this_inode = inode_ref (inode); + +                op_ret = quota_fill_inodectx (this, inode, dict, &local->loc, +                                              buf, &op_errno); +                if (op_ret < 0) +                        op_errno = ENOMEM; +        } -unwind:          QUOTA_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, buf,                              dict, postparent); + +        if (op_ret < 0 || this_inode == NULL || uuid_is_null(this_inode->gfid)) +                goto out; + +        check_ancestory_2 (this, local, this_inode); + +out: +        if (this_inode) +                inode_unref (this_inode); + +        quota_local_cleanup (this, local); +          return 0;  } -  int32_t  quota_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,                dict_t *xattr_req) diff --git a/xlators/features/quota/src/quota.h b/xlators/features/quota/src/quota.h index 5a4bcb2b1e0..dd63ac94a3f 100644 --- a/xlators/features/quota/src/quota.h +++ b/xlators/features/quota/src/quota.h @@ -167,6 +167,7 @@ struct quota_inode_ctx {          struct list_head parents;          struct timeval   tv;          struct timeval   prev_log; +        gf_boolean_t     ancestry_built;          gf_lock_t        lock;  };  typedef struct quota_inode_ctx quota_inode_ctx_t;  | 
