[PATCH v4 09/11] cifs: Remove the server pointer from smb_message

David Howells
2025-11-24T12:43:42Z

Remove the server pointer from smb_message and instead pass it down to all
the things that access it.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com> (RDMA, smbdirect)
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
---
fs/smb/client/cifsglob.h | 10 ++++----
fs/smb/client/cifsproto.h | 21 +++++++++++------
fs/smb/client/cifssmb.c | 15 +++++-------
fs/smb/client/cifstransport.c | 13 +++++------
fs/smb/client/connect.c | 34 +++++++++++++--------------
fs/smb/client/netmisc.c | 5 ++--
fs/smb/client/smb1ops.c | 4 ++--
fs/smb/client/smb2ops.c | 22 +++++++++---------
fs/smb/client/smb2pdu.c | 23 ++++++++----------
fs/smb/client/smb2transport.c | 7 +++---
fs/smb/client/transport.c | 44 ++++++++++++++++-------------------
11 files changed, 97 insertions(+), 101 deletions(-)

diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index f1df282640c1..33e8ecec0067 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -1654,7 +1654,7 @@ typedef int (*mid_receive_t)(struct TCP_Server_Info *server,
* - it will be called by cifsd, with no locks held
* - the mid will be removed from any lists
*/
-typedef void (*mid_callback_t)(struct smb_message *smb);
+typedef void (*mid_callback_t)(struct TCP_Server_Info *srv, struct smb_message *smb);

/*
* This is the protopyte for mid handle function. This is called once the mid
@@ -1666,8 +1666,7 @@ typedef int (*mid_handle_t)(struct TCP_Server_Info *server,
/* one of these for every pending CIFS request to the server */
struct smb_message {
struct list_head qhead; /* mids waiting on reply from this server */
- struct kref refcount;
- struct TCP_Server_Info *server; /* server corresponding to this mid */
+ refcount_t refcount;
__u64 mid; /* multiplex id */
__u16 credits; /* number of credits consumed by this mid */
__u16 credits_received; /* number of credits from the response */
@@ -2334,7 +2333,8 @@ static inline bool cifs_netbios_name(const char *name, size_t namelen)
* Execute mid callback atomically - ensures callback runs exactly once
* and prevents sleeping in atomic context.
*/
-static inline void mid_execute_callback(struct smb_message *smb)
+static inline void mid_execute_callback(struct TCP_Server_Info *server,
+ struct smb_message *smb)
{
mid_callback_t callback;

@@ -2344,7 +2344,7 @@ static inline void mid_execute_callback(struct smb_message *smb)
spin_unlock(&smb->mid_lock);

if (callback)
- callback(smb);
+ callback(server, smb);
}

#define CIFS_REPARSE_SUPPORT(tcon) \
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 4676268bd621..df7e86e0471c 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -133,7 +133,7 @@ int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
ssize_t cifs_discard_from_socket(struct TCP_Server_Info *server, size_t to_read);
int cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter,
unsigned int to_read);
-void dequeue_mid(struct smb_message *mid, bool malformed);
+void dequeue_mid(struct TCP_Server_Info *server, struct smb_message *mid, bool malformed);
int cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required);
int cifs_handle_standard(struct TCP_Server_Info *server, struct smb_message *mid);
int cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs);
@@ -435,7 +435,8 @@ struct vfsmount *cifs_d_automount(struct path *path);
int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
int map_smb_to_linux_error(char *buf, bool logErr);
-int map_and_check_smb_error(struct smb_message *mid, bool logErr);
+int map_and_check_smb_error(struct TCP_Server_Info *server,
+ struct smb_message *mid, bool logErr);
unsigned int smbCalcSize(void *buf);
struct timespec64 cifs_NTtimeToUnix(__le64 ntutc);
u64 cifs_UnixTimeToNT(struct timespec64 t);
@@ -523,9 +524,9 @@ int E_md4hash(const unsigned char *passwd, unsigned char *p16,
/*
* transport.c
*/
-void cifs_wake_up_task(struct smb_message *mid);
-void __release_mid(struct kref *refcount);
-void delete_mid(struct smb_message *mid);
+void cifs_wake_up_task(struct TCP_Server_Info *server, struct smb_message *mid);
+void __release_mid(struct TCP_Server_Info *server, struct smb_message *smb);
+void delete_mid(struct TCP_Server_Info *server, struct smb_message *mid);
int smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
size_t *sent);
unsigned long smb_rqst_len(struct TCP_Server_Info *server, struct smb_rqst *rqst);
@@ -688,9 +689,15 @@ static inline bool dfs_src_pathname_equal(const char *s1, const char *s2)
return true;
}

