summaryrefslogtreecommitdiffstats
path: root/libglusterfs
diff options
context:
space:
mode:
authorPranith Kumar K <pkarampu@redhat.com>2014-10-30 10:56:17 +0530
committerVijay Bellur <vbellur@redhat.com>2014-11-16 23:36:42 -0800
commit139e8d797bf48acfbc422a7d12740c65c34790fc (patch)
treef2469b1e445618eb89eb7ab2608b83209315aec8 /libglusterfs
parent4bc694954190ce62953e1dfd470f621e85138ccc (diff)
inode: Handle '/' in basename in inode_link/unlink
Backport of http://review.gluster.org/9004 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. BUG: 1163570 Change-Id: I96655a0eb4678f80082705ab167327e72f54fa45 Signed-off-by: Pranith Kumar K <pkarampu@redhat.com> Reviewed-on: http://review.gluster.org/9111 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'libglusterfs')
-rw-r--r--libglusterfs/src/inode.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index b06ebe9f8a1..3b1e05077e8 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;
@@ -858,6 +869,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 */
@@ -1016,6 +1032,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;
@@ -1023,8 +1041,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));
+ }
+
}