gfapi: fill iatt in readdirp_cbk if entry->inode is null
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 <rkavunga@redhat.com> Reviewed-on: http://review.gluster.org/14079 NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Smoke: Gluster Build System <jenkins@build.gluster.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
parent
fbb655d90a
commit
9423bdeed1
@ -2508,6 +2508,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);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <stdint.h>
|
||||
#include "compat.h"
|
||||
#include "xlator.h"
|
||||
#include "syncop.h"
|
||||
|
||||
#define ONE 1ULL
|
||||
#define PRESENT_D_OFF_BITS 63
|
||||
@ -257,3 +258,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;
|
||||
}
|
||||
|
@ -61,6 +61,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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user