summaryrefslogtreecommitdiffstats
path: root/xlators/features
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features')
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c29
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h9
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub.c57
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub.h2
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__ */