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 <pkarampu@redhat.com> Reviewed-on: http://review.gluster.org/9004 Reviewed-by: Niels de Vos <ndevos@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
This commit is contained in:
parent
a3252b9d8c
commit
0d7fd69b01
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,7 +162,6 @@ posix_make_ancestryfromgfid (xlator_t *this, char *path, int pathsize,
|
||||
|
||||
pgfidstr = strtok_r (linkname + SLEN("../../00/00/"), "/", &saveptr);
|
||||
dir_name = strtok_r (NULL, "/", &saveptr);
|
||||
strcat (dir_name, "/");
|
||||
|
||||
uuid_parse (pgfidstr, tmp_gfid);
|
||||
|
||||
@ -178,6 +177,7 @@ posix_make_ancestryfromgfid (xlator_t *this, char *path, int pathsize,
|
||||
|
||||
inode = posix_resolve (this, itable, *parent, dir_name, &iabuf);
|
||||
|
||||
strcat (dir_name, "/");
|
||||
ret = posix_make_ancestral_node (priv_base_path, path, pathsize, head,
|
||||
dir_name, &iabuf, inode, type, xdata);
|
||||
if (*parent != NULL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user