diff options
Diffstat (limited to 'xlators/storage/posix')
-rw-r--r-- | xlators/storage/posix/src/posix-handle.c | 53 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-messages.h | 10 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 9 |
3 files changed, 57 insertions, 15 deletions
diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c index 7f5cd5237ae..8e561e4a76f 100644 --- a/xlators/storage/posix/src/posix-handle.c +++ b/xlators/storage/posix/src/posix-handle.c @@ -30,24 +30,42 @@ inode_t * posix_resolve (xlator_t *this, inode_table_t *itable, inode_t *parent, char *bname, struct iatt *iabuf) { - inode_t *inode = NULL, *linked_inode = NULL; + inode_t *inode = NULL; int ret = -1; ret = posix_istat (this, parent->gfid, bname, iabuf); - if (ret < 0) + if (ret < 0) { + gf_log (this->name, GF_LOG_WARNING, "gfid: %s, bname: %s " + "failed", uuid_utoa (parent->gfid), bname); goto out; + } - inode = inode_find (itable, iabuf->ia_gfid); - if (inode == NULL) { - inode = inode_new (itable); + if (__is_root_gfid (iabuf->ia_gfid) && !strcmp (bname, "/")) { + inode = itable->root; + } else { + inode = inode_find (itable, iabuf->ia_gfid); + if (inode == NULL) { + inode = inode_new (itable); + gf_uuid_copy (inode->gfid, iabuf->ia_gfid); + } } - linked_inode = inode_link (inode, parent, bname, iabuf); + /* Linking an inode here, can cause a race in posix_acl. + Parent inode gets linked here, but before + it reaches posix_acl_readdirp_cbk, create/lookup can + come on a leaf-inode, as parent-inode-ctx not yet updated + in posix_acl_readdirp_cbk, create and lookup can fail + with EACCESS. So do the inode linking in the quota xlator + + if (__is_root_gfid (iabuf->ia_gfid) && !strcmp (bname, "/")) + linked_inode = itable->root; + else + linked_inode = inode_link (inode, parent, bname, iabuf); - inode_unref (inode); + inode_unref (inode);*/ out: - return linked_inode; + return inode; } int @@ -67,6 +85,8 @@ posix_make_ancestral_node (const char *priv_base_path, char *path, int pathsize, } strcat (path, dir_name); + if (*dir_name != '/') + strcat (path, "/"); if (type & POSIX_ANCESTRY_DENTRY) { entry = gf_dirent_for_name (dir_name); @@ -127,11 +147,16 @@ posix_make_ancestryfromgfid (xlator_t *this, char *path, int pathsize, *parent = inode_ref (itable->root); } - inode = itable->root; - memset (&iabuf, 0, sizeof (iabuf)); - gf_uuid_copy (iabuf.ia_gfid, inode->gfid); - iabuf.ia_type = inode->ia_type; + inode = posix_resolve (this, itable, *parent, "/", &iabuf); + if (!inode) { + gf_msg (this->name, GF_LOG_ERROR, + P_MSG_INODE_RESOLVE_FAILED, 0, + "posix resolve on the root inode %s failed", + uuid_utoa (gfid)); + *op_errno = ESTALE; + goto out; + } ret = posix_make_ancestral_node (priv_base_path, path, pathsize, head, "/", &iabuf, inode, type, @@ -177,12 +202,14 @@ posix_make_ancestryfromgfid (xlator_t *this, char *path, int pathsize, inode = posix_resolve (this, itable, *parent, dir_name, &iabuf); if (inode == NULL) { + gf_msg (this->name, GF_LOG_ERROR, P_MSG_INODE_RESOLVE_FAILED, + 0, "posix resolve on the root inode %s failed", + uuid_utoa (gfid)); *op_errno = ESTALE; ret = -1; goto out; } - strcat (dir_name, "/"); ret = posix_make_ancestral_node (priv_base_path, path, pathsize, head, dir_name, &iabuf, inode, type, xdata); if (*parent != NULL) { diff --git a/xlators/storage/posix/src/posix-messages.h b/xlators/storage/posix/src/posix-messages.h index ad16c1dc00c..4efdef0a6b9 100644 --- a/xlators/storage/posix/src/posix-messages.h +++ b/xlators/storage/posix/src/posix-messages.h @@ -45,7 +45,7 @@ */ #define POSIX_COMP_BASE GLFS_MSGID_COMP_POSIX -#define GLFS_NUM_MESSAGES 107 +#define GLFS_NUM_MESSAGES 108 #define GLFS_MSGID_END (POSIX_COMP_BASE + GLFS_NUM_MESSAGES + 1) /* Messaged with message IDs */ #define glfs_msg_start_x POSIX_COMP_BASE, "Invalid: Start of messages" @@ -917,6 +917,14 @@ * */ +#define P_MSG_INODE_RESOLVE_FAILED (POSIX_COMP_BASE + 108) +/*! + * @messageid + * @diagnosis + * @recommendedaction + * + */ + /*------------*/ #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index dcd54bd35d6..b5df1d082ee 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -3803,11 +3803,18 @@ posix_links_in_same_directory (char *dirpath, int count, inode_t *leaf_inode, if (entry->d_ino != stbuf->st_ino) continue; + /* Linking an inode here, can cause a race in posix_acl. + Parent inode gets linked here, but before + it reaches posix_acl_readdirp_cbk, create/lookup can + come on a leaf-inode, as parent-inode-ctx not yet updated + in posix_acl_readdirp_cbk, create and lookup can fail + with EACCESS. So do the inode linking in the quota xlator + linked_inode = inode_link (leaf_inode, parent, entry->d_name, NULL); GF_ASSERT (linked_inode == leaf_inode); - inode_unref (linked_inode); + inode_unref (linked_inode);*/ if (type & POSIX_ANCESTRY_DENTRY) { loc_t loc = {0, }; |