-static inline void release_mid(struct smb_message *smb)
+static inline void smb_get_mid(struct smb_message *smb)
{
- kref_put(&smb->refcount, __release_mid);
+ refcount_inc(&smb->refcount);
+}
+
+static inline void release_mid(struct TCP_Server_Info *server, struct smb_message *smb)
+{
+ if (refcount_dec_and_test(&smb->refcount))
+ __release_mid(server, smb);
}

static inline void cifs_free_open_info(struct cifs_open_info_data *data)
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 1460c0daf71f..d28b1b113e79 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -585,12 +585,11 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
* FIXME: maybe we should consider checking that the reply matches request?
*/
static void
-cifs_echo_callback(struct smb_message *smb)
+cifs_echo_callback(struct TCP_Server_Info *server, struct smb_message *smb)
{
- struct TCP_Server_Info *server = smb->callback_data;
struct cifs_credits credits = { .value = 1, .instance = 0 };

- release_mid(smb);
+ release_mid(server, smb);
add_credits(server, &credits, CIFS_ECHO_OP);
}

@@ -1318,12 +1317,11 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
}

static void
-cifs_readv_callback(struct smb_message *smb)
+cifs_readv_callback(struct TCP_Server_Info *server, struct smb_message *smb)
{
struct cifs_io_subrequest *rdata = smb->callback_data;
struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
- struct TCP_Server_Info *server = tcon->ses->server;
struct smb_rqst rqst = { .rq_iov = rdata->iov,
.rq_nvec = 1,
.rq_iter = rdata->subreq.io_iter };
@@ -1421,7 +1419,7 @@ cifs_readv_callback(struct smb_message *smb)
rdata->subreq.transferred += rdata->got_bytes;
trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress);
netfs_read_subreq_terminated(&rdata->subreq);
- release_mid(smb);
+ release_mid(server, smb);
add_credits(server, &credits, 0);
trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
server->credits, server->in_flight,
@@ -1737,10 +1735,9 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
* workqueue completion task.
*/
static void
-cifs_writev_callback(struct smb_message *smb)
+cifs_writev_callback(struct TCP_Server_Info *server, struct smb_message *smb)
{
struct cifs_io_subrequest *wdata = smb->callback_data;
- struct TCP_Server_Info *server = wdata->server;
struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
WRITE_RSP *rsp = (WRITE_RSP *)smb->resp_buf;
struct cifs_credits credits = {
@@ -1804,7 +1801,7 @@ cifs_writev_callback(struct smb_message *smb)
0, cifs_trace_rw_credits_write_response_clear);
wdata->credits.value = 0;
cifs_write_subrequest_terminated(wdata, result);
- release_mid(smb);
+ release_mid(server, smb);
trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0,
server->credits, server->in_flight,
credits.value, cifs_trace_rw_credits_write_response_add);
diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
index 4bb673d9b56b..218c0fad901b 100644
--- a/fs/smb/client/cifstransport.c
+++ b/fs/smb/client/cifstransport.c
@@ -46,7 +46,7 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)

smb = mempool_alloc(&smb_message_pool, GFP_NOFS);
memset(smb, 0, sizeof(struct smb_message));
- kref_init(&smb->refcount);
+ refcount_set(&smb->refcount, 1);
spin_lock_init(&smb->mid_lock);
smb->mid = get_mid(smb_buffer);
smb->pid = current->pid;
@@ -55,7 +55,6 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
/* easier to use jiffies */
/* when mid allocated can be before when sent */
smb->when_alloc = jiffies;
- smb->server = server;

