- struct ptlrpc_request *req, int rc,
- const char *ast_type)
-{
- lnet_process_id_t peer = req->rq_import->imp_connection->c_peer;
-
- if (rc == -ETIMEDOUT || rc == -EINTR || rc == -ENOTCONN) {
- LASSERT(lock->l_export);
- if (lock->l_export->exp_libclient) {
- LDLM_DEBUG(lock, "%s AST to liblustre client (nid %s)"
- " timeout, just cancelling lock", ast_type,
- libcfs_nid2str(peer.nid));
- ldlm_lock_cancel(lock);
- rc = -ERESTART;
- } else if (ldlm_is_cancel(lock)) {
- LDLM_DEBUG(lock, "%s AST timeout from nid %s, but "
- "cancel was received (AST reply lost?)",
- ast_type, libcfs_nid2str(peer.nid));
- ldlm_lock_cancel(lock);
- rc = -ERESTART;
- } else {
- ldlm_del_waiting_lock(lock);
- ldlm_failed_ast(lock, rc, ast_type);
- }
- } else if (rc) {
- if (rc == -EINVAL) {
- struct ldlm_resource *res = lock->l_resource;
- LDLM_DEBUG(lock, "client (nid %s) returned %d"
- " from %s AST - normal race",
- libcfs_nid2str(peer.nid),
- req->rq_repmsg ?
- lustre_msg_get_status(req->rq_repmsg) : -1,
- ast_type);
- if (res) {
- /* update lvbo to return proper attributes.
- * see bug 23174 */
- ldlm_resource_getref(res);
- ldlm_res_lvbo_update(res, NULL, 1);
- ldlm_resource_putref(res);
- }
-
- } else {
- LDLM_ERROR(lock, "client (nid %s) returned %d "
- "from %s AST", libcfs_nid2str(peer.nid),
- (req->rq_repmsg != NULL) ?
- lustre_msg_get_status(req->rq_repmsg) : 0,
- ast_type);
- }
- ldlm_lock_cancel(lock);
- /* Server-side AST functions are called from ldlm_reprocess_all,
- * which needs to be told to please restart its reprocessing. */
- rc = -ERESTART;
- }
-
- return rc;
+ struct ptlrpc_request *req, int rc,
+ const char *ast_type)
+{
+ struct lnet_process_id peer = req->rq_import->imp_connection->c_peer;
+
+ if (!req->rq_replied || (rc && rc != -EINVAL)) {
+ if (ldlm_is_cancel(lock)) {
+ LDLM_DEBUG(lock,
+ "%s AST (req@%p x%llu) timeout from nid %s, but cancel was received (AST reply lost?)",
+ ast_type, req, req->rq_xid,
+ libcfs_nid2str(peer.nid));
+ ldlm_lock_cancel(lock);
+ rc = -ERESTART;
+ } else if (rc == -ENODEV || rc == -ESHUTDOWN ||
+ (rc == -EIO &&
+ req->rq_import->imp_state == LUSTRE_IMP_CLOSED)) {
+ /*
+ * Upon umount process the AST fails because cannot be
+ * sent. This shouldn't lead to the client eviction.
+ * -ENODEV error is returned by ptl_send_rpc() for
+ * new request in such import.
+ * -SHUTDOWN is returned by ptlrpc_import_delay_req()
+ * if imp_invalid is set or obd_no_recov.
+ * Meanwhile there is also check for LUSTRE_IMP_CLOSED
+ * in ptlrpc_import_delay_req() as well with -EIO code.
+ * In all such cases errors are ignored.
+ */
+ LDLM_DEBUG(lock,
+ "%s AST can't be sent due to a server %s failure or umount process: rc = %d\n",
+ ast_type,
+ req->rq_import->imp_obd->obd_name, rc);
+ } else {
+ LDLM_ERROR(lock,
+ "client (nid %s) %s %s AST (req@%p x%llu status %d rc %d), evict it",
+ libcfs_nid2str(peer.nid),
+ req->rq_replied ? "returned error from" :
+ "failed to reply to",
+ ast_type, req, req->rq_xid,
+ (req->rq_repmsg != NULL) ?
+ lustre_msg_get_status(req->rq_repmsg) : 0,
+ rc);
+ ldlm_failed_ast(lock, rc, ast_type);
+ }
+ return rc;
+ }
+
+ if (rc == -EINVAL) {
+ struct ldlm_resource *res = lock->l_resource;
+
+ LDLM_DEBUG(lock,
+ "client (nid %s) returned %d from %s AST (req@%p x%llu) - normal race",
+ libcfs_nid2str(peer.nid),
+ req->rq_repmsg ?
+ lustre_msg_get_status(req->rq_repmsg) : -1,
+ ast_type, req, req->rq_xid);
+ if (res) {
+ /*
+ * update lvbo to return proper attributes.
+ * see b=23174
+ */
+ ldlm_resource_getref(res);
+ ldlm_lvbo_update(res, lock, NULL, 1);
+ ldlm_resource_putref(res);
+ }
+ ldlm_lock_cancel(lock);
+ rc = -ERESTART;
+ }
+
+ return rc;