⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zfcp_erp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	kfree(send_els->resp);	kfree(send_els);}/** * zfcp_test_link - lightweight link test procedure * @port: port to be tested * * Test status of a link to a remote port using the ELS command ADISC. */intzfcp_test_link(struct zfcp_port *port){	int retval;	zfcp_port_get(port);	retval = zfcp_erp_adisc(port);	if (retval != 0) {		zfcp_port_put(port);		ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx "				"on adapter %s\n ", port->wwpn,				zfcp_get_busid_by_port(port));		retval = zfcp_erp_port_forced_reopen(port, 0);		if (retval != 0) {			ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx "					"on adapter %s failed\n", port->wwpn,					zfcp_get_busid_by_port(port));			retval = -EPERM;		}	}	return retval;}/* * function:	 * * purpose:	called if a port failed to be opened normally *		initiates Forced Reopen recovery which is done *		asynchronously * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */static intzfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask){	int retval;	struct zfcp_adapter *adapter = port->adapter;	debug_text_event(adapter->erp_dbf, 5, "pf_ro");	debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));	ZFCP_LOG_DEBUG("forced reopen of port 0x%016Lx on adapter %s\n",		       port->wwpn, zfcp_get_busid_by_port(port));	zfcp_erp_port_block(port, clear_mask);	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {		ZFCP_LOG_DEBUG("skipped forced reopen of failed port 0x%016Lx "			       "on adapter %s\n", port->wwpn,			       zfcp_get_busid_by_port(port));		debug_text_event(adapter->erp_dbf, 5, "pf_ro_f");		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));		retval = -EIO;		goto out;	}	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,					 port->adapter, port, NULL); out:	return retval;}/* * function:	 * * purpose:	Wrappper for zfcp_erp_port_forced_reopen_internal *              used to ensure the correct locking * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */intzfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask){	int retval;	unsigned long flags;	struct zfcp_adapter *adapter;	adapter = port->adapter;	read_lock_irqsave(&zfcp_data.config_lock, flags);	write_lock(&adapter->erp_lock);	retval = zfcp_erp_port_forced_reopen_internal(port, clear_mask);	write_unlock(&adapter->erp_lock);	read_unlock_irqrestore(&zfcp_data.config_lock, flags);	return retval;}/* * function:	 * * purpose:	called if a port is to be opened *		initiates Reopen recovery which is done *		asynchronously * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */static intzfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask){	int retval;	struct zfcp_adapter *adapter = port->adapter;	debug_text_event(adapter->erp_dbf, 5, "p_ro");	debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));	ZFCP_LOG_DEBUG("reopen of port 0x%016Lx on adapter %s\n",		       port->wwpn, zfcp_get_busid_by_port(port));	zfcp_erp_port_block(port, clear_mask);	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) {		ZFCP_LOG_DEBUG("skipped reopen of failed port 0x%016Lx "			       "on adapter %s\n", port->wwpn,			       zfcp_get_busid_by_port(port));		debug_text_event(adapter->erp_dbf, 5, "p_ro_f");		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));		/* ensure propagation of failed status to new devices */		zfcp_erp_port_failed(port);		retval = -EIO;		goto out;	}	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,					 port->adapter, port, NULL); out:	return retval;}/** * zfcp_erp_port_reopen - initiate reopen of a remote port * @port: port to be reopened * @clear_mask: specifies flags in port status to be cleared * Return: 0 on success, < 0 on error * * This is a wrappper function for zfcp_erp_port_reopen_internal. It ensures * correct locking. An error recovery task is initiated to do the reopen. * To wait for the completion of the reopen zfcp_erp_wait should be used. */intzfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask){	int retval;	unsigned long flags;	struct zfcp_adapter *adapter = port->adapter;	read_lock_irqsave(&zfcp_data.config_lock, flags);	write_lock(&adapter->erp_lock);	retval = zfcp_erp_port_reopen_internal(port, clear_mask);	write_unlock(&adapter->erp_lock);	read_unlock_irqrestore(&zfcp_data.config_lock, flags);	return retval;}/* * function:	 * * purpose:	called if a unit is to be opened *		initiates Reopen recovery which is done *		asynchronously * * returns:	0	- initiated action succesfully *		<0	- failed to initiate action */static intzfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask){	int retval;	struct zfcp_adapter *adapter = unit->port->adapter;	debug_text_event(adapter->erp_dbf, 5, "u_ro");	debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));	ZFCP_LOG_DEBUG("reopen of unit 0x%016Lx on port 0x%016Lx "		       "on adapter %s\n", unit->fcp_lun,		       unit->port->wwpn, zfcp_get_busid_by_unit(unit));	zfcp_erp_unit_block(unit, clear_mask);	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status)) {		ZFCP_LOG_DEBUG("skipped reopen of failed unit 0x%016Lx "			       "on port 0x%016Lx on adapter %s\n",			       unit->fcp_lun, unit->port->wwpn,			       zfcp_get_busid_by_unit(unit));		debug_text_event(adapter->erp_dbf, 5, "u_ro_f");		debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,			    sizeof (fcp_lun_t));		retval = -EIO;		goto out;	}	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT,					 unit->port->adapter, unit->port, unit); out:	return retval;}/** * zfcp_erp_unit_reopen - initiate reopen of a unit * @unit: unit to be reopened * @clear_mask: specifies flags in unit status to be cleared * Return: 0 on success, < 0 on error * * This is a wrappper for zfcp_erp_unit_reopen_internal. It ensures correct * locking. An error recovery task is initiated to do the reopen. * To wait for the completion of the reopen zfcp_erp_wait should be used. */intzfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask){	int retval;	unsigned long flags;	struct zfcp_adapter *adapter;	struct zfcp_port *port;	port = unit->port;	adapter = port->adapter;	read_lock_irqsave(&zfcp_data.config_lock, flags);	write_lock(&adapter->erp_lock);	retval = zfcp_erp_unit_reopen_internal(unit, clear_mask);	write_unlock(&adapter->erp_lock);	read_unlock_irqrestore(&zfcp_data.config_lock, flags);	return retval;}/* * function:	 * * purpose:	disable I/O, *		return any open requests and clean them up, *		aim: no pending and incoming I/O * * returns: */static voidzfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask){	debug_text_event(adapter->erp_dbf, 6, "a_bl");	zfcp_erp_modify_adapter_status(adapter,				       ZFCP_STATUS_COMMON_UNBLOCKED |				       clear_mask, ZFCP_CLEAR);}/* * function:	 * * purpose:	enable I/O * * returns: */static voidzfcp_erp_adapter_unblock(struct zfcp_adapter *adapter){	debug_text_event(adapter->erp_dbf, 6, "a_ubl");	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status);}/* * function:	 * * purpose:	disable I/O, *		return any open requests and clean them up, *		aim: no pending and incoming I/O * * returns: */static voidzfcp_erp_port_block(struct zfcp_port *port, int clear_mask){	struct zfcp_adapter *adapter = port->adapter;	debug_text_event(adapter->erp_dbf, 6, "p_bl");	debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));	zfcp_erp_modify_port_status(port,				    ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,				    ZFCP_CLEAR);}/* * function:	 * * purpose:	enable I/O * * returns: */static voidzfcp_erp_port_unblock(struct zfcp_port *port){	struct zfcp_adapter *adapter = port->adapter;	debug_text_event(adapter->erp_dbf, 6, "p_ubl");	debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status);}/* * function:	 * * purpose:	disable I/O, *		return any open requests and clean them up, *		aim: no pending and incoming I/O * * returns: */static voidzfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask){	struct zfcp_adapter *adapter = unit->port->adapter;	debug_text_event(adapter->erp_dbf, 6, "u_bl");	debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));	zfcp_erp_modify_unit_status(unit,				    ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,				    ZFCP_CLEAR);}/* * function:	 * * purpose:	enable I/O * * returns: */static voidzfcp_erp_unit_unblock(struct zfcp_unit *unit){	struct zfcp_adapter *adapter = unit->port->adapter;	debug_text_event(adapter->erp_dbf, 6, "u_ubl");	debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status);}/* * function:	 * * purpose:	 * * returns: */static voidzfcp_erp_action_ready(struct zfcp_erp_action *erp_action){	struct zfcp_adapter *adapter = erp_action->adapter;	debug_text_event(adapter->erp_dbf, 4, "a_ar");	debug_event(adapter->erp_dbf, 4, &erp_action->action, sizeof (int));	zfcp_erp_action_to_ready(erp_action);	up(&adapter->erp_ready_sem);}/* * function:	 * * purpose: * * returns:	<0			erp_action not found in any list *		ZFCP_ERP_ACTION_READY	erp_action is in ready list *		ZFCP_ERP_ACTION_RUNNING	erp_action is in running list * * locks:	erp_lock must be held */static intzfcp_erp_action_exists(struct zfcp_erp_action *erp_action){	int retval = -EINVAL;	struct list_head *entry;	struct zfcp_erp_action *entry_erp_action;	struct zfcp_adapter *adapter = erp_action->adapter;	/* search in running list */	list_for_each(entry, &adapter->erp_running_head) {		entry_erp_action =		    list_entry(entry, struct zfcp_erp_action, list);		if (entry_erp_action == erp_action) {			retval = ZFCP_ERP_ACTION_RUNNING;			goto out;		}	}	/* search in ready list */	list_for_each(entry, &adapter->erp_ready_head) {		entry_erp_action =		    list_entry(entry, struct zfcp_erp_action, list);		if (entry_erp_action == erp_action) {			retval = ZFCP_ERP_ACTION_READY;			goto out;		}	} out:	return retval;}/* * purpose:	checks current status of action (timed out, dismissed, ...) *		and does appropriate preparations (dismiss fsf request, ...) * * locks:	called under erp_lock (disabled interrupts) * * returns:	0 */static intzfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action){	int retval = 0;	struct zfcp_fsf_req *fsf_req = NULL;	struct zfcp_adapter *adapter = erp_action->adapter;	if (erp_action->fsf_req) {		/* take lock to ensure that request is not being deleted meanwhile */		spin_lock(&adapter->fsf_req_list_lock);		/* check whether fsf req does still exist */		list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list)		    if (fsf_req == erp_action->fsf_req)			break;		if (fsf_req && (fsf_req->erp_action == erp_action)) {			/* fsf_req still exists */			debug_text_event(adapter->erp_dbf, 3, "a_ca_req");			debug_event(adapter->erp_dbf, 3, &fsf_req,				    sizeof (unsigned long));			/* dismiss fsf_req of timed out or dismissed erp_action */			if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED |						  ZFCP_STATUS_ERP_TIMEDOUT)) {				debug_text_event(adapter->erp_dbf, 3,						 "a_ca_disreq");				fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;			}			if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {				ZFCP_LOG_NORMAL("error: erp step timed out "						"(action=%d, fsf_req=%p)\n ",						erp_action->action,						erp_action->fsf_req);			}			/*			 * If fsf_req is neither dismissed nor completed			 * then keep it running asynchronously and don't mess			 * with the association of erp_action and fsf_req.			 */			if (fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED |					       ZFCP_STATUS_FSFREQ_DISMISSED)) {				/* forget about association between fsf_req				   and erp_action */				fsf_req->erp_action = NULL;				erp_action->fsf_req = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -