From 0d7fd69b01cf9aebb4f1517f064e89ff65b9ccf8 Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Thu, 30 Oct 2014 10:56:17 +0530 Subject: inode: Handle '/' in basename in inode_link/unlink Problem: inode_link is sometimes called with a trailing '/'. Lookup, dentry operations like link/unlink/mkdir/rmdir/rename etc come without trailing '/' so the stale dentry with '/' remains in the dentry list of the inode. Fix: Add assert checks and return NULL for '/' in bname. Fix ancestry building code to call without '/' at the end. Change-Id: I9c71292a3ac27754538a4e75e53290e182968fad BUG: 1158751 Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/9004 Reviewed-by: Niels de Vos Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- libglusterfs/src/inode.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'libglusterfs/src/inode.c') diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index 63533642a04..e0079524e2d 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -833,6 +833,17 @@ __inode_link (inode_t *inode, inode_t *parent, const char *name, if (inode->table != parent->table) { GF_ASSERT (!"link attempted b/w inodes of diff table"); } + + if (parent->ia_type != IA_IFDIR) { + GF_ASSERT (!"link attempted on non-directory parent"); + return NULL; + } + + if (!name || strlen (name) == 0) { + GF_ASSERT (!"link attempted with no basename on " + "parent"); + return NULL; + } } link_inode = inode; @@ -869,6 +880,11 @@ __inode_link (inode_t *inode, inode_t *parent, const char *name, if (name) { if (!strcmp(name, ".") || !strcmp(name, "..")) return link_inode; + + if (strchr (name, '/')) { + GF_ASSERT (!"inode link attempted with '/' in name"); + return NULL; + } } /* use only link_inode beyond this point */ @@ -1027,6 +1043,8 @@ static void __inode_unlink (inode_t *inode, inode_t *parent, const char *name) { dentry_t *dentry = NULL; + char pgfid[64] = {0}; + char gfid[64] = {0}; if (!inode || !parent || !name) return; @@ -1034,8 +1052,14 @@ __inode_unlink (inode_t *inode, inode_t *parent, const char *name) dentry = __dentry_search_for_inode (inode, parent->gfid, name); /* dentry NULL for corrupted backend */ - if (dentry) + if (dentry) { __dentry_unset (dentry); + } else { + gf_log ("inode", GF_LOG_WARNING, "%s/%s: dentry not " + "found in %s", uuid_utoa_r (parent->gfid, pgfid), name, + uuid_utoa_r (inode->gfid, gfid)); + } + } -- cgit