summaryrefslogtreecommitdiffstats
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
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>
-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, ".."))