diff options
author | Xavier Hernandez <xhernandez@datalab.es> | 2016-06-15 14:42:19 +0200 |
---|---|---|
committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2018-01-16 10:37:22 +0000 |
commit | 7ba7a4b27d124f4ee16fe4776a4670cd5b0160c4 (patch) | |
tree | 73cca7226576b7ce3e480dc991aa70b9cc7cab07 /xlators/protocol | |
parent | 3e9a9c029fac359477fb26d9cc7803749ba038b2 (diff) |
locks: added inodelk/entrylk contention upcall notifications
The locks xlator now is able to send a contention notification to
the current owner of the lock.
This is only a notification that can be used to improve performance
of some client side operations that might benefit from extended
duration of lock ownership. Nothing is done if the lock owner decides
to ignore the message and to not release the lock. For forced
release of acquired resources, leases must be used.
Change-Id: I7f1ad32a0b4b445505b09908a050080ad848f8e0
Signed-off-by: Xavier Hernandez <xhernandez@datalab.es>
Diffstat (limited to 'xlators/protocol')
-rw-r--r-- | xlators/protocol/client/src/client-callback.c | 97 | ||||
-rw-r--r-- | xlators/protocol/client/src/client-messages.h | 4 | ||||
-rw-r--r-- | xlators/protocol/server/src/server.c | 44 |
3 files changed, 138 insertions, 7 deletions
diff --git a/xlators/protocol/client/src/client-callback.c b/xlators/protocol/client/src/client-callback.c index 51164e57230..b2f9a225887 100644 --- a/xlators/protocol/client/src/client-callback.c +++ b/xlators/protocol/client/src/client-callback.c @@ -173,6 +173,101 @@ out: return 0; } +int +client_cbk_inodelk_contention (struct rpc_clnt *rpc, void *mydata, void *data) +{ + int ret = -1; + struct iovec *iov = NULL; + struct gf_upcall upcall_data = {0,}; + struct gf_upcall_inodelk_contention lc = {{0,},}; + gfs4_inodelk_contention_req proto_lc = {{0,},}; + + GF_VALIDATE_OR_GOTO ("client-callback", rpc, out); + GF_VALIDATE_OR_GOTO ("client-callback", mydata, out); + GF_VALIDATE_OR_GOTO ("client-callback", data, out); + + iov = (struct iovec *)data; + ret = xdr_to_generic (*iov, &proto_lc, + (xdrproc_t)xdr_gfs4_inodelk_contention_req); + + if (ret < 0) { + gf_msg (THIS->name, GF_LOG_WARNING, -ret, + PC_MSG_INODELK_CONTENTION_FAIL, + "XDR decode of inodelk contention failed."); + goto out; + } + + upcall_data.data = &lc; + ret = gf_proto_inodelk_contention_to_upcall (&proto_lc, &upcall_data); + if (ret < 0) + goto out; + + upcall_data.event_type = GF_UPCALL_INODELK_CONTENTION; + + default_notify (THIS, GF_EVENT_UPCALL, &upcall_data); + +out: + if (proto_lc.domain) + free (proto_lc.domain); + + if (proto_lc.xdata.xdata_val) + free (proto_lc.xdata.xdata_val); + + if (lc.xdata) + dict_unref (lc.xdata); + + return ret; +} + +int +client_cbk_entrylk_contention (struct rpc_clnt *rpc, void *mydata, void *data) +{ + int ret = -1; + struct iovec *iov = NULL; + struct gf_upcall upcall_data = {0,}; + struct gf_upcall_entrylk_contention lc = {0,}; + gfs4_entrylk_contention_req proto_lc = {{0,},}; + + GF_VALIDATE_OR_GOTO ("client-callback", rpc, out); + GF_VALIDATE_OR_GOTO ("client-callback", mydata, out); + GF_VALIDATE_OR_GOTO ("client-callback", data, out); + + iov = (struct iovec *)data; + ret = xdr_to_generic (*iov, &proto_lc, + (xdrproc_t)xdr_gfs4_entrylk_contention_req); + + if (ret < 0) { + gf_msg (THIS->name, GF_LOG_WARNING, -ret, + PC_MSG_ENTRYLK_CONTENTION_FAIL, + "XDR decode of entrylk contention failed."); + goto out; + } + + upcall_data.data = &lc; + ret = gf_proto_entrylk_contention_to_upcall (&proto_lc, &upcall_data); + if (ret < 0) + goto out; + + upcall_data.event_type = GF_UPCALL_ENTRYLK_CONTENTION; + + default_notify (THIS, GF_EVENT_UPCALL, &upcall_data); + +out: + if (proto_lc.name) + free (proto_lc.name); + + if (proto_lc.domain) + free (proto_lc.domain); + + if (proto_lc.xdata.xdata_val) + free (proto_lc.xdata.xdata_val); + + if (lc.xdata) + dict_unref (lc.xdata); + + return ret; +} + rpcclnt_cb_actor_t gluster_cbk_actors[GF_CBK_MAXVALUE] = { [GF_CBK_NULL] = {"NULL", GF_CBK_NULL, client_cbk_null }, [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, client_cbk_fetchspec }, @@ -181,6 +276,8 @@ rpcclnt_cb_actor_t gluster_cbk_actors[GF_CBK_MAXVALUE] = { [GF_CBK_CHILD_UP] = {"CHILD_UP", GF_CBK_CHILD_UP, client_cbk_child_up }, [GF_CBK_CHILD_DOWN] = {"CHILD_DOWN", GF_CBK_CHILD_DOWN, client_cbk_child_down }, [GF_CBK_RECALL_LEASE] = {"RECALL_LEASE", GF_CBK_RECALL_LEASE, client_cbk_recall_lease }, + [GF_CBK_INODELK_CONTENTION] = {"INODELK_CONTENTION", GF_CBK_INODELK_CONTENTION, client_cbk_inodelk_contention }, + [GF_CBK_ENTRYLK_CONTENTION] = {"ENTRYLK_CONTENTION", GF_CBK_ENTRYLK_CONTENTION, client_cbk_entrylk_contention }, }; diff --git a/xlators/protocol/client/src/client-messages.h b/xlators/protocol/client/src/client-messages.h index 86b721bd593..5f146c67efe 100644 --- a/xlators/protocol/client/src/client-messages.h +++ b/xlators/protocol/client/src/client-messages.h @@ -89,7 +89,9 @@ GLFS_MSGID(PC, PC_MSG_CACHE_INVALIDATION_FAIL, PC_MSG_CHILD_STATUS, PC_MSG_GFID_NULL, - PC_MSG_RECALL_LEASE_FAIL + PC_MSG_RECALL_LEASE_FAIL, + PC_MSG_INODELK_CONTENTION_FAIL, + PC_MSG_ENTRYLK_CONTENTION_FAIL ); #endif /* !_PC_MESSAGES_H__ */ diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index 7154355e690..66122318c79 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -1349,6 +1349,8 @@ server_process_event_upcall (xlator_t *this, void *data) enum gf_cbk_procnum cbk_procnum = GF_CBK_NULL; gfs3_cbk_cache_invalidation_req gf_c_req = {0,}; gfs3_recall_lease_req gf_recall_lease = {{0,},}; + gfs4_inodelk_contention_req gf_inodelk_contention = {{0},}; + gfs4_entrylk_contention_req gf_entrylk_contention = {{0},}; xdrproc_t xdrproc; GF_VALIDATE_OR_GOTO(this->name, data, out); @@ -1358,7 +1360,16 @@ server_process_event_upcall (xlator_t *this, void *data) upcall_data = (struct gf_upcall *)data; client_uid = upcall_data->client_uid; - GF_VALIDATE_OR_GOTO(this->name, client_uid, out); + /* client_uid could be NULL if the upcall was intended for a server's + * child xlator (so no client_uid available) but it hasn't handled + * the notification. For this reason we silently ignore any upcall + * request with a NULL client_uid, but -1 will be returned. + */ + if (client_uid == NULL) { + gf_msg_debug(this->name, 0, + "NULL client_uid for an upcall request"); + goto out; + } switch (upcall_data->event_type) { case GF_UPCALL_CACHE_INVALIDATION: @@ -1381,6 +1392,28 @@ server_process_event_upcall (xlator_t *this, void *data) cbk_procnum = GF_CBK_RECALL_LEASE; xdrproc = (xdrproc_t)xdr_gfs3_recall_lease_req; break; + case GF_UPCALL_INODELK_CONTENTION: + ret = gf_proto_inodelk_contention_from_upcall (this, + &gf_inodelk_contention, + upcall_data); + if (ret < 0) + goto out; + + up_req = &gf_inodelk_contention; + cbk_procnum = GF_CBK_INODELK_CONTENTION; + xdrproc = (xdrproc_t)xdr_gfs4_inodelk_contention_req; + break; + case GF_UPCALL_ENTRYLK_CONTENTION: + ret = gf_proto_entrylk_contention_from_upcall (this, + &gf_entrylk_contention, + upcall_data); + if (ret < 0) + goto out; + + up_req = &gf_entrylk_contention; + cbk_procnum = GF_CBK_ENTRYLK_CONTENTION; + xdrproc = (xdrproc_t)xdr_gfs4_entrylk_contention_req; + break; default: gf_msg (this->name, GF_LOG_WARNING, EINVAL, PS_MSG_INVALID_ENTRY, @@ -1417,11 +1450,10 @@ server_process_event_upcall (xlator_t *this, void *data) pthread_mutex_unlock (&conf->mutex); ret = 0; out: - if ((gf_c_req.xdata).xdata_val) - GF_FREE ((gf_c_req.xdata).xdata_val); - - if ((gf_recall_lease.xdata).xdata_val) - GF_FREE ((gf_recall_lease.xdata).xdata_val); + GF_FREE ((gf_c_req.xdata).xdata_val); + GF_FREE ((gf_recall_lease.xdata).xdata_val); + GF_FREE ((gf_inodelk_contention.xdata).xdata_val); + GF_FREE ((gf_entrylk_contention.xdata).xdata_val); return ret; } |