summaryrefslogtreecommitdiffstats
path: root/api/src/glfs.c
diff options
context:
space:
mode:
authorSoumya Koduri <skoduri@redhat.com>2017-09-22 16:43:39 +0530
committerAmar Tumballi <amarts@redhat.com>2017-10-31 07:53:50 +0000
commitc0e77f643930499966554cd849a40580e4ff68f9 (patch)
tree5baf2c5b33da77b4567fd23a77d526ca890519b0 /api/src/glfs.c
parent4216869c724cf19c12d63c0580de88e9427e6467 (diff)
gfapi: Register/Unregister Upcall events' callback
Polling continuously for upcall events is not optimal. Hence new APIs have been added to allow applications to register and unregister upcall events it is interested in along with callback function to be invoked in case of any such upcalls sent by backend server. @TODO: Make changes in upcall xlator so that events are sent to only those clients which either registered callbacks or started polling. Shall be addressed in separate patch. Updates: #315 Change-Id: I40473fd5cf689172ff2d7bb2869756b7fd5bc761 Signed-off-by: Soumya Koduri <skoduri@redhat.com>
Diffstat (limited to 'api/src/glfs.c')
-rw-r--r--api/src/glfs.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/api/src/glfs.c b/api/src/glfs.c
index 72a2c3724a1..b168f682a7d 100644
--- a/api/src/glfs.c
+++ b/api/src/glfs.c
@@ -703,6 +703,9 @@ glfs_new_fs (const char *volname)
goto err;
fs->pin_refcnt = 0;
+ fs->upcall_events = 0;
+ fs->up_cbk = NULL;
+ fs->up_data = NULL;
return fs;
@@ -1551,3 +1554,100 @@ out:
}
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_sysrq, 3.10.0);
+
+int
+glfs_upcall_register (struct glfs *fs, uint32_t event_list,
+ glfs_upcall_cbk cbk, void *data)
+{
+ int ret = 0;
+
+ /* list of supported upcall events */
+ uint32_t up_events = GLFS_EVENT_INODE_INVALIDATE;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+
+ GF_VALIDATE_OR_GOTO (THIS->name, cbk, out);
+
+ /* Event list should be either GLFS_EVENT_ANY
+ * or list of supported individual events (up_events)
+ */
+ if ((event_list != GLFS_EVENT_ANY) &&
+ (event_list & ~up_events)) {
+ errno = EINVAL;
+ ret = -1;
+ gf_msg (THIS->name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG,
+ "invalid event_list (0x%08x)", event_list);
+ goto out;
+ }
+
+ /* incase other thread does unregister */
+ pthread_mutex_lock (&fs->mutex);
+ {
+ if (event_list & GLFS_EVENT_INODE_INVALIDATE) {
+ /* @todo: Check if features.cache-invalidation is
+ * enabled.
+ */
+ fs->upcall_events |= GF_UPCALL_CACHE_INVALIDATION;
+ ret |= GF_UPCALL_CACHE_INVALIDATION;
+ }
+
+ /* Override cbk function if existing */
+ fs->up_cbk = cbk;
+ fs->up_data = data;
+ fs->cache_upcalls = _gf_true;
+ }
+ pthread_mutex_unlock (&fs->mutex);
+
+out:
+ __GLFS_EXIT_FS;
+
+invalid_fs:
+ return ret;
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_register, 3.13.0);
+
+int glfs_upcall_unregister (struct glfs *fs, uint32_t event_list)
+{
+ int ret = 0;
+ /* list of supported upcall events */
+ uint32_t up_events = GLFS_EVENT_INODE_INVALIDATE;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+
+ /* Event list should be either GLFS_EVENT_ANY
+ * or list of supported individual events (up_events)
+ */
+ if ((event_list != GLFS_EVENT_ANY) &&
+ (event_list & ~up_events)) {
+ errno = EINVAL;
+ ret = -1;
+ gf_msg (THIS->name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG,
+ "invalid event_list (0x%08x)", event_list);
+ goto out;
+ }
+
+ pthread_mutex_lock (&fs->mutex);
+ {
+ if (event_list & GLFS_EVENT_INODE_INVALIDATE) {
+ fs->upcall_events &= ~GF_UPCALL_CACHE_INVALIDATION;
+ ret |= GF_UPCALL_CACHE_INVALIDATION;
+ }
+
+ /* If there are no upcall events registered, reset cbk */
+ if (fs->upcall_events == 0) {
+ fs->up_cbk = NULL;
+ fs->up_data = NULL;
+ fs->cache_upcalls = _gf_false;
+ }
+ }
+ pthread_mutex_unlock (&fs->mutex);
+
+out:
+ __GLFS_EXIT_FS;
+
+invalid_fs:
+ return ret;
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_unregister, 3.13.0);