From ef03f98bf9b5f7f317383b84d251299b8939e5cc Mon Sep 17 00:00:00 2001 From: Anand Avati Date: Tue, 28 Oct 2014 14:05:06 -0700 Subject: 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 Reviewed-on: http://review.gluster.org/8995 Reviewed-by: Harshavardhana Tested-by: Gluster Build System Reviewed-by: Raghavendra G Reviewed-by: Pranith Kumar Karampuri Tested-by: Pranith Kumar Karampuri --- libglusterfs/src/inode.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'libglusterfs') 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, "..")) -- cgit