summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/inode.c
diff options
context:
space:
mode:
authorAnand Avati <avati@redhat.com>2014-10-28 14:05:06 -0700
committerVijay Bellur <vbellur@redhat.com>2014-10-29 01:33:06 -0700
commitef03f98bf9b5f7f317383b84d251299b8939e5cc (patch)
treee9e0d818b77bc253b63050708858db4dd7edd22a /libglusterfs/src/inode.c
parent8df26e838c40f15bb2b26131d1533da339f5be3e (diff)
inode: include dentry cycle checks for all existing inodes
inode_link() has the responsibility of maintaining the DAGness of the dentry tree, and prevent cyclic loops from forming. To do this the technique used is to perform cyclic check only while linking inodes which already were linked in the inode table (i.e linking a new_inode() can never form a loop). While this was how it was supposed to be all along, the @old_inode variable was missed out to get updated if the given inode to inode_link itself was already linked (i.e, the code was only handling a complex case when the given new inode had a gfid which already existed) Without this patch, it is possible to call inode_link in a specific way which results in dentry loops. Change-Id: I4c87fa2d63f11e31c73d8b847e56962f6c983880 BUG: 1158226 Signed-off-by: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.org/8995 Reviewed-by: Harshavardhana <harsha@harshavardhana.net> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Raghavendra G <rgowdapp@redhat.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Diffstat (limited to 'libglusterfs/src/inode.c')
-rw-r--r--libglusterfs/src/inode.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index b06ebe9f8a1..63533642a04 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -853,7 +853,18 @@ __inode_link (inode_t *inode, inode_t *parent, const char *name,
inode->ia_type = iatt->ia_type;
__inode_hash (inode);
}
- }
+ } else {
+ /* @old_inode serves another important purpose - it indicates
+ to the code further below whether a dentry cycle check is
+ required or not (a new inode linkage can never result in
+ creation of a loop.)
+
+ if the given @inode is already hashed, it actually means
+ it is an "old" inode and deserves to undergo the cyclic
+ check.
+ */
+ old_inode = inode;
+ }
if (name) {
if (!strcmp(name, ".") || !strcmp(name, ".."))