diff options
author | Anand Avati <avati@redhat.com> | 2014-10-28 14:05:06 -0700 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-10-29 01:33:06 -0700 |
commit | ef03f98bf9b5f7f317383b84d251299b8939e5cc (patch) | |
tree | e9e0d818b77bc253b63050708858db4dd7edd22a | |
parent | 8df26e838c40f15bb2b26131d1533da339f5be3e (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.c | 13 |
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, "..")) |