|
|
cb8e9e |
From 8509249e4a211013ff923bd5f2c6891da7275143 Mon Sep 17 00:00:00 2001
|
|
|
cb8e9e |
From: Raghavendra Bhat <raghavendra@redhat.com>
|
|
|
cb8e9e |
Date: Wed, 1 Jul 2015 15:56:58 +0530
|
|
|
cb8e9e |
Subject: [PATCH 287/304] protocol/server: forget the inodes which got ENOENT in lookup
|
|
|
cb8e9e |
|
|
|
cb8e9e |
Upstream Review: http://review.gluster.org/11489
|
|
|
cb8e9e |
|
|
|
cb8e9e |
If a looked up object is removed from the backend, then upon getting a
|
|
|
cb8e9e |
revalidated lookup on that object ENOENT error is received. protocol/server
|
|
|
cb8e9e |
xlator handles it by removing dentry upon which ENOENT is received. But the
|
|
|
cb8e9e |
inode associated with it still remains in the inode table, and whoever does
|
|
|
cb8e9e |
nameless lookup on the gfid of that object will be able to do it successfully
|
|
|
cb8e9e |
despite the object being not present.
|
|
|
cb8e9e |
|
|
|
cb8e9e |
For handling this issue, upon getting ENOENT on a looked up entry in revalidate
|
|
|
cb8e9e |
lookups, protocol/server should forget the inode as well.
|
|
|
cb8e9e |
|
|
|
cb8e9e |
Though removing files directly from the backend is not allowed, in case of
|
|
|
cb8e9e |
objects corrupted due to bitrot and marked as bad by scrubber, objects are
|
|
|
cb8e9e |
removed directly from the backend in case of replicate volumes, so that the
|
|
|
cb8e9e |
object is healed from the good copy. For handling this, the inode of the bad
|
|
|
cb8e9e |
object removed from the backend should be forgotten. Otherwise, the inode which
|
|
|
cb8e9e |
knows the object it represents is bad, does not allow read/write operations
|
|
|
cb8e9e |
happening as part of self-heal.
|
|
|
cb8e9e |
|
|
|
cb8e9e |
> Change-Id: I23b7a5bef919c98eea684aa1e977e317066cfc71
|
|
|
cb8e9e |
> BUG: 1238188
|
|
|
cb8e9e |
> Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
|
|
|
cb8e9e |
> Reviewed-on: http://review.gluster.org/11489
|
|
|
cb8e9e |
> Tested-by: NetBSD Build System <jenkins@build.gluster.org>
|
|
|
cb8e9e |
> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
|
|
|
cb8e9e |
> Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
|
|
|
cb8e9e |
|
|
|
cb8e9e |
Change-Id: I9823e8562f05b2a5af0b70c17a5471014e0a179e
|
|
|
cb8e9e |
BUG: 1238171
|
|
|
cb8e9e |
Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
|
|
|
cb8e9e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/55868
|
|
|
cb8e9e |
---
|
|
|
cb8e9e |
libglusterfs/src/inode.c | 26 +++++++++++
|
|
|
cb8e9e |
libglusterfs/src/inode.h | 3 +
|
|
|
cb8e9e |
xlators/protocol/server/src/server-rpc-fops.c | 56 +++++++++++++++----------
|
|
|
cb8e9e |
xlators/protocol/server/src/server.h | 3 +
|
|
|
cb8e9e |
4 files changed, 66 insertions(+), 22 deletions(-)
|
|
|
cb8e9e |
|
|
|
cb8e9e |
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
|
|
|
cb8e9e |
index 7b49fbe..af50865 100644
|
|
|
cb8e9e |
--- a/libglusterfs/src/inode.c
|
|
|
cb8e9e |
+++ b/libglusterfs/src/inode.c
|
|
|
cb8e9e |
@@ -1319,6 +1319,32 @@ inode_parent (inode_t *inode, uuid_t pargfid, const char *name)
|
|
|
cb8e9e |
return parent;
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+static int
|
|
|
cb8e9e |
+__inode_has_dentry (inode_t *inode)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ if (!inode) {
|
|
|
cb8e9e |
+ gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
|
|
|
cb8e9e |
+ LG_MSG_INODE_NOT_FOUND, "inode not found");
|
|
|
cb8e9e |
+ return 0;
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ return !list_empty (&inode->dentry_list);
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+int
|
|
|
cb8e9e |
+inode_has_dentry (inode_t *inode)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ int dentry_present = 0;
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ LOCK (&inode->lock);
|
|
|
cb8e9e |
+ {
|
|
|
cb8e9e |
+ dentry_present = __inode_has_dentry (inode);
|
|
|
cb8e9e |
+ }
|
|
|
cb8e9e |
+ UNLOCK (&inode->lock);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ return dentry_present;
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
int
|
|
|
cb8e9e |
__inode_path (inode_t *inode, const char *name, char **bufp)
|
|
|
cb8e9e |
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
|
|
|
cb8e9e |
index 474dc39..fcc150b 100644
|
|
|
cb8e9e |
--- a/libglusterfs/src/inode.h
|
|
|
cb8e9e |
+++ b/libglusterfs/src/inode.h
|
|
|
cb8e9e |
@@ -272,4 +272,7 @@ inode_ctx_merge (fd_t *fd, inode_t *inode, inode_t *linked_inode);
|
|
|
cb8e9e |
int
|
|
|
cb8e9e |
inode_is_linked (inode_t *inode);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+int
|
|
|
cb8e9e |
+inode_has_dentry (inode_t *inode);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
#endif /* _INODE_H */
|
|
|
cb8e9e |
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
|
|
|
cb8e9e |
index 99b8011..bd1ced4 100644
|
|
|
cb8e9e |
--- a/xlators/protocol/server/src/server-rpc-fops.c
|
|
|
cb8e9e |
+++ b/xlators/protocol/server/src/server-rpc-fops.c
|
|
|
cb8e9e |
@@ -32,6 +32,16 @@
|
|
|
cb8e9e |
ret = RPCSVC_ACTOR_ERROR; \
|
|
|
cb8e9e |
} while (0)
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+void
|
|
|
cb8e9e |
+forget_inode_if_no_dentry (inode_t *inode)
|
|
|
cb8e9e |
+{
|
|
|
cb8e9e |
+ if (!inode_has_dentry (inode))
|
|
|
cb8e9e |
+ inode_forget (inode, 0);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+ return;
|
|
|
cb8e9e |
+}
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
/* Callback function section */
|
|
|
cb8e9e |
int
|
|
|
cb8e9e |
server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
cb8e9e |
@@ -108,6 +118,23 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
cb8e9e |
inode_unlink (state->loc.inode,
|
|
|
cb8e9e |
state->loc.parent,
|
|
|
cb8e9e |
state->loc.name);
|
|
|
cb8e9e |
+ /**
|
|
|
cb8e9e |
+ * If the entry is not present, then just
|
|
|
cb8e9e |
+ * unlinking the associated dentry is not
|
|
|
cb8e9e |
+ * suffecient. This condition should be
|
|
|
cb8e9e |
+ * treated as unlink of the entry. So along
|
|
|
cb8e9e |
+ * with deleting the entry, its also important
|
|
|
cb8e9e |
+ * to forget the inode for it (if the dentry
|
|
|
cb8e9e |
+ * being considered was the last dentry).
|
|
|
cb8e9e |
+ * Otherwise it might lead to inode leak.
|
|
|
cb8e9e |
+ * It also might lead to wrong decisions being
|
|
|
cb8e9e |
+ * taken if the future lookups on this inode are
|
|
|
cb8e9e |
+ * successful since they are able to find the
|
|
|
cb8e9e |
+ * inode in the inode table (atleast gfid based
|
|
|
cb8e9e |
+ * lookups will be successful, if the lookup
|
|
|
cb8e9e |
+ * is a soft lookup)
|
|
|
cb8e9e |
+ */
|
|
|
cb8e9e |
+ forget_inode_if_no_dentry (state->loc.inode);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
goto out;
|
|
|
cb8e9e |
@@ -416,7 +443,6 @@ server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
gfs3_rmdir_rsp rsp = {0,};
|
|
|
cb8e9e |
server_state_t *state = NULL;
|
|
|
cb8e9e |
- inode_t *parent = NULL;
|
|
|
cb8e9e |
rpcsvc_request_t *req = NULL;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
|
|
|
cb8e9e |
@@ -436,15 +462,11 @@ server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
cb8e9e |
|
|
|
cb8e9e |
inode_unlink (state->loc.inode, state->loc.parent,
|
|
|
cb8e9e |
state->loc.name);
|
|
|
cb8e9e |
- parent = inode_parent (state->loc.inode, 0, NULL);
|
|
|
cb8e9e |
- if (parent)
|
|
|
cb8e9e |
- /* parent should not be found for directories after
|
|
|
cb8e9e |
- * inode_unlink, since directories cannot have
|
|
|
cb8e9e |
- * hardlinks.
|
|
|
cb8e9e |
- */
|
|
|
cb8e9e |
- inode_unref (parent);
|
|
|
cb8e9e |
- else
|
|
|
cb8e9e |
- inode_forget (state->loc.inode, 0);
|
|
|
cb8e9e |
+ /* parent should not be found for directories after
|
|
|
cb8e9e |
+ * inode_unlink, since directories cannot have
|
|
|
cb8e9e |
+ * hardlinks.
|
|
|
cb8e9e |
+ */
|
|
|
cb8e9e |
+ forget_inode_if_no_dentry (state->loc.inode);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
gf_stat_from_iatt (&rsp.preparent, preparent);
|
|
|
cb8e9e |
gf_stat_from_iatt (&rsp.postparent, postparent);
|
|
|
cb8e9e |
@@ -1023,12 +1045,7 @@ server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
cb8e9e |
if (tmp_inode) {
|
|
|
cb8e9e |
inode_unlink (tmp_inode, state->loc2.parent,
|
|
|
cb8e9e |
state->loc2.name);
|
|
|
cb8e9e |
- tmp_parent = inode_parent (tmp_inode, 0, NULL);
|
|
|
cb8e9e |
- if (tmp_parent)
|
|
|
cb8e9e |
- inode_unref (tmp_parent);
|
|
|
cb8e9e |
- else
|
|
|
cb8e9e |
- inode_forget (tmp_inode, 0);
|
|
|
cb8e9e |
-
|
|
|
cb8e9e |
+ forget_inode_if_no_dentry (tmp_inode);
|
|
|
cb8e9e |
inode_unref (tmp_inode);
|
|
|
cb8e9e |
}
|
|
|
cb8e9e |
|
|
|
cb8e9e |
@@ -1064,7 +1081,6 @@ server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
cb8e9e |
{
|
|
|
cb8e9e |
gfs3_unlink_rsp rsp = {0,};
|
|
|
cb8e9e |
server_state_t *state = NULL;
|
|
|
cb8e9e |
- inode_t *parent = NULL;
|
|
|
cb8e9e |
rpcsvc_request_t *req = NULL;
|
|
|
cb8e9e |
|
|
|
cb8e9e |
GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
|
|
|
cb8e9e |
@@ -1089,11 +1105,7 @@ server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
cb8e9e |
inode_unlink (state->loc.inode, state->loc.parent,
|
|
|
cb8e9e |
state->loc.name);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
- parent = inode_parent (state->loc.inode, 0, NULL);
|
|
|
cb8e9e |
- if (parent)
|
|
|
cb8e9e |
- inode_unref (parent);
|
|
|
cb8e9e |
- else
|
|
|
cb8e9e |
- inode_forget (state->loc.inode, 0);
|
|
|
cb8e9e |
+ forget_inode_if_no_dentry (state->loc.inode);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
gf_stat_from_iatt (&rsp.preparent, preparent);
|
|
|
cb8e9e |
gf_stat_from_iatt (&rsp.postparent, postparent);
|
|
|
cb8e9e |
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
|
|
|
cb8e9e |
index 6caf449..1055b72 100644
|
|
|
cb8e9e |
--- a/xlators/protocol/server/src/server.h
|
|
|
cb8e9e |
+++ b/xlators/protocol/server/src/server.h
|
|
|
cb8e9e |
@@ -172,4 +172,7 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
|
|
|
cb8e9e |
int gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict);
|
|
|
cb8e9e |
int gf_server_check_getxattr_cmd (call_frame_t *frame, const char *name);
|
|
|
cb8e9e |
|
|
|
cb8e9e |
+void
|
|
|
cb8e9e |
+forget_inode_if_no_dentry (inode_t *inode);
|
|
|
cb8e9e |
+
|
|
|
cb8e9e |
#endif /* !_SERVER_H */
|
|
|
cb8e9e |
--
|
|
|
cb8e9e |
1.7.1
|
|
|
cb8e9e |
|