/*
* The default is for the mid to be synchronous, so the
@@ -120,7 +119,7 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)

rc = cifs_sign_rqst(rqst, server, &smb->sequence_number);
if (rc) {
- release_mid(smb);
+ release_mid(server, smb);
return ERR_PTR(rc);
}

@@ -180,11 +179,11 @@ cifs_check_receive(struct smb_message *smb, struct TCP_Server_Info *server,
}

/* BB special case reconnect tid and uid here? */
- return map_and_check_smb_error(smb, log_error);
+ return map_and_check_smb_error(server, smb, log_error);
}

struct smb_message *
-cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored,
+cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
struct smb_rqst *rqst)
{
int rc;
@@ -194,9 +193,9 @@ cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored,
rc = allocate_mid(ses, hdr, &smb);
if (rc)
return ERR_PTR(rc);
- rc = cifs_sign_rqst(rqst, ses->server, &smb->sequence_number);
+ rc = cifs_sign_rqst(rqst, server, &smb->sequence_number);
if (rc) {
- delete_mid(smb);
+ delete_mid(server, smb);
return ERR_PTR(rc);
}
return smb;
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 86a328b3615a..7a1112fae6ee 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -326,7 +326,7 @@ cifs_abort_connection(struct TCP_Server_Info *server)
cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
spin_lock(&server->mid_queue_lock);
list_for_each_entry_safe(smb, nsmb, &server->pending_mid_q, qhead) {
- kref_get(&smb->refcount);
+ smb_get_mid(smb);
if (smb->mid_state == MID_REQUEST_SUBMITTED)
smb->mid_state = MID_RETRY_NEEDED;
list_move(&smb->qhead, &retry_list);
@@ -338,8 +338,8 @@ cifs_abort_connection(struct TCP_Server_Info *server)
cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
list_for_each_entry_safe(smb, nsmb, &retry_list, qhead) {
list_del_init(&smb->qhead);
- mid_execute_callback(smb);
- release_mid(smb);
+ mid_execute_callback(server, smb);
+ release_mid(server, smb);
}
}

@@ -883,7 +883,7 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
*/
spin_lock(&server->mid_queue_lock);
list_for_each_entry_safe(smb, nsmb, &server->pending_mid_q, qhead) {
- kref_get(&smb->refcount);
+ smb_get_mid(smb);
list_move(&smb->qhead, &dispose_list);
smb->deleted_from_q = true;
}
@@ -916,8 +916,8 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
list_del_init(&smb->qhead);
smb->mid_rc = mid_rc;
smb->mid_state = MID_RC;
- mid_execute_callback(smb);
- release_mid(smb);
+ mid_execute_callback(server, smb);
+ release_mid(server, smb);
}

/*
@@ -949,12 +949,12 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
}

void
-dequeue_mid(struct smb_message *smb, bool malformed)
+dequeue_mid(struct TCP_Server_Info *server, struct smb_message *smb, bool malformed)
{
#ifdef CONFIG_CIFS_STATS2
smb->when_received = jiffies;
#endif
- spin_lock(&smb->server->mid_queue_lock);
+ spin_lock(&server->mid_queue_lock);
if (!malformed)
smb->mid_state = MID_RESPONSE_RECEIVED;
else
@@ -964,12 +964,12 @@ dequeue_mid(struct smb_message *smb, bool malformed)
* function has finished processing it is a bug.
*/
if (smb->deleted_from_q) {
- spin_unlock(&smb->server->mid_queue_lock);
+ spin_unlock(&server->mid_queue_lock);
pr_warn_once("trying to dequeue a deleted mid\n");
} else {
list_del_init(&smb->qhead);
smb->deleted_from_q = true;
- spin_unlock(&smb->server->mid_queue_lock);
+ spin_unlock(&server->mid_queue_lock);
}
}

