|
|
12a457 |
From 44ef95f37891c6023dd625b495849673fe8ccece Mon Sep 17 00:00:00 2001
|
|
|
12a457 |
From: Soumya Koduri <skoduri@redhat.com>
|
|
|
12a457 |
Date: Sat, 30 Apr 2016 22:01:47 +0530
|
|
|
12a457 |
Subject: [PATCH 127/139] gfapi/upcall: Ignore handle create failures
|
|
|
12a457 |
|
|
|
12a457 |
In "glfs_h_poll_cache_invalidation", we need to send upcall only if there
|
|
|
12a457 |
is a corresponding inode entry in the gfapi inode table for that handle.
|
|
|
12a457 |
|
|
|
12a457 |
That's because the application will have reference to the inode as long as
|
|
|
12a457 |
it operates on any handle. That means the only case in which we cannot find
|
|
|
12a457 |
inode is when the application has closed the handle (either as part of unlink
|
|
|
12a457 |
or for any other purpose). But since it will have no more references and will
|
|
|
12a457 |
not be interested in any upcall event for that handle, we can safely ignore such
|
|
|
12a457 |
cases.
|
|
|
12a457 |
|
|
|
12a457 |
Note: This will affect only that particular applicaiton process/local libgfapi
|
|
|
12a457 |
client.
|
|
|
12a457 |
|
|
|
12a457 |
This is backport of the below upstream fixes -
|
|
|
12a457 |
http://review.gluster.org/14132 (upstream)
|
|
|
12a457 |
http://review.gluster.org/#/c/14181/ (release-3.7)
|
|
|
12a457 |
|
|
|
12a457 |
Change-Id: I9499cd9c284350d4a271e58f2a0966db65a7a61c
|
|
|
12a457 |
BUG: 1323424
|
|
|
12a457 |
Signed-off-by: Soumya Koduri <skoduri@redhat.com>
|
|
|
12a457 |
Reviewed-on: http://review.gluster.org/14132
|
|
|
12a457 |
Reviewed-by: jiffin tony Thottan <jthottan@redhat.com>
|
|
|
12a457 |
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
|
|
|
12a457 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/73590
|
|
|
12a457 |
Reviewed-by: Jiffin Thottan <jthottan@redhat.com>
|
|
|
12a457 |
Reviewed-by: Kaleb Keithley <kkeithle@redhat.com>
|
|
|
12a457 |
Tested-by: Kaleb Keithley <kkeithle@redhat.com>
|
|
|
12a457 |
---
|
|
|
12a457 |
api/src/glfs-handleops.c | 142 ++++++++++++++++++++++++++++++++++++++--------
|
|
|
12a457 |
1 files changed, 118 insertions(+), 24 deletions(-)
|
|
|
12a457 |
|
|
|
12a457 |
diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c
|
|
|
12a457 |
index a230578..72aa7de 100644
|
|
|
12a457 |
--- a/api/src/glfs-handleops.c
|
|
|
12a457 |
+++ b/api/src/glfs-handleops.c
|
|
|
12a457 |
@@ -1805,6 +1805,69 @@ invalid_fs:
|
|
|
12a457 |
|
|
|
12a457 |
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2);
|
|
|
12a457 |
|
|
|
12a457 |
+/*
|
|
|
12a457 |
+ * Given a handle/gfid, find if the corresponding inode is present in
|
|
|
12a457 |
+ * the inode table. If yes create and return the corresponding glfs_object.
|
|
|
12a457 |
+ */
|
|
|
12a457 |
+struct glfs_object *
|
|
|
12a457 |
+glfs_h_find_handle (struct glfs *fs, unsigned char *handle, int len)
|
|
|
12a457 |
+{
|
|
|
12a457 |
+ int ret = -1;
|
|
|
12a457 |
+ inode_t *newinode = NULL;
|
|
|
12a457 |
+ xlator_t *subvol = NULL;
|
|
|
12a457 |
+ struct glfs_object *object = NULL;
|
|
|
12a457 |
+ uuid_t gfid;
|
|
|
12a457 |
+
|
|
|
12a457 |
+ /* validate in args */
|
|
|
12a457 |
+ if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) {
|
|
|
12a457 |
+ errno = EINVAL;
|
|
|
12a457 |
+ return NULL;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
+ DECLARE_OLD_THIS;
|
|
|
12a457 |
+ __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
|
|
|
12a457 |
+
|
|
|
12a457 |
+ /* get the active volume */
|
|
|
12a457 |
+ subvol = glfs_active_subvol (fs);
|
|
|
12a457 |
+ if (!subvol) {
|
|
|
12a457 |
+ errno = EIO;
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
+ memcpy (gfid, handle, GFAPI_HANDLE_LENGTH);
|
|
|
12a457 |
+
|
|
|
12a457 |
+ /* make sure the gfid received is valid */
|
|
|
12a457 |
+ GF_VALIDATE_OR_GOTO ("glfs_h_find_handle",
|
|
|
12a457 |
+ !(gf_uuid_is_null (gfid)), out);
|
|
|
12a457 |
+
|
|
|
12a457 |
+ newinode = inode_find (subvol->itable, gfid);
|
|
|
12a457 |
+ if (!newinode) {
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
+ object = GF_CALLOC (1, sizeof(struct glfs_object),
|
|
|
12a457 |
+ glfs_mt_glfs_object_t);
|
|
|
12a457 |
+ if (object == NULL) {
|
|
|
12a457 |
+ errno = ENOMEM;
|
|
|
12a457 |
+ ret = -1;
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
+
|
|
|
12a457 |
+ /* populate the return object. The ref taken here
|
|
|
12a457 |
+ * is un'refed when the application does glfs_h_close() */
|
|
|
12a457 |
+ object->inode = inode_ref(newinode);
|
|
|
12a457 |
+ gf_uuid_copy (object->gfid, object->inode->gfid);
|
|
|
12a457 |
+
|
|
|
12a457 |
+out:
|
|
|
12a457 |
+ glfs_subvol_done (fs, subvol);
|
|
|
12a457 |
+
|
|
|
12a457 |
+ __GLFS_EXIT_FS;
|
|
|
12a457 |
+
|
|
|
12a457 |
+invalid_fs:
|
|
|
12a457 |
+ return object;
|
|
|
12a457 |
+
|
|
|
12a457 |
+}
|
|
|
12a457 |
+
|
|
|
12a457 |
int
|
|
|
12a457 |
glfs_h_poll_cache_invalidation (struct glfs *fs,
|
|
|
12a457 |
struct callback_arg *up_arg,
|
|
|
12a457 |
@@ -1821,11 +1884,24 @@ glfs_h_poll_cache_invalidation (struct glfs *fs,
|
|
|
12a457 |
GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
|
|
|
12a457 |
ca_data, out);
|
|
|
12a457 |
|
|
|
12a457 |
- object = glfs_h_create_from_handle (fs, upcall_data->gfid,
|
|
|
12a457 |
- GFAPI_HANDLE_LENGTH,
|
|
|
12a457 |
- NULL);
|
|
|
12a457 |
- GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
|
|
|
12a457 |
- object, out);
|
|
|
12a457 |
+ object = glfs_h_find_handle (fs, upcall_data->gfid,
|
|
|
12a457 |
+ GFAPI_HANDLE_LENGTH);
|
|
|
12a457 |
+ if (!object) {
|
|
|
12a457 |
+ /* The reason handle creation will fail is because we
|
|
|
12a457 |
+ * couldn't find the inode in the gfapi inode table.
|
|
|
12a457 |
+ *
|
|
|
12a457 |
+ * But since application would have taken inode_ref, the
|
|
|
12a457 |
+ * only case when this can happen is when it has closed
|
|
|
12a457 |
+ * the handle and hence will no more be interested in
|
|
|
12a457 |
+ * the upcall for this particular gfid.
|
|
|
12a457 |
+ */
|
|
|
12a457 |
+ gf_msg (THIS->name, GF_LOG_DEBUG, errno,
|
|
|
12a457 |
+ API_MSG_CREATE_HANDLE_FAILED,
|
|
|
12a457 |
+ "handle creation of %s failed",
|
|
|
12a457 |
+ uuid_utoa (upcall_data->gfid));
|
|
|
12a457 |
+ errno = ESTALE;
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
|
|
|
12a457 |
up_inode_arg = calloc (1, sizeof (struct callback_inode_arg));
|
|
|
12a457 |
GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
|
|
|
12a457 |
@@ -1844,12 +1920,17 @@ glfs_h_poll_cache_invalidation (struct glfs *fs,
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
if (ca_data->flags & GFAPI_UP_PARENT_TIMES) {
|
|
|
12a457 |
- p_object = glfs_h_create_from_handle (fs,
|
|
|
12a457 |
- ca_data->p_stat.ia_gfid,
|
|
|
12a457 |
- GFAPI_HANDLE_LENGTH,
|
|
|
12a457 |
- NULL);
|
|
|
12a457 |
- GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
|
|
|
12a457 |
- p_object, out);
|
|
|
12a457 |
+ p_object = glfs_h_find_handle (fs,
|
|
|
12a457 |
+ ca_data->p_stat.ia_gfid,
|
|
|
12a457 |
+ GFAPI_HANDLE_LENGTH);
|
|
|
12a457 |
+ if (!p_object) {
|
|
|
12a457 |
+ gf_msg (THIS->name, GF_LOG_DEBUG, errno,
|
|
|
12a457 |
+ API_MSG_CREATE_HANDLE_FAILED,
|
|
|
12a457 |
+ "handle creation of %s failed",
|
|
|
12a457 |
+ uuid_utoa (ca_data->p_stat.ia_gfid));
|
|
|
12a457 |
+ errno = ESTALE;
|
|
|
12a457 |
+ goto out;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
|
|
|
12a457 |
glfs_iatt_to_stat (fs, &ca_data->p_stat, &up_inode_arg->p_buf);
|
|
|
12a457 |
}
|
|
|
12a457 |
@@ -1857,12 +1938,21 @@ glfs_h_poll_cache_invalidation (struct glfs *fs,
|
|
|
12a457 |
|
|
|
12a457 |
/* In case of RENAME, update old parent as well */
|
|
|
12a457 |
if (ca_data->flags & GFAPI_UP_RENAME) {
|
|
|
12a457 |
- oldp_object = glfs_h_create_from_handle (fs,
|
|
|
12a457 |
- ca_data->oldp_stat.ia_gfid,
|
|
|
12a457 |
- GFAPI_HANDLE_LENGTH,
|
|
|
12a457 |
- NULL);
|
|
|
12a457 |
- GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
|
|
|
12a457 |
- oldp_object, out);
|
|
|
12a457 |
+ oldp_object = glfs_h_find_handle (fs,
|
|
|
12a457 |
+ ca_data->oldp_stat.ia_gfid,
|
|
|
12a457 |
+ GFAPI_HANDLE_LENGTH);
|
|
|
12a457 |
+ if (!oldp_object) {
|
|
|
12a457 |
+ gf_msg (THIS->name, GF_LOG_DEBUG, errno,
|
|
|
12a457 |
+ API_MSG_CREATE_HANDLE_FAILED,
|
|
|
12a457 |
+ "handle creation of %s failed",
|
|
|
12a457 |
+ uuid_utoa (ca_data->oldp_stat.ia_gfid));
|
|
|
12a457 |
+ errno = ESTALE;
|
|
|
12a457 |
+ /* By the time we receive upcall old parent_dir may
|
|
|
12a457 |
+ * have got removed. We still need to send upcall
|
|
|
12a457 |
+ * for the file/dir and current parent handles. */
|
|
|
12a457 |
+ up_inode_arg->oldp_object = NULL;
|
|
|
12a457 |
+ ret = 0;
|
|
|
12a457 |
+ }
|
|
|
12a457 |
|
|
|
12a457 |
glfs_iatt_to_stat (fs, &ca_data->oldp_stat,
|
|
|
12a457 |
&up_inode_arg->oldp_buf);
|
|
|
12a457 |
@@ -1872,6 +1962,15 @@ glfs_h_poll_cache_invalidation (struct glfs *fs,
|
|
|
12a457 |
ret = 0;
|
|
|
12a457 |
|
|
|
12a457 |
out:
|
|
|
12a457 |
+ if (ret) {
|
|
|
12a457 |
+ /* Close p_object and oldp_object as well if being referenced.*/
|
|
|
12a457 |
+ if (object)
|
|
|
12a457 |
+ glfs_h_close (object);
|
|
|
12a457 |
+
|
|
|
12a457 |
+ /* Reset event_arg as well*/
|
|
|
12a457 |
+ up_arg->event_arg = NULL;
|
|
|
12a457 |
+ GF_FREE (up_inode_arg);
|
|
|
12a457 |
+ }
|
|
|
12a457 |
return ret;
|
|
|
12a457 |
}
|
|
|
12a457 |
|
|
|
12a457 |
@@ -1972,16 +2071,11 @@ pub_glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *up_arg)
|
|
|
12a457 |
}
|
|
|
12a457 |
/* It could so happen that the file which got
|
|
|
12a457 |
* upcall notification may have got deleted
|
|
|
12a457 |
- * by other thread. Irrespective of the error,
|
|
|
12a457 |
- * log it and return with CBK_NULL reason.
|
|
|
12a457 |
+ * by the same client. Irrespective of the error,
|
|
|
12a457 |
+ * return with CBK_NULL reason.
|
|
|
12a457 |
*
|
|
|
12a457 |
* Applications will ignore this notification
|
|
|
12a457 |
* as up_arg->object will be NULL */
|
|
|
12a457 |
- gf_msg (subvol->name, GF_LOG_WARNING, errno,
|
|
|
12a457 |
- API_MSG_CREATE_HANDLE_FAILED,
|
|
|
12a457 |
- "handle creation of %s failed",
|
|
|
12a457 |
- uuid_utoa (upcall_data->gfid));
|
|
|
12a457 |
-
|
|
|
12a457 |
reason = GFAPI_CBK_EVENT_NULL;
|
|
|
12a457 |
break;
|
|
|
12a457 |
default:
|
|
|
12a457 |
--
|
|
|
12a457 |
1.7.1
|
|
|
12a457 |
|