diff options
author | Soumya Koduri <skoduri@redhat.com> | 2015-02-16 11:47:58 +0530 |
---|---|---|
committer | Kaleb KEITHLEY <kkeithle@redhat.com> | 2015-03-17 14:01:21 -0700 |
commit | 2a4561ef08b8be3b7d79b951252e87ba8f987120 (patch) | |
tree | ed5cc0c87f6532b167ebb2b775389a9a391a3cf4 /api/src/glfs-handleops.c | |
parent | d81182cf69a4f188f304fcce6d651ffd56b67aac (diff) |
gfapi: APIs to store and process upcall notifications received
In case of any upcall cbk events received by the protocol/client,
gfapi will be notified which queues them up in a list (<gfapi_cbk_upcall>).
Applicatons are responsible to provide APIs to process & notify them in case
of any such upcall events queued.
Added a new API which will be used by Ganesha to repeatedly poll for any
such upcall event notified (<glfs_h_poll_upcall>).
A new test-file has been added to test the cache_invalidation upcall events.
Below link has a writeup which explains the code changes done -
URL: https://soumyakoduri.wordpress.com/2015/02/25/glusterfs-understanding-upcall-infrastructure-and-cache-invalidation-support/
Change-Id: Iafc6880000c865fd4da22d0cfc388ec135b5a1c5
BUG: 1200262
Signed-off-by: Soumya Koduri <skoduri@redhat.com>
Reviewed-on: http://review.gluster.org/9536
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
Diffstat (limited to 'api/src/glfs-handleops.c')
-rw-r--r-- | api/src/glfs-handleops.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c index 631af01d97b..037315a518d 100644 --- a/api/src/glfs-handleops.c +++ b/api/src/glfs-handleops.c @@ -1594,3 +1594,132 @@ out: GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2); +/* + * This API is used to poll for upcall events stored in the + * upcall list. Current users of this API is NFS-Ganesha. + * Incase of any event received, it will be mapped appropriately + * into 'callback_arg' along with the handle to be passed to + * NFS-Ganesha. + * + * Application is responsible for allocating and passing the + * references of all the pointers except for "glhandle". + * After processing the event, it needs to free "glhandle" + * + * TODO: there should be a glfs api to destroy these handles, + * maybe "glfs_destroy_object" to free the object. + * + * Also similar to I/Os, the application should ideally stop polling + * before calling glfs_fini(..). Hence making an assumption that + * 'fs' & ctx structures cannot be freed while in this routine. + */ +int +pub_glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *up_arg) +{ + struct glfs_object *handle = NULL; + uuid_t gfid; + upcall_entry *u_list = NULL; + upcall_entry *tmp = NULL; + xlator_t *subvol = NULL; + int found = 0; + int reason = 0; + glusterfs_ctx_t *ctx = NULL; + int ret = -1; + + if (!fs || !up_arg) { + errno = EINVAL; + goto err; + } + + __glfs_entry_fs (fs); + + /* get the active volume */ + subvol = glfs_active_subvol (fs); + + if (!subvol) { + errno = EIO; + goto err; + } + + up_arg->handle = NULL; + + /* Ideally applications should stop polling before calling + * 'glfs_fini'. Yet cross check if cleanup has started + */ + pthread_mutex_lock (&fs->mutex); + { + ctx = fs->ctx; + + if (ctx->cleanup_started) { + pthread_mutex_unlock (&fs->mutex); + goto out; + } + + fs->pin_refcnt++; + } + pthread_mutex_unlock (&fs->mutex); + + pthread_mutex_lock (&fs->upcall_list_mutex); + { + list_for_each_entry_safe (u_list, tmp, + &fs->upcall_list, + upcall_list) { + uuid_copy (gfid, u_list->gfid); + found = 1; + break; + } + } + /* No other thread can delete this entry. So unlock it */ + pthread_mutex_unlock (&fs->upcall_list_mutex); + + if (found) { + handle = glfs_h_create_from_handle (fs, gfid, + GFAPI_HANDLE_LENGTH, + &up_arg->buf); + + if (!handle) { + errno = ENOMEM; + goto out; + } + + switch (u_list->event_type) { + case CACHE_INVALIDATION: + if (u_list->flags & (~(INODE_UPDATE_FLAGS))) { + /* Invalidate CACHE */ + reason = INODE_INVALIDATE; + gf_log (subvol->name, GF_LOG_DEBUG, + "Reason - INODE_INVALIDATION"); + } else { + reason = INODE_UPDATE; + gf_log (subvol->name, GF_LOG_DEBUG, + "Reason - INODE_UPDATE"); + } + break; + default: + break; + } + + up_arg->handle = handle; + up_arg->reason = reason; + up_arg->flags = u_list->flags; + up_arg->expire_time_attr = u_list->expire_time_attr; + + list_del_init (&u_list->upcall_list); + GF_FREE (u_list); + } + + ret = 0; + +out: + pthread_mutex_lock (&fs->mutex); + { + fs->pin_refcnt--; + } + pthread_mutex_unlock (&fs->mutex); + + glfs_subvol_done (fs, subvol); + +err: + return ret; +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_poll_upcall, 3.7.0); |