diff options
author | Jiffin Tony Thottan <jthottan@redhat.com> | 2017-06-11 07:33:52 +0530 |
---|---|---|
committer | Jeff Darcy <jeff@pl.atyp.us> | 2017-06-20 12:32:20 +0000 |
commit | a052b413242783f39cb3312a6a02bdd025b10f0c (patch) | |
tree | 52339cdf92857bc252360aae3e58c454b51f0c8b /api | |
parent | 475ec9928ef96b63a0bfa859a9ae68709275033c (diff) |
gfapi : Resolve "." and ".." only for named lookups
The patch https://review.gluster.org/#/c/17177 resolves "." and ".."
to corrosponding inodes and names before sending the request to the
backend server. But this will only work if inode and its parent is
linked properly. Incase of nameless lookup(applications like ganesha)
the inode of parent can be NULL(only gfid is send). So this patch will
resolve "." and ".." only if proper parent is available
Change-Id: I4c50258b0d896dabf000a547ab180b57df308a0b
BUG: 1460514
Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>
Reviewed-on: https://review.gluster.org/17502
Smoke: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Poornima G <pgurusid@redhat.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: soumya k <skoduri@redhat.com>
Reviewed-by: Jeff Darcy <jeff@pl.atyp.us>
Diffstat (limited to 'api')
-rw-r--r-- | api/src/glfs-resolve.c | 72 |
1 files changed, 64 insertions, 8 deletions
diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c index 44d013ce0bc..8e91cd71c20 100644 --- a/api/src/glfs-resolve.c +++ b/api/src/glfs-resolve.c @@ -268,6 +268,7 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent, { loc_t loc = {0, }; inode_t *inode = NULL; + inode_t *temp_parent = NULL; int reval = 0; int ret = -1; int glret = -1; @@ -276,14 +277,12 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent, dict_t *xattr_req = NULL; uint64_t ctx_value = LOOKUP_NOT_NEEDED; - loc.name = component; - loc.parent = inode_ref (parent); gf_uuid_copy (loc.pargfid, parent->gfid); - /* At this point we should never have '.' or ".." in path */ if (__is_root_gfid (parent->gfid) && - (strcmp (component, "/") == 0)) { + ((strcmp (component, ".") == 0) || + (strcmp (component, "..") == 0))) { if (!force_lookup) { inode = inode_ref (parent); } else { @@ -293,8 +292,68 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent, } goto found; } + /* * + * if the component name is either "." or "..", it will try to + * resolve that if inode has a proper parent (named lookup). + * + * Below condition works like this + * + * Example 1 : + * Path /out_dir/dir/in_dir/. + * In put values : + * parent = in_dir + * component : "." + * + * Out put values: + * parent : dir + * component : "in_dir" + * + * Example 2 : + * Path /out_dir/dir/in_dir/.. + * In put values : + * parent = in_dir + * component : ".." + * + * Out put values: + * parent : output_dir + * component : "dir" + * + * Incase of nameless lookup, both "." and ".." retained + */ + + if (strcmp (component, ".") == 0) { + loc.inode = inode_ref (parent); + temp_parent = inode_parent (loc.inode, 0, 0); + if (temp_parent) { + inode_unref (loc.parent); + loc.parent = temp_parent; + inode_find_directory_name (loc.inode, &loc.name); + } + + } else if (strcmp (component, "..") == 0) { + loc.inode = inode_parent (parent, 0, 0); + if (loc.inode) { + temp_parent = inode_parent (loc.inode, 0, 0); + if (temp_parent) { + inode_unref (loc.parent); + loc.parent = temp_parent; + inode_find_directory_name (loc.inode, &loc.name); + } else if (__is_root_gfid (loc.inode->gfid)) { + inode_unref (loc.parent); + loc.parent = inode_ref (loc.inode); + loc.name = ""; + } else { + inode_unref (loc.inode); + loc.inode = NULL; + } + + } + } else + loc.inode = inode_grep (parent->table, parent, component); + + if (!loc.name) + loc.name = component; - loc.inode = inode_grep (parent->table, parent, component); if (loc.inode) { gf_uuid_copy (loc.gfid, loc.inode->gfid); reval = 1; @@ -389,7 +448,6 @@ found: out: if (xattr_req) dict_unref (xattr_req); - loc_wipe (&loc); return inode; @@ -409,7 +467,6 @@ priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at, char *next_component = NULL; int ret = -1; struct iatt ciatt = {0, }; - char dentry_name[PATH_MAX] = {0, }; DECLARE_OLD_THIS; __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs); @@ -441,7 +498,6 @@ priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at, if (parent) inode_unref (parent); parent = inode; - glusterfs_normalize_dentry (&parent, &component, dentry_name); inode = glfs_resolve_component (fs, subvol, parent, component, &ciatt, /* force hard lookup on the last |