@@ -1005,7 +1005,7 @@ handle_mid(struct smb_message *smb, struct TCP_Server_Info *server,
else
server->smallbuf = NULL;
}
- dequeue_mid(smb, malformed);
+ dequeue_mid(server, smb, malformed);
}

int
@@ -1102,7 +1102,7 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
smb = list_entry(tmp, struct smb_message, qhead);
cifs_dbg(FYI, "Clearing mid %llu\n", smb->mid);
- kref_get(&smb->refcount);
+ smb_get_mid(smb);
smb->mid_state = MID_SHUTDOWN;
list_move(&smb->qhead, &dispose_list);
smb->deleted_from_q = true;
@@ -1114,8 +1114,8 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
smb = list_entry(tmp, struct smb_message, qhead);
cifs_dbg(FYI, "Callback mid %llu\n", smb->mid);
list_del_init(&smb->qhead);
- mid_execute_callback(smb);
- release_mid(smb);
+ mid_execute_callback(server, smb);
+ release_mid(server, smb);
}
/* 1/8th of sec is more than enough time for them to exit */
msleep(125);
@@ -1356,7 +1356,7 @@ cifs_demultiplex_thread(void *p)
if (length < 0) {
for (i = 0; i < num_smbs; i++)
if (smbs[i])
- release_mid(smbs[i]);
+ release_mid(server, smbs[i]);
continue;
}

@@ -1389,9 +1389,9 @@ cifs_demultiplex_thread(void *p)
}

if (!smbs[i]->multiRsp || smbs[i]->multiEnd)
- mid_execute_callback(smbs[i]);
+ mid_execute_callback(server, smbs[i]);

- release_mid(smbs[i]);
+ release_mid(server, smbs[i]);
} else if (server->ops->is_oplock_break &&
server->ops->is_oplock_break(bufs[i],
server)) {
diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c
index fa994fae048b..7ad5a3cc05d1 100644
--- a/fs/smb/client/netmisc.c
+++ b/fs/smb/client/netmisc.c
@@ -889,7 +889,8 @@ map_smb_to_linux_error(char *buf, bool logErr)
}

int
-map_and_check_smb_error(struct smb_message *smb, bool logErr)
+map_and_check_smb_error(struct TCP_Server_Info *server,
+ struct smb_message *smb, bool logErr)
{
int rc;
struct smb_hdr *rhdr = (struct smb_hdr *)smb->resp_buf;
@@ -904,7 +905,7 @@ map_and_check_smb_error(struct smb_message *smb, bool logErr)
if (class == ERRSRV && code == ERRbaduid) {
cifs_dbg(FYI, "Server returned 0x%x, reconnecting session...\n",
code);
- cifs_signal_cifsd_for_reconnect(smb->server, false);
+ cifs_signal_cifsd_for_reconnect(server, false);
}
}

diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 5754427a4d30..fb4c146b6cb3 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -147,7 +147,7 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
if (compare_mid(smb->mid, buf) &&
smb->mid_state == MID_REQUEST_SUBMITTED &&
le16_to_cpu(smb->command) == buf->Command) {
- kref_get(&smb->refcount);
+ smb_get_mid(smb);
spin_unlock(&server->mid_queue_lock);
return smb;
}
@@ -449,7 +449,7 @@ cifs_check_trans2(struct smb_message *smb, struct TCP_Server_Info *server,
return true;
/* All parts received or packet is malformed. */
smb->multiEnd = true;
- dequeue_mid(smb, malformed);
+ dequeue_mid(server, smb, malformed);
return true;
}
if (!server->large_buf) {
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 5c8ed852cf55..0bc2e4cc2617 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -406,7 +406,7 @@ __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue)
if ((smb->mid == wire_mid) &&
(smb->mid_state == MID_REQUEST_SUBMITTED) &&
(smb->command == shdr->Command)) {
- kref_get(&smb->refcount);
+ smb_get_mid(smb);
if (dequeue) {
list_del_init(&smb->qhead);
smb->deleted_from_q = true;
@@ -4717,7 +4717,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
if (is_offloaded)
smb->mid_state = MID_RESPONSE_RECEIVED;
else
- dequeue_mid(smb, false);
+ dequeue_mid(server, smb, false);
return 0;
}

@@ -4744,7 +4744,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
if (is_offloaded)
smb->mid_state = MID_RESPONSE_MALFORMED;
else
- dequeue_mid(smb, rdata->result);
+ dequeue_mid(server, smb, rdata->result);
return 0;
}

