* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2014, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
return 0;
CDEBUG(D_SEC, "found delayed sec adapt expired, do it now\n");
- return sptlrpc_import_sec_adapt(imp, NULL, 0);
+ return sptlrpc_import_sec_adapt(imp, NULL, NULL);
}
+/**
+ * Get and validate the client side ptlrpc security facilities from
+ * \a imp. There is a race condition on client reconnect when the import is
+ * being destroyed while there are outstanding client bound requests. In
+ * this case do not output any error messages if import secuity is not
+ * found.
+ *
+ * \param[in] imp obd import associated with client
+ * \param[out] sec client side ptlrpc security
+ *
+ * \retval 0 if security retrieved successfully
+ * \retval -ve errno if there was a problem
+ */
static int import_sec_validate_get(struct obd_import *imp,
- struct ptlrpc_sec **sec)
+ struct ptlrpc_sec **sec)
{
- int rc;
+ int rc;
- if (unlikely(imp->imp_sec_expire)) {
- rc = import_sec_check_expire(imp);
- if (rc)
- return rc;
- }
+ if (unlikely(imp->imp_sec_expire)) {
+ rc = import_sec_check_expire(imp);
+ if (rc)
+ return rc;
+ }
- *sec = sptlrpc_import_sec_ref(imp);
- if (*sec == NULL) {
- CERROR("import %p (%s) with no sec\n",
- imp, ptlrpc_import_state_name(imp->imp_state));
- return -EACCES;
- }
+ *sec = sptlrpc_import_sec_ref(imp);
+ /* Only output an error when the import is still active */
+ if (*sec == NULL) {
+ if (list_empty(&imp->imp_zombie_chain))
+ CERROR("import %p (%s) with no sec\n",
+ imp, ptlrpc_import_state_name(imp->imp_state));
+ return -EACCES;
+ }
- if (unlikely((*sec)->ps_dying)) {
- CERROR("attempt to use dying sec %p\n", sec);
- sptlrpc_sec_put(*sec);
- return -EACCES;
- }
+ if (unlikely((*sec)->ps_dying)) {
+ CERROR("attempt to use dying sec %p\n", sec);
+ sptlrpc_sec_put(*sec);
+ return -EACCES;
+ }
- return 0;
+ return 0;
}
/**
- * Given a \a req, find or allocate a appropriate context for it.
+ * Given a \a req, find or allocate an appropriate context for it.
* \pre req->rq_cli_ctx == NULL.
*
* \retval 0 succeed, and req->rq_cli_ctx is set.
sptlrpc_sec_put(sec);
- if (!req->rq_cli_ctx) {
- CERROR("req %p: fail to get context\n", req);
- RETURN(-ENOMEM);
- }
+ if (!req->rq_cli_ctx) {
+ CERROR("req %p: fail to get context\n", req);
+ RETURN(-ECONNREFUSED);
+ }
RETURN(0);
}
newctx, newctx->cc_flags);
schedule_timeout_and_set_state(TASK_INTERRUPTIBLE,
- HZ);
+ msecs_to_jiffies(MSEC_PER_SEC));
} else {
/*
* it's possible newctx == oldctx if we're switching
* it for reply reconstruction.
*
* Commonly the original context should be uptodate because we
- * have a expiry nice time; server will keep its context because
+ * have an expiry nice time; server will keep its context because
* we at least hold a ref of old context which prevent context
- * destroying RPC being sent. So server still can accept the request
- * and finish the RPC. But if that's not the case:
+ * from destroying RPC being sent. So server still can accept the
+ * request and finish the RPC. But if that's not the case:
* 1. If server side context has been trimmed, a NO_CONTEXT will
* be returned, gss_cli_ctx_verify/unseal will switch to new
* context by force.
req->rq_restart = 0;
spin_unlock(&req->rq_lock);
- lwi = LWI_TIMEOUT_INTR(timeout * HZ, ctx_refresh_timeout,
+ lwi = LWI_TIMEOUT_INTR(msecs_to_jiffies(timeout * MSEC_PER_SEC),
+ ctx_refresh_timeout,
ctx_refresh_interrupt, req);
rc = l_wait_event(req->rq_reply_waitq, ctx_check_refresh(ctx), &lwi);
if (!req)
RETURN(-ENOMEM);
- spin_lock_init(&req->rq_lock);
+ ptlrpc_cli_req_init(req);
atomic_set(&req->rq_refcount, 10000);
- INIT_LIST_HEAD(&req->rq_ctx_chain);
- init_waitqueue_head(&req->rq_reply_waitq);
- init_waitqueue_head(&req->rq_set_waitq);
+
req->rq_import = imp;
req->rq_flvr = sec->ps_flvr;
req->rq_cli_ctx = ctx;
struct ptlrpc_request **req_ret)
{
struct ptlrpc_request *early_req;
- char *early_buf;
- int early_bufsz, early_size;
- int rc;
+ char *early_buf;
+ int early_bufsz, early_size;
+ int rc;
ENTRY;
early_req = ptlrpc_request_cache_alloc(GFP_NOFS);
if (early_req == NULL)
RETURN(-ENOMEM);
+ ptlrpc_cli_req_init(early_req);
+
early_size = req->rq_nob_received;
early_bufsz = size_roundup_power2(early_size);
OBD_ALLOC_LARGE(early_buf, early_bufsz);
memcpy(early_buf, req->rq_repbuf, early_size);
spin_unlock(&req->rq_lock);
- spin_lock_init(&early_req->rq_lock);
early_req->rq_cli_ctx = sptlrpc_cli_ctx_get(req->rq_cli_ctx);
early_req->rq_flvr = req->rq_flvr;
early_req->rq_repbuf = early_buf;
/**
* Used by ptlrpc server, to perform transformation upon request message of
- * incoming \a req. This must be the first thing to do with a incoming
+ * incoming \a req. This must be the first thing to do with an incoming
* request in ptlrpc layer.
*
* \retval SECSVC_OK success, and req->rq_reqmsg point to request message in