|
|
21ab4e |
From 4b1fdb2a6c56f7dbfdab4f12fe8320d29260d7f4 Mon Sep 17 00:00:00 2001
|
|
|
21ab4e |
From: Jiffin Tony Thottan <jthottan@redhat.com>
|
|
|
21ab4e |
Date: Sun, 11 Jun 2017 07:33:52 +0530
|
|
|
21ab4e |
Subject: [PATCH 522/525] gfapi : Resolve "." and ".." only for named lookups
|
|
|
21ab4e |
|
|
|
21ab4e |
The patch https://review.gluster.org/#/c/17177 resolves "." and ".."
|
|
|
21ab4e |
to corrosponding inodes and names before sending the request to the
|
|
|
21ab4e |
backend server. But this will only work if inode and its parent is
|
|
|
21ab4e |
linked properly. Incase of nameless lookup(applications like ganesha)
|
|
|
21ab4e |
the inode of parent can be NULL(only gfid is send). So this patch will
|
|
|
21ab4e |
resolve "." and ".." only if proper parent is available
|
|
|
21ab4e |
|
|
|
21ab4e |
Upstream reference :
|
|
|
21ab4e |
>Change-Id: I4c50258b0d896dabf000a547ab180b57df308a0b
|
|
|
21ab4e |
>BUG: 1460514
|
|
|
21ab4e |
>Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>
|
|
|
21ab4e |
>Reviewed-on: https://review.gluster.org/17502
|
|
|
21ab4e |
>Smoke: Gluster Build System <jenkins@build.gluster.org>
|
|
|
21ab4e |
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
|
|
|
21ab4e |
>Reviewed-by: Poornima G <pgurusid@redhat.com>
|
|
|
21ab4e |
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
|
|
|
21ab4e |
>Reviewed-by: soumya k <skoduri@redhat.com>
|
|
|
21ab4e |
>Reviewed-by: Jeff Darcy <jeff@pl.atyp.us>
|
|
|
21ab4e |
>Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>
|
|
|
21ab4e |
|
|
|
21ab4e |
Change-Id: I4c50258b0d896dabf000a547ab180b57df308a0b
|
|
|
21ab4e |
BUG: 1457183
|
|
|
21ab4e |
Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>
|
|
|
21ab4e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/109520
|
|
|
21ab4e |
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
|
|
|
21ab4e |
---
|
|
|
21ab4e |
api/src/glfs-resolve.c | 72 +++++++++++++++++++++++++----
|
|
|
21ab4e |
libglusterfs/src/inode.c | 118 ++++++++---------------------------------------
|
|
|
21ab4e |
libglusterfs/src/inode.h | 17 +------
|
|
|
21ab4e |
3 files changed, 83 insertions(+), 124 deletions(-)
|
|
|
21ab4e |
|
|
|
21ab4e |
diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c
|
|
|
21ab4e |
index 44d013c..8e91cd7 100644
|
|
|
21ab4e |
--- a/api/src/glfs-resolve.c
|
|
|
21ab4e |
+++ b/api/src/glfs-resolve.c
|
|
|
21ab4e |
@@ -268,6 +268,7 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
|
|
|
21ab4e |
{
|
|
|
21ab4e |
loc_t loc = {0, };
|
|
|
21ab4e |
inode_t *inode = NULL;
|
|
|
21ab4e |
+ inode_t *temp_parent = NULL;
|
|
|
21ab4e |
int reval = 0;
|
|
|
21ab4e |
int ret = -1;
|
|
|
21ab4e |
int glret = -1;
|
|
|
21ab4e |
@@ -276,14 +277,12 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
|
|
|
21ab4e |
dict_t *xattr_req = NULL;
|
|
|
21ab4e |
uint64_t ctx_value = LOOKUP_NOT_NEEDED;
|
|
|
21ab4e |
|
|
|
21ab4e |
- loc.name = component;
|
|
|
21ab4e |
-
|
|
|
21ab4e |
loc.parent = inode_ref (parent);
|
|
|
21ab4e |
gf_uuid_copy (loc.pargfid, parent->gfid);
|
|
|
21ab4e |
|
|
|
21ab4e |
- /* At this point we should never have '.' or ".." in path */
|
|
|
21ab4e |
if (__is_root_gfid (parent->gfid) &&
|
|
|
21ab4e |
- (strcmp (component, "/") == 0)) {
|
|
|
21ab4e |
+ ((strcmp (component, ".") == 0) ||
|
|
|
21ab4e |
+ (strcmp (component, "..") == 0))) {
|
|
|
21ab4e |
if (!force_lookup) {
|
|
|
21ab4e |
inode = inode_ref (parent);
|
|
|
21ab4e |
} else {
|
|
|
21ab4e |
@@ -293,8 +292,68 @@ glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
|
|
|
21ab4e |
}
|
|
|
21ab4e |
goto found;
|
|
|
21ab4e |
}
|
|
|
21ab4e |
+ /* *
|
|
|
21ab4e |
+ * if the component name is either "." or "..", it will try to
|
|
|
21ab4e |
+ * resolve that if inode has a proper parent (named lookup).
|
|
|
21ab4e |
+ *
|
|
|
21ab4e |
+ * Below condition works like this
|
|
|
21ab4e |
+ *
|
|
|
21ab4e |
+ * Example 1 :
|
|
|
21ab4e |
+ * Path /out_dir/dir/in_dir/.
|
|
|
21ab4e |
+ * In put values :
|
|
|
21ab4e |
+ * parent = in_dir
|
|
|
21ab4e |
+ * component : "."
|
|
|
21ab4e |
+ *
|
|
|
21ab4e |
+ * Out put values:
|
|
|
21ab4e |
+ * parent : dir
|
|
|
21ab4e |
+ * component : "in_dir"
|
|
|
21ab4e |
+ *
|
|
|
21ab4e |
+ * Example 2 :
|
|
|
21ab4e |
+ * Path /out_dir/dir/in_dir/..
|
|
|
21ab4e |
+ * In put values :
|
|
|
21ab4e |
+ * parent = in_dir
|
|
|
21ab4e |
+ * component : ".."
|
|
|
21ab4e |
+ *
|
|
|
21ab4e |
+ * Out put values:
|
|
|
21ab4e |
+ * parent : output_dir
|
|
|
21ab4e |
+ * component : "dir"
|
|
|
21ab4e |
+ *
|
|
|
21ab4e |
+ * Incase of nameless lookup, both "." and ".." retained
|
|
|
21ab4e |
+ */
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ if (strcmp (component, ".") == 0) {
|
|
|
21ab4e |
+ loc.inode = inode_ref (parent);
|
|
|
21ab4e |
+ temp_parent = inode_parent (loc.inode, 0, 0);
|
|
|
21ab4e |
+ if (temp_parent) {
|
|
|
21ab4e |
+ inode_unref (loc.parent);
|
|
|
21ab4e |
+ loc.parent = temp_parent;
|
|
|
21ab4e |
+ inode_find_directory_name (loc.inode, &loc.name);
|
|
|
21ab4e |
+ }
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ } else if (strcmp (component, "..") == 0) {
|
|
|
21ab4e |
+ loc.inode = inode_parent (parent, 0, 0);
|
|
|
21ab4e |
+ if (loc.inode) {
|
|
|
21ab4e |
+ temp_parent = inode_parent (loc.inode, 0, 0);
|
|
|
21ab4e |
+ if (temp_parent) {
|
|
|
21ab4e |
+ inode_unref (loc.parent);
|
|
|
21ab4e |
+ loc.parent = temp_parent;
|
|
|
21ab4e |
+ inode_find_directory_name (loc.inode, &loc.name);
|
|
|
21ab4e |
+ } else if (__is_root_gfid (loc.inode->gfid)) {
|
|
|
21ab4e |
+ inode_unref (loc.parent);
|
|
|
21ab4e |
+ loc.parent = inode_ref (loc.inode);
|
|
|
21ab4e |
+ loc.name = "";
|
|
|
21ab4e |
+ } else {
|
|
|
21ab4e |
+ inode_unref (loc.inode);
|
|
|
21ab4e |
+ loc.inode = NULL;
|
|
|
21ab4e |
+ }
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ }
|
|
|
21ab4e |
+ } else
|
|
|
21ab4e |
+ loc.inode = inode_grep (parent->table, parent, component);
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ if (!loc.name)
|
|
|
21ab4e |
+ loc.name = component;
|
|
|
21ab4e |
|
|
|
21ab4e |
- loc.inode = inode_grep (parent->table, parent, component);
|
|
|
21ab4e |
if (loc.inode) {
|
|
|
21ab4e |
gf_uuid_copy (loc.gfid, loc.inode->gfid);
|
|
|
21ab4e |
reval = 1;
|
|
|
21ab4e |
@@ -389,7 +448,6 @@ found:
|
|
|
21ab4e |
out:
|
|
|
21ab4e |
if (xattr_req)
|
|
|
21ab4e |
dict_unref (xattr_req);
|
|
|
21ab4e |
-
|
|
|
21ab4e |
loc_wipe (&loc;;
|
|
|
21ab4e |
|
|
|
21ab4e |
return inode;
|
|
|
21ab4e |
@@ -409,7 +467,6 @@ priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at,
|
|
|
21ab4e |
char *next_component = NULL;
|
|
|
21ab4e |
int ret = -1;
|
|
|
21ab4e |
struct iatt ciatt = {0, };
|
|
|
21ab4e |
- char dentry_name[PATH_MAX] = {0, };
|
|
|
21ab4e |
|
|
|
21ab4e |
DECLARE_OLD_THIS;
|
|
|
21ab4e |
__GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
|
|
|
21ab4e |
@@ -441,7 +498,6 @@ priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at,
|
|
|
21ab4e |
if (parent)
|
|
|
21ab4e |
inode_unref (parent);
|
|
|
21ab4e |
parent = inode;
|
|
|
21ab4e |
- glusterfs_normalize_dentry (&parent, &component, dentry_name);
|
|
|
21ab4e |
inode = glfs_resolve_component (fs, subvol, parent,
|
|
|
21ab4e |
component, &ciatt,
|
|
|
21ab4e |
/* force hard lookup on the last
|
|
|
21ab4e |
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
|
|
|
21ab4e |
index 90a5608..0353825 100644
|
|
|
21ab4e |
--- a/libglusterfs/src/inode.c
|
|
|
21ab4e |
+++ b/libglusterfs/src/inode.c
|
|
|
21ab4e |
@@ -2549,112 +2549,30 @@ out:
|
|
|
21ab4e |
return size;
|
|
|
21ab4e |
}
|
|
|
21ab4e |
|
|
|
21ab4e |
-static void
|
|
|
21ab4e |
-inode_parent_null_check(inode_t **parent, inode_t *inode, char **component)
|
|
|
21ab4e |
-{
|
|
|
21ab4e |
- GF_VALIDATE_OR_GOTO ("inode", inode, out);
|
|
|
21ab4e |
- GF_VALIDATE_OR_GOTO ("inode", (*component), out);
|
|
|
21ab4e |
-
|
|
|
21ab4e |
- if (!(*parent) && __is_root_gfid (inode->gfid)) {
|
|
|
21ab4e |
- *parent = inode_ref (inode);
|
|
|
21ab4e |
- *component = "/";
|
|
|
21ab4e |
- }
|
|
|
21ab4e |
-out:
|
|
|
21ab4e |
- return;
|
|
|
21ab4e |
-}
|
|
|
21ab4e |
-
|
|
|
21ab4e |
-/*
|
|
|
21ab4e |
- * This function changes component name and parent inode
|
|
|
21ab4e |
- * if the component name is either "." or ".."
|
|
|
21ab4e |
- *
|
|
|
21ab4e |
- * @Paramas:
|
|
|
21ab4e |
- * Parent : Parent inode of current dentry
|
|
|
21ab4e |
- * component : component name that we need to test
|
|
|
21ab4e |
- * dentry_name : Address for memory if need to change component.
|
|
|
21ab4e |
- * The caller has to preallocate this memory with
|
|
|
21ab4e |
- * PATH_MAX as the size.
|
|
|
21ab4e |
- *
|
|
|
21ab4e |
- * We return the updated parent inode and component in the
|
|
|
21ab4e |
- * respective structures.
|
|
|
21ab4e |
- *
|
|
|
21ab4e |
- * Basic Idea of the function:
|
|
|
21ab4e |
- *
|
|
|
21ab4e |
- * Example 1 :
|
|
|
21ab4e |
- * Path /out_dir/dir/in_dir/.
|
|
|
21ab4e |
- * In put values :
|
|
|
21ab4e |
- * parent = in_dir
|
|
|
21ab4e |
- * component : "."
|
|
|
21ab4e |
- *
|
|
|
21ab4e |
- * Out put values:
|
|
|
21ab4e |
- * parent : dir
|
|
|
21ab4e |
- * component : "in_dir"
|
|
|
21ab4e |
- *
|
|
|
21ab4e |
- * Example 2 :
|
|
|
21ab4e |
- * Path /out_dir/dir/in_dir/..
|
|
|
21ab4e |
- * In put values :
|
|
|
21ab4e |
- * parent = in_dir
|
|
|
21ab4e |
- * component : ".."
|
|
|
21ab4e |
- *
|
|
|
21ab4e |
- * Out put values:
|
|
|
21ab4e |
- * parent : output_dir
|
|
|
21ab4e |
- * component : "dir"
|
|
|
21ab4e |
- */
|
|
|
21ab4e |
+/* *
|
|
|
21ab4e |
+ * This function finds name of the inode, if it has dentry. The dentry will be
|
|
|
21ab4e |
+ * created only if inode_link happens with valid parent and name. And this
|
|
|
21ab4e |
+ * function is only applicable for directories because multiple dentries are
|
|
|
21ab4e |
+ * not possible(no hardlinks)
|
|
|
21ab4e |
+ * */
|
|
|
21ab4e |
void
|
|
|
21ab4e |
-glusterfs_normalize_dentry (inode_t **parent, char **component,
|
|
|
21ab4e |
- char *dentry_name)
|
|
|
21ab4e |
-{
|
|
|
21ab4e |
- inode_t *temp_inode = NULL;
|
|
|
21ab4e |
- dentry_t *dentry = NULL;
|
|
|
21ab4e |
+inode_find_directory_name (inode_t *inode, const char **name) {
|
|
|
21ab4e |
+ dentry_t *dentry = NULL;
|
|
|
21ab4e |
|
|
|
21ab4e |
- GF_VALIDATE_OR_GOTO ("inode", (*parent), out);
|
|
|
21ab4e |
- GF_VALIDATE_OR_GOTO ("inode", (*component), out);
|
|
|
21ab4e |
- GF_VALIDATE_OR_GOTO ("inode", (dentry_name), out);
|
|
|
21ab4e |
+ GF_VALIDATE_OR_GOTO ("inode", inode, out);
|
|
|
21ab4e |
+ GF_VALIDATE_OR_GOTO ("inode", name, out);
|
|
|
21ab4e |
|
|
|
21ab4e |
- /* After this point, there should not be "." or ".."
|
|
|
21ab4e |
- * in the path. Dot and double dots are replaced with
|
|
|
21ab4e |
- * appropriate base name and parent inode.
|
|
|
21ab4e |
- */
|
|
|
21ab4e |
+ if (!IA_ISDIR (inode->ia_type))
|
|
|
21ab4e |
+ return;
|
|
|
21ab4e |
|
|
|
21ab4e |
- /* During the resolving, if it goes beyond the mount point
|
|
|
21ab4e |
- * we do lookup on the mount itself like "/.. " will be
|
|
|
21ab4e |
- * converted as "/"
|
|
|
21ab4e |
- */
|
|
|
21ab4e |
- if (strcmp (*component, ".") == 0) {
|
|
|
21ab4e |
- temp_inode = *parent;
|
|
|
21ab4e |
- *parent = inode_parent (*parent, 0, 0);
|
|
|
21ab4e |
- inode_parent_null_check (parent, temp_inode, component);
|
|
|
21ab4e |
- pthread_mutex_lock (&temp_inode->table->lock);
|
|
|
21ab4e |
- {
|
|
|
21ab4e |
- dentry = __dentry_search_arbit (temp_inode);
|
|
|
21ab4e |
- if (dentry) {
|
|
|
21ab4e |
- snprintf (dentry_name, PATH_MAX, "%s",
|
|
|
21ab4e |
- dentry->name);
|
|
|
21ab4e |
- *component = dentry_name;
|
|
|
21ab4e |
- }
|
|
|
21ab4e |
- }
|
|
|
21ab4e |
- pthread_mutex_unlock (&temp_inode->table->lock);
|
|
|
21ab4e |
- inode_unref (temp_inode);
|
|
|
21ab4e |
- } else if (strcmp (*component, "..") == 0) {
|
|
|
21ab4e |
- temp_inode = *parent;
|
|
|
21ab4e |
- *parent = inode_parent (*parent, 0, 0);
|
|
|
21ab4e |
- inode_parent_null_check (parent, temp_inode, component);
|
|
|
21ab4e |
- inode_unref (temp_inode);
|
|
|
21ab4e |
-
|
|
|
21ab4e |
- temp_inode = *parent;
|
|
|
21ab4e |
- *parent = inode_parent (*parent, 0, 0);
|
|
|
21ab4e |
- inode_parent_null_check (parent, temp_inode, component);
|
|
|
21ab4e |
- pthread_mutex_lock (&temp_inode->table->lock);
|
|
|
21ab4e |
- {
|
|
|
21ab4e |
- dentry = __dentry_search_arbit (temp_inode);
|
|
|
21ab4e |
- if (dentry) {
|
|
|
21ab4e |
- snprintf (dentry_name, PATH_MAX, "%s",
|
|
|
21ab4e |
- dentry->name);
|
|
|
21ab4e |
- *component = dentry_name;
|
|
|
21ab4e |
- }
|
|
|
21ab4e |
+ pthread_mutex_lock (&inode->table->lock);
|
|
|
21ab4e |
+ {
|
|
|
21ab4e |
+ dentry = __dentry_search_arbit (inode);
|
|
|
21ab4e |
+ if (dentry) {
|
|
|
21ab4e |
+ *name = dentry->name;
|
|
|
21ab4e |
}
|
|
|
21ab4e |
- pthread_mutex_unlock (&temp_inode->table->lock);
|
|
|
21ab4e |
- inode_unref (temp_inode);
|
|
|
21ab4e |
}
|
|
|
21ab4e |
+ pthread_mutex_unlock (&inode->table->lock);
|
|
|
21ab4e |
out:
|
|
|
21ab4e |
return;
|
|
|
21ab4e |
}
|
|
|
21ab4e |
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
|
|
|
21ab4e |
index e3c38bb..e4ad046 100644
|
|
|
21ab4e |
--- a/libglusterfs/src/inode.h
|
|
|
21ab4e |
+++ b/libglusterfs/src/inode.h
|
|
|
21ab4e |
@@ -282,21 +282,6 @@ inode_has_dentry (inode_t *inode);
|
|
|
21ab4e |
size_t
|
|
|
21ab4e |
inode_ctx_size (inode_t *inode);
|
|
|
21ab4e |
|
|
|
21ab4e |
-/*
|
|
|
21ab4e |
- * This function is used to change the dentry from a path
|
|
|
21ab4e |
- * if it contains any "." or ".." .
|
|
|
21ab4e |
- *
|
|
|
21ab4e |
- * It replaces "." and ".." to proper bname after resolving
|
|
|
21ab4e |
- * and will change the component accordingly.
|
|
|
21ab4e |
- *
|
|
|
21ab4e |
- * This fucntion also replaces the parent inode based on the
|
|
|
21ab4e |
- * bname.
|
|
|
21ab4e |
- *
|
|
|
21ab4e |
- * We should give a allocated memory as a third argument to store
|
|
|
21ab4e |
- * the component in case if we are modifying it.
|
|
|
21ab4e |
- */
|
|
|
21ab4e |
-
|
|
|
21ab4e |
void
|
|
|
21ab4e |
-glusterfs_normalize_dentry (inode_t **parent, char **component,
|
|
|
21ab4e |
- char *dentry_name);
|
|
|
21ab4e |
+inode_find_directory_name (inode_t *inode, const char **name);
|
|
|
21ab4e |
#endif /* _INODE_H */
|
|
|
21ab4e |
--
|
|
|
21ab4e |
1.8.3.1
|
|
|
21ab4e |
|