@@ -4763,7 +4763,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
if (is_offloaded)
smb->mid_state = MID_RESPONSE_MALFORMED;
else
- dequeue_mid(smb, rdata->result);
+ dequeue_mid(server, smb, rdata->result);
return 0;
}

@@ -4773,7 +4773,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
if (is_offloaded)
smb->mid_state = MID_RESPONSE_MALFORMED;
else
- dequeue_mid(smb, rdata->result);
+ dequeue_mid(server, smb, rdata->result);
return 0;
}

@@ -4784,7 +4784,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
if (is_offloaded)
smb->mid_state = MID_RESPONSE_MALFORMED;
else
- dequeue_mid(smb, rdata->result);
+ dequeue_mid(server, smb, rdata->result);
return 0;
}
rdata->got_bytes = buffer_len;
@@ -4803,14 +4803,14 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
if (is_offloaded)
smb->mid_state = MID_RESPONSE_MALFORMED;
else
- dequeue_mid(smb, rdata->result);
+ dequeue_mid(server, smb, rdata->result);
return 0;
}

if (is_offloaded)
smb->mid_state = MID_RESPONSE_RECEIVED;
else
- dequeue_mid(smb, false);
+ dequeue_mid(server, smb, false);
return 0;
}

@@ -4857,7 +4857,7 @@ static void smb2_decrypt_offload(struct work_struct *work)
dw->server->ops->is_network_name_deleted(dw->buf,
dw->server);

- mid_execute_callback(smb);
+ mid_execute_callback(dw->server, smb);
} else {
spin_lock(&dw->server->srv_lock);
if (dw->server->tcpStatus == CifsNeedReconnect) {
@@ -4865,7 +4865,7 @@ static void smb2_decrypt_offload(struct work_struct *work)
smb->mid_state = MID_RETRY_NEEDED;
spin_unlock(&dw->server->mid_queue_lock);
spin_unlock(&dw->server->srv_lock);
- mid_execute_callback(smb);
+ mid_execute_callback(dw->server, smb);
} else {
spin_lock(&dw->server->mid_queue_lock);
smb->mid_state = MID_REQUEST_SUBMITTED;
@@ -4876,7 +4876,7 @@ static void smb2_decrypt_offload(struct work_struct *work)
spin_unlock(&dw->server->srv_lock);
}
}
- release_mid(smb);
+ release_mid(dw->server, smb);
}

free_pages:
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index d8a88f62dcac..9c21521061a9 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -4092,9 +4092,8 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
* FIXME: maybe we should consider checking that the reply matches request?
*/
static void
-smb2_echo_callback(struct smb_message *smb)
+smb2_echo_callback(struct TCP_Server_Info *server, struct smb_message *smb)
{
- struct TCP_Server_Info *server = smb->callback_data;
struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)smb->resp_buf;
struct cifs_credits credits = { .value = 0, .instance = 0 };

@@ -4104,7 +4103,7 @@ smb2_echo_callback(struct smb_message *smb)
credits.instance = server->reconnect_instance;
}

- release_mid(smb);
+ release_mid(server, smb);
add_credits(server, &credits, CIFS_ECHO_OP);
}

@@ -4519,12 +4518,11 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
}

