diff options
Diffstat (limited to 'xlators/features/bit-rot')
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__ */  | 
