Skip to content

Commit cfaf773

Browse files
committed
Merge tag 'v6.17rc-part2-SMB3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull more smb client updates from Steve French: "Non-smbdirect: - Fix null ptr deref caused by delay in global spinlock initialization - Two fixes for native symlink creation with SMB3.1.1 POSIX Extensions - Fix for socket special file creation with SMB3.1.1 POSIX Exensions - Reduce lock contention by splitting out mid_counter_lock - move SMB1 transport code to separate file to reduce module size when support for legacy servers is disabled - Two cleanup patches: rename mid_lock to make it clearer what it protects and one to convert mid flags to bool to make clearer Smbdirect/RDMA restructuring and fixes: - Fix for error handling in send done - Remove unneeded empty packet queue - Fix put_receive_buffer error path - Two fixes to recv_done error paths - Remove unused variable - Improve response and recvmsg type handling - Fix handling of incoming message type - Two cleanup fixes for better handling smbdirect recv io - Two cleanup fixes for socket spinlock - Two patches that add socket reassembly struct - Remove unused connection_status enum - Use flag in common header for SMBDIRECT_RECV_IO_MAX_SGE - Two cleanup patches to introduce and use smbdirect send io - Two cleanup patches to introduce and use smbdirect send_io struct - Fix to return error if rdma connect takes longer than 5 seconds - Error logging improvements - Fix redundand call to init_waitqueue_head - Remove unneeded wait queue" * tag 'v6.17rc-part2-SMB3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: (33 commits) smb: client: only use a single wait_queue to monitor smbdirect connection status smb: client: don't call init_waitqueue_head(&info->conn_wait) twice in _smbd_get_connection smb: client: improve logging in smbd_conn_upcall() smb: client: return an error if rdma_connect does not return within 5 seconds smb: client: make use of smbdirect_socket.{send,recv}_io.mem.{cache,pool} smb: smbdirect: add smbdirect_socket.{send,recv}_io.mem.{cache,pool} smb: client: make use of struct smbdirect_send_io smb: smbdirect: introduce struct smbdirect_send_io smb: client: make use of SMBDIRECT_RECV_IO_MAX_SGE smb: smbdirect: add SMBDIRECT_RECV_IO_MAX_SGE smb: client: remove unused enum smbd_connection_status smb: client: make use of smbdirect_socket.recv_io.reassembly.* smb: smbdirect: introduce smbdirect_socket.recv_io.reassembly.* smb: client: make use of smb: smbdirect_socket.recv_io.free.{list,lock} smb: smbdirect: introduce smbdirect_socket.recv_io.free.{list,lock} smb: client: make use of struct smbdirect_recv_io smb: smbdirect: introduce struct smbdirect_recv_io smb: client: make use of smbdirect_socket->recv_io.expected smb: smbdirect: introduce smbdirect_socket.recv_io.expected smb: client: remove unused smbd_connection->fragment_reassembly_remaining ...
2 parents 471025c + dfe6f14 commit cfaf773

20 files changed

+1066
-1031
lines changed

fs/smb/client/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ cifs-$(CONFIG_CIFS_SMB_DIRECT) += smbdirect.o
3232

3333
cifs-$(CONFIG_CIFS_ROOT) += cifsroot.o
3434

35-
cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += smb1ops.o cifssmb.o
35+
cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += smb1ops.o cifssmb.o cifstransport.o
3636

3737
cifs-$(CONFIG_CIFS_COMPRESSION) += compress.o compress/lz77.o

fs/smb/client/cifs_debug.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
6060
return;
6161

6262
cifs_dbg(VFS, "Dump pending requests:\n");
63-
spin_lock(&server->mid_lock);
63+
spin_lock(&server->mid_queue_lock);
6464
list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
6565
cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n",
6666
mid_entry->mid_state,
@@ -83,7 +83,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
8383
mid_entry->resp_buf, 62);
8484
}
8585
}
86-
spin_unlock(&server->mid_lock);
86+
spin_unlock(&server->mid_queue_lock);
8787
#endif /* CONFIG_CIFS_DEBUG2 */
8888
}
8989

@@ -412,6 +412,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
412412
spin_lock(&cifs_tcp_ses_lock);
413413
list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
414414
#ifdef CONFIG_CIFS_SMB_DIRECT
415+
struct smbdirect_socket *sc;
415416
struct smbdirect_socket_parameters *sp;
416417
#endif
417418

@@ -436,7 +437,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
436437
seq_printf(m, "\nSMBDirect transport not available");
437438
goto skip_rdma;
438439
}
439-
sp = &server->smbd_conn->socket.parameters;
440+
sc = &server->smbd_conn->socket;
441+
sp = &sc->parameters;
440442

