|
|
d1681e |
From 59fafc2b918846cc59daac107981211fa1568335 Mon Sep 17 00:00:00 2001
|
|
|
d1681e |
From: Susant Palai <spalai@redhat.com>
|
|
|
d1681e |
Date: Mon, 6 Aug 2018 15:02:58 +0530
|
|
|
d1681e |
Subject: [PATCH 350/351] cluster/dht: fix inode ref management in
|
|
|
d1681e |
dht_heal_path
|
|
|
d1681e |
|
|
|
d1681e |
In dht_heal_path, the inodes are created & looked up from top to down.
|
|
|
d1681e |
|
|
|
d1681e |
If the path is "a/b/c", then lookup will be done on a, then b and so
|
|
|
d1681e |
on. Here is a rough snippet of the function "dht_heal_path".
|
|
|
d1681e |
|
|
|
d1681e |
<snippet>
|
|
|
d1681e |
if (bname) { ref_count
|
|
|
d1681e |
- loc.inode = create/grep inode 1
|
|
|
d1681e |
- syncop_lookup (loc.inode)
|
|
|
d1681e |
- linked_inode = inode_link (loc.inode) 2
|
|
|
d1681e |
/*clean up current loc*/
|
|
|
d1681e |
- loc_wipe(&loc) 1
|
|
|
d1681e |
/*set up parent and bname for next child */
|
|
|
d1681e |
- loc.parent = inode
|
|
|
d1681e |
- bname = next_child_name
|
|
|
d1681e |
}
|
|
|
d1681e |
out:
|
|
|
d1681e |
- inode_ref (linked_inode) 2
|
|
|
d1681e |
- loc_wipe (&loc) 1
|
|
|
d1681e |
</snippet>
|
|
|
d1681e |
|
|
|
d1681e |
The problem with the above code is if _bname_ is empty ie the chain lookup is
|
|
|
d1681e |
done, then for the next iteration we populate loc.parent anyway. Now that
|
|
|
d1681e |
bname is empty, the loc_wipe is done in the _out_ section as well. Since, the
|
|
|
d1681e |
loc.parent was set to the previous inode, we lose a ref unwantedly. Now a
|
|
|
d1681e |
dht_local_wipe as part of the DHT_STACK_UNWIND takes away the last ref leading
|
|
|
d1681e |
to inode_destroy.
|
|
|
d1681e |
|
|
|
d1681e |
This problenm is observed currently with nfs-ganesha with the nameless lookup.
|
|
|
d1681e |
Post the inode_purge, gfapi does not get the new inode to link and hence, it links
|
|
|
d1681e |
the inode it sent in the lookup fop, which does not have any dht related context
|
|
|
d1681e |
(layout) leading to "invalid argument error" in lookup path done parallely with tar
|
|
|
d1681e |
operation.
|
|
|
d1681e |
|
|
|
d1681e |
test done in the following way:
|
|
|
d1681e |
- create two nfs client connected with two different nfs servers.
|
|
|
d1681e |
- run untar on one client and run lookup continuously on the other.
|
|
|
d1681e |
- Prior to this patch, invalid arguement was seen which is fixed with
|
|
|
d1681e |
the current patch.
|
|
|
d1681e |
|
|
|
d1681e |
> Change-Id: Ifb90c178a2f3c16604068c7da8fa562b877f5c61
|
|
|
d1681e |
> fixes: bz#1610256
|
|
|
d1681e |
> Signed-off-by: Susant Palai <spalai@redhat.com>
|
|
|
d1681e |
(backport of https://review.gluster.org/#/c/glusterfs/+/20643/)
|
|
|
d1681e |
|
|
|
d1681e |
Fixes: bz#1569657
|
|
|
d1681e |
Change-Id: I94329f2d148c31fe85a8753256e7aaf1d4d337ac
|
|
|
d1681e |
BUG: 1569657
|
|
|
d1681e |
Signed-off-by: Susant Palai <spalai@redhat.com>
|
|
|
d1681e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/146966
|
|
|
d1681e |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
d1681e |
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
|
|
|
d1681e |
---
|
|
|
d1681e |
xlators/cluster/dht/src/dht-helper.c | 9 +++++++--
|
|
|
d1681e |
1 file changed, 7 insertions(+), 2 deletions(-)
|
|
|
d1681e |
|
|
|
d1681e |
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
|
|
|
d1681e |
index 09ca966..d35d7e8 100644
|
|
|
d1681e |
--- a/xlators/cluster/dht/src/dht-helper.c
|
|
|
d1681e |
+++ b/xlators/cluster/dht/src/dht-helper.c
|
|
|
d1681e |
@@ -1974,12 +1974,16 @@ dht_heal_path (xlator_t *this, char *path, inode_table_t *itable)
|
|
|
d1681e |
} else {
|
|
|
d1681e |
/*
|
|
|
d1681e |
* Inode is already populated in the inode table.
|
|
|
d1681e |
- * Which means we already looked up the inde and
|
|
|
d1681e |
+ * Which means we already looked up the inode and
|
|
|
d1681e |
* linked with a dentry. So that we will skip
|
|
|
d1681e |
* lookup on this entry, and proceed to next.
|
|
|
d1681e |
*/
|
|
|
d1681e |
+ linked_inode = loc.inode;
|
|
|
d1681e |
bname = strtok_r (NULL, "/", &save_ptr);
|
|
|
d1681e |
inode_unref (loc.parent);
|
|
|
d1681e |
+ if (!bname) {
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
loc.parent = loc.inode;
|
|
|
d1681e |
gf_uuid_copy (loc.pargfid, loc.inode->gfid);
|
|
|
d1681e |
loc.inode = NULL;
|
|
|
d1681e |
@@ -2005,9 +2009,10 @@ dht_heal_path (xlator_t *this, char *path, inode_table_t *itable)
|
|
|
d1681e |
loc_wipe (&loc;;
|
|
|
d1681e |
gf_uuid_copy (loc.pargfid, linked_inode->gfid);
|
|
|
d1681e |
loc.inode = NULL;
|
|
|
d1681e |
- loc.parent = linked_inode;
|
|
|
d1681e |
|
|
|
d1681e |
bname = strtok_r (NULL, "/", &save_ptr);
|
|
|
d1681e |
+ if (bname)
|
|
|
d1681e |
+ loc.parent = linked_inode;
|
|
|
d1681e |
}
|
|
|
d1681e |
out:
|
|
|
d1681e |
inode_ref (linked_inode);
|
|
|
d1681e |
--
|
|
|
d1681e |
1.8.3.1
|
|
|
d1681e |
|