From 3a35e939ec811926f810afd792979f526f8dcce9 Mon Sep 17 00:00:00 2001 From: Venky Shankar Date: Thu, 23 Jan 2014 12:40:09 +0530 Subject: features/gfid-access: fix lookup on .gfid//bname In gfid translator, lookup was not handling the case when the lookup is sent on .gfid//bname. In this case, we flip with fake inode of the parent with the real inode in loc and send it downwards. Change-Id: I639ff1dce10ffc045da419e333d455e208b6a0f0 BUG: 1057881 Signed-off-by: Venky Shankar Reviewed-on: http://review.gluster.org/6795 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- libglusterfs/src/xlator.c | 39 ++++++++++++++++++++++++++ libglusterfs/src/xlator.h | 2 ++ xlators/features/gfid-access/src/gfid-access.c | 17 +++++++++++ 3 files changed, 58 insertions(+) diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 7c8c3cdba..9ce52407f 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -649,6 +649,45 @@ loc_gfid_utoa (loc_t *loc) return uuid_utoa (gfid); } +int +loc_copy_overload_parent (loc_t *dst, loc_t *src, inode_t *parent) +{ + int ret = -1; + + GF_VALIDATE_OR_GOTO ("xlator", dst, err); + GF_VALIDATE_OR_GOTO ("xlator", src, err); + GF_VALIDATE_OR_GOTO ("xlator", parent, err); + + uuid_copy (dst->gfid, src->gfid); + uuid_copy (dst->pargfid, parent->gfid); + + if (src->inode) + dst->inode = inode_ref (src->inode); + + if (parent) + dst->parent = inode_ref (parent); + + if (src->path) { + dst->path = gf_strdup (src->path); + + if (!dst->path) + goto out; + + if (src->name) + dst->name = strrchr (dst->path, '/'); + if (dst->name) + dst->name++; + } + + ret = 0; +out: + if (ret == -1) + loc_wipe (dst); + +err: + return ret; +} + int loc_copy (loc_t *dst, loc_t *src) { diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 2f3bc9d6f..1daa06ec2 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -937,6 +937,8 @@ xlator_t *xlator_search_by_name (xlator_t *any, const char *name); void inode_destroy_notify (inode_t *inode, const char *xlname); int loc_copy (loc_t *dst, loc_t *src); +int loc_copy_overload_parent (loc_t *dst, + loc_t *src, inode_t *parent); #define loc_dup(src, dst) loc_copy(dst, src) void loc_wipe (loc_t *loc); int loc_path (loc_t *loc, const char *bname); diff --git a/xlators/features/gfid-access/src/gfid-access.c b/xlators/features/gfid-access/src/gfid-access.c index 25ef93697..a2bcbb74b 100644 --- a/xlators/features/gfid-access/src/gfid-access.c +++ b/xlators/features/gfid-access/src/gfid-access.c @@ -762,7 +762,24 @@ ga_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) but on gfid-path */ if (!((loc->parent && __is_gfid_access_dir (loc->parent->gfid)) || __is_gfid_access_dir (loc->pargfid))) { + if (!loc->parent) goto wind; + + ret = inode_ctx_get (loc->parent, this, &value); + if (ret) + goto wind; + + inode = (inode_t *) value; + + ret = loc_copy_overload_parent (&tmp_loc, loc, inode); + if (ret) + goto err; + + STACK_WIND (frame, ga_lookup_cbk, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->lookup, &tmp_loc, xdata); + + loc_wipe (&tmp_loc); + return 0; } /* make sure the 'basename' is actually a 'canonical-gfid', -- cgit