441443
seq_printf(m, "\nSMBDirect (in hex) protocol version: %x "
442444
"transport status: %x",
@@ -465,26 +467,22 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
465467
seq_printf(m, "\nRead Queue count_reassembly_queue: %x "
466468
"count_enqueue_reassembly_queue: %x "
467469
"count_dequeue_reassembly_queue: %x "
468-
"fragment_reassembly_remaining: %x "
469470
"reassembly_data_length: %x "
470471
"reassembly_queue_length: %x",
471472
server->smbd_conn->count_reassembly_queue,
472473
server->smbd_conn->count_enqueue_reassembly_queue,
473474
server->smbd_conn->count_dequeue_reassembly_queue,
474-
server->smbd_conn->fragment_reassembly_remaining,
475-
server->smbd_conn->reassembly_data_length,
476-
server->smbd_conn->reassembly_queue_length);
475+
sc->recv_io.reassembly.data_length,
476+
sc->recv_io.reassembly.queue_length);
477477
seq_printf(m, "\nCurrent Credits send_credits: %x "
478478
"receive_credits: %x receive_credit_target: %x",
479479
atomic_read(&server->smbd_conn->send_credits),
480480
atomic_read(&server->smbd_conn->receive_credits),
481481
server->smbd_conn->receive_credit_target);
482482
seq_printf(m, "\nPending send_pending: %x ",
483483
atomic_read(&server->smbd_conn->send_pending));
484-
seq_printf(m, "\nReceive buffers count_receive_queue: %x "
485-
"count_empty_packet_queue: %x",
486-
server->smbd_conn->count_receive_queue,
487-
server->smbd_conn->count_empty_packet_queue);
484+
seq_printf(m, "\nReceive buffers count_receive_queue: %x ",
485+
server->smbd_conn->count_receive_queue);
488486
seq_printf(m, "\nMR responder_resources: %x "
489487
"max_frmr_depth: %x mr_type: %x",
490488
server->smbd_conn->responder_resources,
@@ -672,7 +670,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
672670

673671
seq_printf(m, "\n\tServer ConnectionId: 0x%llx",
674672
chan_server->conn_id);
675-
spin_lock(&chan_server->mid_lock);
673+
spin_lock(&chan_server->mid_queue_lock);
676674
list_for_each_entry(mid_entry, &chan_server->pending_mid_q, qhead) {
677675
seq_printf(m, "\n\t\tState: %d com: %d pid: %d cbdata: %p mid %llu",
678676
mid_entry->mid_state,
@@ -681,7 +679,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
681679
mid_entry->callback_data,
682680
mid_entry->mid);
683681
}
684-
spin_unlock(&chan_server->mid_lock);
682+
spin_unlock(&chan_server->mid_queue_lock);
685683
}
686684
spin_unlock(&ses->chan_lock);
687685
seq_puts(m, "\n--\n");

fs/smb/client/cifsfs.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ unsigned int global_secflags = CIFSSEC_DEF;
7777
unsigned int GlobalCurrentXid; /* protected by GlobalMid_Lock */
7878
unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Lock */
7979
unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Lock */
80-
spinlock_t GlobalMid_Lock; /* protects above & list operations on midQ entries */
80+
DEFINE_SPINLOCK(GlobalMid_Lock); /* protects above & list operations on midQ entries */
8181

8282
/*
8383
* Global counters, updated atomically
@@ -97,7 +97,7 @@ atomic_t total_buf_alloc_count;
9797
atomic_t total_small_buf_alloc_count;
9898
#endif/* STATS2 */
9999
struct list_head cifs_tcp_ses_list;
100-
spinlock_t cifs_tcp_ses_lock;
100+
DEFINE_SPINLOCK(cifs_tcp_ses_lock);
101101
static const struct super_operations cifs_super_ops;
102102
unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
103103
module_param(CIFSMaxBufSize, uint, 0444);
@@ -723,7 +723,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
723723
else
724724
seq_puts(s, ",nativesocket");
725725
seq_show_option(s, "symlink",
726-
cifs_symlink_type_str(get_cifs_symlink_type(cifs_sb)));
726+
cifs_symlink_type_str(cifs_symlink_type(cifs_sb)));
727727

728728
seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize);
729729
seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize);
@@ -1863,8 +1863,6 @@ init_cifs(void)
18631863
GlobalCurrentXid = 0;
18641864
GlobalTotalActiveXid = 0;
18651865
GlobalMaxActiveXid = 0;
1866-
spin_lock_init(&cifs_tcp_ses_lock);
1867-
spin_lock_init(&GlobalMid_Lock);
18681866

18691867
cifs_lock_secret = get_random_u32();
18701868

