summaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/src/glfs-fops.c16
-rw-r--r--api/src/glfs-resolve.c49
2 files changed, 51 insertions, 14 deletions
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c
index e1762ae1285..b66f336338d 100644
--- a/api/src/glfs-fops.c
+++ b/api/src/glfs-fops.c
@@ -2270,6 +2270,7 @@ glfd_entry_refresh (struct glfs_fd *glfd, int plus)
xlator_t *subvol = NULL;
gf_dirent_t entries;
gf_dirent_t old;
+ gf_dirent_t *entry = NULL;
int ret = -1;
fd_t *fd = NULL;
@@ -2304,8 +2305,20 @@ glfd_entry_refresh (struct glfs_fd *glfd, int plus)
&entries, NULL, NULL);
DECODE_SYNCOP_ERR (ret);
if (ret >= 0) {
- if (plus)
+ if (plus) {
+ /**
+ * Set inode_needs_lookup flag before linking the
+ * inode. Doing it later post linkage might lead
+ * to a race where a fop comes after inode link
+ * but before setting need_lookup flag.
+ */
+ list_for_each_entry (entry, &glfd->entries, list) {
+ if (entry->inode)
+ inode_set_need_lookup (entry->inode, THIS);
+ }
+
gf_link_inodes_from_dirent (THIS, fd->inode, &entries);
+ }
list_splice_init (&glfd->entries, &old.list);
list_splice_init (&entries.list, &glfd->entries);
@@ -2314,6 +2327,7 @@ glfd_entry_refresh (struct glfs_fd *glfd, int plus)
errno = 0;
}
+
if (ret > 0)
glfd->next = list_entry (glfd->entries.next, gf_dirent_t, list);
diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c
index 2767abf1c39..b5efcbae0e7 100644
--- a/api/src/glfs-resolve.c
+++ b/api/src/glfs-resolve.c
@@ -75,27 +75,44 @@ __glfs_first_lookup (struct glfs *fs, xlator_t *subvol)
}
+/**
+ * We have to check if need_lookup flag is set in both old and the new inodes.
+ * If its set in oldinode, then directly go ahead and do an explicit lookup.
+ * But if its not set in the oldinode, then check if the newinode is linked
+ * via readdirp. If so an explicit lookup is needed on the new inode, so that
+ * below xlators can set their respective contexts.
+ */
inode_t *
-glfs_refresh_inode_safe (xlator_t *subvol, inode_t *oldinode)
+glfs_refresh_inode_safe (xlator_t *subvol, inode_t *oldinode,
+ gf_boolean_t need_lookup)
{
loc_t loc = {0, };
int ret = -1;
struct iatt iatt = {0, };
inode_t *newinode = NULL;
+ gf_boolean_t lookup_needed = _gf_false;
if (!oldinode)
return NULL;
- if (oldinode->table->xl == subvol)
+ if (!need_lookup && oldinode->table->xl == subvol)
return inode_ref (oldinode);
newinode = inode_find (subvol->itable, oldinode->gfid);
- if (newinode)
- return newinode;
+ if (!need_lookup && newinode) {
+
+ lookup_needed = inode_needs_lookup (newinode, THIS);
+ if (!lookup_needed)
+ return newinode;
+ }
gf_uuid_copy (loc.gfid, oldinode->gfid);
- loc.inode = inode_new (subvol->itable);
+ if (!newinode)
+ loc.inode = inode_new (subvol->itable);
+ else
+ loc.inode = newinode;
+
if (!loc.inode)
return NULL;
@@ -122,14 +139,15 @@ glfs_refresh_inode_safe (xlator_t *subvol, inode_t *oldinode)
inode_t *
-__glfs_refresh_inode (struct glfs *fs, xlator_t *subvol, inode_t *inode)
+__glfs_refresh_inode (struct glfs *fs, xlator_t *subvol, inode_t *inode,
+ gf_boolean_t need_lookup)
{
inode_t *newinode = NULL;
fs->migration_in_progress = 1;
pthread_mutex_unlock (&fs->mutex);
{
- newinode = glfs_refresh_inode_safe (subvol, inode);
+ newinode = glfs_refresh_inode_safe (subvol, inode, need_lookup);
}
pthread_mutex_lock (&fs->mutex);
fs->migration_in_progress = 0;
@@ -622,7 +640,7 @@ glfs_migrate_fd_safe (struct glfs *fs, xlator_t *newsubvol, fd_t *oldfd)
}
}
- newinode = glfs_refresh_inode_safe (newsubvol, oldinode);
+ newinode = glfs_refresh_inode_safe (newsubvol, oldinode, _gf_false);
if (!newinode) {
gf_msg (fs->volname, GF_LOG_WARNING, errno,
API_MSG_INODE_REFRESH_FAILED,
@@ -810,7 +828,8 @@ __glfs_active_subvol (struct glfs *fs)
}
if (fs->cwd) {
- new_cwd = __glfs_refresh_inode (fs, new_subvol, fs->cwd);
+ new_cwd = __glfs_refresh_inode (fs, new_subvol, fs->cwd,
+ _gf_false);
if (!new_cwd) {
char buf1[64];
@@ -904,7 +923,8 @@ int
__glfs_cwd_set (struct glfs *fs, inode_t *inode)
{
if (inode->table->xl != fs->active_subvol) {
- inode = __glfs_refresh_inode (fs, fs->active_subvol, inode);
+ inode = __glfs_refresh_inode (fs, fs->active_subvol, inode,
+ _gf_false);
if (!inode)
return -1;
} else {
@@ -948,7 +968,7 @@ __glfs_cwd_get (struct glfs *fs)
return cwd;
}
- cwd = __glfs_refresh_inode (fs, fs->active_subvol, fs->cwd);
+ cwd = __glfs_refresh_inode (fs, fs->active_subvol, fs->cwd, _gf_false);
return cwd;
}
@@ -972,12 +992,15 @@ __glfs_resolve_inode (struct glfs *fs, xlator_t *subvol,
struct glfs_object *object)
{
inode_t *inode = NULL;
+ gf_boolean_t lookup_needed = _gf_false;
+
+ lookup_needed = inode_needs_lookup (object->inode, THIS);
- if (object->inode->table->xl == subvol)
+ if (!lookup_needed && object->inode->table->xl == subvol)
return inode_ref (object->inode);
inode = __glfs_refresh_inode (fs, fs->active_subvol,
- object->inode);
+ object->inode, lookup_needed);
if (!inode)
return NULL;