From b86a7de9b5ea9dcd0a630dbe09fce6d9ad0d8944 Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Tue, 6 Sep 2016 18:28:42 +0530 Subject: feature/bitrot: Fix recovery of corrupted hardlink Problem: When a file with hardlink is corrupted in ec volume, the recovery steps mentioned was not working. Only name and metadata was healing but not the data. Cause: The bad file marker in the inode context is not removed. Hence when self heal tries to open the file for data healing, it fails with EIO. Background: The bitrot deletes inode context during forget. Briefly, the recovery steps involves following steps. 1. Delete the entry marked with bad file xattr from backend. Delete all the hardlinks including .glusters hardlink as well. 2. Access the each hardlink of the file including original from the mount. The step 2 will send lookup to the brick where the files are deleted from backend and returns with ENOENT. On ENOENT, server xlator forgets the inode if there are no dentries associated with it. But in case hardlinks, the forget won't be called as dentries (other hardlink files) are associated with the inode. Hence bitrot stube won't delete it's context failing the data self heal. Fix: Bitrot-stub should delete the inode context on getting ENOENT during lookup. Change-Id: Ice6adc18625799e7afd842ab33b3517c2be264c1 BUG: 1373520 Signed-off-by: Kotresh HR Reviewed-on: http://review.gluster.org/15408 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Raghavendra Bhat --- xlators/features/bit-rot/src/stub/bit-rot-stub.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'xlators/features/bit-rot/src/stub/bit-rot-stub.c') diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.c b/xlators/features/bit-rot/src/stub/bit-rot-stub.c index 67103f6b5e1..4e01f5c86b1 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c @@ -2631,6 +2631,18 @@ br_stub_handle_lookup_error (xlator_t *this, inode_t *inode, int32_t op_errno) } UNLOCK (&inode->lock); + if (__br_stub_is_bad_object (ctx)) { + /* File is not present, might be deleted for recovery, + * del the bitrot inode context + */ + ctx_addr = 0; + inode_ctx_del (inode, this, &ctx_addr); + if (ctx_addr) { + ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; + GF_FREE (ctx); + } + } + out: return; } -- cgit