mirror of
https://github.com/torvalds/linux.git
synced 2026-06-09 23:23:53 +02:00
smb: smbdirect: introduce smbdirect_socket_schedule_cleanup[{_lvl,_status}]()
smbdirect_socket_schedule_cleanup() is more or less copy of smbd_disconnect_rdma_connection() and smb_direct_disconnect_rdma_connection(). It will replace them in the next steps. A difference is that the location of the first error is logged, which makes it easier to analyze problems. And also disable any complex work from recv_io objects, currently these are not used and the work is always disabled anyway, but this prepares future changes. It also gets an explicit error passed in instead of hardcoding -ECONNABORTED. Beside the main smbdirect_socket_schedule_cleanup() there are some special additions: - smbdirect_socket_schedule_cleanup_lvl(), will be used for cases where we don't want a log message with SMBDIRECT_LOG_ERR. - smbdirect_socket_schedule_cleanup_status(), will be used to specify the log level together with a direct final status, for the RDMA_CM_EVENT_DEVICE_REMOVAL and RDMA_CM_EVENT_DISCONNECTED cases where we need to avoid SMBDIRECT_SOCKET_DISCONNECTING and rdma_disconnect() in smbdirect_socket_cleanup_work(). With this we're also able to define a default for __SMBDIRECT_SOCKET_DISCONNECT() just using: smbdirect_socket_schedule_cleanup(__sc, -ECONNABORTED) Cc: Steve French <smfrench@gmail.com> Cc: Tom Talpey <tom@talpey.com> Cc: Long Li <longli@microsoft.com> Cc: Namjae Jeon <linkinjeon@kernel.org> Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Signed-off-by: Stefan Metzmacher <metze@samba.org> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
1be83fad0c
commit
d856148601
|
|
@ -10,4 +10,26 @@
|
|||
#include "smbdirect_pdu.h"
|
||||
#include "smbdirect_socket.h"
|
||||
|
||||
static void __smbdirect_socket_schedule_cleanup(struct smbdirect_socket *sc,
|
||||
const char *macro_name,
|
||||
unsigned int lvl,
|
||||
const char *func,
|
||||
unsigned int line,
|
||||
int error,
|
||||
enum smbdirect_socket_status *force_status);
|
||||
#define smbdirect_socket_schedule_cleanup(__sc, __error) \
|
||||
__smbdirect_socket_schedule_cleanup(__sc, \
|
||||
"smbdirect_socket_schedule_cleanup", SMBDIRECT_LOG_ERR, \
|
||||
__func__, __LINE__, __error, NULL)
|
||||
#define smbdirect_socket_schedule_cleanup_lvl(__sc, __lvl, __error) \
|
||||
__smbdirect_socket_schedule_cleanup(__sc, \
|
||||
"smbdirect_socket_schedule_cleanup_lvl", __lvl, \
|
||||
__func__, __LINE__, __error, NULL)
|
||||
#define smbdirect_socket_schedule_cleanup_status(__sc, __lvl, __error, __status) do { \
|
||||
enum smbdirect_socket_status __force_status = __status; \
|
||||
__smbdirect_socket_schedule_cleanup(__sc, \
|
||||
"smbdirect_socket_schedule_cleanup_status", __lvl, \
|
||||
__func__, __LINE__, __error, &__force_status); \
|
||||
} while (0)
|
||||
|
||||
#endif /* __FS_SMB_COMMON_SMBDIRECT_INTERNAL_H__ */
|
||||
|
|
|
|||
|
|
@ -67,6 +67,101 @@ static void smbdirect_socket_wake_up_all(struct smbdirect_socket *sc)
|
|||
wake_up_all(&sc->mr_io.cleanup.wait_queue);
|
||||
}
|
||||
|
||||
__maybe_unused /* this is temporary while this file is included in others */
|
||||
static void __smbdirect_socket_schedule_cleanup(struct smbdirect_socket *sc,
|
||||
const char *macro_name,
|
||||
unsigned int lvl,
|
||||
const char *func,
|
||||
unsigned int line,
|
||||
int error,
|
||||
enum smbdirect_socket_status *force_status)
|
||||
{
|
||||
bool was_first = false;
|
||||
|
||||
if (!sc->first_error) {
|
||||
___smbdirect_log_generic(sc, func, line,
|
||||
lvl,
|
||||
SMBDIRECT_LOG_RDMA_EVENT,
|
||||
"%s(%1pe%s%s) called from %s in line=%u status=%s\n",
|
||||
macro_name,
|
||||
SMBDIRECT_DEBUG_ERR_PTR(error),
|
||||
force_status ? ", " : "",
|
||||
force_status ? smbdirect_socket_status_string(*force_status) : "",
|
||||
func, line,
|
||||
smbdirect_socket_status_string(sc->status));
|
||||
if (error)
|
||||
sc->first_error = error;
|
||||
else
|
||||
sc->first_error = -ECONNABORTED;
|
||||
was_first = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure other work (than disconnect_work)
|
||||
* is not queued again but here we don't block and avoid
|
||||
* disable[_delayed]_work_sync()
|
||||
*/
|
||||
disable_work(&sc->connect.work);
|
||||
disable_work(&sc->recv_io.posted.refill_work);
|
||||
disable_work(&sc->mr_io.recovery_work);
|
||||
disable_work(&sc->idle.immediate_work);
|
||||
disable_delayed_work(&sc->idle.timer_work);
|
||||
|
||||
switch (sc->status) {
|
||||
case SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED:
|
||||
case SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED:
|
||||
case SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED:
|
||||
case SMBDIRECT_SOCKET_NEGOTIATE_FAILED:
|
||||
case SMBDIRECT_SOCKET_ERROR:
|
||||
case SMBDIRECT_SOCKET_DISCONNECTING:
|
||||
case SMBDIRECT_SOCKET_DISCONNECTED:
|
||||
case SMBDIRECT_SOCKET_DESTROYED:
|
||||
/*
|
||||
* Keep the current error status
|
||||
*/
|
||||
break;
|
||||
|
||||
case SMBDIRECT_SOCKET_RESOLVE_ADDR_NEEDED:
|
||||
case SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING:
|
||||
sc->status = SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED;
|
||||
break;
|
||||
|
||||
case SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED:
|
||||
case SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING:
|
||||
sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED;
|
||||
break;
|
||||
|
||||
case SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED:
|
||||
case SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING:
|
||||
sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED;
|
||||
break;
|
||||
|
||||
case SMBDIRECT_SOCKET_NEGOTIATE_NEEDED:
|
||||
case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING:
|
||||
sc->status = SMBDIRECT_SOCKET_NEGOTIATE_FAILED;
|
||||
break;
|
||||
|
||||
case SMBDIRECT_SOCKET_CREATED:
|
||||
sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
|
||||
break;
|
||||
|
||||
case SMBDIRECT_SOCKET_CONNECTED:
|
||||
sc->status = SMBDIRECT_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (force_status && (was_first || *force_status > sc->status))
|
||||
sc->status = *force_status;
|
||||
|
||||
/*
|
||||
* Wake up all waiters in all wait queues
|
||||
* in order to notice the broken connection.
|
||||
*/
|
||||
smbdirect_socket_wake_up_all(sc);
|
||||
|
||||
queue_work(sc->workqueue, &sc->disconnect_work);
|
||||
}
|
||||
|
||||
static void smbdirect_socket_cleanup_work(struct work_struct *work)
|
||||
{
|
||||
struct smbdirect_socket *sc =
|
||||
|
|
|
|||
|
|
@ -602,6 +602,11 @@ static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc)
|
|||
#define SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status) \
|
||||
__SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, /* nothing */)
|
||||
|
||||
#ifndef __SMBDIRECT_SOCKET_DISCONNECT
|
||||
#define __SMBDIRECT_SOCKET_DISCONNECT(__sc) \
|
||||
smbdirect_socket_schedule_cleanup(__sc, -ECONNABORTED)
|
||||
#endif /* ! __SMBDIRECT_SOCKET_DISCONNECT */
|
||||
|
||||
#define SMBDIRECT_CHECK_STATUS_DISCONNECT(__sc, __expected_status) \
|
||||
__SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, \
|
||||
__SMBDIRECT_SOCKET_DISCONNECT(__sc);)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user