/* Sleeps until awaken by ecryptfs_receive_message or until the amount of time exceeds ecryptfs_message_wait_timeout. If zero is returned, msg will point to a valid message from userspace; a non-zero value is returned upon failure to receive a message or an error occurs. Callee must free @msg on success.  */
int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, struct ecryptfs_message **msg)
/* Sleeps until awaken by ecryptfs_receive_message or until the amount of time exceeds ecryptfs_message_wait_timeout. If zero is returned, msg will point to a valid message from userspace; a non-zero value is returned upon failure to receive a message or an error occurs. Callee must free @msg on success.  */
int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, struct ecryptfs_message **msg)
{
	signed long timeout = ecryptfs_message_wait_timeout * HZ;
	int rc = 0;
sleep:
	timeout = schedule_timeout_interruptible(timeout);
	mutex_lock(&ecryptfs_msg_ctx_lists_mux);
	mutex_lock(&msg_ctx->mux);
	if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_DONE) {
		if (timeout) {
			mutex_unlock(&msg_ctx->mux);
			mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
			goto sleep;
		}
		rc = -ENOMSG;
	} else {
		*msg = msg_ctx->msg;
		msg_ctx->msg = NULL;
	}
	ecryptfs_msg_ctx_alloc_to_free(msg_ctx);
	mutex_unlock(&msg_ctx->mux);
	mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
	return rc;
}