diff options
Diffstat (limited to 'xlators/features')
4 files changed, 95 insertions, 2 deletions
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c b/xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c index f637e150a57..306b44da083 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c @@ -194,6 +194,35 @@ out: return -1; } +int +br_stub_del (xlator_t *this, uuid_t gfid) +{ + int32_t op_errno __attribute__((unused)) = 0; + br_stub_private_t *priv = NULL; + int ret = 0; + char gfid_path[PATH_MAX] = {0}; + + priv = this->private; + GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, !gf_uuid_is_null (gfid), + out, op_errno, EINVAL); + br_stub_linked_entry (priv, gfid_path, gfid, + sizeof (gfid_path)); + ret = sys_unlink (gfid_path); + if (ret && (errno != ENOENT)) { + gf_msg (this->name, GF_LOG_ERROR, errno, + BRS_MSG_BAD_OBJ_UNLINK_FAIL, + "%s: failed to delete bad object link from quarantine " + "directory", gfid_path); + ret = -errno; + goto out; + } + + ret = 0; + +out: + return ret; +} + static int br_stub_check_stub_directory (xlator_t *this, char *fullpath) { diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h b/xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h index ee39e4c6d9f..c0fcfd324a5 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h @@ -40,7 +40,7 @@ */ #define GLFS_BITROT_STUB_BASE GLFS_MSGID_COMP_BITROT_STUB -#define GLFS_BITROT_STUB_NUM_MESSAGES 30 +#define GLFS_BITROT_STUB_NUM_MESSAGES 31 #define GLFS_MSGID_END (GLFS_BITROT_STUB_BASE + \ GLFS_BITROT_STUB_NUM_MESSAGES + 1) /* Messaged with message IDs */ @@ -258,6 +258,13 @@ * @recommendedaction * */ +#define BRS_MSG_BAD_OBJ_UNLINK_FAIL (GLFS_BITROT_STUB_BASE + 31) +/*! + * @messageid + * @diagnosis + * @recommendedaction + * + */ /*------------*/ #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" 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 27a5ff7559a..052b663e9b5 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c @@ -2575,6 +2575,44 @@ br_stub_readdirp (call_frame_t *frame, xlator_t *this, /* lookup() */ +/** + * This function mainly handles the ENOENT error for the bad objects. Though + * br_stub_forget () handles removal of the link for the bad object from the + * quarantine directory, its better to handle it in lookup as well, where + * a failed lookup on a bad object with ENOENT, will trigger deletion of the + * link for the bad object from quarantine directory. So whoever comes first + * either forget () or lookup () will take care of removing the link. + */ +void +br_stub_handle_lookup_error (xlator_t *this, inode_t *inode, int32_t op_errno) +{ + int32_t ret = -1; + uint64_t ctx_addr = 0; + br_stub_inode_ctx_t *ctx = NULL; + + if (op_errno != ENOENT) + goto out; + + if (!inode_is_linked (inode)) + goto out; + + ret = br_stub_get_inode_ctx (this, inode, &ctx_addr); + if (ret) + goto out; + + ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; + + LOCK (&inode->lock); + { + if (__br_stub_is_bad_object (ctx)) + (void) br_stub_del (this, inode->gfid); + } + UNLOCK (&inode->lock); + +out: + return; +} + int br_stub_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, @@ -2582,8 +2620,11 @@ br_stub_lookup_cbk (call_frame_t *frame, void *cookie, { int32_t ret = 0; - if (op_ret < 0) + if (op_ret < 0) { + (void) br_stub_handle_lookup_error (this, inode, op_errno); goto unwind; + } + if (!IA_ISREG (stbuf->ia_type)) goto unwind; @@ -2737,6 +2778,20 @@ br_stub_forget (xlator_t *this, inode_t *inode) return 0; ctx = (br_stub_inode_ctx_t *) (long) ctx_addr; + + LOCK (&inode->lock); + { + /** + * Ignoring the return value of br_stub_del (). + * There is not much that can be done if unlinking + * of the entry in the quarantine directory fails. + * The failure is logged. + */ + if (__br_stub_is_bad_object (ctx)) + (void) br_stub_del (this, inode->gfid); + } + UNLOCK (&inode->lock); + GF_FREE (ctx); return 0; diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.h b/xlators/features/bit-rot/src/stub/bit-rot-stub.h index 26ed5fe0bdb..2d515417059 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub.h +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.h @@ -457,5 +457,7 @@ int32_t br_stub_readdir_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, dict_t *xdata); +int +br_stub_del (xlator_t *this, uuid_t gfid); #endif /* __BIT_ROT_STUB_H__ */ |