fs/smb/client/cifsglob.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,8 @@ struct TCP_Server_Info {
732732
#endif
733733
wait_queue_head_t response_q;
734734
wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
735-
spinlock_t mid_lock; /* protect mid queue and it's entries */
735+
spinlock_t mid_queue_lock; /* protect mid queue */
736+
spinlock_t mid_counter_lock;
736737
struct list_head pending_mid_q;
737738
bool noblocksnd; /* use blocking sendmsg */
738739
bool noautotune; /* do not autotune send buf sizes */
@@ -770,7 +771,7 @@ struct TCP_Server_Info {
770771
/* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
771772
unsigned int capabilities; /* selective disabling of caps by smb sess */
772773
int timeAdj; /* Adjust for difference in server time zone in sec */
773-
__u64 CurrentMid; /* multiplex id - rotating counter, protected by GlobalMid_Lock */
774+
__u64 current_mid; /* multiplex id - rotating counter, protected by mid_counter_lock */
774775
char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */
775776
/* 16th byte of RFC1001 workstation name is always null */
776777
char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
@@ -1729,9 +1730,10 @@ struct mid_q_entry {
17291730
unsigned int resp_buf_size;
17301731
int mid_state; /* wish this were enum but can not pass to wait_event */
17311732
int mid_rc; /* rc for MID_RC */
1732-
unsigned int mid_flags;
17331733
__le16 command; /* smb command code */
17341734
unsigned int optype; /* operation type */
1735+
bool wait_cancelled:1; /* Cancelled while waiting for response */
1736+
bool deleted_from_q:1; /* Whether Mid has been dequeued frem pending_mid_q */
17351737
bool large_buf:1; /* if valid response, is pointer to large buf */
17361738
bool multiRsp:1; /* multiple trans2 responses for one request */
17371739
bool multiEnd:1; /* both received */
@@ -1893,10 +1895,6 @@ static inline bool is_replayable_error(int error)
18931895
#define MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */
18941896
#define MID_RC 0x80 /* mid_rc contains custom rc */
18951897

1896-
/* Flags */
1897-
#define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */
1898-
#define MID_DELETED 2 /* Mid has been dequeued/deleted */
1899-
19001898
/* Types of response buffer returned from SendReceive2 */
19011899
#define CIFS_NO_BUFFER 0 /* Response buffer not returned */
19021900
#define CIFS_SMALL_BUFFER 1
@@ -2007,9 +2005,9 @@ require use of the stronger protocol */
20072005
* GlobalCurrentXid
20082006
* GlobalTotalActiveXid
20092007
* TCP_Server_Info->srv_lock (anything in struct not protected by another lock and can change)
2010-
* TCP_Server_Info->mid_lock TCP_Server_Info->pending_mid_q cifs_get_tcp_session
2011-
* ->CurrentMid
2012-
* (any changes in mid_q_entry fields)
2008+
* TCP_Server_Info->mid_queue_lock TCP_Server_Info->pending_mid_q cifs_get_tcp_session
2009+
* mid_q_entry->deleted_from_q
2010+
* TCP_Server_Info->mid_counter_lock TCP_Server_Info->current_mid cifs_get_tcp_session
20132011
* TCP_Server_Info->req_lock TCP_Server_Info->in_flight cifs_get_tcp_session
20142012
* ->credits
20152013
* ->echo_credits
@@ -2377,4 +2375,9 @@ static inline bool cifs_netbios_name(const char *name, size_t namelen)
23772375
return ret;
23782376
}
23792377

2378+
#define CIFS_REPARSE_SUPPORT(tcon) \
2379+
((tcon)->posix_extensions || \
2380+
(le32_to_cpu((tcon)->fsAttrInfo.Attributes) & \
2381+
FILE_SUPPORTS_REPARSE_POINTS))
2382+
23802383
#endif /* _CIFS_GLOB_H */

fs/smb/client/cifsproto.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,31 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
116116
int * /* bytes returned */ , const int);
117117
extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
118118
char *in_buf, int flags);
119+
int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server);
119120
extern struct mid_q_entry *cifs_setup_request(struct cifs_ses *,
120121
struct TCP_Server_Info *,
121122
struct smb_rqst *);
122123
extern struct mid_q_entry *cifs_setup_async_request(struct TCP_Server_Info *,
123124
struct smb_rqst *);
125+
int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
126+
struct smb_rqst *rqst);
124127
extern int cifs_check_receive(struct mid_q_entry *mid,
125128
struct TCP_Server_Info *server, bool log_error);
129+
int wait_for_free_request(struct TCP_Server_Info *server, const int flags,
130+
unsigned int *instance);
126131
extern int cifs_wait_mtu_credits(struct TCP_Server_Info *server,
127132
size_t size, size_t *num,
128133
struct cifs_credits *credits);
134+
135+
static inline int
136+
send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
137+
struct mid_q_entry *mid)
138+
{
139+
return server->ops->send_cancel ?
140+
server->ops->send_cancel(server, rqst, mid) : 0;
141+
}
142+
143+
int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ);
129144
extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
130145
struct kvec *, int /* nvec to send */,
131146
int * /* type of buf returned */, const int flags,

fs/smb/client/cifssmb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2751,7 +2751,7 @@ int cifs_query_reparse_point(const unsigned int xid,
27512751
if (cap_unix(tcon->ses))
27522752
return -EOPNOTSUPP;
27532753

2754-
if (!(le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS))
2754+
if (!CIFS_REPARSE_SUPPORT(tcon))
27552755
return -EOPNOTSUPP;
27562756

27572757
oparms = (struct cifs_open_parms) {
@@ -2879,7 +2879,7 @@ struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
28792879
* attempt to create reparse point. This will prevent creating unusable
28802880
* empty object on the server.
28812881
*/
2882-
if (!(le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS))
2882+
if (!CIFS_REPARSE_SUPPORT(tcon))
28832883
return ERR_PTR(-EOPNOTSUPP);
28842884

28852885
#ifndef CONFIG_CIFS_XATTR

0 commit comments

Comments
 (0)