From: Stefan Metzmacher Date: Fri, 19 Sep 2025 07:48:58 +0000 (+0200) Subject: smb: smbdirect: introduce smbdirect_socket_wait_for_credits() X-Git-Tag: v7.1-rc1~128^2~116 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0ad03ed97da1761a8c42bf4fad559409dfbe0db7;p=thirdparty%2Fkernel%2Flinux.git smb: smbdirect: introduce smbdirect_socket_wait_for_credits() This is a copy of wait_for_credits() in the server, which will be replaced by this soon. This will allow us to share more common code between client and server soon. Cc: Steve French Cc: Tom Talpey Cc: Long Li Cc: Namjae Jeon Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Signed-off-by: Stefan Metzmacher Acked-by: Namjae Jeon Signed-off-by: Steve French --- diff --git a/fs/smb/common/smbdirect/smbdirect_internal.h b/fs/smb/common/smbdirect/smbdirect_internal.h index 2d7c69f71ee06..ff4db1c3f1281 100644 --- a/fs/smb/common/smbdirect/smbdirect_internal.h +++ b/fs/smb/common/smbdirect/smbdirect_internal.h @@ -32,6 +32,13 @@ static void __smbdirect_socket_schedule_cleanup(struct smbdirect_socket *sc, __func__, __LINE__, __error, &__force_status); \ } while (0) +static int smbdirect_socket_wait_for_credits(struct smbdirect_socket *sc, + enum smbdirect_socket_status expected_status, + int unexpected_errno, + wait_queue_head_t *waitq, + atomic_t *total_credits, + int needed); + static void smbdirect_connection_idle_timer_work(struct work_struct *work); #endif /* __FS_SMB_COMMON_SMBDIRECT_INTERNAL_H__ */ diff --git a/fs/smb/common/smbdirect/smbdirect_socket.c b/fs/smb/common/smbdirect/smbdirect_socket.c index 05a284526aa21..bbd794fddc1ec 100644 --- a/fs/smb/common/smbdirect/smbdirect_socket.c +++ b/fs/smb/common/smbdirect/smbdirect_socket.c @@ -250,3 +250,32 @@ static void smbdirect_socket_cleanup_work(struct work_struct *work) */ smbdirect_socket_wake_up_all(sc); } + +__maybe_unused /* this is temporary while this file is included in others */ +static int smbdirect_socket_wait_for_credits(struct smbdirect_socket *sc, + enum smbdirect_socket_status expected_status, + int unexpected_errno, + wait_queue_head_t *waitq, + atomic_t *total_credits, + int needed) +{ + int ret; + + if (WARN_ON_ONCE(needed < 0)) + return -EINVAL; + + do { + if (atomic_sub_return(needed, total_credits) >= 0) + return 0; + + atomic_add(needed, total_credits); + ret = wait_event_interruptible(*waitq, + atomic_read(total_credits) >= needed || + sc->status != expected_status); + + if (sc->status != expected_status) + return unexpected_errno; + else if (ret < 0) + return ret; + } while (true); +}