summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/inode.c
diff options
context:
space:
mode:
authorMohammed Rafi KC <rkavunga@redhat.com>2017-05-03 17:19:57 +0530
committerJeff Darcy <jeff@pl.atyp.us>2017-05-14 13:13:59 +0000
commit269e2ccf45ddc662d8373eb887ae6cef96e2ef37 (patch)
treeca0344bee23cf084771cdc306059ecd0e2f3866a /libglusterfs/src/inode.c
parent642f3e290ade6a5a7087816a5cf633083ef9f608 (diff)
gfapi: fix handling of dot and double dot in path
This patch is to handle "." and ".." in file path. Which means this special dentry names will be resolved before sending fops on the path. Change-Id: I5e92f6d1ad1412bf432eb2488e53fb7731edb013 BUG: 1447266 Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com> Reviewed-on: https://review.gluster.org/17177 Smoke: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Niels de Vos <ndevos@redhat.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Jeff Darcy <jeff@pl.atyp.us>
Diffstat (limited to 'libglusterfs/src/inode.c')
-rw-r--r--libglusterfs/src/inode.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index 3a6464ac5e1..6f3bc535a14 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -2569,3 +2569,113 @@ inode_ctx_size (inode_t *inode)
out:
return size;
}
+
+static void
+inode_parent_null_check(inode_t **parent, inode_t *inode, char **component)
+{
+ GF_VALIDATE_OR_GOTO ("inode", inode, out);
+ GF_VALIDATE_OR_GOTO ("inode", (*component), out);
+
+ if (!(*parent) && __is_root_gfid (inode->gfid)) {
+ *parent = inode_ref (inode);
+ *component = "/";
+ }
+out:
+ return;
+}
+
+/*
+ * This function changes component name and parent inode
+ * if the component name is either "." or ".."
+ *
+ * @Paramas:
+ * Parent : Parent inode of current dentry
+ * component : component name that we need to test
+ * dentry_name : Address for memory if need to change component.
+ * The caller has to preallocate this memory with
+ * PATH_MAX as the size.
+ *
+ * We return the updated parent inode and component in the
+ * respective structures.
+ *
+ * Basic Idea of the function:
+ *
+ * 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"
+ */
+void
+glusterfs_normalize_dentry (inode_t **parent, char **component,
+ char *dentry_name)
+{
+ inode_t *temp_inode = NULL;
+ dentry_t *dentry = NULL;
+
+ GF_VALIDATE_OR_GOTO ("inode", (*parent), out);
+ GF_VALIDATE_OR_GOTO ("inode", (*component), out);
+ GF_VALIDATE_OR_GOTO ("inode", (dentry_name), out);
+
+ /* After this point, there should not be "." or ".."
+ * in the path. Dot and double dots are replaced with
+ * appropriate base name and parent inode.
+ */
+
+ /* During the resolving, if it goes beyond the mount point
+ * we do lookup on the mount itself like "/.. " will be
+ * converted as "/"
+ */
+ if (strcmp (*component, ".") == 0) {
+ temp_inode = *parent;
+ *parent = inode_parent (*parent, 0, 0);
+ inode_parent_null_check (parent, temp_inode, component);
+ pthread_mutex_lock (&temp_inode->table->lock);
+ {
+ dentry = __dentry_search_arbit (temp_inode);
+ if (dentry) {
+ snprintf (dentry_name, PATH_MAX, "%s",
+ dentry->name);
+ *component = dentry_name;
+ }
+ }
+ pthread_mutex_unlock (&temp_inode->table->lock);
+ inode_unref (temp_inode);
+ } else if (strcmp (*component, "..") == 0) {
+ temp_inode = *parent;
+ *parent = inode_parent (*parent, 0, 0);
+ inode_parent_null_check (parent, temp_inode, component);
+ inode_unref (temp_inode);
+
+ temp_inode = *parent;
+ *parent = inode_parent (*parent, 0, 0);
+ inode_parent_null_check (parent, temp_inode, component);
+ pthread_mutex_lock (&temp_inode->table->lock);
+ {
+ dentry = __dentry_search_arbit (temp_inode);
+ if (dentry) {
+ snprintf (dentry_name, PATH_MAX, "%s",
+ dentry->name);
+ *component = dentry_name;
+ }
+ }
+ pthread_mutex_unlock (&temp_inode->table->lock);
+ inode_unref (temp_inode);
+ }
+out:
+ return;
+}