From 51c40fa1d1cfb6b63b513ac0d718cbb8d8da5774 Mon Sep 17 00:00:00 2001 From: Mohammed Rafi KC Date: Tue, 26 Apr 2016 16:59:30 +0530 Subject: [PATCH 099/104] gfapi: fill iatt in readdirp_cbk if entry->inode is null Back port of > http://review.gluster.org/#/c/14079/ If any of dirent have inode as null in readdirp_cbk, which indicates that the stat information is not valid. So for such entries, we send explicit lookup to fill the stat information. >Change-Id: I0604bce34583db0bb04b5aae8933766201c6ddad >BUG: 1330567 >Signed-off-by: Mohammed Rafi KC Change-Id: I5ac08e6bd7ab26cd9f2996ddde1a757d8533413e BUG: 1322247 Signed-off-by: Mohammed Rafi KC Reviewed-on: https://code.engineering.redhat.com/gerrit/73265 Reviewed-by: Poornima Gurusiddaiah Reviewed-by: Rajesh Joseph Tested-by: Rajesh Joseph --- api/src/glfs-fops.c | 11 +++++++++++ libglusterfs/src/gf-dirent.c | 42 ++++++++++++++++++++++++++++++++++++++++++ libglusterfs/src/gf-dirent.h | 3 +++ 3 files changed, 56 insertions(+), 0 deletions(-) diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index 98be987..7a3dffa 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -2446,6 +2446,17 @@ glfd_entry_refresh (struct glfs_fd *glfd, int plus) list_for_each_entry (entry, &entries.list, list) { if (entry->inode) inode_set_need_lookup (entry->inode, THIS); + else if (!IA_ISDIR (entry->d_stat.ia_type)) { + /* entry->inode for directories will be + * always set to null to force a lookup + * on the dentry. Also we will have + * proper stat if directory present on + * hashed subvolume. + */ + gf_fill_iatt_for_dirent (entry, + fd->inode, + subvol); + } } gf_link_inodes_from_dirent (THIS, fd->inode, &entries); diff --git a/libglusterfs/src/gf-dirent.c b/libglusterfs/src/gf-dirent.c index 4c077e9..e3c7bf6 100644 --- a/libglusterfs/src/gf-dirent.c +++ b/libglusterfs/src/gf-dirent.c @@ -20,6 +20,7 @@ #include #include "compat.h" #include "xlator.h" +#include "syncop.h" #define ONE 1ULL #define PRESENT_D_OFF_BITS 63 @@ -262,3 +263,44 @@ gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent, return 0; } + +int +gf_fill_iatt_for_dirent (gf_dirent_t *entry, inode_t *parent, xlator_t *subvol) +{ + loc_t loc = {0, }; + int ret = -1; + char *path = NULL; + struct iatt iatt = {0,}; + + loc.inode = inode_grep (parent->table, parent, entry->d_name); + if (!loc.inode) { + loc.inode = inode_new (parent->table); + gf_uuid_copy (loc.inode->gfid, entry->d_stat.ia_gfid); + } + + gf_uuid_copy (loc.pargfid, parent->gfid); + loc.name = entry->d_name; + loc.parent = inode_ref (parent); + ret = inode_path (loc.inode, entry->d_name, &path); + loc.path = path; + if (ret < 0) + goto out; + + ret = syncop_lookup (subvol, &loc, &iatt, NULL, NULL, NULL); + if (ret) + goto out; + + entry->d_stat = iatt; + entry->inode = inode_ref (loc.inode); + /* We don't need to link inode here, because as part of readdirp_cbk + * we will link all dirents. + * + * Since we did a proper lookup, we don't need to set need_lookup + * flag. + */ + + ret = 0; +out: + loc_wipe (&loc); + return ret; +} diff --git a/libglusterfs/src/gf-dirent.h b/libglusterfs/src/gf-dirent.h index faeaf41..faffabf 100644 --- a/libglusterfs/src/gf-dirent.h +++ b/libglusterfs/src/gf-dirent.h @@ -66,6 +66,9 @@ void gf_dirent_entry_free (gf_dirent_t *entry); void gf_dirent_free (gf_dirent_t *entries); int gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent, gf_dirent_t *entries); +int +gf_fill_iatt_for_dirent (gf_dirent_t *entry, inode_t *parent, + xlator_t *subvol); void gf_link_inode_from_dirent (xlator_t *this, inode_t *parent, gf_dirent_t *entry); -- 1.7.1