summaryrefslogtreecommitdiffstats
path: root/api/src/glfs-handleops.c
diff options
context:
space:
mode:
Diffstat (limited to 'api/src/glfs-handleops.c')
-rw-r--r--api/src/glfs-handleops.c132
1 files changed, 97 insertions, 35 deletions
diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c
index c3ac789569d..13b47a1b74d 100644
--- a/api/src/glfs-handleops.c
+++ b/api/src/glfs-handleops.c
@@ -1621,6 +1621,76 @@ out:
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2);
+int
+glfs_h_poll_cache_invalidation (struct glfs *fs,
+ struct callback_arg *up_arg,
+ struct gf_upcall *upcall_data)
+{
+ int ret = -1;
+ struct glfs_object *p_object = NULL;
+ struct glfs_object *oldp_object = NULL;
+ struct glfs_object *object = NULL;
+ struct gf_upcall_cache_invalidation *ca_data = NULL;
+ struct callback_inode_arg *up_inode_arg = NULL;
+
+ ca_data = upcall_data->data;
+ GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
+ ca_data, out);
+
+ object = glfs_h_create_from_handle (fs, upcall_data->gfid,
+ GFAPI_HANDLE_LENGTH,
+ NULL);
+ GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
+ object, out);
+
+ up_inode_arg = calloc (1, sizeof (struct callback_inode_arg));
+ GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
+ up_inode_arg, out);
+
+ up_arg->event_arg = up_inode_arg;
+
+ up_inode_arg->object = object;
+ up_inode_arg->flags = ca_data->flags;
+ up_inode_arg->expire_time_attr = ca_data->expire_time_attr;
+
+ /* XXX: Update stat as well incase of UP_*_TIMES.
+ * This will be addressed as part of INODE_UPDATE */
+ if (ca_data->flags & GFAPI_INODE_UPDATE_FLAGS) {
+ glfs_iatt_to_stat (fs, &ca_data->stat, &up_inode_arg->buf);
+ }
+
+ if (ca_data->flags & GFAPI_UP_PARENT_TIMES) {
+ p_object = glfs_h_create_from_handle (fs,
+ ca_data->p_stat.ia_gfid,
+ GFAPI_HANDLE_LENGTH,
+ NULL);
+ GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
+ p_object, out);
+
+ glfs_iatt_to_stat (fs, &ca_data->p_stat, &up_inode_arg->p_buf);
+ }
+ up_inode_arg->p_object = p_object;
+
+ /* In case of RENAME, update old parent as well */
+ if (ca_data->flags & GFAPI_UP_RENAME) {
+ oldp_object = glfs_h_create_from_handle (fs,
+ ca_data->oldp_stat.ia_gfid,
+ GFAPI_HANDLE_LENGTH,
+ NULL);
+ GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
+ oldp_object, out);
+
+ glfs_iatt_to_stat (fs, &ca_data->oldp_stat,
+ &up_inode_arg->oldp_buf);
+ }
+ up_inode_arg->oldp_object = oldp_object;
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
/*
* This API is used to poll for upcall events stored in the
* upcall list. Current users of this API is NFS-Ganesha.
@@ -1628,11 +1698,17 @@ GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2);
* into 'callback_arg' along with the handle object to be passed
* to NFS-Ganesha.
*
- * On success, applications need to check for 'object' to decide
+ * On success, applications need to check for 'reason' to decide
* if any upcall event is received.
*
- * After processing the event, they need to free "object"
- * using glfs_h_close(..).
+ * Current supported upcall_events -
+ * GFAPI_INODE_INVALIDATE -
+ * 'arg - callback_inode_arg
+ *
+ * After processing the event, applications need to free 'event_arg'.
+ *
+ * Incase of INODE_INVALIDATE, applications need to free "object",
+ * "p_object" and "oldp_object" using glfs_h_close(..).
*
* Also similar to I/Os, the application should ideally stop polling
* before calling glfs_fini(..). Hence making an assumption that
@@ -1641,8 +1717,6 @@ GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2);
int
pub_glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *up_arg)
{
- struct glfs_object *object = NULL;
- uuid_t gfid;
upcall_entry *u_list = NULL;
upcall_entry *tmp = NULL;
xlator_t *subvol = NULL;
@@ -1651,7 +1725,6 @@ pub_glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *up_arg)
glusterfs_ctx_t *ctx = NULL;
int ret = -1;
struct gf_upcall *upcall_data = NULL;
- struct gf_upcall_cache_invalidation *ca_data = NULL;
if (!fs || !up_arg) {
errno = EINVAL;
@@ -1668,8 +1741,6 @@ pub_glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *up_arg)
goto err;
}
- up_arg->object = NULL;
-
/* Ideally applications should stop polling before calling
* 'glfs_fini'. Yet cross check if cleanup has started
*/
@@ -1691,7 +1762,6 @@ pub_glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *up_arg)
list_for_each_entry_safe (u_list, tmp,
&fs->upcall_list,
upcall_list) {
- gf_uuid_copy (gfid, u_list->upcall_data.gfid);
found = 1;
break;
}
@@ -1700,11 +1770,20 @@ pub_glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *up_arg)
pthread_mutex_unlock (&fs->upcall_list_mutex);
if (found) {
- object = glfs_h_create_from_handle (fs, gfid,
- GFAPI_HANDLE_LENGTH,
- NULL);
+ upcall_data = &u_list->upcall_data;
- if (!object) {
+ switch (upcall_data->event_type) {
+ case GF_UPCALL_CACHE_INVALIDATION:
+ /* XXX: Need to revisit this to support
+ * GFAPI_INODE_UPDATE if required.
+ */
+ reason = GFAPI_INODE_INVALIDATE;
+ ret = glfs_h_poll_cache_invalidation (fs,
+ up_arg,
+ upcall_data);
+ if (!ret) {
+ break;
+ }
/* It could so happen that the file which got
* upcall notification may have got deleted
* by other thread. Irrespective of the error,
@@ -1714,32 +1793,15 @@ pub_glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *up_arg)
* as up_arg->object will be NULL */
gf_log (subvol->name, GF_LOG_WARNING,
"handle creation of %s failed: %s",
- uuid_utoa (gfid), strerror (errno));
+ uuid_utoa (upcall_data->gfid),
+ strerror (errno));
reason = GFAPI_CBK_EVENT_NULL;
- } else {
-
- upcall_data = &u_list->upcall_data;
-
- switch (upcall_data->event_type) {
- case GF_UPCALL_CACHE_INVALIDATION:
- /* XXX: Need to revisit this to support
- * GFAPI_INODE_UPDATE if required.
- */
- ca_data = upcall_data->data;
- GF_VALIDATE_OR_GOTO ("glfs_h_poll_upcall",
- ca_data, out);
- reason = GFAPI_INODE_INVALIDATE;
- up_arg->flags = ca_data->flags;
- up_arg->expire_time_attr = ca_data->expire_time_attr;
-
- break;
- default:
- break;
- }
+ break;
+ default:
+ break;
}
- up_arg->object = object;
up_arg->reason = reason;
list_del_init (&u_list->upcall_list);