static void
-smb2_readv_callback(struct smb_message *smb)
+smb2_readv_callback(struct TCP_Server_Info *server, struct smb_message *smb)
{
struct cifs_io_subrequest *rdata = smb->callback_data;
struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
- struct TCP_Server_Info *server = rdata->server;
struct smb2_hdr *shdr = (struct smb2_hdr *)rdata->iov[0].iov_base;
struct cifs_credits credits = {
.value = 0,
@@ -4540,9 +4538,9 @@ smb2_readv_callback(struct smb_message *smb)
rqst.rq_iter = rdata->subreq.io_iter;
}

- WARN_ONCE(rdata->server != smb->server,
+ WARN_ONCE(rdata->server != server,
"rdata server %p != mid server %p",
- rdata->server, smb->server);
+ rdata->server, server);

cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu/%zu\n",
__func__, smb->mid, smb->mid_state, rdata->result,
@@ -4643,7 +4641,7 @@ smb2_readv_callback(struct smb_message *smb)
rdata->subreq.transferred += rdata->got_bytes;
trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress);
netfs_read_subreq_terminated(&rdata->subreq);
- release_mid(smb);
+ release_mid(server, smb);
trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
server->credits, server->in_flight,
credits.value, cifs_trace_rw_credits_read_response_add);
@@ -4820,11 +4818,10 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
* workqueue completion task.
*/
static void
-smb2_writev_callback(struct smb_message *smb)
+smb2_writev_callback(struct TCP_Server_Info *server, struct smb_message *smb)
{
struct cifs_io_subrequest *wdata = smb->callback_data;
struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
- struct TCP_Server_Info *server = wdata->server;
struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)smb->resp_buf;
struct cifs_credits credits = {
.value = 0,
@@ -4837,9 +4834,9 @@ smb2_writev_callback(struct smb_message *smb)
ssize_t result = 0;
size_t written;

- WARN_ONCE(wdata->server != smb->server,
+ WARN_ONCE(wdata->server != server,
"wdata server %p != mid server %p",
- wdata->server, smb->server);
+ wdata->server, server);

switch (smb->mid_state) {
case MID_RESPONSE_RECEIVED:
@@ -4929,7 +4926,7 @@ smb2_writev_callback(struct smb_message *smb)
0, cifs_trace_rw_credits_write_response_clear);
wdata->credits.value = 0;
cifs_write_subrequest_terminated(wdata, result ?: written);
- release_mid(smb);
+ release_mid(server, smb);
trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
server->credits, server->in_flight,
credits.value, cifs_trace_rw_credits_write_response_add);
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 21b027040643..6d76b0c6d73d 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -655,14 +655,13 @@ smb2_mid_entry_alloc(const struct smb2_hdr *shdr,

smb = mempool_alloc(&smb_message_pool, GFP_NOFS);
memset(smb, 0, sizeof(*smb));
- kref_init(&smb->refcount);
+ refcount_set(&smb->refcount, 1);
spin_lock_init(&smb->mid_lock);
smb->mid = le64_to_cpu(shdr->MessageId);
smb->credits = credits > 0 ? credits : 1;
smb->pid = current->pid;
smb->command = shdr->Command; /* Always LE */
smb->when_alloc = jiffies;
- smb->server = server;

/*
* The default is for the mid to be synchronous, so the
@@ -779,7 +778,7 @@ smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
rc = smb2_sign_rqst(rqst, server);
if (rc) {
revert_current_mid_from_hdr(server, shdr);
- delete_mid(mid);
+ delete_mid(server, mid);
return ERR_PTR(rc);
}

@@ -813,7 +812,7 @@ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
rc = smb2_sign_rqst(rqst, server);
if (rc) {
revert_current_mid_from_hdr(server, shdr);
- release_mid(smb);
+ release_mid(server, smb);
return ERR_PTR(rc);
}

diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index d347febc821a..362c5c6c91a4 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -32,24 +32,21 @@
#include "compress.h"

void
-cifs_wake_up_task(struct smb_message *smb)
+cifs_wake_up_task(struct TCP_Server_Info *server, struct smb_message *smb)
{
if (smb->mid_state == MID_RESPONSE_RECEIVED)
smb->mid_state = MID_RESPONSE_READY;
wake_up_process(smb->callback_data);
}

-void __release_mid(struct kref *refcount)
+void __release_mid(struct TCP_Server_Info *server, struct smb_message *smb)
{
- struct smb_message *smb =
- container_of(refcount, struct smb_message, refcount);
#ifdef CONFIG_CIFS_STATS2
- __le16 command = smb->server->vals->lock_cmd;
+ __le16 command = server->vals->lock_cmd;
__u16 smb_cmd = le16_to_cpu(smb->command);
unsigned long now;
unsigned long roundtrip_time;
#endif
- struct TCP_Server_Info *server = smb->server;

if (smb->resp_buf && smb->wait_cancelled &&
(smb->mid_state == MID_RESPONSE_RECEIVED ||
@@ -120,17 +117,17 @@ void __release_mid(struct kref *refcount)
}

void
-delete_mid(struct smb_message *smb)
+delete_mid(struct TCP_Server_Info *server, struct smb_message *smb)
{
- spin_lock(&smb->server->mid_queue_lock);
+ spin_lock(&server->mid_queue_lock);

if (!smb->deleted_from_q) {
list_del_init(&smb->qhead);
smb->deleted_from_q = true;
}
- spin_unlock(&smb->server->mid_queue_lock);
+ spin_unlock(&server->mid_queue_lock);

- release_mid(smb);
+ release_mid(server, smb);
}

/*
@@ -728,7 +725,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
if (rc < 0) {
revert_current_mid(server, smb->credits);
server->sequence_number -= 2;
- delete_mid(smb);
+ delete_mid(server, smb);
}

cifs_server_unlock(server);
@@ -778,14 +775,13 @@ int cifs_sync_mid_result(struct smb_message *smb, struct TCP_Server_Info *server
spin_unlock(&server->mid_queue_lock);

sync_mid_done:
- release_mid(smb);
+ release_mid(server, smb);
return rc;
}

static void
-cifs_compound_callback(struct smb_message *smb)
+cifs_compound_callback(struct TCP_Server_Info *server, struct smb_message *smb)
{
- struct TCP_Server_Info *server = smb->server;
struct cifs_credits credits = {
.value = server->ops->get_credits(smb),
.instance = server->reconnect_instance,
@@ -798,17 +794,17 @@ cifs_compound_callback(struct smb_message *smb)
}

static void
-cifs_compound_last_callback(struct smb_message *smb)
+cifs_compound_last_callback(struct TCP_Server_Info *server, struct smb_message *smb)
{
- cifs_compound_callback(smb);
- cifs_wake_up_task(smb);
+ cifs_compound_callback(server, smb);
+ cifs_wake_up_task(server, smb);
}

static void
-cifs_cancelled_callback(struct smb_message *smb)
+cifs_cancelled_callback(struct TCP_Server_Info *server, struct smb_message *smb)
{
- cifs_compound_callback(smb);
- release_mid(smb);
+ cifs_compound_callback(server, smb);
+ release_mid(server, smb);
}

/*
@@ -942,7 +938,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
if (IS_ERR(smb[i])) {
revert_current_mid(server, i);
for (j = 0; j < i; j++)
- delete_mid(smb[j]);
+ delete_mid(server, smb[j]);
cifs_server_unlock(server);

/* Update # of requests on wire to server */
@@ -1094,7 +1090,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
*/
for (i = 0; i < num_rqst; i++) {
if (!cancelled_mid[i])
- delete_mid(smb[i]);
+ delete_mid(server, smb[i]);
}

return rc;
@@ -1143,7 +1139,7 @@ __cifs_readv_discard(struct TCP_Server_Info *server, struct smb_message *smb,
int length;

length = cifs_discard_remaining_data(server);
- dequeue_mid(smb, malformed);
+ dequeue_mid(server, smb, malformed);
smb->resp_buf = server->smallbuf;
server->smallbuf = NULL;
return length;
@@ -1280,7 +1276,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
if (server->total_read < buflen)
return cifs_readv_discard(server, smb);

- dequeue_mid(smb, false);
+ dequeue_mid(server, smb, false);
smb->resp_buf = server->smallbuf;
server->smallbuf = NULL;
return length;