diff options
| author | Pranith Kumar K <pkarampu@redhat.com> | 2014-10-30 10:56:17 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2014-11-07 09:42:28 -0800 | 
| commit | 0d7fd69b01cf9aebb4f1517f064e89ff65b9ccf8 (patch) | |
| tree | 51a8e84b9ea2b229b7d7380f651be85c22ff886d | |
| parent | a3252b9d8c4cc024b5528ca88076c7e33aecad38 (diff) | |
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>
| -rw-r--r-- | libglusterfs/src/inode.c | 26 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix-handle.c | 2 | 
2 files changed, 26 insertions, 2 deletions
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)); +        } +  } diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c index 9439b295cb9..ab202d79dc9 100644 --- a/xlators/storage/posix/src/posix-handle.c +++ b/xlators/storage/posix/src/posix-handle.c @@ -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) {  | 
