History

Merge tag '5.20-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs updates from Steve French: "Mostly cleanup, including smb1 refactoring: - multichannel perf improvement - move additional SMB1 code to not be compiled in when legacy support is disabled. - bug fixes, including one important one for memory leak - various cleanup patches We are still working on and testing some deferred close improvements including an important lease break fix for case when multiple deferred closes are still open, and also some additional perf improvements - those are not included here" * tag '5.20-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6: cifs: update internal module number cifs: alloc_mid function should be marked as static cifs: remove "cifs_" prefix from init/destroy mids functions cifs: remove useless DeleteMidQEntry() cifs: when insecure legacy is disabled shrink amount of SMB1 code cifs: trivial style fixup cifs: fix wrong unlock before return from cifs_tree_connect() cifs: avoid use of global locks for high contention data cifs: remove remaining build warnings cifs: list_for_each() -> list_for_each_entry() cifs: update MAINTAINERS file with reviewers smb2: small refactor in smb2_check_message() cifs: Fix memory leak when using fscache cifs: remove minor build warning cifs: remove some camelCase and also some static build warnings cifs: remove unnecessary (void*) conversions. cifs: remove unnecessary type castings cifs: remove redundant initialization to variable mnt_sign_enabled smb3: check xattr value length earlier

Linus Torvalds committed 4 years ago

Commit 3bc1bc02 parents eb5699b 0d168a527 files · +1104 −907Browse files

Unified · Split

27 files
  1. MAINTAINERS +5 −2
  2. fs/cifs/Makefile +2 −2
  3. fs/cifs/cifs_debug.c +23 −49
  4. fs/cifs/cifsacl.c +2 −0
  5. fs/cifs/cifsencrypt.c +3 −3
  6. fs/cifs/cifsfs.c +41 −12
  7. fs/cifs/cifsfs.h +2 −2
  8. fs/cifs/cifsglob.h +91 −44
  9. fs/cifs/cifsproto.h +4 −6
  10. fs/cifs/cifssmb.c +14 −463
  11. fs/cifs/connect.c +187 −112
  12. fs/cifs/dfs_cache.c +7 −1
  13. fs/cifs/dir.c +8 −0
  14. fs/cifs/file.c +269 −14
  15. fs/cifs/inode.c +57 −7
  16. fs/cifs/ioctl.c +2 −0
  17. fs/cifs/link.c +8 −0
  18. fs/cifs/misc.c +13 −20
  19. fs/cifs/netmisc.c +1 −1
  20. fs/cifs/sess.c +4 −1
  21. fs/cifs/smb1ops.c +5 −5
  22. fs/cifs/smb2misc.c +29 −20
  23. fs/cifs/smb2ops.c +32 −29
  24. fs/cifs/smb2pdu.c +16 −16
  25. fs/cifs/smb2transport.c +20 −18
  26. fs/cifs/transport.c +255 −79
  27. fs/cifs/xattr.c +4 −1
MAINTAINERS+5−2
@@ -5123,12 +5123,15 @@ F: include/linux/clk/ · 5122 unmodified lines
5123F: include/linux/of_clk.h5123F: include/linux/of_clk.h
5124X: drivers/clk/clkdev.c5124X: drivers/clk/clkdev.c
5125 5125
5126COMMON INTERNET FILE SYSTEM CLIENT (CIFS)5126COMMON INTERNET FILE SYSTEM CLIENT (CIFS and SMB3)
5127M: Steve French <sfrench@samba.org>5127M: Steve French <sfrench@samba.org>
5128R: Paulo Alcantara <pc@cjr.nz> (DFS, global name space)
5129R: Ronnie Sahlberg <lsahlber@redhat.com> (directory leases, sparse files)
5130R: Shyam Prasad N <sprasad@microsoft.com> (multichannel)
5128L: linux-cifs@vger.kernel.org5131L: linux-cifs@vger.kernel.org
5129L: samba-technical@lists.samba.org (moderated for non-subscribers)5132L: samba-technical@lists.samba.org (moderated for non-subscribers)
5130S: Supported5133S: Supported
5131W: http://linux-cifs.samba.org/5134W: https://wiki.samba.org/index.php/LinuxCIFS
5132T: git git://git.samba.org/sfrench/cifs-2.6.git5135T: git git://git.samba.org/sfrench/cifs-2.6.git
5133F: Documentation/admin-guide/cifs/5136F: Documentation/admin-guide/cifs/
5134F: fs/cifs/5137F: fs/cifs/
fs/cifs/Makefile+2−2
@@ -5,7 +5,7 @@ · 4 unmodified lines
5ccflags-y += -I$(src) # needed for trace events5ccflags-y += -I$(src) # needed for trace events
6obj-$(CONFIG_CIFS) += cifs.o6obj-$(CONFIG_CIFS) += cifs.o
7 7
8cifs-y := trace.o cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o \8cifs-y := trace.o cifsfs.o cifs_debug.o connect.o dir.o file.o \
9 inode.o link.o misc.o netmisc.o smbencrypt.o transport.o \9 inode.o link.o misc.o netmisc.o smbencrypt.o transport.o \
10 cifs_unicode.o nterr.o cifsencrypt.o \10 cifs_unicode.o nterr.o cifsencrypt.o \
11 readdir.o ioctl.o sess.o export.o unc.o winucase.o \11 readdir.o ioctl.o sess.o export.o unc.o winucase.o \
@@ -31,4 +31,4 @@ cifs-$(CONFIG_CIFS_SMB_DIRECT) += smbdirect.o · 19 unmodified lines
31 31
32cifs-$(CONFIG_CIFS_ROOT) += cifsroot.o32cifs-$(CONFIG_CIFS_ROOT) += cifsroot.o
33 33
34cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += smb1ops.o34cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += smb1ops.o cifssmb.o
fs/cifs/cifs_debug.c+23−49
@@ -36,7 +36,7 @@ cifs_dump_mem(char *label, void *data, int length) · 35 unmodified lines
36void cifs_dump_detail(void *buf, struct TCP_Server_Info *server)36void cifs_dump_detail(void *buf, struct TCP_Server_Info *server)
37{37{
38#ifdef CONFIG_CIFS_DEBUG238#ifdef CONFIG_CIFS_DEBUG2
39 struct smb_hdr *smb = (struct smb_hdr *)buf;39 struct smb_hdr *smb = buf;
40 40
41 cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d\n",41 cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d\n",
42 smb->Command, smb->Status.CifsError,42 smb->Command, smb->Status.CifsError,
@@ -55,7 +55,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server) · 12 unmodified lines
55 return;55 return;
56 56
57 cifs_dbg(VFS, "Dump pending requests:\n");57 cifs_dbg(VFS, "Dump pending requests:\n");
58 spin_lock(&GlobalMid_Lock);58 spin_lock(&server->mid_lock);
59 list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {59 list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
60 cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n",60 cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n",
61 mid_entry->mid_state,61 mid_entry->mid_state,
@@ -78,7 +78,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server) · 16 unmodified lines
78 mid_entry->resp_buf, 62);78 mid_entry->resp_buf, 62);
79 }79 }
80 }80 }
81 spin_unlock(&GlobalMid_Lock);81 spin_unlock(&server->mid_lock);
82#endif /* CONFIG_CIFS_DEBUG2 */82#endif /* CONFIG_CIFS_DEBUG2 */
83}83}
84 84
@@ -168,7 +168,6 @@ cifs_dump_iface(struct seq_file *m, struct cifs_server_iface *iface) · 83 unmodified lines
168 168
169static int cifs_debug_files_proc_show(struct seq_file *m, void *v)169static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
170{170{
171 struct list_head *tmp, *tmp1, *tmp2;
172 struct TCP_Server_Info *server;171 struct TCP_Server_Info *server;
173 struct cifs_ses *ses;172 struct cifs_ses *ses;
174 struct cifs_tcon *tcon;173 struct cifs_tcon *tcon;
@@ -184,14 +183,10 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v) · 9 unmodified lines
184#endif /* CIFS_DEBUG2 */183#endif /* CIFS_DEBUG2 */
185 spin_lock(&cifs_tcp_ses_lock);184 spin_lock(&cifs_tcp_ses_lock);
186 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {185 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
187 list_for_each(tmp, &server->smb_ses_list) {186 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
188 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);187 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
189 list_for_each(tmp1, &ses->tcon_list) {
190 tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
191 spin_lock(&tcon->open_file_lock);188 spin_lock(&tcon->open_file_lock);
192 list_for_each(tmp2, &tcon->openFileList) {189 list_for_each_entry(cfile, &tcon->openFileList, tlist) {
193 cfile = list_entry(tmp2, struct cifsFileInfo,
194 tlist);
195 seq_printf(m,190 seq_printf(m,
196 "0x%x 0x%llx 0x%x %d %d %d %pd",191 "0x%x 0x%llx 0x%x %d %d %d %pd",
197 tcon->tid,192 tcon->tid,
@@ -218,7 +213,6 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v) · 20 unmodified lines
218 213
219static int cifs_debug_data_proc_show(struct seq_file *m, void *v)214static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
220{215{
221 struct list_head *tmp2, *tmp3;
222 struct mid_q_entry *mid_entry;216 struct mid_q_entry *mid_entry;
223 struct TCP_Server_Info *server;217 struct TCP_Server_Info *server;
224 struct cifs_ses *ses;218 struct cifs_ses *ses;
@@ -381,9 +375,7 @@ skip_rdma: · 156 unmodified lines
381 375
382 seq_printf(m, "\n\n\tSessions: ");376 seq_printf(m, "\n\n\tSessions: ");
383 i = 0;377 i = 0;
384 list_for_each(tmp2, &server->smb_ses_list) {378 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
385 ses = list_entry(tmp2, struct cifs_ses,
386 smb_ses_list);
387 i++;379 i++;
388 if ((ses->serverDomain == NULL) ||380 if ((ses->serverDomain == NULL) ||
389 (ses->serverOS == NULL) ||381 (ses->serverOS == NULL) ||
@@ -447,9 +439,7 @@ skip_rdma: · 57 unmodified lines
447 else439 else
448 seq_puts(m, "none\n");440 seq_puts(m, "none\n");
449 441
450 list_for_each(tmp3, &ses->tcon_list) {442 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
451 tcon = list_entry(tmp3, struct cifs_tcon,
452 tcon_list);
453 ++j;443 ++j;
454 seq_printf(m, "\n\t%d) ", j);444 seq_printf(m, "\n\t%d) ", j);
455 cifs_debug_tcon(m, tcon);445 cifs_debug_tcon(m, tcon);
@@ -473,10 +463,8 @@ skip_rdma: · 17 unmodified lines
473 seq_printf(m, "\n\t\t[NONE]");463 seq_printf(m, "\n\t\t[NONE]");
474 464
475 seq_puts(m, "\n\n\tMIDs: ");465 seq_puts(m, "\n\n\tMIDs: ");
476 spin_lock(&GlobalMid_Lock);466 spin_lock(&server->mid_lock);
477 list_for_each(tmp3, &server->pending_mid_q) {467 list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
478 mid_entry = list_entry(tmp3, struct mid_q_entry,
479 qhead);
480 seq_printf(m, "\n\tState: %d com: %d pid:"468 seq_printf(m, "\n\tState: %d com: %d pid:"
481 " %d cbdata: %p mid %llu\n",469 " %d cbdata: %p mid %llu\n",
482 mid_entry->mid_state,470 mid_entry->mid_state,
@@ -485,7 +473,7 @@ skip_rdma: · 2 unmodified lines
485 mid_entry->callback_data,473 mid_entry->callback_data,
486 mid_entry->mid);474 mid_entry->mid);
487 }475 }
488 spin_unlock(&GlobalMid_Lock);476 spin_unlock(&server->mid_lock);
489 seq_printf(m, "\n--\n");477 seq_printf(m, "\n--\n");
490 }478 }
491 if (c == 0)479 if (c == 0)
@@ -504,7 +492,6 @@ static ssize_t cifs_stats_proc_write(struct file *file, · 12 unmodified lines
504{492{
505 bool bv;493 bool bv;
506 int rc;494 int rc;
507 struct list_head *tmp1, *tmp2, *tmp3;
508 struct TCP_Server_Info *server;495 struct TCP_Server_Info *server;
509 struct cifs_ses *ses;496 struct cifs_ses *ses;
510 struct cifs_tcon *tcon;497 struct cifs_tcon *tcon;
@@ -514,8 +501,8 @@ static ssize_t cifs_stats_proc_write(struct file *file, · 3 unmodified lines
514#ifdef CONFIG_CIFS_STATS2501#ifdef CONFIG_CIFS_STATS2
515 int i;502 int i;
516 503
517 atomic_set(&totBufAllocCount, 0);504 atomic_set(&total_buf_alloc_count, 0);
518 atomic_set(&totSmBufAllocCount, 0);505 atomic_set(&total_small_buf_alloc_count, 0);
519#endif /* CONFIG_CIFS_STATS2 */506#endif /* CONFIG_CIFS_STATS2 */
520 atomic_set(&tcpSesReconnectCount, 0);507 atomic_set(&tcpSesReconnectCount, 0);
521 atomic_set(&tconInfoReconnectCount, 0);508 atomic_set(&tconInfoReconnectCount, 0);
@@ -525,9 +512,7 @@ static ssize_t cifs_stats_proc_write(struct file *file, · 3 unmodified lines
525 GlobalCurrentXid = 0;512 GlobalCurrentXid = 0;
526 spin_unlock(&GlobalMid_Lock);513 spin_unlock(&GlobalMid_Lock);
527 spin_lock(&cifs_tcp_ses_lock);514 spin_lock(&cifs_tcp_ses_lock);
528 list_for_each(tmp1, &cifs_tcp_ses_list) {515 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
529 server = list_entry(tmp1, struct TCP_Server_Info,
530 tcp_ses_list);
531 server->max_in_flight = 0;516 server->max_in_flight = 0;
532#ifdef CONFIG_CIFS_STATS2517#ifdef CONFIG_CIFS_STATS2
533 for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {518 for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
@@ -538,13 +523,8 @@ static ssize_t cifs_stats_proc_write(struct file *file, · 4 unmodified lines
538 server->fastest_cmd[0] = 0;523 server->fastest_cmd[0] = 0;
539 }524 }
540#endif /* CONFIG_CIFS_STATS2 */525#endif /* CONFIG_CIFS_STATS2 */
541 list_for_each(tmp2, &server->smb_ses_list) {526 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
542 ses = list_entry(tmp2, struct cifs_ses,527 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
543 smb_ses_list);
544 list_for_each(tmp3, &ses->tcon_list) {
545 tcon = list_entry(tmp3,
546 struct cifs_tcon,
547 tcon_list);
548 atomic_set(&tcon->num_smbs_sent, 0);528 atomic_set(&tcon->num_smbs_sent, 0);
549 spin_lock(&tcon->stat_lock);529 spin_lock(&tcon->stat_lock);
550 tcon->bytes_read = 0;530 tcon->bytes_read = 0;
@@ -569,7 +549,6 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) · 18 unmodified lines
569#ifdef CONFIG_CIFS_STATS2549#ifdef CONFIG_CIFS_STATS2
570 int j;550 int j;
571#endif /* STATS2 */551#endif /* STATS2 */
572 struct list_head *tmp2, *tmp3;
573 struct TCP_Server_Info *server;552 struct TCP_Server_Info *server;
574 struct cifs_ses *ses;553 struct cifs_ses *ses;
575 struct cifs_tcon *tcon;554 struct cifs_tcon *tcon;
@@ -579,17 +558,17 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) · 3 unmodified lines
579 seq_printf(m, "Share (unique mount targets): %d\n",558 seq_printf(m, "Share (unique mount targets): %d\n",
580 tconInfoAllocCount.counter);559 tconInfoAllocCount.counter);
581 seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n",560 seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n",
582 bufAllocCount.counter,561 buf_alloc_count.counter,
583 cifs_min_rcv + tcpSesAllocCount.counter);562 cifs_min_rcv + tcpSesAllocCount.counter);
584 seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n",563 seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n",
585 smBufAllocCount.counter, cifs_min_small);564 small_buf_alloc_count.counter, cifs_min_small);
586#ifdef CONFIG_CIFS_STATS2565#ifdef CONFIG_CIFS_STATS2
587 seq_printf(m, "Total Large %d Small %d Allocations\n",566 seq_printf(m, "Total Large %d Small %d Allocations\n",
588 atomic_read(&totBufAllocCount),567 atomic_read(&total_buf_alloc_count),
589 atomic_read(&totSmBufAllocCount));568 atomic_read(&total_small_buf_alloc_count));
590#endif /* CONFIG_CIFS_STATS2 */569#endif /* CONFIG_CIFS_STATS2 */
591 570
592 seq_printf(m, "Operations (MIDs): %d\n", atomic_read(&midCount));571 seq_printf(m, "Operations (MIDs): %d\n", atomic_read(&mid_count));
593 seq_printf(m,572 seq_printf(m,
594 "\n%d session %d share reconnects\n",573 "\n%d session %d share reconnects\n",
595 tcpSesReconnectCount.counter, tconInfoReconnectCount.counter);574 tcpSesReconnectCount.counter, tconInfoReconnectCount.counter);
@@ -619,13 +598,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) · 23 unmodified lines
619 atomic_read(&server->smb2slowcmd[j]),598 atomic_read(&server->smb2slowcmd[j]),
620 server->hostname, j);599 server->hostname, j);
621#endif /* STATS2 */600#endif /* STATS2 */
622 list_for_each(tmp2, &server->smb_ses_list) {601 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
623 ses = list_entry(tmp2, struct cifs_ses,602 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
624 smb_ses_list);
625 list_for_each(tmp3, &ses->tcon_list) {
626 tcon = list_entry(tmp3,
627 struct cifs_tcon,
628 tcon_list);
629 i++;603 i++;
630 seq_printf(m, "\n%d) %s", i, tcon->treeName);604 seq_printf(m, "\n%d) %s", i, tcon->treeName);
631 if (tcon->need_reconnect)605 if (tcon->need_reconnect)
fs/cifs/cifsacl.c+2−0
@@ -1379,6 +1379,7 @@ chown_chgrp_exit: · 1378 unmodified lines
1379 return rc;1379 return rc;
1380}1380}
1381 1381
1382#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1382struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,1383struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1383 const struct cifs_fid *cifsfid, u32 *pacllen,1384 const struct cifs_fid *cifsfid, u32 *pacllen,
1384 u32 __maybe_unused unused)1385 u32 __maybe_unused unused)
@@ -1512,6 +1513,7 @@ out: · 127 unmodified lines
1512 cifs_put_tlink(tlink);1513 cifs_put_tlink(tlink);
1513 return rc;1514 return rc;
1514}1515}
1516#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1515 1517
1516/* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */1518/* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1517int1519int
fs/cifs/cifsencrypt.c+3−3
@@ -141,13 +141,13 @@ int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server, · 140 unmodified lines
141 if ((cifs_pdu == NULL) || (server == NULL))141 if ((cifs_pdu == NULL) || (server == NULL))
142 return -EINVAL;142 return -EINVAL;
143 143
144 spin_lock(&cifs_tcp_ses_lock);144 spin_lock(&server->srv_lock);
145 if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||145 if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
146 server->tcpStatus == CifsNeedNegotiate) {146 server->tcpStatus == CifsNeedNegotiate) {
147 spin_unlock(&cifs_tcp_ses_lock);147 spin_unlock(&server->srv_lock);
148 return rc;148 return rc;
149 }149 }
150 spin_unlock(&cifs_tcp_ses_lock);150 spin_unlock(&server->srv_lock);
151 151
152 if (!server->session_estab) {152 if (!server->session_estab) {
153 memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);153 memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
fs/cifs/cifsfs.c+41−12
@@ -68,6 +68,34 @@ bool enable_negotiate_signing; /* false by default */ · 67 unmodified lines
68unsigned int global_secflags = CIFSSEC_DEF;68unsigned int global_secflags = CIFSSEC_DEF;
69/* unsigned int ntlmv2_support = 0; */69/* unsigned int ntlmv2_support = 0; */
70unsigned int sign_CIFS_PDUs = 1;70unsigned int sign_CIFS_PDUs = 1;
71
72/*
73 * Global transaction id (XID) information
74 */
75unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */
76unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
77unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
78spinlock_t GlobalMid_Lock; /* protects above & list operations on midQ entries */
79
80/*
81 * Global counters, updated atomically
82 */
83atomic_t sesInfoAllocCount;
84atomic_t tconInfoAllocCount;
85atomic_t tcpSesNextId;
86atomic_t tcpSesAllocCount;
87atomic_t tcpSesReconnectCount;
88atomic_t tconInfoReconnectCount;
89
90atomic_t mid_count;
91atomic_t buf_alloc_count;
92atomic_t small_buf_alloc_count;
93#ifdef CONFIG_CIFS_STATS2
94atomic_t total_buf_alloc_count;
95atomic_t total_small_buf_alloc_count;
96#endif/* STATS2 */
97struct list_head cifs_tcp_ses_list;
98spinlock_t cifs_tcp_ses_lock;
71static const struct super_operations cifs_super_ops;99static const struct super_operations cifs_super_ops;
72unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;100unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
73module_param(CIFSMaxBufSize, uint, 0444);101module_param(CIFSMaxBufSize, uint, 0444);
@@ -703,14 +731,17 @@ static void cifs_umount_begin(struct super_block *sb) · 629 unmodified lines
703 tcon = cifs_sb_master_tcon(cifs_sb);731 tcon = cifs_sb_master_tcon(cifs_sb);
704 732
705 spin_lock(&cifs_tcp_ses_lock);733 spin_lock(&cifs_tcp_ses_lock);
734 spin_lock(&tcon->tc_lock);
706 if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {735 if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {
707 /* we have other mounts to same share or we have736 /* we have other mounts to same share or we have
708 already tried to force umount this and woken up737 already tried to force umount this and woken up
709 all waiting network requests, nothing to do */738 all waiting network requests, nothing to do */
739 spin_unlock(&tcon->tc_lock);
710 spin_unlock(&cifs_tcp_ses_lock);740 spin_unlock(&cifs_tcp_ses_lock);
711 return;741 return;
712 } else if (tcon->tc_count == 1)742 } else if (tcon->tc_count == 1)
713 tcon->status = TID_EXITING;743 tcon->status = TID_EXITING;
744 spin_unlock(&tcon->tc_lock);
714 spin_unlock(&cifs_tcp_ses_lock);745 spin_unlock(&cifs_tcp_ses_lock);
715 746
716 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */747 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
@@ -1537,8 +1568,7 @@ cifs_destroy_request_bufs(void) · 820 unmodified lines
1537 kmem_cache_destroy(cifs_sm_req_cachep);1568 kmem_cache_destroy(cifs_sm_req_cachep);
1538}1569}
1539 1570
1540static int1571static int init_mids(void)
1541cifs_init_mids(void)
1542{1572{
1543 cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",1573 cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
1544 sizeof(struct mid_q_entry), 0,1574 sizeof(struct mid_q_entry), 0,
@@ -1556,8 +1586,7 @@ cifs_init_mids(void) · 11 unmodified lines
1556 return 0;1586 return 0;
1557}1587}
1558 1588
1559static void1589static void destroy_mids(void)
1560cifs_destroy_mids(void)
1561{1590{
1562 mempool_destroy(cifs_mid_poolp);1591 mempool_destroy(cifs_mid_poolp);
1563 kmem_cache_destroy(cifs_mid_cachep);1592 kmem_cache_destroy(cifs_mid_cachep);
@@ -1579,11 +1608,11 @@ init_cifs(void) · 15 unmodified lines
1579 atomic_set(&tcpSesReconnectCount, 0);1608 atomic_set(&tcpSesReconnectCount, 0);
1580 atomic_set(&tconInfoReconnectCount, 0);1609 atomic_set(&tconInfoReconnectCount, 0);
1581 1610
1582 atomic_set(&bufAllocCount, 0);1611 atomic_set(&buf_alloc_count, 0);
1583 atomic_set(&smBufAllocCount, 0);1612 atomic_set(&small_buf_alloc_count, 0);
1584#ifdef CONFIG_CIFS_STATS21613#ifdef CONFIG_CIFS_STATS2
1585 atomic_set(&totBufAllocCount, 0);1614 atomic_set(&total_buf_alloc_count, 0);
1586 atomic_set(&totSmBufAllocCount, 0);1615 atomic_set(&total_small_buf_alloc_count, 0);
1587 if (slow_rsp_threshold < 1)1616 if (slow_rsp_threshold < 1)
1588 cifs_dbg(FYI, "slow_response_threshold msgs disabled\n");1617 cifs_dbg(FYI, "slow_response_threshold msgs disabled\n");
1589 else if (slow_rsp_threshold > 32767)1618 else if (slow_rsp_threshold > 32767)
@@ -1591,7 +1620,7 @@ init_cifs(void) · 1 unmodified line
1591 "slow response threshold set higher than recommended (0 to 32767)\n");1620 "slow response threshold set higher than recommended (0 to 32767)\n");
1592#endif /* CONFIG_CIFS_STATS2 */1621#endif /* CONFIG_CIFS_STATS2 */
1593 1622
1594 atomic_set(&midCount, 0);1623 atomic_set(&mid_count, 0);
1595 GlobalCurrentXid = 0;1624 GlobalCurrentXid = 0;
1596 GlobalTotalActiveXid = 0;1625 GlobalTotalActiveXid = 0;
1597 GlobalMaxActiveXid = 0;1626 GlobalMaxActiveXid = 0;
@@ -1654,7 +1683,7 @@ init_cifs(void) · 56 unmodified lines
1654 if (rc)1683 if (rc)
1655 goto out_destroy_deferredclose_wq;1684 goto out_destroy_deferredclose_wq;
1656 1685
1657 rc = cifs_init_mids();1686 rc = init_mids();
1658 if (rc)1687 if (rc)
1659 goto out_destroy_inodecache;1688 goto out_destroy_inodecache;
1660 1689
@@ -1711,7 +1740,7 @@ out_destroy_request_bufs: · 50 unmodified lines
1711#endif1740#endif
1712 cifs_destroy_request_bufs();1741 cifs_destroy_request_bufs();
1713out_destroy_mids:1742out_destroy_mids:
1714 cifs_destroy_mids();1743 destroy_mids();
1715out_destroy_inodecache:1744out_destroy_inodecache:
1716 cifs_destroy_inodecache();1745 cifs_destroy_inodecache();
1717out_destroy_deferredclose_wq:1746out_destroy_deferredclose_wq:
@@ -1747,7 +1776,7 @@ exit_cifs(void) · 29 unmodified lines
1747 dfs_cache_destroy();1776 dfs_cache_destroy();
1748#endif1777#endif
1749 cifs_destroy_request_bufs();1778 cifs_destroy_request_bufs();
1750 cifs_destroy_mids();1779 destroy_mids();
1751 cifs_destroy_inodecache();1780 cifs_destroy_inodecache();
1752 destroy_workqueue(deferredclose_wq);1781 destroy_workqueue(deferredclose_wq);
1753 destroy_workqueue(cifsoplockd_wq);1782 destroy_workqueue(cifsoplockd_wq);
fs/cifs/cifsfs.h+2−2
@@ -153,6 +153,6 @@ extern const struct export_operations cifs_export_ops; · 152 unmodified lines
153#endif /* CONFIG_CIFS_NFSD_EXPORT */153#endif /* CONFIG_CIFS_NFSD_EXPORT */
154 154
155/* when changing internal version - update following two lines at same time */155/* when changing internal version - update following two lines at same time */
156#define SMB3_PRODUCT_BUILD 37156#define SMB3_PRODUCT_BUILD 38
157#define CIFS_VERSION "2.37"157#define CIFS_VERSION "2.38"
158#endif /* _CIFSFS_H */158#endif /* _CIFSFS_H */
fs/cifs/cifsglob.h+91−44
@@ -605,6 +605,7 @@ inc_rfc1001_len(void *buf, int count) · 604 unmodified lines
605struct TCP_Server_Info {605struct TCP_Server_Info {
606 struct list_head tcp_ses_list;606 struct list_head tcp_ses_list;
607 struct list_head smb_ses_list;607 struct list_head smb_ses_list;
608 spinlock_t srv_lock; /* protect anything here that is not protected */
608 __u64 conn_id; /* connection identifier (useful for debugging) */609 __u64 conn_id; /* connection identifier (useful for debugging) */
609 int srv_count; /* reference counter */610 int srv_count; /* reference counter */
610 /* 15 character server name + 0x20 16th byte indicating type = srv */611 /* 15 character server name + 0x20 16th byte indicating type = srv */
@@ -622,6 +623,7 @@ struct TCP_Server_Info { · 11 unmodified lines
622#endif623#endif
623 wait_queue_head_t response_q;624 wait_queue_head_t response_q;
624 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/625 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
626 spinlock_t mid_lock; /* protect mid queue and it's entries */
625 struct list_head pending_mid_q;627 struct list_head pending_mid_q;
626 bool noblocksnd; /* use blocking sendmsg */628 bool noblocksnd; /* use blocking sendmsg */
627 bool noautotune; /* do not autotune send buf sizes */629 bool noautotune; /* do not autotune send buf sizes */
@@ -1008,6 +1010,7 @@ struct cifs_ses { · 380 unmodified lines
1008 struct list_head rlist; /* reconnect list */1010 struct list_head rlist; /* reconnect list */
1009 struct list_head tcon_list;1011 struct list_head tcon_list;
1010 struct cifs_tcon *tcon_ipc;1012 struct cifs_tcon *tcon_ipc;
1013 spinlock_t ses_lock; /* protect anything here that is not protected */
1011 struct mutex session_mutex;1014 struct mutex session_mutex;
1012 struct TCP_Server_Info *server; /* pointer to server info */1015 struct TCP_Server_Info *server; /* pointer to server info */
1013 int ses_count; /* reference counter */1016 int ses_count; /* reference counter */
@@ -1169,6 +1172,7 @@ struct cifs_tcon { · 155 unmodified lines
1169 struct list_head tcon_list;1172 struct list_head tcon_list;
1170 int tc_count;1173 int tc_count;
1171 struct list_head rlist; /* reconnect list */1174 struct list_head rlist; /* reconnect list */
1175 spinlock_t tc_lock; /* protect anything here that is not protected */
1172 atomic_t num_local_opens; /* num of all opens including disconnected */1176 atomic_t num_local_opens; /* num of all opens including disconnected */
1173 atomic_t num_remote_opens; /* num of all network opens on server */1177 atomic_t num_remote_opens; /* num of all network opens on server */
1174 struct list_head openFileList;1178 struct list_head openFileList;
@@ -1899,33 +1903,78 @@ require use of the stronger protocol */ · 724 unmodified lines
1899 */1903 */
1900 1904
1901/****************************************************************************1905/****************************************************************************
1902 * Locking notes. All updates to global variables and lists should be1906 * Here are all the locks (spinlock, mutex, semaphore) in cifs.ko, arranged according
1903 * protected by spinlocks or semaphores.1907 * to the locking order. i.e. if two locks are to be held together, the lock that
1908 * appears higher in this list needs to be taken before the other.
1904 *1909 *
1905 * Spinlocks1910 * If you hold a lock that is lower in this list, and you need to take a higher lock
1906 * ---------1911 * (or if you think that one of the functions that you're calling may need to), first
1907 * GlobalMid_Lock protects:1912 * drop the lock you hold, pick up the higher lock, then the lower one. This will
1908 * list operations on pending_mid_q and oplockQ1913 * ensure that locks are picked up only in one direction in the below table
1909 * updates to XID counters, multiplex id and SMB sequence numbers1914 * (top to bottom).
1910 * list operations on global DnotifyReqList
1911 * updates to ses->status and TCP_Server_Info->tcpStatus
1912 * updates to server->CurrentMid
1913 * tcp_ses_lock protects:
1914 * list operations on tcp and SMB session lists
1915 * tcon->open_file_lock protects the list of open files hanging off the tcon
1916 * inode->open_file_lock protects the openFileList hanging off the inode
1917 * cfile->file_info_lock protects counters and fields in cifs file struct
1918 * f_owner.lock protects certain per file struct operations
1919 * mapping->page_lock protects certain per page operations
1920 *1915 *
1921 * Note that the cifs_tcon.open_file_lock should be taken before1916 * Also, if you expect a function to be called with a lock held, explicitly document
1922 * not after the cifsInodeInfo.open_file_lock1917 * this in the comments on top of your function definition.
1923 *1918 *
1924 * Semaphores1919 * And also, try to keep the critical sections (lock hold time) to be as minimal as
1925 * ----------1920 * possible. Blocking / calling other functions with a lock held always increase
1926 * cifsInodeInfo->lock_sem protects:1921 * the risk of a possible deadlock.
1927 * the list of locks held by the inode
1928 *1922 *
1923 * Following this rule will avoid unnecessary deadlocks, which can get really hard to
1924 * debug. Also, any new lock that you introduce, please add to this list in the correct
1925 * order.
1926 *
1927 * Please populate this list whenever you introduce new locks in your changes. Or in
1928 * case I've missed some existing locks. Please ensure that it's added in the list
1929 * based on the locking order expected.
1930 *
1931 * =====================================================================================
1932 * Lock Protects Initialization fn
1933 * =====================================================================================
1934 * vol_list_lock
1935 * vol_info->ctx_lock vol_info->ctx
1936 * cifs_sb_info->tlink_tree_lock cifs_sb_info->tlink_tree cifs_setup_cifs_sb
1937 * TCP_Server_Info-> TCP_Server_Info cifs_get_tcp_session
1938 * reconnect_mutex
1939 * TCP_Server_Info->srv_mutex TCP_Server_Info cifs_get_tcp_session
1940 * cifs_ses->session_mutex cifs_ses sesInfoAlloc
1941 * cifs_tcon
1942 * cifs_tcon->open_file_lock cifs_tcon->openFileList tconInfoAlloc
1943 * cifs_tcon->pending_opens
1944 * cifs_tcon->stat_lock cifs_tcon->bytes_read tconInfoAlloc
1945 * cifs_tcon->bytes_written
1946 * cifs_tcp_ses_lock cifs_tcp_ses_list sesInfoAlloc
1947 * GlobalMid_Lock GlobalMaxActiveXid init_cifs
1948 * GlobalCurrentXid
1949 * GlobalTotalActiveXid
1950 * TCP_Server_Info->srv_lock (anything in struct not protected by another lock and can change)
1951 * TCP_Server_Info->mid_lock TCP_Server_Info->pending_mid_q cifs_get_tcp_session
1952 * ->CurrentMid
1953 * (any changes in mid_q_entry fields)
1954 * TCP_Server_Info->req_lock TCP_Server_Info->in_flight cifs_get_tcp_session
1955 * ->credits
1956 * ->echo_credits
1957 * ->oplock_credits
1958 * ->reconnect_instance
1959 * cifs_ses->ses_lock (anything that is not protected by another lock and can change)
1960 * cifs_ses->iface_lock cifs_ses->iface_list sesInfoAlloc
1961 * ->iface_count
1962 * ->iface_last_update
1963 * cifs_ses->chan_lock cifs_ses->chans
1964 * ->chans_need_reconnect
1965 * ->chans_in_reconnect
1966 * cifs_tcon->tc_lock (anything that is not protected by another lock and can change)
1967 * cifsInodeInfo->open_file_lock cifsInodeInfo->openFileList cifs_alloc_inode
1968 * cifsInodeInfo->writers_lock cifsInodeInfo->writers cifsInodeInfo_alloc
1969 * cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once
1970 * ->can_cache_brlcks
1971 * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc
1972 * cached_fid->fid_mutex cifs_tcon->crfid tconInfoAlloc
1973 * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo
1974 * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo
1975 * ->invalidHandle initiate_cifs_search
1976 * ->oplock_break_cancelled
1977 * cifs_aio_ctx->aio_mutex cifs_aio_ctx cifs_aio_ctx_alloc
1929 ****************************************************************************/1978 ****************************************************************************/
1930 1979
1931#ifdef DECLARE_GLOBALS_HERE1980#ifdef DECLARE_GLOBALS_HERE
@@ -1941,47 +1990,44 @@ require use of the stronger protocol */ · 9 unmodified lines
1941 * sessions (and from that the tree connections) can be found1990 * sessions (and from that the tree connections) can be found
1942 * by iterating over cifs_tcp_ses_list1991 * by iterating over cifs_tcp_ses_list
1943 */1992 */
1944GLOBAL_EXTERN struct list_head cifs_tcp_ses_list;1993extern struct list_head cifs_tcp_ses_list;
1945 1994
1946/*1995/*
1947 * This lock protects the cifs_tcp_ses_list, the list of smb sessions per1996 * This lock protects the cifs_tcp_ses_list, the list of smb sessions per
1948 * tcp session, and the list of tcon's per smb session. It also protects1997 * tcp session, and the list of tcon's per smb session. It also protects
1949 * the reference counters for the server, smb session, and tcon. It also1998 * the reference counters for the server, smb session, and tcon.
1950 * protects some fields in the TCP_Server_Info struct such as dstaddr. Finally,
1951 * changes to the tcon->tidStatus should be done while holding this lock.
1952 * generally the locks should be taken in order tcp_ses_lock before1999 * generally the locks should be taken in order tcp_ses_lock before
1953 * tcon->open_file_lock and that before file->file_info_lock since the2000 * tcon->open_file_lock and that before file->file_info_lock since the
1954 * structure order is cifs_socket-->cifs_ses-->cifs_tcon-->cifs_file2001 * structure order is cifs_socket-->cifs_ses-->cifs_tcon-->cifs_file
1955 */2002 */
1956GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock;2003extern spinlock_t cifs_tcp_ses_lock;
1957 2004
1958/*2005/*
1959 * Global transaction id (XID) information2006 * Global transaction id (XID) information
1960 */2007 */
1961GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */2008extern unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */
1962GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */2009extern unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
1963GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */2010extern unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
1964GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */2011extern spinlock_t GlobalMid_Lock; /* protects above & list operations on midQ entries */
1965 /* on midQ entries */2012
1966/*2013/*
1967 * Global counters, updated atomically2014 * Global counters, updated atomically
1968 */2015 */
1969GLOBAL_EXTERN atomic_t sesInfoAllocCount;2016extern atomic_t sesInfoAllocCount;
1970GLOBAL_EXTERN atomic_t tconInfoAllocCount;2017extern atomic_t tconInfoAllocCount;
1971GLOBAL_EXTERN atomic_t tcpSesNextId;2018extern atomic_t tcpSesNextId;
1972GLOBAL_EXTERN atomic_t tcpSesAllocCount;2019extern atomic_t tcpSesAllocCount;
1973GLOBAL_EXTERN atomic_t tcpSesReconnectCount;2020extern atomic_t tcpSesReconnectCount;
1974GLOBAL_EXTERN atomic_t tconInfoReconnectCount;2021extern atomic_t tconInfoReconnectCount;
1975 2022
1976/* Various Debug counters */2023/* Various Debug counters */
1977GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */2024extern atomic_t buf_alloc_count; /* current number allocated */
2025extern atomic_t small_buf_alloc_count;
1978#ifdef CONFIG_CIFS_STATS22026#ifdef CONFIG_CIFS_STATS2
1979GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */2027extern atomic_t total_buf_alloc_count; /* total allocated over all time */
1980GLOBAL_EXTERN atomic_t totSmBufAllocCount;2028extern atomic_t total_small_buf_alloc_count;
1981extern unsigned int slow_rsp_threshold; /* number of secs before logging */2029extern unsigned int slow_rsp_threshold; /* number of secs before logging */
1982#endif2030#endif
1983GLOBAL_EXTERN atomic_t smBufAllocCount;
1984GLOBAL_EXTERN atomic_t midCount;
1985 2031
1986/* Misc globals */2032/* Misc globals */
1987extern bool enable_oplocks; /* enable or disable oplocks */2033extern bool enable_oplocks; /* enable or disable oplocks */
@@ -1998,6 +2044,7 @@ extern unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ · 10 unmodified lines
1998extern unsigned int cifs_min_small; /* min size of small buf pool */2044extern unsigned int cifs_min_small; /* min size of small buf pool */
1999extern unsigned int cifs_max_pending; /* MAX requests at once to server*/2045extern unsigned int cifs_max_pending; /* MAX requests at once to server*/
2000extern bool disable_legacy_dialects; /* forbid vers=1.0 and vers=2.0 mounts */2046extern bool disable_legacy_dialects; /* forbid vers=1.0 and vers=2.0 mounts */
2047extern atomic_t mid_count;
2001 2048
2002void cifs_oplock_break(struct work_struct *work);2049void cifs_oplock_break(struct work_struct *work);
2003void cifs_queue_oplock_break(struct cifsFileInfo *cfile);2050void cifs_queue_oplock_break(struct cifsFileInfo *cfile);
fs/cifs/cifsproto.h+4−6
@@ -78,12 +78,8 @@ extern char *build_wildcard_path_from_dentry(struct dentry *direntry); · 77 unmodified lines
78extern char *cifs_compose_mount_options(const char *sb_mountdata,78extern char *cifs_compose_mount_options(const char *sb_mountdata,
79 const char *fullpath, const struct dfs_info3_param *ref,79 const char *fullpath, const struct dfs_info3_param *ref,
80 char **devname);80 char **devname);
81/* extern void renew_parental_timestamps(struct dentry *direntry);*/81extern void delete_mid(struct mid_q_entry *mid);
82extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,82extern void release_mid(struct mid_q_entry *mid);
83 struct TCP_Server_Info *server);
84extern void DeleteMidQEntry(struct mid_q_entry *midEntry);
85extern void cifs_delete_mid(struct mid_q_entry *mid);
86extern void cifs_mid_q_entry_release(struct mid_q_entry *midEntry);
87extern void cifs_wake_up_task(struct mid_q_entry *mid);83extern void cifs_wake_up_task(struct mid_q_entry *mid);
88extern int cifs_handle_standard(struct TCP_Server_Info *server,84extern int cifs_handle_standard(struct TCP_Server_Info *server,
89 struct mid_q_entry *mid);85 struct mid_q_entry *mid);
@@ -521,6 +517,7 @@ extern int generate_smb30signingkey(struct cifs_ses *ses, · 431 unmodified lines
521extern int generate_smb311signingkey(struct cifs_ses *ses,517extern int generate_smb311signingkey(struct cifs_ses *ses,
522 struct TCP_Server_Info *server);518 struct TCP_Server_Info *server);
523 519
520#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
524extern int CIFSSMBCopy(unsigned int xid,521extern int CIFSSMBCopy(unsigned int xid,
525 struct cifs_tcon *source_tcon,522 struct cifs_tcon *source_tcon,
526 const char *fromName,523 const char *fromName,
@@ -551,6 +548,7 @@ extern int CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon, · 24 unmodified lines
551 const struct nls_table *nls_codepage, int remap_special_chars);548 const struct nls_table *nls_codepage, int remap_special_chars);
552extern int CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,549extern int CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
553 const int netfid, __u64 *pExtAttrBits, __u64 *pMask);550 const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
551#endif /* CIFS_ALLOW_INSECURE_LEGACY */
554extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);552extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
555extern bool couldbe_mf_symlink(const struct cifs_fattr *fattr);553extern bool couldbe_mf_symlink(const struct cifs_fattr *fattr);
556extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,554extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
fs/cifs/cifssmb.c+14−463
@@ -29,7 +29,6 @@ · 28 unmodified lines
29#include "cifsproto.h"29#include "cifsproto.h"
30#include "cifs_unicode.h"30#include "cifs_unicode.h"
31#include "cifs_debug.h"31#include "cifs_debug.h"
32#include "smb2proto.h"
33#include "fscache.h"32#include "fscache.h"
34#include "smbdirect.h"33#include "smbdirect.h"
35#ifdef CONFIG_CIFS_DFS_UPCALL34#ifdef CONFIG_CIFS_DFS_UPCALL
@@ -62,52 +61,6 @@ static struct { · 26 unmodified lines
62#define CIFS_NUM_PROT 161#define CIFS_NUM_PROT 1
63#endif /* CIFS_POSIX */62#endif /* CIFS_POSIX */
64 63
65/*
66 * Mark as invalid, all open files on tree connections since they
67 * were closed when session to server was lost.
68 */
69void
70cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
71{
72 struct cifsFileInfo *open_file = NULL;
73 struct list_head *tmp;
74 struct list_head *tmp1;
75
76 /* only send once per connect */
77 spin_lock(&cifs_tcp_ses_lock);
78 if ((tcon->ses->ses_status != SES_GOOD) || (tcon->status != TID_NEED_RECON)) {
79 spin_unlock(&cifs_tcp_ses_lock);
80 return;
81 }
82 tcon->status = TID_IN_FILES_INVALIDATE;
83 spin_unlock(&cifs_tcp_ses_lock);
84
85 /* list all files open on tree connection and mark them invalid */
86 spin_lock(&tcon->open_file_lock);
87 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
88 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
89 open_file->invalidHandle = true;
90 open_file->oplock_break_cancelled = true;
91 }
92 spin_unlock(&tcon->open_file_lock);
93
94 mutex_lock(&tcon->crfid.fid_mutex);
95 tcon->crfid.is_valid = false;
96 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
97 close_cached_dir_lease_locked(&tcon->crfid);
98 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
99 mutex_unlock(&tcon->crfid.fid_mutex);
100
101 spin_lock(&cifs_tcp_ses_lock);
102 if (tcon->status == TID_IN_FILES_INVALIDATE)
103 tcon->status = TID_NEED_TCON;
104 spin_unlock(&cifs_tcp_ses_lock);
105
106 /*
107 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
108 * to this tcon.
109 */
110}
111 64
112/* reconnect the socket, tcon, and smb session if needed */65/* reconnect the socket, tcon, and smb session if needed */
113static int66static int
@@ -134,18 +87,18 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) · 20 unmodified lines
134 * only tree disconnect, open, and write, (and ulogoff which does not87 * only tree disconnect, open, and write, (and ulogoff which does not
135 * have tcon) are allowed as we start force umount88 * have tcon) are allowed as we start force umount
136 */89 */
137 spin_lock(&cifs_tcp_ses_lock);90 spin_lock(&tcon->tc_lock);
138 if (tcon->status == TID_EXITING) {91 if (tcon->status == TID_EXITING) {
139 if (smb_command != SMB_COM_WRITE_ANDX &&92 if (smb_command != SMB_COM_WRITE_ANDX &&
140 smb_command != SMB_COM_OPEN_ANDX &&93 smb_command != SMB_COM_OPEN_ANDX &&
141 smb_command != SMB_COM_TREE_DISCONNECT) {94 smb_command != SMB_COM_TREE_DISCONNECT) {
142 spin_unlock(&cifs_tcp_ses_lock);95 spin_unlock(&tcon->tc_lock);
143 cifs_dbg(FYI, "can not send cmd %d while umounting\n",96 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
144 smb_command);97 smb_command);
145 return -ENODEV;98 return -ENODEV;
146 }99 }
147 }100 }
148 spin_unlock(&cifs_tcp_ses_lock);101 spin_unlock(&tcon->tc_lock);
149 102
150 retries = server->nr_targets;103 retries = server->nr_targets;
151 104
@@ -165,12 +118,12 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) · 13 unmodified lines
165 }118 }
166 119
167 /* are we still trying to reconnect? */120 /* are we still trying to reconnect? */
168 spin_lock(&cifs_tcp_ses_lock);121 spin_lock(&server->srv_lock);
169 if (server->tcpStatus != CifsNeedReconnect) {122 if (server->tcpStatus != CifsNeedReconnect) {
170 spin_unlock(&cifs_tcp_ses_lock);123 spin_unlock(&server->srv_lock);
171 break;124 break;
172 }125 }
173 spin_unlock(&cifs_tcp_ses_lock);126 spin_unlock(&server->srv_lock);
174 127
175 if (retries && --retries)128 if (retries && --retries)
176 continue;129 continue;
@@ -201,13 +154,13 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) · 24 unmodified lines
201 * and the server never sends an answer the socket will be closed154 * and the server never sends an answer the socket will be closed
202 * and tcpStatus set to reconnect.155 * and tcpStatus set to reconnect.
203 */156 */
204 spin_lock(&cifs_tcp_ses_lock);157 spin_lock(&server->srv_lock);
205 if (server->tcpStatus == CifsNeedReconnect) {158 if (server->tcpStatus == CifsNeedReconnect) {
206 spin_unlock(&cifs_tcp_ses_lock);159 spin_unlock(&server->srv_lock);
207 rc = -EHOSTDOWN;160 rc = -EHOSTDOWN;
208 goto out;161 goto out;
209 }162 }
210 spin_unlock(&cifs_tcp_ses_lock);163 spin_unlock(&server->srv_lock);
211 164
212 /*165 /*
213 * need to prevent multiple threads trying to simultaneously166 * need to prevent multiple threads trying to simultaneously
@@ -457,52 +410,6 @@ decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr) · 243 unmodified lines
457 return 0;410 return 0;
458}411}
459 412
460int
461cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
462{
463 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
464 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
465 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN;
466
467 /*
468 * Is signing required by mnt options? If not then check
469 * global_secflags to see if it is there.
470 */
471 if (!mnt_sign_required)
472 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
473 CIFSSEC_MUST_SIGN);
474
475 /*
476 * If signing is required then it's automatically enabled too,
477 * otherwise, check to see if the secflags allow it.
478 */
479 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
480 (global_secflags & CIFSSEC_MAY_SIGN);
481
482 /* If server requires signing, does client allow it? */
483 if (srv_sign_required) {
484 if (!mnt_sign_enabled) {
485 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
486 return -ENOTSUPP;
487 }
488 server->sign = true;
489 }
490
491 /* If client requires signing, does server allow it? */
492 if (mnt_sign_required) {
493 if (!srv_sign_enabled) {
494 cifs_dbg(VFS, "Server does not support signing!\n");
495 return -ENOTSUPP;
496 }
497 server->sign = true;
498 }
499
500 if (cifs_rdma_enabled(server) && server->sign)
501 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
502
503 return 0;
504}
505
506static bool413static bool
507should_set_ext_sec_flag(enum securityEnum sectype)414should_set_ext_sec_flag(enum securityEnum sectype)
508{415{
@@ -684,7 +591,7 @@ cifs_echo_callback(struct mid_q_entry *mid) · 175 unmodified lines
684 struct TCP_Server_Info *server = mid->callback_data;591 struct TCP_Server_Info *server = mid->callback_data;
685 struct cifs_credits credits = { .value = 1, .instance = 0 };592 struct cifs_credits credits = { .value = 1, .instance = 0 };
686 593
687 DeleteMidQEntry(mid);594 release_mid(mid);
688 add_credits(server, &credits, CIFS_ECHO_OP);595 add_credits(server, &credits, CIFS_ECHO_OP);
689}596}
690 597
@@ -1379,184 +1286,6 @@ openRetry: · 688 unmodified lines
1379 return rc;1286 return rc;
1380}1287}
1381 1288
1382/*
1383 * Discard any remaining data in the current SMB. To do this, we borrow the
1384 * current bigbuf.
1385 */
1386int
1387cifs_discard_remaining_data(struct TCP_Server_Info *server)
1388{
1389 unsigned int rfclen = server->pdu_size;
1390 int remaining = rfclen + server->vals->header_preamble_size -
1391 server->total_read;
1392
1393 while (remaining > 0) {
1394 int length;
1395
1396 length = cifs_discard_from_socket(server,
1397 min_t(size_t, remaining,
1398 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1399 if (length < 0)
1400 return length;
1401 server->total_read += length;
1402 remaining -= length;
1403 }
1404
1405 return 0;
1406}
1407
1408static int
1409__cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1410 bool malformed)
1411{
1412 int length;
1413
1414 length = cifs_discard_remaining_data(server);
1415 dequeue_mid(mid, malformed);
1416 mid->resp_buf = server->smallbuf;
1417 server->smallbuf = NULL;
1418 return length;
1419}
1420
1421static int
1422cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1423{
1424 struct cifs_readdata *rdata = mid->callback_data;
1425
1426 return __cifs_readv_discard(server, mid, rdata->result);
1427}
1428
1429int
1430cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1431{
1432 int length, len;
1433 unsigned int data_offset, data_len;
1434 struct cifs_readdata *rdata = mid->callback_data;
1435 char *buf = server->smallbuf;
1436 unsigned int buflen = server->pdu_size +
1437 server->vals->header_preamble_size;
1438 bool use_rdma_mr = false;
1439
1440 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1441 __func__, mid->mid, rdata->offset, rdata->bytes);
1442
1443 /*
1444 * read the rest of READ_RSP header (sans Data array), or whatever we
1445 * can if there's not enough data. At this point, we've read down to
1446 * the Mid.
1447 */
1448 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1449 HEADER_SIZE(server) + 1;
1450
1451 length = cifs_read_from_socket(server,
1452 buf + HEADER_SIZE(server) - 1, len);
1453 if (length < 0)
1454 return length;
1455 server->total_read += length;
1456
1457 if (server->ops->is_session_expired &&
1458 server->ops->is_session_expired(buf)) {
1459 cifs_reconnect(server, true);
1460 return -1;
1461 }
1462
1463 if (server->ops->is_status_pending &&
1464 server->ops->is_status_pending(buf, server)) {
1465 cifs_discard_remaining_data(server);
1466 return -1;
1467 }
1468
1469 /* set up first two iov for signature check and to get credits */
1470 rdata->iov[0].iov_base = buf;
1471 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1472 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1473 rdata->iov[1].iov_len =
1474 server->total_read - server->vals->header_preamble_size;
1475 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1476 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1477 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1478 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1479
1480 /* Was the SMB read successful? */
1481 rdata->result = server->ops->map_error(buf, false);
1482 if (rdata->result != 0) {
1483 cifs_dbg(FYI, "%s: server returned error %d\n",
1484 __func__, rdata->result);
1485 /* normal error on read response */
1486 return __cifs_readv_discard(server, mid, false);
1487 }
1488
1489 /* Is there enough to get to the rest of the READ_RSP header? */
1490 if (server->total_read < server->vals->read_rsp_size) {
1491 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1492 __func__, server->total_read,
1493 server->vals->read_rsp_size);
1494 rdata->result = -EIO;
1495 return cifs_readv_discard(server, mid);
1496 }
1497
1498 data_offset = server->ops->read_data_offset(buf) +
1499 server->vals->header_preamble_size;
1500 if (data_offset < server->total_read) {
1501 /*
1502 * win2k8 sometimes sends an offset of 0 when the read
1503 * is beyond the EOF. Treat it as if the data starts just after
1504 * the header.
1505 */
1506 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1507 __func__, data_offset);
1508 data_offset = server->total_read;
1509 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1510 /* data_offset is beyond the end of smallbuf */
1511 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1512 __func__, data_offset);
1513 rdata->result = -EIO;
1514 return cifs_readv_discard(server, mid);
1515 }
1516
1517 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1518 __func__, server->total_read, data_offset);
1519
1520 len = data_offset - server->total_read;
1521 if (len > 0) {
1522 /* read any junk before data into the rest of smallbuf */
1523 length = cifs_read_from_socket(server,
1524 buf + server->total_read, len);
1525 if (length < 0)
1526 return length;
1527 server->total_read += length;
1528 }
1529
1530 /* how much data is in the response? */
1531#ifdef CONFIG_CIFS_SMB_DIRECT
1532 use_rdma_mr = rdata->mr;
1533#endif
1534 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1535 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1536 /* data_len is corrupt -- discard frame */
1537 rdata->result = -EIO;
1538 return cifs_readv_discard(server, mid);
1539 }
1540
1541 length = rdata->read_into_pages(server, rdata, data_len);
1542 if (length < 0)
1543 return length;
1544
1545 server->total_read += length;
1546
1547 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1548 server->total_read, buflen, data_len);
1549
1550 /* discard anything left over */
1551 if (server->total_read < buflen)
1552 return cifs_readv_discard(server, mid);
1553
1554 dequeue_mid(mid, false);
1555 mid->resp_buf = server->smallbuf;
1556 server->smallbuf = NULL;
1557 return length;
1558}
1559
1560static void1289static void
1561cifs_readv_callback(struct mid_q_entry *mid)1290cifs_readv_callback(struct mid_q_entry *mid)
1562{1291{
@@ -1607,7 +1336,7 @@ cifs_readv_callback(struct mid_q_entry *mid) · 44 unmodified lines
1607 }1336 }
1608 1337
1609 queue_work(cifsiod_wq, &rdata->work);1338 queue_work(cifsiod_wq, &rdata->work);
1610 DeleteMidQEntry(mid);1339 release_mid(mid);
1611 add_credits(server, &credits, 0);1340 add_credits(server, &credits, 0);
1612}1341}
1613 1342
@@ -1909,183 +1638,6 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms, · 295 unmodified lines
1909 return rc;1638 return rc;
1910}1639}
1911 1640
1912void
1913cifs_writedata_release(struct kref *refcount)
1914{
1915 struct cifs_writedata *wdata = container_of(refcount,
1916 struct cifs_writedata, refcount);
1917#ifdef CONFIG_CIFS_SMB_DIRECT
1918 if (wdata->mr) {
1919 smbd_deregister_mr(wdata->mr);
1920 wdata->mr = NULL;
1921 }
1922#endif
1923
1924 if (wdata->cfile)
1925 cifsFileInfo_put(wdata->cfile);
1926
1927 kvfree(wdata->pages);
1928 kfree(wdata);
1929}
1930
1931/*
1932 * Write failed with a retryable error. Resend the write request. It's also
1933 * possible that the page was redirtied so re-clean the page.
1934 */
1935static void
1936cifs_writev_requeue(struct cifs_writedata *wdata)
1937{
1938 int i, rc = 0;
1939 struct inode *inode = d_inode(wdata->cfile->dentry);
1940 struct TCP_Server_Info *server;
1941 unsigned int rest_len;
1942
1943 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
1944 i = 0;
1945 rest_len = wdata->bytes;
1946 do {
1947 struct cifs_writedata *wdata2;
1948 unsigned int j, nr_pages, wsize, tailsz, cur_len;
1949
1950 wsize = server->ops->wp_retry_size(inode);
1951 if (wsize < rest_len) {
1952 nr_pages = wsize / PAGE_SIZE;
1953 if (!nr_pages) {
1954 rc = -ENOTSUPP;
1955 break;
1956 }
1957 cur_len = nr_pages * PAGE_SIZE;
1958 tailsz = PAGE_SIZE;
1959 } else {
1960 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
1961 cur_len = rest_len;
1962 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
1963 }
1964
1965 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
1966 if (!wdata2) {
1967 rc = -ENOMEM;
1968 break;
1969 }
1970
1971 for (j = 0; j < nr_pages; j++) {
1972 wdata2->pages[j] = wdata->pages[i + j];
1973 lock_page(wdata2->pages[j]);
1974 clear_page_dirty_for_io(wdata2->pages[j]);
1975 }
1976
1977 wdata2->sync_mode = wdata->sync_mode;
1978 wdata2->nr_pages = nr_pages;
1979 wdata2->offset = page_offset(wdata2->pages[0]);
1980 wdata2->pagesz = PAGE_SIZE;
1981 wdata2->tailsz = tailsz;
1982 wdata2->bytes = cur_len;
1983
1984 rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
1985 &wdata2->cfile);
1986 if (!wdata2->cfile) {
1987 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
1988 rc);
1989 if (!is_retryable_error(rc))
1990 rc = -EBADF;
1991 } else {
1992 wdata2->pid = wdata2->cfile->pid;
1993 rc = server->ops->async_writev(wdata2,
1994 cifs_writedata_release);
1995 }
1996
1997 for (j = 0; j < nr_pages; j++) {
1998 unlock_page(wdata2->pages[j]);
1999 if (rc != 0 && !is_retryable_error(rc)) {
2000 SetPageError(wdata2->pages[j]);
2001 end_page_writeback(wdata2->pages[j]);
2002 put_page(wdata2->pages[j]);
2003 }
2004 }
2005
2006 kref_put(&wdata2->refcount, cifs_writedata_release);
2007 if (rc) {
2008 if (is_retryable_error(rc))
2009 continue;
2010 i += nr_pages;
2011 break;
2012 }
2013
2014 rest_len -= cur_len;
2015 i += nr_pages;
2016 } while (i < wdata->nr_pages);
2017
2018 /* cleanup remaining pages from the original wdata */
2019 for (; i < wdata->nr_pages; i++) {
2020 SetPageError(wdata->pages[i]);
2021 end_page_writeback(wdata->pages[i]);
2022 put_page(wdata->pages[i]);
2023 }
2024
2025 if (rc != 0 && !is_retryable_error(rc))
2026 mapping_set_error(inode->i_mapping, rc);
2027 kref_put(&wdata->refcount, cifs_writedata_release);
2028}
2029
2030void
2031cifs_writev_complete(struct work_struct *work)
2032{
2033 struct cifs_writedata *wdata = container_of(work,
2034 struct cifs_writedata, work);
2035 struct inode *inode = d_inode(wdata->cfile->dentry);
2036 int i = 0;
2037
2038 if (wdata->result == 0) {
2039 spin_lock(&inode->i_lock);
2040 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2041 spin_unlock(&inode->i_lock);
2042 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2043 wdata->bytes);
2044 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2045 return cifs_writev_requeue(wdata);
2046
2047 for (i = 0; i < wdata->nr_pages; i++) {
2048 struct page *page = wdata->pages[i];
2049 if (wdata->result == -EAGAIN)
2050 __set_page_dirty_nobuffers(page);
2051 else if (wdata->result < 0)
2052 SetPageError(page);
2053 end_page_writeback(page);
2054 cifs_readpage_to_fscache(inode, page);
2055 put_page(page);
2056 }
2057 if (wdata->result != -EAGAIN)
2058 mapping_set_error(inode->i_mapping, wdata->result);
2059 kref_put(&wdata->refcount, cifs_writedata_release);
2060}
2061
2062struct cifs_writedata *
2063cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2064{
2065 struct page **pages =
2066 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2067 if (pages)
2068 return cifs_writedata_direct_alloc(pages, complete);
2069
2070 return NULL;
2071}
2072
2073struct cifs_writedata *
2074cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2075{
2076 struct cifs_writedata *wdata;
2077
2078 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2079 if (wdata != NULL) {
2080 wdata->pages = pages;
2081 kref_init(&wdata->refcount);
2082 INIT_LIST_HEAD(&wdata->list);
2083 init_completion(&wdata->done);
2084 INIT_WORK(&wdata->work, complete);
2085 }
2086 return wdata;
2087}
2088
2089/*1641/*
2090 * Check the mid_state and signature on received buffer (if any), and queue the1642 * Check the mid_state and signature on received buffer (if any), and queue the
2091 * workqueue completion task.1643 * workqueue completion task.
@@ -2132,7 +1684,7 @@ cifs_writev_callback(struct mid_q_entry *mid) · 40 unmodified lines
2132 }1684 }
2133 1685
2134 queue_work(cifsiod_wq, &wdata->work);1686 queue_work(cifsiod_wq, &wdata->work);
2135 DeleteMidQEntry(mid);1687 release_mid(mid);
2136 add_credits(tcon->ses->server, &credits, 0);1688 add_credits(tcon->ses->server, &credits, 0);
2137}1689}
2138 1690
@@ -3660,7 +3212,6 @@ setACLerrorExit: · 1521 unmodified lines
3660 return rc;3212 return rc;
3661}3213}
3662 3214
3663/* BB fix tabs in this function FIXME BB */
3664int3215int
3665CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,3216CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
3666 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)3217 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
@@ -3677,7 +3228,7 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon, · 10 unmodified lines
3677 3228
3678GetExtAttrRetry:3229GetExtAttrRetry:
3679 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,3230 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3680 (void **) &pSMBr);3231 (void **) &pSMBr);
3681 if (rc)3232 if (rc)
3682 return rc;3233 return rc;
3683 3234
@@ -3723,7 +3274,7 @@ GetExtAttrRetry: · 39 unmodified lines
3723 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);3274 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3724 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);3275 __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
3725 struct file_chattr_info *pfinfo;3276 struct file_chattr_info *pfinfo;
3726 /* BB Do we need a cast or hash here ? */3277
3727 if (count != 16) {3278 if (count != 16) {
3728 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");3279 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
3729 rc = -EIO;3280 rc = -EIO;
fs/cifs/connect.c+187−112
@@ -119,10 +119,10 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server) · 118 unmodified lines
119 goto requeue_resolve;119 goto requeue_resolve;
120 }120 }
121 121
122 spin_lock(&cifs_tcp_ses_lock);122 spin_lock(&server->srv_lock);
123 rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr,123 rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr,
124 strlen(ipaddr));124 strlen(ipaddr));
125 spin_unlock(&cifs_tcp_ses_lock);125 spin_unlock(&server->srv_lock);
126 kfree(ipaddr);126 kfree(ipaddr);
127 127
128 /* rc == 1 means success here */128 /* rc == 1 means success here */
@@ -205,17 +205,22 @@ cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server, · 76 unmodified lines
205 /* If server is a channel, select the primary channel */205 /* If server is a channel, select the primary channel */
206 pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;206 pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
207 207
208 spin_lock(&cifs_tcp_ses_lock);208 spin_lock(&pserver->srv_lock);
209 if (!all_channels) {209 if (!all_channels) {
210 pserver->tcpStatus = CifsNeedReconnect;210 pserver->tcpStatus = CifsNeedReconnect;
211 spin_unlock(&cifs_tcp_ses_lock);211 spin_unlock(&pserver->srv_lock);
212 return;212 return;
213 }213 }
214 spin_unlock(&pserver->srv_lock);
214 215
216 spin_lock(&cifs_tcp_ses_lock);
215 list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {217 list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
216 spin_lock(&ses->chan_lock);218 spin_lock(&ses->chan_lock);
217 for (i = 0; i < ses->chan_count; i++)219 for (i = 0; i < ses->chan_count; i++) {
220 spin_lock(&ses->chans[i].server->srv_lock);
218 ses->chans[i].server->tcpStatus = CifsNeedReconnect;221 ses->chans[i].server->tcpStatus = CifsNeedReconnect;
222 spin_unlock(&ses->chans[i].server->srv_lock);
223 }
219 spin_unlock(&ses->chan_lock);224 spin_unlock(&ses->chan_lock);
220 }225 }
221 spin_unlock(&cifs_tcp_ses_lock);226 spin_unlock(&cifs_tcp_ses_lock);
@@ -252,17 +257,8 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server, · 30 unmodified lines
252 spin_lock(&cifs_tcp_ses_lock);257 spin_lock(&cifs_tcp_ses_lock);
253 list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) {258 list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) {
254 /* check if iface is still active */259 /* check if iface is still active */
255 if (!cifs_chan_is_iface_active(ses, server)) {260 if (!cifs_chan_is_iface_active(ses, server))
256 /*
257 * HACK: drop the lock before calling
258 * cifs_chan_update_iface to avoid deadlock
259 */
260 ses->ses_count++;
261 spin_unlock(&cifs_tcp_ses_lock);
262 cifs_chan_update_iface(ses, server);261 cifs_chan_update_iface(ses, server);
263 spin_lock(&cifs_tcp_ses_lock);
264 ses->ses_count--;
265 }
266 262
267 spin_lock(&ses->chan_lock);263 spin_lock(&ses->chan_lock);
268 if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server))264 if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server))
@@ -323,7 +319,7 @@ cifs_abort_connection(struct TCP_Server_Info *server) · 54 unmodified lines
323 /* mark submitted MIDs for retry and issue callback */319 /* mark submitted MIDs for retry and issue callback */
324 INIT_LIST_HEAD(&retry_list);320 INIT_LIST_HEAD(&retry_list);
325 cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);321 cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
326 spin_lock(&GlobalMid_Lock);322 spin_lock(&server->mid_lock);
327 list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) {323 list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) {
328 kref_get(&mid->refcount);324 kref_get(&mid->refcount);
329 if (mid->mid_state == MID_REQUEST_SUBMITTED)325 if (mid->mid_state == MID_REQUEST_SUBMITTED)
@@ -331,14 +327,14 @@ cifs_abort_connection(struct TCP_Server_Info *server) · 1 unmodified line
331 list_move(&mid->qhead, &retry_list);327 list_move(&mid->qhead, &retry_list);
332 mid->mid_flags |= MID_DELETED;328 mid->mid_flags |= MID_DELETED;
333 }329 }
334 spin_unlock(&GlobalMid_Lock);330 spin_unlock(&server->mid_lock);
335 cifs_server_unlock(server);331 cifs_server_unlock(server);
336 332
337 cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);333 cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
338 list_for_each_entry_safe(mid, nmid, &retry_list, qhead) {334 list_for_each_entry_safe(mid, nmid, &retry_list, qhead) {
339 list_del_init(&mid->qhead);335 list_del_init(&mid->qhead);
340 mid->callback(mid);336 mid->callback(mid);
341 cifs_mid_q_entry_release(mid);337 release_mid(mid);
342 }338 }
343 339
344 if (cifs_rdma_enabled(server)) {340 if (cifs_rdma_enabled(server)) {
@@ -350,11 +346,11 @@ cifs_abort_connection(struct TCP_Server_Info *server) · 5 unmodified lines
350 346
351static bool cifs_tcp_ses_needs_reconnect(struct TCP_Server_Info *server, int num_targets)347static bool cifs_tcp_ses_needs_reconnect(struct TCP_Server_Info *server, int num_targets)
352{348{
353 spin_lock(&cifs_tcp_ses_lock);349 spin_lock(&server->srv_lock);
354 server->nr_targets = num_targets;350 server->nr_targets = num_targets;
355 if (server->tcpStatus == CifsExiting) {351 if (server->tcpStatus == CifsExiting) {
356 /* the demux thread will exit normally next time through the loop */352 /* the demux thread will exit normally next time through the loop */
357 spin_unlock(&cifs_tcp_ses_lock);353 spin_unlock(&server->srv_lock);
358 wake_up(&server->response_q);354 wake_up(&server->response_q);
359 return false;355 return false;
360 }356 }
@@ -364,7 +360,7 @@ static bool cifs_tcp_ses_needs_reconnect(struct TCP_Server_Info *server, int num · 3 unmodified lines
364 server->hostname);360 server->hostname);
365 server->tcpStatus = CifsNeedReconnect;361 server->tcpStatus = CifsNeedReconnect;
366 362
367 spin_unlock(&cifs_tcp_ses_lock);363 spin_unlock(&server->srv_lock);
368 return true;364 return true;
369}365}
370 366
@@ -414,20 +410,20 @@ static int __cifs_reconnect(struct TCP_Server_Info *server, · 43 unmodified lines
414 } else {410 } else {
415 atomic_inc(&tcpSesReconnectCount);411 atomic_inc(&tcpSesReconnectCount);
416 set_credits(server, 1);412 set_credits(server, 1);
417 spin_lock(&cifs_tcp_ses_lock);413 spin_lock(&server->srv_lock);
418 if (server->tcpStatus != CifsExiting)414 if (server->tcpStatus != CifsExiting)
419 server->tcpStatus = CifsNeedNegotiate;415 server->tcpStatus = CifsNeedNegotiate;
420 spin_unlock(&cifs_tcp_ses_lock);416 spin_unlock(&server->srv_lock);
421 cifs_swn_reset_server_dstaddr(server);417 cifs_swn_reset_server_dstaddr(server);
422 cifs_server_unlock(server);418 cifs_server_unlock(server);
423 mod_delayed_work(cifsiod_wq, &server->reconnect, 0);419 mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
424 }420 }
425 } while (server->tcpStatus == CifsNeedReconnect);421 } while (server->tcpStatus == CifsNeedReconnect);
426 422
427 spin_lock(&cifs_tcp_ses_lock);423 spin_lock(&server->srv_lock);
428 if (server->tcpStatus == CifsNeedNegotiate)424 if (server->tcpStatus == CifsNeedNegotiate)
429 mod_delayed_work(cifsiod_wq, &server->echo, 0);425 mod_delayed_work(cifsiod_wq, &server->echo, 0);
430 spin_unlock(&cifs_tcp_ses_lock);426 spin_unlock(&server->srv_lock);
431 427
432 wake_up(&server->response_q);428 wake_up(&server->response_q);
433 return rc;429 return rc;
@@ -541,10 +537,10 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server) · 107 unmodified lines
541 */537 */
542 atomic_inc(&tcpSesReconnectCount);538 atomic_inc(&tcpSesReconnectCount);
543 set_credits(server, 1);539 set_credits(server, 1);
544 spin_lock(&cifs_tcp_ses_lock);540 spin_lock(&server->srv_lock);
545 if (server->tcpStatus != CifsExiting)541 if (server->tcpStatus != CifsExiting)
546 server->tcpStatus = CifsNeedNegotiate;542 server->tcpStatus = CifsNeedNegotiate;
547 spin_unlock(&cifs_tcp_ses_lock);543 spin_unlock(&server->srv_lock);
548 cifs_swn_reset_server_dstaddr(server);544 cifs_swn_reset_server_dstaddr(server);
549 cifs_server_unlock(server);545 cifs_server_unlock(server);
550 mod_delayed_work(cifsiod_wq, &server->reconnect, 0);546 mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
@@ -556,11 +552,10 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server) · 5 unmodified lines
556 dfs_cache_free_tgts(&tl);552 dfs_cache_free_tgts(&tl);
557 553
558 /* Need to set up echo worker again once connection has been established */554 /* Need to set up echo worker again once connection has been established */
559 spin_lock(&cifs_tcp_ses_lock);555 spin_lock(&server->srv_lock);
560 if (server->tcpStatus == CifsNeedNegotiate)556 if (server->tcpStatus == CifsNeedNegotiate)
561 mod_delayed_work(cifsiod_wq, &server->echo, 0);557 mod_delayed_work(cifsiod_wq, &server->echo, 0);
562 558 spin_unlock(&server->srv_lock);
563 spin_unlock(&cifs_tcp_ses_lock);
564 559
565 wake_up(&server->response_q);560 wake_up(&server->response_q);
566 return rc;561 return rc;
@@ -569,12 +564,12 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server) · 2 unmodified lines
569int cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session)564int cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session)
570{565{
571 /* If tcp session is not an dfs connection, then reconnect to last target server */566 /* If tcp session is not an dfs connection, then reconnect to last target server */
572 spin_lock(&cifs_tcp_ses_lock);567 spin_lock(&server->srv_lock);
573 if (!server->is_dfs_conn) {568 if (!server->is_dfs_conn) {
574 spin_unlock(&cifs_tcp_ses_lock);569 spin_unlock(&server->srv_lock);
575 return __cifs_reconnect(server, mark_smb_session);570 return __cifs_reconnect(server, mark_smb_session);
576 }571 }
577 spin_unlock(&cifs_tcp_ses_lock);572 spin_unlock(&server->srv_lock);
578 573
579 mutex_lock(&server->refpath_lock);574 mutex_lock(&server->refpath_lock);
580 if (!server->origin_fullpath || !server->leaf_fullpath) {575 if (!server->origin_fullpath || !server->leaf_fullpath) {
@@ -670,18 +665,18 @@ server_unresponsive(struct TCP_Server_Info *server) · 89 unmodified lines
670 * 65s kernel_recvmsg times out, and we see that we haven't gotten665 * 65s kernel_recvmsg times out, and we see that we haven't gotten
671 * a response in >60s.666 * a response in >60s.
672 */667 */
673 spin_lock(&cifs_tcp_ses_lock);668 spin_lock(&server->srv_lock);
674 if ((server->tcpStatus == CifsGood ||669 if ((server->tcpStatus == CifsGood ||
675 server->tcpStatus == CifsNeedNegotiate) &&670 server->tcpStatus == CifsNeedNegotiate) &&
676 (!server->ops->can_echo || server->ops->can_echo(server)) &&671 (!server->ops->can_echo || server->ops->can_echo(server)) &&
677 time_after(jiffies, server->lstrp + 3 * server->echo_interval)) {672 time_after(jiffies, server->lstrp + 3 * server->echo_interval)) {
678 spin_unlock(&cifs_tcp_ses_lock);673 spin_unlock(&server->srv_lock);
679 cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n",674 cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n",
680 (3 * server->echo_interval) / HZ);675 (3 * server->echo_interval) / HZ);
681 cifs_reconnect(server, false);676 cifs_reconnect(server, false);
682 return true;677 return true;
683 }678 }
684 spin_unlock(&cifs_tcp_ses_lock);679 spin_unlock(&server->srv_lock);
685 680
686 return false;681 return false;
687}682}
@@ -726,18 +721,18 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg) · 38 unmodified lines
726 else721 else
727 length = sock_recvmsg(server->ssocket, smb_msg, 0);722 length = sock_recvmsg(server->ssocket, smb_msg, 0);
728 723
729 spin_lock(&cifs_tcp_ses_lock);724 spin_lock(&server->srv_lock);
730 if (server->tcpStatus == CifsExiting) {725 if (server->tcpStatus == CifsExiting) {
731 spin_unlock(&cifs_tcp_ses_lock);726 spin_unlock(&server->srv_lock);
732 return -ESHUTDOWN;727 return -ESHUTDOWN;
733 }728 }
734 729
735 if (server->tcpStatus == CifsNeedReconnect) {730 if (server->tcpStatus == CifsNeedReconnect) {
736 spin_unlock(&cifs_tcp_ses_lock);731 spin_unlock(&server->srv_lock);
737 cifs_reconnect(server, false);732 cifs_reconnect(server, false);
738 return -ECONNABORTED;733 return -ECONNABORTED;
739 }734 }
740 spin_unlock(&cifs_tcp_ses_lock);735 spin_unlock(&server->srv_lock);
741 736
742 if (length == -ERESTARTSYS ||737 if (length == -ERESTARTSYS ||
743 length == -EAGAIN ||738 length == -EAGAIN ||
@@ -849,7 +844,7 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed) · 105 unmodified lines
849#ifdef CONFIG_CIFS_STATS2844#ifdef CONFIG_CIFS_STATS2
850 mid->when_received = jiffies;845 mid->when_received = jiffies;
851#endif846#endif
852 spin_lock(&GlobalMid_Lock);847 spin_lock(&mid->server->mid_lock);
853 if (!malformed)848 if (!malformed)
854 mid->mid_state = MID_RESPONSE_RECEIVED;849 mid->mid_state = MID_RESPONSE_RECEIVED;
855 else850 else
@@ -859,12 +854,12 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed) · 3 unmodified lines
859 * function has finished processing it is a bug.854 * function has finished processing it is a bug.
860 */855 */
861 if (mid->mid_flags & MID_DELETED) {856 if (mid->mid_flags & MID_DELETED) {
862 spin_unlock(&GlobalMid_Lock);857 spin_unlock(&mid->server->mid_lock);
863 pr_warn_once("trying to dequeue a deleted mid\n");858 pr_warn_once("trying to dequeue a deleted mid\n");
864 } else {859 } else {
865 list_del_init(&mid->qhead);860 list_del_init(&mid->qhead);
866 mid->mid_flags |= MID_DELETED;861 mid->mid_flags |= MID_DELETED;
867 spin_unlock(&GlobalMid_Lock);862 spin_unlock(&mid->server->mid_lock);
868 }863 }
869}864}
870 865
@@ -903,21 +898,68 @@ handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, · 32 unmodified lines
903 dequeue_mid(mid, malformed);898 dequeue_mid(mid, malformed);
904}899}
905 900
901int
902cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
903{
904 bool srv_sign_required = server->sec_mode & server->vals->signing_required;
905 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
906 bool mnt_sign_enabled;
907
908 /*
909 * Is signing required by mnt options? If not then check
910 * global_secflags to see if it is there.
911 */
912 if (!mnt_sign_required)
913 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
914 CIFSSEC_MUST_SIGN);
915
916 /*
917 * If signing is required then it's automatically enabled too,
918 * otherwise, check to see if the secflags allow it.
919 */
920 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
921 (global_secflags & CIFSSEC_MAY_SIGN);
922
923 /* If server requires signing, does client allow it? */
924 if (srv_sign_required) {
925 if (!mnt_sign_enabled) {
926 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
927 return -EOPNOTSUPP;
928 }
929 server->sign = true;
930 }
931
932 /* If client requires signing, does server allow it? */
933 if (mnt_sign_required) {
934 if (!srv_sign_enabled) {
935 cifs_dbg(VFS, "Server does not support signing!\n");
936 return -EOPNOTSUPP;
937 }
938 server->sign = true;
939 }
940
941 if (cifs_rdma_enabled(server) && server->sign)
942 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
943
944 return 0;
945}
946
947
906static void clean_demultiplex_info(struct TCP_Server_Info *server)948static void clean_demultiplex_info(struct TCP_Server_Info *server)
907{949{
908 int length;950 int length;
909 951
910 /* take it off the list, if it's not already */952 /* take it off the list, if it's not already */
911 spin_lock(&cifs_tcp_ses_lock);953 spin_lock(&server->srv_lock);
912 list_del_init(&server->tcp_ses_list);954 list_del_init(&server->tcp_ses_list);
913 spin_unlock(&cifs_tcp_ses_lock);955 spin_unlock(&server->srv_lock);
914 956
915 cancel_delayed_work_sync(&server->echo);957 cancel_delayed_work_sync(&server->echo);
916 cancel_delayed_work_sync(&server->resolve);958 cancel_delayed_work_sync(&server->resolve);
917 959
918 spin_lock(&cifs_tcp_ses_lock);960 spin_lock(&server->srv_lock);
919 server->tcpStatus = CifsExiting;961 server->tcpStatus = CifsExiting;
920 spin_unlock(&cifs_tcp_ses_lock);962 spin_unlock(&server->srv_lock);
921 wake_up_all(&server->response_q);963 wake_up_all(&server->response_q);
922 964
923 /* check if we have blocked requests that need to free */965 /* check if we have blocked requests that need to free */
@@ -948,7 +990,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) · 24 unmodified lines
948 struct list_head *tmp, *tmp2;990 struct list_head *tmp, *tmp2;
949 991
950 INIT_LIST_HEAD(&dispose_list);992 INIT_LIST_HEAD(&dispose_list);
951 spin_lock(&GlobalMid_Lock);993 spin_lock(&server->mid_lock);
952 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {994 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
953 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);995 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
954 cifs_dbg(FYI, "Clearing mid %llu\n", mid_entry->mid);996 cifs_dbg(FYI, "Clearing mid %llu\n", mid_entry->mid);
@@ -957,7 +999,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) · 2 unmodified lines
957 list_move(&mid_entry->qhead, &dispose_list);999 list_move(&mid_entry->qhead, &dispose_list);
958 mid_entry->mid_flags |= MID_DELETED;1000 mid_entry->mid_flags |= MID_DELETED;
959 }1001 }
960 spin_unlock(&GlobalMid_Lock);1002 spin_unlock(&server->mid_lock);
961 1003
962 /* now walk dispose list and issue callbacks */1004 /* now walk dispose list and issue callbacks */
963 list_for_each_safe(tmp, tmp2, &dispose_list) {1005 list_for_each_safe(tmp, tmp2, &dispose_list) {
@@ -965,7 +1007,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) · 1 unmodified line
965 cifs_dbg(FYI, "Callback mid %llu\n", mid_entry->mid);1007 cifs_dbg(FYI, "Callback mid %llu\n", mid_entry->mid);
966 list_del_init(&mid_entry->qhead);1008 list_del_init(&mid_entry->qhead);
967 mid_entry->callback(mid_entry);1009 mid_entry->callback(mid_entry);
968 cifs_mid_q_entry_release(mid_entry);1010 release_mid(mid_entry);
969 }1011 }
970 /* 1/8th of sec is more than enough time for them to exit */1012 /* 1/8th of sec is more than enough time for them to exit */
971 msleep(125);1013 msleep(125);
@@ -1039,19 +1081,18 @@ int · 67 unmodified lines
1039cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)1081cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1040{1082{
1041 char *buf = server->large_buf ? server->bigbuf : server->smallbuf;1083 char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
1042 int length;1084 int rc;
1043 1085
1044 /*1086 /*
1045 * We know that we received enough to get to the MID as we1087 * We know that we received enough to get to the MID as we
1046 * checked the pdu_length earlier. Now check to see1088 * checked the pdu_length earlier. Now check to see
1047 * if the rest of the header is OK. We borrow the length1089 * if the rest of the header is OK.
1048 * var for the rest of the loop to avoid a new stack var.
1049 *1090 *
1050 * 48 bytes is enough to display the header and a little bit1091 * 48 bytes is enough to display the header and a little bit
1051 * into the payload for debugging purposes.1092 * into the payload for debugging purposes.
1052 */1093 */
1053 length = server->ops->check_message(buf, server->total_read, server);1094 rc = server->ops->check_message(buf, server->total_read, server);
1054 if (length != 0)1095 if (rc)
1055 cifs_dump_mem("Bad SMB: ", buf,1096 cifs_dump_mem("Bad SMB: ", buf,
1056 min_t(unsigned int, server->total_read, 48));1097 min_t(unsigned int, server->total_read, 48));
1057 1098
@@ -1066,9 +1107,9 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid) · 8 unmodified lines
1066 return -1;1107 return -1;
1067 1108
1068 if (!mid)1109 if (!mid)
1069 return length;1110 return rc;
1070 1111
1071 handle_mid(mid, server, buf, length);1112 handle_mid(mid, server, buf, rc);
1072 return 0;1113 return 0;
1073}1114}
1074 1115
@@ -1205,7 +1246,7 @@ next_pdu: · 130 unmodified lines
1205 if (length < 0) {1246 if (length < 0) {
1206 for (i = 0; i < num_mids; i++)1247 for (i = 0; i < num_mids; i++)
1207 if (mids[i])1248 if (mids[i])
1208 cifs_mid_q_entry_release(mids[i]);1249 release_mid(mids[i]);
1209 continue;1250 continue;
1210 }1251 }
1211 1252
@@ -1232,7 +1273,7 @@ next_pdu: · 20 unmodified lines
1232 if (!mids[i]->multiRsp || mids[i]->multiEnd)1273 if (!mids[i]->multiRsp || mids[i]->multiEnd)
1233 mids[i]->callback(mids[i]);1274 mids[i]->callback(mids[i]);
1234 1275
1235 cifs_mid_q_entry_release(mids[i]);1276 release_mid(mids[i]);
1236 } else if (server->ops->is_oplock_break &&1277 } else if (server->ops->is_oplock_break &&
1237 server->ops->is_oplock_break(bufs[i],1278 server->ops->is_oplock_break(bufs[i],
1238 server)) {1279 server)) {
@@ -1240,7 +1281,7 @@ next_pdu: · 1 unmodified line
1240 cifs_dbg(FYI, "Received oplock break\n");1281 cifs_dbg(FYI, "Received oplock break\n");
1241 } else {1282 } else {
1242 cifs_server_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",1283 cifs_server_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
1243 atomic_read(&midCount));1284 atomic_read(&mid_count));
1244 cifs_dump_mem("Received Data is: ", bufs[i],1285 cifs_dump_mem("Received Data is: ", bufs[i],
1245 HEADER_SIZE(server));1286 HEADER_SIZE(server));
1246 smb2_add_credits_from_hdr(bufs[i], server);1287 smb2_add_credits_from_hdr(bufs[i], server);
@@ -1411,6 +1452,7 @@ match_security(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) · 164 unmodified lines
1411 return true;1452 return true;
1412}1453}
1413 1454
1455/* this function must be called with srv_lock held */
1414static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)1456static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
1415{1457{
1416 struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;1458 struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
@@ -1471,6 +1513,7 @@ cifs_find_tcp_session(struct smb3_fs_context *ctx) · 54 unmodified lines
1471 1513
1472 spin_lock(&cifs_tcp_ses_lock);1514 spin_lock(&cifs_tcp_ses_lock);
1473 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {1515 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1516 spin_lock(&server->srv_lock);
1474#ifdef CONFIG_CIFS_DFS_UPCALL1517#ifdef CONFIG_CIFS_DFS_UPCALL
1475 /*1518 /*
1476 * DFS failover implementation in cifs_reconnect() requires unique tcp sessions for1519 * DFS failover implementation in cifs_reconnect() requires unique tcp sessions for
@@ -1478,15 +1521,20 @@ cifs_find_tcp_session(struct smb3_fs_context *ctx) · 1 unmodified line
1478 * shares or even links that may connect to same server but having completely1521 * shares or even links that may connect to same server but having completely
1479 * different failover targets.1522 * different failover targets.
1480 */1523 */
1481 if (server->is_dfs_conn)1524 if (server->is_dfs_conn) {
1525 spin_unlock(&server->srv_lock);
1482 continue;1526 continue;
1527 }
1483#endif1528#endif
1484 /*1529 /*
1485 * Skip ses channels since they're only handled in lower layers1530 * Skip ses channels since they're only handled in lower layers
1486 * (e.g. cifs_send_recv).1531 * (e.g. cifs_send_recv).
1487 */1532 */
1488 if (CIFS_SERVER_IS_CHAN(server) || !match_server(server, ctx))1533 if (CIFS_SERVER_IS_CHAN(server) || !match_server(server, ctx)) {
1534 spin_unlock(&server->srv_lock);
1489 continue;1535 continue;
1536 }
1537 spin_unlock(&server->srv_lock);
1490 1538
1491 ++server->srv_count;1539 ++server->srv_count;
1492 spin_unlock(&cifs_tcp_ses_lock);1540 spin_unlock(&cifs_tcp_ses_lock);
@@ -1534,9 +1582,9 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect) · 41 unmodified lines
1534 else1582 else
1535 cancel_delayed_work_sync(&server->reconnect);1583 cancel_delayed_work_sync(&server->reconnect);
1536 1584
1537 spin_lock(&cifs_tcp_ses_lock);1585 spin_lock(&server->srv_lock);
1538 server->tcpStatus = CifsExiting;1586 server->tcpStatus = CifsExiting;
1539 spin_unlock(&cifs_tcp_ses_lock);1587 spin_unlock(&server->srv_lock);
1540 1588
1541 cifs_crypto_secmech_release(server);1589 cifs_crypto_secmech_release(server);
1542 1590
@@ -1595,8 +1643,8 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx, · 52 unmodified lines
1595 if (primary_server) {1643 if (primary_server) {
1596 spin_lock(&cifs_tcp_ses_lock);1644 spin_lock(&cifs_tcp_ses_lock);
1597 ++primary_server->srv_count;1645 ++primary_server->srv_count;
1598 tcp_ses->primary_server = primary_server;
1599 spin_unlock(&cifs_tcp_ses_lock);1646 spin_unlock(&cifs_tcp_ses_lock);
1647 tcp_ses->primary_server = primary_server;
1600 }1648 }
1601 init_waitqueue_head(&tcp_ses->response_q);1649 init_waitqueue_head(&tcp_ses->response_q);
1602 init_waitqueue_head(&tcp_ses->request_q);1650 init_waitqueue_head(&tcp_ses->request_q);
@@ -1612,6 +1660,8 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx, · 9 unmodified lines
1612 tcp_ses->lstrp = jiffies;1660 tcp_ses->lstrp = jiffies;
1613 tcp_ses->compress_algorithm = cpu_to_le16(ctx->compression);1661 tcp_ses->compress_algorithm = cpu_to_le16(ctx->compression);
1614 spin_lock_init(&tcp_ses->req_lock);1662 spin_lock_init(&tcp_ses->req_lock);
1663 spin_lock_init(&tcp_ses->srv_lock);
1664 spin_lock_init(&tcp_ses->mid_lock);
1615 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);1665 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1616 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);1666 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1617 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);1667 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
@@ -1685,9 +1735,9 @@ smbd_connected: · 67 unmodified lines
1685 * to the struct since the kernel thread not created yet1735 * to the struct since the kernel thread not created yet
1686 * no need to spinlock this update of tcpStatus1736 * no need to spinlock this update of tcpStatus
1687 */1737 */
1688 spin_lock(&cifs_tcp_ses_lock);1738 spin_lock(&tcp_ses->srv_lock);
1689 tcp_ses->tcpStatus = CifsNeedNegotiate;1739 tcp_ses->tcpStatus = CifsNeedNegotiate;
1690 spin_unlock(&cifs_tcp_ses_lock);1740 spin_unlock(&tcp_ses->srv_lock);
1691 1741
1692 if ((ctx->max_credits < 20) || (ctx->max_credits > 60000))1742 if ((ctx->max_credits < 20) || (ctx->max_credits > 60000))
1693 tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE;1743 tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE;
@@ -1729,6 +1779,7 @@ out_err: · 35 unmodified lines
1729 return ERR_PTR(rc);1779 return ERR_PTR(rc);
1730}1780}
1731 1781
1782/* this function must be called with ses_lock held */
1732static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)1783static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
1733{1784{
1734 if (ctx->sectype != Unspecified &&1785 if (ctx->sectype != Unspecified &&
@@ -1864,10 +1915,17 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) · 129 unmodified lines
1864 1915
1865 spin_lock(&cifs_tcp_ses_lock);1916 spin_lock(&cifs_tcp_ses_lock);
1866 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {1917 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1867 if (ses->ses_status == SES_EXITING)1918 spin_lock(&ses->ses_lock);
1919 if (ses->ses_status == SES_EXITING) {
1920 spin_unlock(&ses->ses_lock);
1868 continue;1921 continue;
1869 if (!match_session(ses, ctx))1922 }
1923 if (!match_session(ses, ctx)) {
1924 spin_unlock(&ses->ses_lock);
1870 continue;1925 continue;
1926 }
1927 spin_unlock(&ses->ses_lock);
1928
1871 ++ses->ses_count;1929 ++ses->ses_count;
1872 spin_unlock(&cifs_tcp_ses_lock);1930 spin_unlock(&cifs_tcp_ses_lock);
1873 return ses;1931 return ses;
@@ -1882,26 +1940,28 @@ void cifs_put_smb_ses(struct cifs_ses *ses) · 8 unmodified lines
1882 unsigned int chan_count;1940 unsigned int chan_count;
1883 struct TCP_Server_Info *server = ses->server;1941 struct TCP_Server_Info *server = ses->server;
1884 1942
1885 spin_lock(&cifs_tcp_ses_lock);1943 spin_lock(&ses->ses_lock);
1886 if (ses->ses_status == SES_EXITING) {1944 if (ses->ses_status == SES_EXITING) {
1887 spin_unlock(&cifs_tcp_ses_lock);1945 spin_unlock(&ses->ses_lock);
1888 return;1946 return;
1889 }1947 }
1948 spin_unlock(&ses->ses_lock);
1890 1949
1891 cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count);1950 cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count);
1892 cifs_dbg(FYI, "%s: ses ipc: %s\n", __func__, ses->tcon_ipc ? ses->tcon_ipc->treeName : "NONE");1951 cifs_dbg(FYI, "%s: ses ipc: %s\n", __func__, ses->tcon_ipc ? ses->tcon_ipc->treeName : "NONE");
1893 1952
1953 spin_lock(&cifs_tcp_ses_lock);
1894 if (--ses->ses_count > 0) {1954 if (--ses->ses_count > 0) {
1895 spin_unlock(&cifs_tcp_ses_lock);1955 spin_unlock(&cifs_tcp_ses_lock);
1896 return;1956 return;
1897 }1957 }
1958 spin_unlock(&cifs_tcp_ses_lock);
1898 1959
1899 /* ses_count can never go negative */1960 /* ses_count can never go negative */
1900 WARN_ON(ses->ses_count < 0);1961 WARN_ON(ses->ses_count < 0);
1901 1962
1902 if (ses->ses_status == SES_GOOD)1963 if (ses->ses_status == SES_GOOD)
1903 ses->ses_status = SES_EXITING;1964 ses->ses_status = SES_EXITING;
1904 spin_unlock(&cifs_tcp_ses_lock);
1905 1965
1906 cifs_free_ipc(ses);1966 cifs_free_ipc(ses);
1907 1967
@@ -2236,6 +2296,7 @@ get_ses_fail: · 328 unmodified lines
2236 return ERR_PTR(rc);2296 return ERR_PTR(rc);
2237}2297}
2238 2298
2299/* this function must be called with tc_lock held */
2239static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)2300static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
2240{2301{
2241 if (tcon->status == TID_EXITING)2302 if (tcon->status == TID_EXITING)
@@ -2258,16 +2319,17 @@ static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) · 16 unmodified lines
2258static struct cifs_tcon *2319static struct cifs_tcon *
2259cifs_find_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)2320cifs_find_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
2260{2321{
2261 struct list_head *tmp;
2262 struct cifs_tcon *tcon;2322 struct cifs_tcon *tcon;
2263 2323
2264 spin_lock(&cifs_tcp_ses_lock);2324 spin_lock(&cifs_tcp_ses_lock);
2265 list_for_each(tmp, &ses->tcon_list) {2325 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
2266 tcon = list_entry(tmp, struct cifs_tcon, tcon_list);2326 spin_lock(&tcon->tc_lock);
2267 2327 if (!match_tcon(tcon, ctx)) {
2268 if (!match_tcon(tcon, ctx))2328 spin_unlock(&tcon->tc_lock);
2269 continue;2329 continue;
2330 }
2270 ++tcon->tc_count;2331 ++tcon->tc_count;
2332 spin_unlock(&tcon->tc_lock);
2271 spin_unlock(&cifs_tcp_ses_lock);2333 spin_unlock(&cifs_tcp_ses_lock);
2272 return tcon;2334 return tcon;
2273 }2335 }
@@ -2644,7 +2706,7 @@ match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data) · 370 unmodified lines
2644int2706int
2645cifs_match_super(struct super_block *sb, void *data)2707cifs_match_super(struct super_block *sb, void *data)
2646{2708{
2647 struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data;2709 struct cifs_mnt_data *mnt_data = data;
2648 struct smb3_fs_context *ctx;2710 struct smb3_fs_context *ctx;
2649 struct cifs_sb_info *cifs_sb;2711 struct cifs_sb_info *cifs_sb;
2650 struct TCP_Server_Info *tcp_srv;2712 struct TCP_Server_Info *tcp_srv;
@@ -2667,6 +2729,9 @@ cifs_match_super(struct super_block *sb, void *data) · 16 unmodified lines
2667 2729
2668 ctx = mnt_data->ctx;2730 ctx = mnt_data->ctx;
2669 2731
2732 spin_lock(&tcp_srv->srv_lock);
2733 spin_lock(&ses->ses_lock);
2734 spin_lock(&tcon->tc_lock);
2670 if (!match_server(tcp_srv, ctx) ||2735 if (!match_server(tcp_srv, ctx) ||
2671 !match_session(ses, ctx) ||2736 !match_session(ses, ctx) ||
2672 !match_tcon(tcon, ctx) ||2737 !match_tcon(tcon, ctx) ||
@@ -2677,6 +2742,10 @@ cifs_match_super(struct super_block *sb, void *data) · 4 unmodified lines
2677 2742
2678 rc = compare_mount_options(sb, mnt_data);2743 rc = compare_mount_options(sb, mnt_data);
2679out:2744out:
2745 spin_unlock(&tcon->tc_lock);
2746 spin_unlock(&ses->ses_lock);
2747 spin_unlock(&tcp_srv->srv_lock);
2748
2680 spin_unlock(&cifs_tcp_ses_lock);2749 spin_unlock(&cifs_tcp_ses_lock);
2681 cifs_put_tlink(tlink);2750 cifs_put_tlink(tlink);
2682 return rc;2751 return rc;
@@ -2954,6 +3023,7 @@ ip_connect(struct TCP_Server_Info *server) · 271 unmodified lines
2954 return generic_ip_connect(server);3023 return generic_ip_connect(server);
2955}3024}
2956 3025
3026#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
2957void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,3027void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
2958 struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)3028 struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
2959{3029{
@@ -3059,6 +3129,7 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, · 99 unmodified lines
3059 }3129 }
3060 }3130 }
3061}3131}
3132#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
3062 3133
3063int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)3134int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
3064{3135{
@@ -3175,6 +3246,7 @@ static int mount_get_conns(struct mount_ctx *mnt_ctx) · 110 unmodified lines
3175 if (tcon->posix_extensions)3246 if (tcon->posix_extensions)
3176 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;3247 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
3177 3248
3249#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
3178 /* tell server which Unix caps we support */3250 /* tell server which Unix caps we support */
3179 if (cap_unix(tcon->ses)) {3251 if (cap_unix(tcon->ses)) {
3180 /*3252 /*
@@ -3182,16 +3254,17 @@ static int mount_get_conns(struct mount_ctx *mnt_ctx) · 1 unmodified line
3182 * for just this mount.3254 * for just this mount.
3183 */3255 */
3184 reset_cifs_unix_caps(xid, tcon, cifs_sb, ctx);3256 reset_cifs_unix_caps(xid, tcon, cifs_sb, ctx);
3185 spin_lock(&cifs_tcp_ses_lock);3257 spin_lock(&tcon->ses->server->srv_lock);
3186 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&3258 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
3187 (le64_to_cpu(tcon->fsUnixInfo.Capability) &3259 (le64_to_cpu(tcon->fsUnixInfo.Capability) &
3188 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {3260 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {
3189 spin_unlock(&cifs_tcp_ses_lock);3261 spin_unlock(&tcon->ses->server->srv_lock);
3190 rc = -EACCES;3262 rc = -EACCES;
3191 goto out;3263 goto out;
3192 }3264 }
3193 spin_unlock(&cifs_tcp_ses_lock);3265 spin_unlock(&tcon->ses->server->srv_lock);
3194 } else3266 } else
3267#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
3195 tcon->unix_ext = 0; /* server does not support them */3268 tcon->unix_ext = 0; /* server does not support them */
3196 3269
3197 /* do not care if a following call succeed - informational */3270 /* do not care if a following call succeed - informational */
@@ -3273,9 +3346,9 @@ static int mount_get_dfs_conns(struct mount_ctx *mnt_ctx) · 75 unmodified lines
3273 rc = mount_get_conns(mnt_ctx);3346 rc = mount_get_conns(mnt_ctx);
3274 if (mnt_ctx->server) {3347 if (mnt_ctx->server) {
3275 cifs_dbg(FYI, "%s: marking tcp session as a dfs connection\n", __func__);3348 cifs_dbg(FYI, "%s: marking tcp session as a dfs connection\n", __func__);
3276 spin_lock(&cifs_tcp_ses_lock);3349 spin_lock(&mnt_ctx->server->srv_lock);
3277 mnt_ctx->server->is_dfs_conn = true;3350 mnt_ctx->server->is_dfs_conn = true;
3278 spin_unlock(&cifs_tcp_ses_lock);3351 spin_unlock(&mnt_ctx->server->srv_lock);
3279 }3352 }
3280 return rc;3353 return rc;
3281}3354}
@@ -3990,28 +4063,28 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses, · 708 unmodified lines
3990 return -ENOSYS;4063 return -ENOSYS;
3991 4064
3992 /* only send once per connect */4065 /* only send once per connect */
3993 spin_lock(&cifs_tcp_ses_lock);4066 spin_lock(&server->srv_lock);
3994 if (!server->ops->need_neg(server) ||4067 if (!server->ops->need_neg(server) ||
3995 server->tcpStatus != CifsNeedNegotiate) {4068 server->tcpStatus != CifsNeedNegotiate) {
3996 spin_unlock(&cifs_tcp_ses_lock);4069 spin_unlock(&server->srv_lock);
3997 return 0;4070 return 0;
3998 }4071 }
3999 server->tcpStatus = CifsInNegotiate;4072 server->tcpStatus = CifsInNegotiate;
4000 spin_unlock(&cifs_tcp_ses_lock);4073 spin_unlock(&server->srv_lock);
4001 4074
4002 rc = server->ops->negotiate(xid, ses, server);4075 rc = server->ops->negotiate(xid, ses, server);
4003 if (rc == 0) {4076 if (rc == 0) {
4004 spin_lock(&cifs_tcp_ses_lock);4077 spin_lock(&server->srv_lock);
4005 if (server->tcpStatus == CifsInNegotiate)4078 if (server->tcpStatus == CifsInNegotiate)
4006 server->tcpStatus = CifsGood;4079 server->tcpStatus = CifsGood;
4007 else4080 else
4008 rc = -EHOSTDOWN;4081 rc = -EHOSTDOWN;
4009 spin_unlock(&cifs_tcp_ses_lock);4082 spin_unlock(&server->srv_lock);
4010 } else {4083 } else {
4011 spin_lock(&cifs_tcp_ses_lock);4084 spin_lock(&server->srv_lock);
4012 if (server->tcpStatus == CifsInNegotiate)4085 if (server->tcpStatus == CifsInNegotiate)
4013 server->tcpStatus = CifsNeedNegotiate;4086 server->tcpStatus = CifsNeedNegotiate;
4014 spin_unlock(&cifs_tcp_ses_lock);4087 spin_unlock(&server->srv_lock);
4015 }4088 }
4016 4089
4017 return rc;4090 return rc;
@@ -4027,7 +4100,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, · 9 unmodified lines
4027 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;4100 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
4028 bool is_binding = false;4101 bool is_binding = false;
4029 4102
4030 spin_lock(&cifs_tcp_ses_lock);4103 spin_lock(&ses->ses_lock);
4031 if (server->dstaddr.ss_family == AF_INET6)4104 if (server->dstaddr.ss_family == AF_INET6)
4032 scnprintf(ses->ip_addr, sizeof(ses->ip_addr), "%pI6", &addr6->sin6_addr);4105 scnprintf(ses->ip_addr, sizeof(ses->ip_addr), "%pI6", &addr6->sin6_addr);
4033 else4106 else
@@ -4036,7 +4109,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, · 2 unmodified lines
4036 if (ses->ses_status != SES_GOOD &&4109 if (ses->ses_status != SES_GOOD &&
4037 ses->ses_status != SES_NEW &&4110 ses->ses_status != SES_NEW &&
4038 ses->ses_status != SES_NEED_RECON) {4111 ses->ses_status != SES_NEED_RECON) {
4039 spin_unlock(&cifs_tcp_ses_lock);4112 spin_unlock(&ses->ses_lock);
4040 return 0;4113 return 0;
4041 }4114 }
4042 4115
@@ -4045,7 +4118,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, · 2 unmodified lines
4045 if (CIFS_ALL_CHANS_GOOD(ses) ||4118 if (CIFS_ALL_CHANS_GOOD(ses) ||
4046 cifs_chan_in_reconnect(ses, server)) {4119 cifs_chan_in_reconnect(ses, server)) {
4047 spin_unlock(&ses->chan_lock);4120 spin_unlock(&ses->chan_lock);
4048 spin_unlock(&cifs_tcp_ses_lock);4121 spin_unlock(&ses->ses_lock);
4049 return 0;4122 return 0;
4050 }4123 }
4051 is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);4124 is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
@@ -4054,7 +4127,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, · 2 unmodified lines
4054 4127
4055 if (!is_binding)4128 if (!is_binding)
4056 ses->ses_status = SES_IN_SETUP;4129 ses->ses_status = SES_IN_SETUP;
4057 spin_unlock(&cifs_tcp_ses_lock);4130 spin_unlock(&ses->ses_lock);
4058 4131
4059 if (!is_binding) {4132 if (!is_binding) {
4060 ses->capabilities = server->capabilities;4133 ses->capabilities = server->capabilities;
@@ -4078,22 +4151,22 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, · 17 unmodified lines
4078 4151
4079 if (rc) {4152 if (rc) {
4080 cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc);4153 cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc);
4081 spin_lock(&cifs_tcp_ses_lock);4154 spin_lock(&ses->ses_lock);
4082 if (ses->ses_status == SES_IN_SETUP)4155 if (ses->ses_status == SES_IN_SETUP)
4083 ses->ses_status = SES_NEED_RECON;4156 ses->ses_status = SES_NEED_RECON;
4084 spin_lock(&ses->chan_lock);4157 spin_lock(&ses->chan_lock);
4085 cifs_chan_clear_in_reconnect(ses, server);4158 cifs_chan_clear_in_reconnect(ses, server);
4086 spin_unlock(&ses->chan_lock);4159 spin_unlock(&ses->chan_lock);
4087 spin_unlock(&cifs_tcp_ses_lock);4160 spin_unlock(&ses->ses_lock);
4088 } else {4161 } else {
4089 spin_lock(&cifs_tcp_ses_lock);4162 spin_lock(&ses->ses_lock);
4090 if (ses->ses_status == SES_IN_SETUP)4163 if (ses->ses_status == SES_IN_SETUP)
4091 ses->ses_status = SES_GOOD;4164 ses->ses_status = SES_GOOD;
4092 spin_lock(&ses->chan_lock);4165 spin_lock(&ses->chan_lock);
4093 cifs_chan_clear_in_reconnect(ses, server);4166 cifs_chan_clear_in_reconnect(ses, server);
4094 cifs_chan_clear_need_reconnect(ses, server);4167 cifs_chan_clear_need_reconnect(ses, server);
4095 spin_unlock(&ses->chan_lock);4168 spin_unlock(&ses->chan_lock);
4096 spin_unlock(&cifs_tcp_ses_lock);4169 spin_unlock(&ses->ses_lock);
4097 }4170 }
4098 4171
4099 return rc;4172 return rc;
@@ -4167,8 +4240,10 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) · 67 unmodified lines
4167 goto out;4240 goto out;
4168 }4241 }
4169 4242
4243#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
4170 if (cap_unix(ses))4244 if (cap_unix(ses))
4171 reset_cifs_unix_caps(0, tcon, NULL, ctx);4245 reset_cifs_unix_caps(0, tcon, NULL, ctx);
4246#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
4172 4247
4173out:4248out:
4174 kfree(ctx->username);4249 kfree(ctx->username);
@@ -4557,15 +4632,15 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru · 382 unmodified lines
4557 struct dfs_info3_param ref = {0};4632 struct dfs_info3_param ref = {0};
4558 4633
4559 /* only send once per connect */4634 /* only send once per connect */
4560 spin_lock(&cifs_tcp_ses_lock);4635 spin_lock(&tcon->tc_lock);
4561 if (tcon->ses->ses_status != SES_GOOD ||4636 if (tcon->ses->ses_status != SES_GOOD ||
4562 (tcon->status != TID_NEW &&4637 (tcon->status != TID_NEW &&
4563 tcon->status != TID_NEED_TCON)) {4638 tcon->status != TID_NEED_TCON)) {
4564 spin_unlock(&cifs_tcp_ses_lock);4639 spin_unlock(&tcon->tc_lock);
4565 return 0;4640 return 0;
4566 }4641 }
4567 tcon->status = TID_IN_TCON;4642 tcon->status = TID_IN_TCON;
4568 spin_unlock(&cifs_tcp_ses_lock);4643 spin_unlock(&tcon->tc_lock);
4569 4644
4570 tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);4645 tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
4571 if (!tree) {4646 if (!tree) {
@@ -4604,15 +4679,15 @@ out: · 32 unmodified lines
4604 cifs_put_tcp_super(sb);4679 cifs_put_tcp_super(sb);
4605 4680
4606 if (rc) {4681 if (rc) {
4607 spin_lock(&cifs_tcp_ses_lock);4682 spin_lock(&tcon->tc_lock);
4608 if (tcon->status == TID_IN_TCON)4683 if (tcon->status == TID_IN_TCON)
4609 tcon->status = TID_NEED_TCON;4684 tcon->status = TID_NEED_TCON;
4610 spin_unlock(&cifs_tcp_ses_lock);4685 spin_unlock(&tcon->tc_lock);
4611 } else {4686 } else {
4612 spin_lock(&cifs_tcp_ses_lock);4687 spin_lock(&tcon->tc_lock);
4613 if (tcon->status == TID_IN_TCON)4688 if (tcon->status == TID_IN_TCON)
4614 tcon->status = TID_GOOD;4689 tcon->status = TID_GOOD;
4615 spin_unlock(&cifs_tcp_ses_lock);4690 spin_unlock(&tcon->tc_lock);
4616 tcon->need_reconnect = false;4691 tcon->need_reconnect = false;
4617 }4692 }
4618 4693
@@ -4625,28 +4700,28 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru · 6 unmodified lines
4625 const struct smb_version_operations *ops = tcon->ses->server->ops;4700 const struct smb_version_operations *ops = tcon->ses->server->ops;
4626 4701
4627 /* only send once per connect */4702 /* only send once per connect */
4628 spin_lock(&cifs_tcp_ses_lock);4703 spin_lock(&tcon->tc_lock);
4629 if (tcon->ses->ses_status != SES_GOOD ||4704 if (tcon->ses->ses_status != SES_GOOD ||
4630 (tcon->status != TID_NEW &&4705 (tcon->status != TID_NEW &&
4631 tcon->status != TID_NEED_TCON)) {4706 tcon->status != TID_NEED_TCON)) {
4632 spin_unlock(&cifs_tcp_ses_lock);4707 spin_unlock(&tcon->tc_lock);
4633 return 0;4708 return 0;
4634 }4709 }
4635 tcon->status = TID_IN_TCON;4710 tcon->status = TID_IN_TCON;
4636 spin_unlock(&cifs_tcp_ses_lock);4711 spin_unlock(&tcon->tc_lock);
4637 4712
4638 rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc);4713 rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc);
4639 if (rc) {4714 if (rc) {
4640 spin_lock(&cifs_tcp_ses_lock);4715 spin_lock(&tcon->tc_lock);
4641 if (tcon->status == TID_IN_TCON)4716 if (tcon->status == TID_IN_TCON)
4642 tcon->status = TID_NEED_TCON;4717 tcon->status = TID_NEED_TCON;
4643 spin_unlock(&cifs_tcp_ses_lock);4718 spin_unlock(&tcon->tc_lock);
4644 } else {4719 } else {
4645 spin_lock(&cifs_tcp_ses_lock);4720 spin_lock(&tcon->tc_lock);
4646 if (tcon->status == TID_IN_TCON)4721 if (tcon->status == TID_IN_TCON)
4647 tcon->status = TID_GOOD;4722 tcon->status = TID_GOOD;
4648 spin_unlock(&cifs_tcp_ses_lock);
4649 tcon->need_reconnect = false;4723 tcon->need_reconnect = false;
4724 spin_unlock(&tcon->tc_lock);
4650 }4725 }
4651 4726
4652 return rc;4727 return rc;
fs/cifs/dfs_cache.c+7−1
@@ -1526,15 +1526,21 @@ static void refresh_mounts(struct cifs_ses **sessions) · 1525 unmodified lines
1526 1526
1527 spin_lock(&cifs_tcp_ses_lock);1527 spin_lock(&cifs_tcp_ses_lock);
1528 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {1528 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1529 if (!server->is_dfs_conn)1529 spin_lock(&server->srv_lock);
1530 if (!server->is_dfs_conn) {
1531 spin_unlock(&server->srv_lock);
1530 continue;1532 continue;
1533 }
1534 spin_unlock(&server->srv_lock);
1531 1535
1532 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {1536 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1533 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {1537 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
1538 spin_lock(&tcon->tc_lock);
1534 if (!tcon->ipc && !tcon->need_reconnect) {1539 if (!tcon->ipc && !tcon->need_reconnect) {
1535 tcon->tc_count++;1540 tcon->tc_count++;
1536 list_add_tail(&tcon->ulist, &tcons);1541 list_add_tail(&tcon->ulist, &tcons);
1537 }1542 }
1543 spin_unlock(&tcon->tc_lock);
1538 }1544 }
1539 }1545 }
1540 }1546 }
fs/cifs/dir.c+8−0
@@ -193,6 +193,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, · 192 unmodified lines
193 return PTR_ERR(full_path);193 return PTR_ERR(full_path);
194 }194 }
195 195
196#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
196 if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open &&197 if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open &&
197 (CIFS_UNIX_POSIX_PATH_OPS_CAP &198 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
198 le64_to_cpu(tcon->fsUnixInfo.Capability))) {199 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
@@ -261,6 +262,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, · 62 unmodified lines
261 * rare for path not covered on files)262 * rare for path not covered on files)
262 */263 */
263 }264 }
265#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
264 266
265 desired_access = 0;267 desired_access = 0;
266 if (OPEN_FMODE(oflags) & FMODE_READ)268 if (OPEN_FMODE(oflags) & FMODE_READ)
@@ -316,6 +318,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, · 49 unmodified lines
316 goto out;318 goto out;
317 }319 }
318 320
321#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
319 /*322 /*
320 * If Open reported that we actually created a file then we now have to323 * If Open reported that we actually created a file then we now have to
321 * set the mode if possible.324 * set the mode if possible.
@@ -357,6 +360,9 @@ cifs_create_get_file_info: · 35 unmodified lines
357 rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,360 rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,
358 xid);361 xid);
359 else {362 else {
363#else
364 {
365#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
360 /* TODO: Add support for calling POSIX query info here, but passing in fid */366 /* TODO: Add support for calling POSIX query info here, but passing in fid */
361 rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb,367 rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb,
362 xid, fid);368 xid, fid);
@@ -377,7 +383,9 @@ cifs_create_get_file_info: · 14 unmodified lines
377 }383 }
378 }384 }
379 385
386#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
380cifs_create_set_dentry:387cifs_create_set_dentry:
388#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
381 if (rc != 0) {389 if (rc != 0) {
382 cifs_dbg(FYI, "Create worked, get_inode_info failed rc = %d\n",390 cifs_dbg(FYI, "Create worked, get_inode_info failed rc = %d\n",
383 rc);391 rc);
fs/cifs/file.c+269−14
@@ -26,6 +26,7 @@ · 25 unmodified lines
26#include "cifspdu.h"26#include "cifspdu.h"
27#include "cifsglob.h"27#include "cifsglob.h"
28#include "cifsproto.h"28#include "cifsproto.h"
29#include "smb2proto.h"
29#include "cifs_unicode.h"30#include "cifs_unicode.h"
30#include "cifs_debug.h"31#include "cifs_debug.h"
31#include "cifs_fs_sb.h"32#include "cifs_fs_sb.h"
@@ -34,6 +35,53 @@ · 2 unmodified lines
34#include "fs_context.h"35#include "fs_context.h"
35#include "cifs_ioctl.h"36#include "cifs_ioctl.h"
36 37
38/*
39 * Mark as invalid, all open files on tree connections since they
40 * were closed when session to server was lost.
41 */
42void
43cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
44{
45 struct cifsFileInfo *open_file = NULL;
46 struct list_head *tmp;
47 struct list_head *tmp1;
48
49 /* only send once per connect */
50 spin_lock(&tcon->ses->ses_lock);
51 if ((tcon->ses->ses_status != SES_GOOD) || (tcon->status != TID_NEED_RECON)) {
52 spin_unlock(&tcon->ses->ses_lock);
53 return;
54 }
55 tcon->status = TID_IN_FILES_INVALIDATE;
56 spin_unlock(&tcon->ses->ses_lock);
57
58 /* list all files open on tree connection and mark them invalid */
59 spin_lock(&tcon->open_file_lock);
60 list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
61 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
62 open_file->invalidHandle = true;
63 open_file->oplock_break_cancelled = true;
64 }
65 spin_unlock(&tcon->open_file_lock);
66
67 mutex_lock(&tcon->crfid.fid_mutex);
68 tcon->crfid.is_valid = false;
69 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
70 close_cached_dir_lease_locked(&tcon->crfid);
71 memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
72 mutex_unlock(&tcon->crfid.fid_mutex);
73
74 spin_lock(&tcon->tc_lock);
75 if (tcon->status == TID_IN_FILES_INVALIDATE)
76 tcon->status = TID_NEED_TCON;
77 spin_unlock(&tcon->tc_lock);
78
79 /*
80 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
81 * to this tcon.
82 */
83}
84
37static inline int cifs_convert_flags(unsigned int flags)85static inline int cifs_convert_flags(unsigned int flags)
38{86{
39 if ((flags & O_ACCMODE) == O_RDONLY)87 if ((flags & O_ACCMODE) == O_RDONLY)
@@ -52,6 +100,7 @@ static inline int cifs_convert_flags(unsigned int flags) · 12 unmodified lines
52 FILE_READ_DATA);100 FILE_READ_DATA);
53}101}
54 102
103#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
55static u32 cifs_posix_convert_flags(unsigned int flags)104static u32 cifs_posix_convert_flags(unsigned int flags)
56{105{
57 u32 posix_flags = 0;106 u32 posix_flags = 0;
@@ -85,6 +134,7 @@ static u32 cifs_posix_convert_flags(unsigned int flags) · 27 unmodified lines
85 134
86 return posix_flags;135 return posix_flags;
87}136}
137#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
88 138
89static inline int cifs_get_disposition(unsigned int flags)139static inline int cifs_get_disposition(unsigned int flags)
90{140{
@@ -100,6 +150,7 @@ static inline int cifs_get_disposition(unsigned int flags) · 9 unmodified lines
100 return FILE_OPEN;150 return FILE_OPEN;
101}151}
102 152
153#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
103int cifs_posix_open(const char *full_path, struct inode **pinode,154int cifs_posix_open(const char *full_path, struct inode **pinode,
104 struct super_block *sb, int mode, unsigned int f_flags,155 struct super_block *sb, int mode, unsigned int f_flags,
105 __u32 *poplock, __u16 *pnetfid, unsigned int xid)156 __u32 *poplock, __u16 *pnetfid, unsigned int xid)
@@ -161,6 +212,7 @@ posix_open_ret: · 55 unmodified lines
161 kfree(presp_data);212 kfree(presp_data);
162 return rc;213 return rc;
163}214}
215#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
164 216
165static int217static int
166cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,218cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
@@ -579,6 +631,7 @@ int cifs_open(struct inode *inode, struct file *file) · 412 unmodified lines
579 else631 else
580 oplock = 0;632 oplock = 0;
581 633
634#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
582 if (!tcon->broken_posix_open && tcon->unix_ext &&635 if (!tcon->broken_posix_open && tcon->unix_ext &&
583 cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &636 cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
584 le64_to_cpu(tcon->fsUnixInfo.Capability))) {637 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
@@ -603,6 +656,7 @@ int cifs_open(struct inode *inode, struct file *file) · 18 unmodified lines
603 * or DFS errors.656 * or DFS errors.
604 */657 */
605 }658 }
659#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
606 660
607 if (server->ops->get_lease_key)661 if (server->ops->get_lease_key)
608 server->ops->get_lease_key(inode, &fid);662 server->ops->get_lease_key(inode, &fid);
@@ -630,6 +684,7 @@ int cifs_open(struct inode *inode, struct file *file) · 21 unmodified lines
630 goto out;684 goto out;
631 }685 }
632 686
687#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
633 if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) {688 if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) {
634 /*689 /*
635 * Time to set mode which we can not set earlier due to690 * Time to set mode which we can not set earlier due to
@@ -647,6 +702,7 @@ int cifs_open(struct inode *inode, struct file *file) · 11 unmodified lines
647 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid.netfid,702 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid.netfid,
648 cfile->pid);703 cfile->pid);
649 }704 }
705#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
650 706
651use_cache:707use_cache:
652 fscache_use_cookie(cifs_inode_cookie(file_inode(file)),708 fscache_use_cookie(cifs_inode_cookie(file_inode(file)),
@@ -664,7 +720,9 @@ out: · 11 unmodified lines
664 return rc;720 return rc;
665}721}
666 722
723#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
667static int cifs_push_posix_locks(struct cifsFileInfo *cfile);724static int cifs_push_posix_locks(struct cifsFileInfo *cfile);
725#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
668 726
669/*727/*
670 * Try to reacquire byte range locks that were released when session728 * Try to reacquire byte range locks that were released when session
@@ -673,10 +731,12 @@ static int cifs_push_posix_locks(struct cifsFileInfo *cfile); · 2 unmodified lines
673static int731static int
674cifs_relock_file(struct cifsFileInfo *cfile)732cifs_relock_file(struct cifsFileInfo *cfile)
675{733{
676 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
677 struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry));734 struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry));
678 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);735 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
679 int rc = 0;736 int rc = 0;
737#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
738 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
739#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
680 740
681 down_read_nested(&cinode->lock_sem, SINGLE_DEPTH_NESTING);741 down_read_nested(&cinode->lock_sem, SINGLE_DEPTH_NESTING);
682 if (cinode->can_cache_brlcks) {742 if (cinode->can_cache_brlcks) {
@@ -685,11 +745,13 @@ cifs_relock_file(struct cifsFileInfo *cfile) · 2 unmodified lines
685 return rc;745 return rc;
686 }746 }
687 747
748#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
688 if (cap_unix(tcon->ses) &&749 if (cap_unix(tcon->ses) &&
689 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&750 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
690 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))751 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
691 rc = cifs_push_posix_locks(cfile);752 rc = cifs_push_posix_locks(cfile);
692 else753 else
754#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
693 rc = tcon->ses->server->ops->push_mand_locks(cfile);755 rc = tcon->ses->server->ops->push_mand_locks(cfile);
694 756
695 up_read(&cinode->lock_sem);757 up_read(&cinode->lock_sem);
@@ -750,6 +812,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) · 54 unmodified lines
750 else812 else
751 oplock = 0;813 oplock = 0;
752 814
815#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
753 if (tcon->unix_ext && cap_unix(tcon->ses) &&816 if (tcon->unix_ext && cap_unix(tcon->ses) &&
754 (CIFS_UNIX_POSIX_PATH_OPS_CAP &817 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
755 le64_to_cpu(tcon->fsUnixInfo.Capability))) {818 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
@@ -773,6 +836,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) · 17 unmodified lines
773 * in the reconnect path it is important to retry hard836 * in the reconnect path it is important to retry hard
774 */837 */
775 }838 }
839#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
776 840
777 desired_access = cifs_convert_flags(cfile->f_flags);841 desired_access = cifs_convert_flags(cfile->f_flags);
778 842
@@ -817,7 +881,9 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) · 38 unmodified lines
817 goto reopen_error_exit;881 goto reopen_error_exit;
818 }882 }
819 883
884#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
820reopen_success:885reopen_success:
886#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
821 cfile->invalidHandle = false;887 cfile->invalidHandle = false;
822 mutex_unlock(&cfile->fh_mutex);888 mutex_unlock(&cfile->fh_mutex);
823 cinode = CIFS_I(inode);889 cinode = CIFS_I(inode);
@@ -928,9 +994,7 @@ int cifs_close(struct inode *inode, struct file *file) · 104 unmodified lines
928void994void
929cifs_reopen_persistent_handles(struct cifs_tcon *tcon)995cifs_reopen_persistent_handles(struct cifs_tcon *tcon)
930{996{
931 struct cifsFileInfo *open_file;997 struct cifsFileInfo *open_file, *tmp;
932 struct list_head *tmp;
933 struct list_head *tmp1;
934 struct list_head tmp_list;998 struct list_head tmp_list;
935 999
936 if (!tcon->use_persistent || !tcon->need_reopen_files)1000 if (!tcon->use_persistent || !tcon->need_reopen_files)
@@ -943,8 +1007,7 @@ cifs_reopen_persistent_handles(struct cifs_tcon *tcon) · 6 unmodified lines
943 1007
944 /* list all files open on tree connection, reopen resilient handles */1008 /* list all files open on tree connection, reopen resilient handles */
945 spin_lock(&tcon->open_file_lock);1009 spin_lock(&tcon->open_file_lock);
946 list_for_each(tmp, &tcon->openFileList) {1010 list_for_each_entry(open_file, &tcon->openFileList, tlist) {
947 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
948 if (!open_file->invalidHandle)1011 if (!open_file->invalidHandle)
949 continue;1012 continue;
950 cifsFileInfo_get(open_file);1013 cifsFileInfo_get(open_file);
@@ -952,8 +1015,7 @@ cifs_reopen_persistent_handles(struct cifs_tcon *tcon) · 1 unmodified line
952 }1015 }
953 spin_unlock(&tcon->open_file_lock);1016 spin_unlock(&tcon->open_file_lock);
954 1017
955 list_for_each_safe(tmp, tmp1, &tmp_list) {1018 list_for_each_entry_safe(open_file, tmp, &tmp_list, rlist) {
956 open_file = list_entry(tmp, struct cifsFileInfo, rlist);
957 if (cifs_reopen_file(open_file, false /* do not flush */))1019 if (cifs_reopen_file(open_file, false /* do not flush */))
958 tcon->need_reopen_files = true;1020 tcon->need_reopen_files = true;
959 list_del_init(&open_file->rlist);1021 list_del_init(&open_file->rlist);
@@ -1196,6 +1258,7 @@ try_again: · 236 unmodified lines
1196 return rc;1258 return rc;
1197}1259}
1198 1260
1261#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1199/*1262/*
1200 * Check if there is another lock that prevents us to set the lock (posix1263 * Check if there is another lock that prevents us to set the lock (posix
1201 * style). If such a lock exists, update the flock structure with its1264 * style). If such a lock exists, update the flock structure with its
@@ -1334,6 +1397,7 @@ hash_lockowner(fl_owner_t owner) · 132 unmodified lines
1334{1397{
1335 return cifs_lock_secret ^ hash32_ptr((const void *)owner);1398 return cifs_lock_secret ^ hash32_ptr((const void *)owner);
1336}1399}
1400#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1337 1401
1338struct lock_to_push {1402struct lock_to_push {
1339 struct list_head llist;1403 struct list_head llist;
@@ -1344,6 +1408,7 @@ struct lock_to_push { · 4 unmodified lines
1344 __u8 type;1408 __u8 type;
1345};1409};
1346 1410
1411#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1347static int1412static int
1348cifs_push_posix_locks(struct cifsFileInfo *cfile)1413cifs_push_posix_locks(struct cifsFileInfo *cfile)
1349{1414{
@@ -1431,14 +1496,17 @@ err_out: · 81 unmodified lines
1431 }1496 }
1432 goto out;1497 goto out;
1433}1498}
1499#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1434 1500
1435static int1501static int
1436cifs_push_locks(struct cifsFileInfo *cfile)1502cifs_push_locks(struct cifsFileInfo *cfile)
1437{1503{
1438 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
1439 struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry));1504 struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry));
1440 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);1505 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1441 int rc = 0;1506 int rc = 0;
1507#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1508 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
1509#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1442 1510
1443 /* we are going to update can_cache_brlcks here - need a write access */1511 /* we are going to update can_cache_brlcks here - need a write access */
1444 cifs_down_write(&cinode->lock_sem);1512 cifs_down_write(&cinode->lock_sem);
@@ -1447,11 +1515,13 @@ cifs_push_locks(struct cifsFileInfo *cfile) · 2 unmodified lines
1447 return rc;1515 return rc;
1448 }1516 }
1449 1517
1518#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1450 if (cap_unix(tcon->ses) &&1519 if (cap_unix(tcon->ses) &&
1451 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&1520 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
1452 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))1521 ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
1453 rc = cifs_push_posix_locks(cfile);1522 rc = cifs_push_posix_locks(cfile);
1454 else1523 else
1524#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1455 rc = tcon->ses->server->ops->push_mand_locks(cfile);1525 rc = tcon->ses->server->ops->push_mand_locks(cfile);
1456 1526
1457 cinode->can_cache_brlcks = false;1527 cinode->can_cache_brlcks = false;
@@ -1515,6 +1585,7 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type, · 57 unmodified lines
1515 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;1585 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
1516 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);1586 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1517 struct TCP_Server_Info *server = tcon->ses->server;1587 struct TCP_Server_Info *server = tcon->ses->server;
1588#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1518 __u16 netfid = cfile->fid.netfid;1589 __u16 netfid = cfile->fid.netfid;
1519 1590
1520 if (posix_lck) {1591 if (posix_lck) {
@@ -1534,6 +1605,7 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u32 type, · 13 unmodified lines
1534 posix_lock_type, wait_flag);1605 posix_lock_type, wait_flag);
1535 return rc;1606 return rc;
1536 }1607 }
1608#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1537 1609
1538 rc = cifs_lock_test(cfile, flock->fl_start, length, type, flock);1610 rc = cifs_lock_test(cfile, flock->fl_start, length, type, flock);
1539 if (!rc)1611 if (!rc)
@@ -1594,6 +1666,7 @@ cifs_free_llist(struct list_head *llist) · 54 unmodified lines
1594 }1666 }
1595}1667}
1596 1668
1669#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1597int1670int
1598cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,1671cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
1599 unsigned int xid)1672 unsigned int xid)
@@ -1706,6 +1779,7 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, · 106 unmodified lines
1706 kfree(buf);1779 kfree(buf);
1707 return rc;1780 return rc;
1708}1781}
1782#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1709 1783
1710static int1784static int
1711cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,1785cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
@@ -1719,6 +1793,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, · 7 unmodified lines
1719 struct TCP_Server_Info *server = tcon->ses->server;1793 struct TCP_Server_Info *server = tcon->ses->server;
1720 struct inode *inode = d_inode(cfile->dentry);1794 struct inode *inode = d_inode(cfile->dentry);
1721 1795
1796#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1722 if (posix_lck) {1797 if (posix_lck) {
1723 int posix_lock_type;1798 int posix_lock_type;
1724 1799
@@ -1740,7 +1815,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, · 15 unmodified lines
1740 NULL, posix_lock_type, wait_flag);1815 NULL, posix_lock_type, wait_flag);
1741 goto out;1816 goto out;
1742 }1817 }
1743 1818#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1744 if (lock) {1819 if (lock) {
1745 struct cifsLockInfo *lock;1820 struct cifsLockInfo *lock;
1746 1821
@@ -2204,6 +2279,185 @@ cifs_get_readable_path(struct cifs_tcon *tcon, const char *name, · 457 unmodified lines
2204 return -ENOENT;2279 return -ENOENT;
2205}2280}
2206 2281
2282void
2283cifs_writedata_release(struct kref *refcount)
2284{
2285 struct cifs_writedata *wdata = container_of(refcount,
2286 struct cifs_writedata, refcount);
2287#ifdef CONFIG_CIFS_SMB_DIRECT
2288 if (wdata->mr) {
2289 smbd_deregister_mr(wdata->mr);
2290 wdata->mr = NULL;
2291 }
2292#endif
2293
2294 if (wdata->cfile)
2295 cifsFileInfo_put(wdata->cfile);
2296
2297 kvfree(wdata->pages);
2298 kfree(wdata);
2299}
2300
2301/*
2302 * Write failed with a retryable error. Resend the write request. It's also
2303 * possible that the page was redirtied so re-clean the page.
2304 */
2305static void
2306cifs_writev_requeue(struct cifs_writedata *wdata)
2307{
2308 int i, rc = 0;
2309 struct inode *inode = d_inode(wdata->cfile->dentry);
2310 struct TCP_Server_Info *server;
2311 unsigned int rest_len;
2312
2313 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
2314 i = 0;
2315 rest_len = wdata->bytes;
2316 do {
2317 struct cifs_writedata *wdata2;
2318 unsigned int j, nr_pages, wsize, tailsz, cur_len;
2319
2320 wsize = server->ops->wp_retry_size(inode);
2321 if (wsize < rest_len) {
2322 nr_pages = wsize / PAGE_SIZE;
2323 if (!nr_pages) {
2324 rc = -EOPNOTSUPP;
2325 break;
2326 }
2327 cur_len = nr_pages * PAGE_SIZE;
2328 tailsz = PAGE_SIZE;
2329 } else {
2330 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE);
2331 cur_len = rest_len;
2332 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE;
2333 }
2334
2335 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete);
2336 if (!wdata2) {
2337 rc = -ENOMEM;
2338 break;
2339 }
2340
2341 for (j = 0; j < nr_pages; j++) {
2342 wdata2->pages[j] = wdata->pages[i + j];
2343 lock_page(wdata2->pages[j]);
2344 clear_page_dirty_for_io(wdata2->pages[j]);
2345 }
2346
2347 wdata2->sync_mode = wdata->sync_mode;
2348 wdata2->nr_pages = nr_pages;
2349 wdata2->offset = page_offset(wdata2->pages[0]);
2350 wdata2->pagesz = PAGE_SIZE;
2351 wdata2->tailsz = tailsz;
2352 wdata2->bytes = cur_len;
2353
2354 rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
2355 &wdata2->cfile);
2356 if (!wdata2->cfile) {
2357 cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
2358 rc);
2359 if (!is_retryable_error(rc))
2360 rc = -EBADF;
2361 } else {
2362 wdata2->pid = wdata2->cfile->pid;
2363 rc = server->ops->async_writev(wdata2,
2364 cifs_writedata_release);
2365 }
2366
2367 for (j = 0; j < nr_pages; j++) {
2368 unlock_page(wdata2->pages[j]);
2369 if (rc != 0 && !is_retryable_error(rc)) {
2370 SetPageError(wdata2->pages[j]);
2371 end_page_writeback(wdata2->pages[j]);
2372 put_page(wdata2->pages[j]);
2373 }
2374 }
2375
2376 kref_put(&wdata2->refcount, cifs_writedata_release);
2377 if (rc) {
2378 if (is_retryable_error(rc))
2379 continue;
2380 i += nr_pages;
2381 break;
2382 }
2383
2384 rest_len -= cur_len;
2385 i += nr_pages;
2386 } while (i < wdata->nr_pages);
2387
2388 /* cleanup remaining pages from the original wdata */
2389 for (; i < wdata->nr_pages; i++) {
2390 SetPageError(wdata->pages[i]);
2391 end_page_writeback(wdata->pages[i]);
2392 put_page(wdata->pages[i]);
2393 }
2394
2395 if (rc != 0 && !is_retryable_error(rc))
2396 mapping_set_error(inode->i_mapping, rc);
2397 kref_put(&wdata->refcount, cifs_writedata_release);
2398}
2399
2400void
2401cifs_writev_complete(struct work_struct *work)
2402{
2403 struct cifs_writedata *wdata = container_of(work,
2404 struct cifs_writedata, work);
2405 struct inode *inode = d_inode(wdata->cfile->dentry);
2406 int i = 0;
2407
2408 if (wdata->result == 0) {
2409 spin_lock(&inode->i_lock);
2410 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
2411 spin_unlock(&inode->i_lock);
2412 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
2413 wdata->bytes);
2414 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
2415 return cifs_writev_requeue(wdata);
2416
2417 for (i = 0; i < wdata->nr_pages; i++) {
2418 struct page *page = wdata->pages[i];
2419
2420 if (wdata->result == -EAGAIN)
2421 __set_page_dirty_nobuffers(page);
2422 else if (wdata->result < 0)
2423 SetPageError(page);
2424 end_page_writeback(page);
2425 cifs_readpage_to_fscache(inode, page);
2426 put_page(page);
2427 }
2428 if (wdata->result != -EAGAIN)
2429 mapping_set_error(inode->i_mapping, wdata->result);
2430 kref_put(&wdata->refcount, cifs_writedata_release);
2431}
2432
2433struct cifs_writedata *
2434cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
2435{
2436 struct page **pages =
2437 kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
2438 if (pages)
2439 return cifs_writedata_direct_alloc(pages, complete);
2440
2441 return NULL;
2442}
2443
2444struct cifs_writedata *
2445cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
2446{
2447 struct cifs_writedata *wdata;
2448
2449 wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
2450 if (wdata != NULL) {
2451 wdata->pages = pages;
2452 kref_init(&wdata->refcount);
2453 INIT_LIST_HEAD(&wdata->list);
2454 init_completion(&wdata->done);
2455 INIT_WORK(&wdata->work, complete);
2456 }
2457 return wdata;
2458}
2459
2460
2207static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)2461static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
2208{2462{
2209 struct address_space *mapping = page->mapping;2463 struct address_space *mapping = page->mapping;
@@ -4459,10 +4713,11 @@ static void cifs_readahead(struct readahead_control *ractl) · 2249 unmodified lines
4459 * TODO: Send a whole batch of pages to be read4713 * TODO: Send a whole batch of pages to be read
4460 * by the cache.4714 * by the cache.
4461 */4715 */
4462 page = readahead_page(ractl);4716 struct folio *folio = readahead_folio(ractl);
4463 last_batch_size = 1 << thp_order(page);4717
4718 last_batch_size = folio_nr_pages(folio);
4464 if (cifs_readpage_from_fscache(ractl->mapping->host,4719 if (cifs_readpage_from_fscache(ractl->mapping->host,
4465 page) < 0) {4720 &folio->page) < 0) {
4466 /*4721 /*
4467 * TODO: Deal with cache read failure4722 * TODO: Deal with cache read failure
4468 * here, but for the moment, delegate4723 * here, but for the moment, delegate
@@ -4470,7 +4725,7 @@ static void cifs_readahead(struct readahead_control *ractl) · 1 unmodified line
4470 */4725 */
4471 caching = false;4726 caching = false;
4472 }4727 }
4473 unlock_page(page);4728 folio_unlock(folio);
4474 next_cached++;4729 next_cached++;
4475 cache_nr_pages--;4730 cache_nr_pages--;
4476 if (cache_nr_pages == 0)4731 if (cache_nr_pages == 0)
fs/cifs/inode.c+57−7
@@ -339,6 +339,7 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) · 338 unmodified lines
339 fattr->cf_flags = CIFS_FATTR_DFS_REFERRAL;339 fattr->cf_flags = CIFS_FATTR_DFS_REFERRAL;
340}340}
341 341
342#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
342static int343static int
343cifs_get_file_info_unix(struct file *filp)344cifs_get_file_info_unix(struct file *filp)
344{345{
@@ -432,6 +433,14 @@ int cifs_get_inode_info_unix(struct inode **pinode, · 87 unmodified lines
432cgiiu_exit:433cgiiu_exit:
433 return rc;434 return rc;
434}435}
436#else
437int cifs_get_inode_info_unix(struct inode **pinode,
438 const unsigned char *full_path,
439 struct super_block *sb, unsigned int xid)
440{
441 return -EOPNOTSUPP;
442}
443#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
435 444
436static int445static int
437cifs_sfu_type(struct cifs_fattr *fattr, const char *path,446cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
@@ -795,6 +804,7 @@ static __u64 simple_hashstr(const char *str) · 357 unmodified lines
795 return hash;804 return hash;
796}805}
797 806
807#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
798/**808/**
799 * cifs_backup_query_path_info - SMB1 fallback code to get ino809 * cifs_backup_query_path_info - SMB1 fallback code to get ino
800 *810 *
@@ -847,6 +857,7 @@ cifs_backup_query_path_info(int xid, · 46 unmodified lines
847 *data = (FILE_ALL_INFO *)info.srch_entries_start;857 *data = (FILE_ALL_INFO *)info.srch_entries_start;
848 return 0;858 return 0;
849}859}
860#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
850 861
851static void862static void
852cifs_set_fattr_ino(int xid,863cifs_set_fattr_ino(int xid,
@@ -991,6 +1002,7 @@ cifs_get_inode_info(struct inode **inode, · 138 unmodified lines
991 rc = 0;1002 rc = 0;
992 break;1003 break;
993 case -EACCES:1004 case -EACCES:
1005#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
994 /*1006 /*
995 * perm errors, try again with backup flags if possible1007 * perm errors, try again with backup flags if possible
996 *1008 *
@@ -1022,6 +1034,9 @@ cifs_get_inode_info(struct inode **inode, · 25 unmodified lines
1022 /* nothing we can do, bail out */1034 /* nothing we can do, bail out */
1023 goto out;1035 goto out;
1024 }1036 }
1037#else
1038 goto out;
1039#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1025 break;1040 break;
1026 default:1041 default:
1027 cifs_dbg(FYI, "%s: unhandled err rc %d\n", __func__, rc);1042 cifs_dbg(FYI, "%s: unhandled err rc %d\n", __func__, rc);
@@ -1037,8 +1052,9 @@ cifs_get_inode_info(struct inode **inode, · 9 unmodified lines
1037 /*1052 /*
1038 * 4. Tweak fattr based on mount options1053 * 4. Tweak fattr based on mount options
1039 */1054 */
1040 1055#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1041handle_mnt_opt:1056handle_mnt_opt:
1057#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1042 /* query for SFU type info if supported and needed */1058 /* query for SFU type info if supported and needed */
1043 if (fattr.cf_cifsattrs & ATTR_SYSTEM &&1059 if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
1044 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {1060 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
@@ -1223,7 +1239,7 @@ static const struct inode_operations cifs_ipc_inode_ops = { · 178 unmodified lines
1223static int1239static int
1224cifs_find_inode(struct inode *inode, void *opaque)1240cifs_find_inode(struct inode *inode, void *opaque)
1225{1241{
1226 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;1242 struct cifs_fattr *fattr = opaque;
1227 1243
1228 /* don't match inode with different uniqueid */1244 /* don't match inode with different uniqueid */
1229 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)1245 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
@@ -1247,7 +1263,7 @@ cifs_find_inode(struct inode *inode, void *opaque) · 17 unmodified lines
1247static int1263static int
1248cifs_init_inode(struct inode *inode, void *opaque)1264cifs_init_inode(struct inode *inode, void *opaque)
1249{1265{
1250 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;1266 struct cifs_fattr *fattr = opaque;
1251 1267
1252 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;1268 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
1253 CIFS_I(inode)->createtime = fattr->cf_createtime;1269 CIFS_I(inode)->createtime = fattr->cf_createtime;
@@ -1435,6 +1451,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid, · 181 unmodified lines
1435 return server->ops->set_file_info(inode, full_path, &info_buf, xid);1451 return server->ops->set_file_info(inode, full_path, &info_buf, xid);
1436}1452}
1437 1453
1454#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1438/*1455/*
1439 * Open the given file (if it isn't already), set the DELETE_ON_CLOSE bit1456 * Open the given file (if it isn't already), set the DELETE_ON_CLOSE bit
1440 * and rename it to a random name that hopefully won't conflict with1457 * and rename it to a random name that hopefully won't conflict with
@@ -1565,6 +1582,7 @@ undo_setattr: · 124 unmodified lines
1565 1582
1566 goto out_close;1583 goto out_close;
1567}1584}
1585#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1568 1586
1569/* copied from fs/nfs/dir.c with small changes */1587/* copied from fs/nfs/dir.c with small changes */
1570static void1588static void
@@ -1627,6 +1645,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) · 56 unmodified lines
1627 }1645 }
1628 1646
1629 cifs_close_deferred_file_under_dentry(tcon, full_path);1647 cifs_close_deferred_file_under_dentry(tcon, full_path);
1648#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1630 if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &1649 if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1631 le64_to_cpu(tcon->fsUnixInfo.Capability))) {1650 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1632 rc = CIFSPOSIXDelFile(xid, tcon, full_path,1651 rc = CIFSPOSIXDelFile(xid, tcon, full_path,
@@ -1636,6 +1655,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) · 3 unmodified lines
1636 if ((rc == 0) || (rc == -ENOENT))1655 if ((rc == 0) || (rc == -ENOENT))
1637 goto psx_del_no_retry;1656 goto psx_del_no_retry;
1638 }1657 }
1658#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1639 1659
1640retry_std_delete:1660retry_std_delete:
1641 if (!server->ops->unlink) {1661 if (!server->ops->unlink) {
@@ -1714,9 +1734,11 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, · 72 unmodified lines
1714 1734
1715 if (tcon->posix_extensions)1735 if (tcon->posix_extensions)
1716 rc = smb311_posix_get_inode_info(&inode, full_path, parent->i_sb, xid);1736 rc = smb311_posix_get_inode_info(&inode, full_path, parent->i_sb, xid);
1737#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1717 else if (tcon->unix_ext)1738 else if (tcon->unix_ext)
1718 rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb,1739 rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb,
1719 xid);1740 xid);
1741#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1720 else1742 else
1721 rc = cifs_get_inode_info(&inode, full_path, NULL, parent->i_sb,1743 rc = cifs_get_inode_info(&inode, full_path, NULL, parent->i_sb,
1722 xid, NULL);1744 xid, NULL);
@@ -1746,6 +1768,7 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, · 23 unmodified lines
1746 if (parent->i_mode & S_ISGID)1768 if (parent->i_mode & S_ISGID)
1747 mode |= S_ISGID;1769 mode |= S_ISGID;
1748 1770
1771#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1749 if (tcon->unix_ext) {1772 if (tcon->unix_ext) {
1750 struct cifs_unix_set_info_args args = {1773 struct cifs_unix_set_info_args args = {
1751 .mode = mode,1774 .mode = mode,
@@ -1768,6 +1791,9 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, · 16 unmodified lines
1768 cifs_sb->local_nls,1791 cifs_sb->local_nls,
1769 cifs_remap(cifs_sb));1792 cifs_remap(cifs_sb));
1770 } else {1793 } else {
1794#else
1795 {
1796#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1771 struct TCP_Server_Info *server = tcon->ses->server;1797 struct TCP_Server_Info *server = tcon->ses->server;
1772 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&1798 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1773 (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo)1799 (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo)
@@ -1788,6 +1814,7 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, · 14 unmodified lines
1788 return 0;1814 return 0;
1789}1815}
1790 1816
1817#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1791static int1818static int
1792cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode,1819cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode,
1793 const char *full_path, struct cifs_sb_info *cifs_sb,1820 const char *full_path, struct cifs_sb_info *cifs_sb,
@@ -1850,6 +1877,7 @@ posix_mkdir_get_info: · 56 unmodified lines
1850 xid);1877 xid);
1851 goto posix_mkdir_out;1878 goto posix_mkdir_out;
1852}1879}
1880#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1853 1881
1854int cifs_mkdir(struct user_namespace *mnt_userns, struct inode *inode,1882int cifs_mkdir(struct user_namespace *mnt_userns, struct inode *inode,
1855 struct dentry *direntry, umode_t mode)1883 struct dentry *direntry, umode_t mode)
@@ -1892,6 +1920,7 @@ int cifs_mkdir(struct user_namespace *mnt_userns, struct inode *inode, · 36 unmodified lines
1892 goto mkdir_out;1920 goto mkdir_out;
1893 }1921 }
1894 1922
1923#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1895 if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &1924 if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1896 le64_to_cpu(tcon->fsUnixInfo.Capability))) {1925 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1897 rc = cifs_posix_mkdir(inode, direntry, mode, full_path, cifs_sb,1926 rc = cifs_posix_mkdir(inode, direntry, mode, full_path, cifs_sb,
@@ -1899,6 +1928,7 @@ int cifs_mkdir(struct user_namespace *mnt_userns, struct inode *inode, · 1 unmodified line
1899 if (rc != -EOPNOTSUPP)1928 if (rc != -EOPNOTSUPP)
1900 goto mkdir_out;1929 goto mkdir_out;
1901 }1930 }
1931#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1902 1932
1903 if (!server->ops->mkdir) {1933 if (!server->ops->mkdir) {
1904 rc = -ENOSYS;1934 rc = -ENOSYS;
@@ -2015,9 +2045,12 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, · 110 unmodified lines
2015 struct tcon_link *tlink;2045 struct tcon_link *tlink;
2016 struct cifs_tcon *tcon;2046 struct cifs_tcon *tcon;
2017 struct TCP_Server_Info *server;2047 struct TCP_Server_Info *server;
2048#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
2018 struct cifs_fid fid;2049 struct cifs_fid fid;
2019 struct cifs_open_parms oparms;2050 struct cifs_open_parms oparms;
2020 int oplock, rc;2051 int oplock;
2052#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
2053 int rc;
2021 2054
2022 tlink = cifs_sb_tlink(cifs_sb);2055 tlink = cifs_sb_tlink(cifs_sb);
2023 if (IS_ERR(tlink))2056 if (IS_ERR(tlink))
@@ -2043,6 +2076,7 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, · 19 unmodified lines
2043 if (server->vals->protocol_id != 0)2076 if (server->vals->protocol_id != 0)
2044 goto do_rename_exit;2077 goto do_rename_exit;
2045 2078
2079#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
2046 /* open-file renames don't work across directories */2080 /* open-file renames don't work across directories */
2047 if (to_dentry->d_parent != from_dentry->d_parent)2081 if (to_dentry->d_parent != from_dentry->d_parent)
2048 goto do_rename_exit;2082 goto do_rename_exit;
@@ -2064,6 +2098,7 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, · 15 unmodified lines
2064 cifs_sb->local_nls, cifs_remap(cifs_sb));2098 cifs_sb->local_nls, cifs_remap(cifs_sb));
2065 CIFSSMBClose(xid, tcon, fid.netfid);2099 CIFSSMBClose(xid, tcon, fid.netfid);
2066 }2100 }
2101#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
2067do_rename_exit:2102do_rename_exit:
2068 if (rc == 0)2103 if (rc == 0)
2069 d_move(from_dentry, to_dentry);2104 d_move(from_dentry, to_dentry);
@@ -2081,11 +2116,13 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir, · 11 unmodified lines
2081 struct cifs_sb_info *cifs_sb;2116 struct cifs_sb_info *cifs_sb;
2082 struct tcon_link *tlink;2117 struct tcon_link *tlink;
2083 struct cifs_tcon *tcon;2118 struct cifs_tcon *tcon;
2084 FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
2085 FILE_UNIX_BASIC_INFO *info_buf_target;
2086 unsigned int xid;2119 unsigned int xid;
2087 int rc, tmprc;2120 int rc, tmprc;
2088 int retry_count = 0;2121 int retry_count = 0;
2122 FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
2123#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
2124 FILE_UNIX_BASIC_INFO *info_buf_target;
2125#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
2089 2126
2090 if (flags & ~RENAME_NOREPLACE)2127 if (flags & ~RENAME_NOREPLACE)
2091 return -EINVAL;2128 return -EINVAL;
@@ -2139,6 +2176,7 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir, · 47 unmodified lines
2139 if (flags & RENAME_NOREPLACE)2176 if (flags & RENAME_NOREPLACE)
2140 goto cifs_rename_exit;2177 goto cifs_rename_exit;
2141 2178
2179#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
2142 if (rc == -EEXIST && tcon->unix_ext) {2180 if (rc == -EEXIST && tcon->unix_ext) {
2143 /*2181 /*
2144 * Are src and dst hardlinks of same inode? We can only tell2182 * Are src and dst hardlinks of same inode? We can only tell
@@ -2178,6 +2216,8 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir, · 33 unmodified lines
2178 */2216 */
2179 2217
2180unlink_target:2218unlink_target:
2219#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
2220
2181 /* Try unlinking the target dentry if it's not negative */2221 /* Try unlinking the target dentry if it's not negative */
2182 if (d_really_is_positive(target_dentry) && (rc == -EACCES || rc == -EEXIST)) {2222 if (d_really_is_positive(target_dentry) && (rc == -EACCES || rc == -EEXIST)) {
2183 if (d_is_dir(target_dentry))2223 if (d_is_dir(target_dentry))
@@ -2337,14 +2377,18 @@ int cifs_revalidate_file_attr(struct file *filp) · 153 unmodified lines
2337{2377{
2338 int rc = 0;2378 int rc = 0;
2339 struct dentry *dentry = file_dentry(filp);2379 struct dentry *dentry = file_dentry(filp);
2380#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
2340 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;2381 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
2382#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
2341 2383
2342 if (!cifs_dentry_needs_reval(dentry))2384 if (!cifs_dentry_needs_reval(dentry))
2343 return rc;2385 return rc;
2344 2386
2387#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
2345 if (tlink_tcon(cfile->tlink)->unix_ext)2388 if (tlink_tcon(cfile->tlink)->unix_ext)
2346 rc = cifs_get_file_info_unix(filp);2389 rc = cifs_get_file_info_unix(filp);
2347 else2390 else
2391#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
2348 rc = cifs_get_file_info(filp);2392 rc = cifs_get_file_info(filp);
2349 2393
2350 return rc;2394 return rc;
@@ -2653,6 +2697,7 @@ set_size_out: · 302 unmodified lines
2653 return rc;2697 return rc;
2654}2698}
2655 2699
2700#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
2656static int2701static int
2657cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)2702cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
2658{2703{
@@ -2800,6 +2845,7 @@ out: · 141 unmodified lines
2800 free_xid(xid);2845 free_xid(xid);
2801 return rc;2846 return rc;
2802}2847}
2848#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
2803 2849
2804static int2850static int
2805cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)2851cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
@@ -2995,16 +3041,20 @@ cifs_setattr(struct user_namespace *mnt_userns, struct dentry *direntry, · 189 unmodified lines
2995 struct iattr *attrs)3041 struct iattr *attrs)
2996{3042{
2997 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);3043 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
2998 struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
2999 int rc, retries = 0;3044 int rc, retries = 0;
3045#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
3046 struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
3047#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
3000 3048
3001 if (unlikely(cifs_forced_shutdown(cifs_sb)))3049 if (unlikely(cifs_forced_shutdown(cifs_sb)))
3002 return -EIO;3050 return -EIO;
3003 3051
3004 do {3052 do {
3053#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
3005 if (pTcon->unix_ext)3054 if (pTcon->unix_ext)
3006 rc = cifs_setattr_unix(direntry, attrs);3055 rc = cifs_setattr_unix(direntry, attrs);
3007 else3056 else
3057#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
3008 rc = cifs_setattr_nounix(direntry, attrs);3058 rc = cifs_setattr_nounix(direntry, attrs);
3009 retries++;3059 retries++;
3010 } while (is_retryable_error(rc) && retries < 2);3060 } while (is_retryable_error(rc) && retries < 2);
fs/cifs/ioctl.c+2−0
@@ -333,6 +333,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) · 332 unmodified lines
333 tcon = tlink_tcon(pSMBFile->tlink);333 tcon = tlink_tcon(pSMBFile->tlink);
334 caps = le64_to_cpu(tcon->fsUnixInfo.Capability);334 caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
335#ifdef CONFIG_CIFS_POSIX335#ifdef CONFIG_CIFS_POSIX
336#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
336 if (CIFS_UNIX_EXTATTR_CAP & caps) {337 if (CIFS_UNIX_EXTATTR_CAP & caps) {
337 __u64 ExtAttrMask = 0;338 __u64 ExtAttrMask = 0;
338 rc = CIFSGetExtAttr(xid, tcon,339 rc = CIFSGetExtAttr(xid, tcon,
@@ -345,6 +346,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) · 6 unmodified lines
345 if (rc != EOPNOTSUPP)346 if (rc != EOPNOTSUPP)
346 break;347 break;
347 }348 }
349#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
348#endif /* CONFIG_CIFS_POSIX */350#endif /* CONFIG_CIFS_POSIX */
349 rc = 0;351 rc = 0;
350 if (CIFS_I(inode)->cifsAttrs & ATTR_COMPRESSED) {352 if (CIFS_I(inode)->cifsAttrs & ATTR_COMPRESSED) {
fs/cifs/link.c+8−0
@@ -286,6 +286,7 @@ out: · 285 unmodified lines
286 return rc;286 return rc;
287}287}
288 288
289#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
289/*290/*
290 * SMB 1.0 Protocol specific functions291 * SMB 1.0 Protocol specific functions
291 */292 */
@@ -368,6 +369,7 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, · 76 unmodified lines
368 CIFSSMBClose(xid, tcon, fid.netfid);369 CIFSSMBClose(xid, tcon, fid.netfid);
369 return rc;370 return rc;
370}371}
372#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
371 373
372/*374/*
373 * SMB 2.1/SMB3 Protocol specific functions375 * SMB 2.1/SMB3 Protocol specific functions
@@ -532,11 +534,15 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, · 158 unmodified lines
532 goto cifs_hl_exit;534 goto cifs_hl_exit;
533 }535 }
534 536
537#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
535 if (tcon->unix_ext)538 if (tcon->unix_ext)
536 rc = CIFSUnixCreateHardLink(xid, tcon, from_name, to_name,539 rc = CIFSUnixCreateHardLink(xid, tcon, from_name, to_name,
537 cifs_sb->local_nls,540 cifs_sb->local_nls,
538 cifs_remap(cifs_sb));541 cifs_remap(cifs_sb));
539 else {542 else {
543#else
544 {
545#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
540 server = tcon->ses->server;546 server = tcon->ses->server;
541 if (!server->ops->create_hardlink) {547 if (!server->ops->create_hardlink) {
542 rc = -ENOSYS;548 rc = -ENOSYS;
@@ -704,10 +710,12 @@ cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode, · 161 unmodified lines
704 /* BB what if DFS and this volume is on different share? BB */710 /* BB what if DFS and this volume is on different share? BB */
705 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)711 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
706 rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname);712 rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname);
713#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
707 else if (pTcon->unix_ext)714 else if (pTcon->unix_ext)
708 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,715 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
709 cifs_sb->local_nls,716 cifs_sb->local_nls,
710 cifs_remap(cifs_sb));717 cifs_remap(cifs_sb));
718#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
711 /* else719 /* else
712 rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,720 rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,
713 cifs_sb_target->local_nls); */721 cifs_sb_target->local_nls); */
fs/cifs/misc.c+13−20
@@ -69,6 +69,7 @@ sesInfoAlloc(void) · 68 unmodified lines
69 ret_buf = kzalloc(sizeof(struct cifs_ses), GFP_KERNEL);69 ret_buf = kzalloc(sizeof(struct cifs_ses), GFP_KERNEL);
70 if (ret_buf) {70 if (ret_buf) {
71 atomic_inc(&sesInfoAllocCount);71 atomic_inc(&sesInfoAllocCount);
72 spin_lock_init(&ret_buf->ses_lock);
72 ret_buf->ses_status = SES_NEW;73 ret_buf->ses_status = SES_NEW;
73 ++ret_buf->ses_count;74 ++ret_buf->ses_count;
74 INIT_LIST_HEAD(&ret_buf->smb_ses_list);75 INIT_LIST_HEAD(&ret_buf->smb_ses_list);
@@ -126,6 +127,7 @@ tconInfoAlloc(void) · 51 unmodified lines
126 atomic_inc(&tconInfoAllocCount);127 atomic_inc(&tconInfoAllocCount);
127 ret_buf->status = TID_NEW;128 ret_buf->status = TID_NEW;
128 ++ret_buf->tc_count;129 ++ret_buf->tc_count;
130 spin_lock_init(&ret_buf->tc_lock);
129 INIT_LIST_HEAD(&ret_buf->openFileList);131 INIT_LIST_HEAD(&ret_buf->openFileList);
130 INIT_LIST_HEAD(&ret_buf->tcon_list);132 INIT_LIST_HEAD(&ret_buf->tcon_list);
131 spin_lock_init(&ret_buf->open_file_lock);133 spin_lock_init(&ret_buf->open_file_lock);
@@ -172,9 +174,9 @@ cifs_buf_get(void) · 40 unmodified lines
172 /* clear the first few header bytes */174 /* clear the first few header bytes */
173 /* for most paths, more is cleared in header_assemble */175 /* for most paths, more is cleared in header_assemble */
174 memset(ret_buf, 0, buf_size + 3);176 memset(ret_buf, 0, buf_size + 3);
175 atomic_inc(&bufAllocCount);177 atomic_inc(&buf_alloc_count);
176#ifdef CONFIG_CIFS_STATS2178#ifdef CONFIG_CIFS_STATS2
177 atomic_inc(&totBufAllocCount);179 atomic_inc(&total_buf_alloc_count);
178#endif /* CONFIG_CIFS_STATS2 */180#endif /* CONFIG_CIFS_STATS2 */
179 181
180 return ret_buf;182 return ret_buf;
@@ -189,7 +191,7 @@ cifs_buf_release(void *buf_to_free) · 8 unmodified lines
189 }191 }
190 mempool_free(buf_to_free, cifs_req_poolp);192 mempool_free(buf_to_free, cifs_req_poolp);
191 193
192 atomic_dec(&bufAllocCount);194 atomic_dec(&buf_alloc_count);
193 return;195 return;
194}196}
195 197
@@ -205,9 +207,9 @@ cifs_small_buf_get(void) · 9 unmodified lines
205 ret_buf = mempool_alloc(cifs_sm_req_poolp, GFP_NOFS);207 ret_buf = mempool_alloc(cifs_sm_req_poolp, GFP_NOFS);
206 /* No need to clear memory here, cleared in header assemble */208 /* No need to clear memory here, cleared in header assemble */
207 /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/209 /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
208 atomic_inc(&smBufAllocCount);210 atomic_inc(&small_buf_alloc_count);
209#ifdef CONFIG_CIFS_STATS2211#ifdef CONFIG_CIFS_STATS2
210 atomic_inc(&totSmBufAllocCount);212 atomic_inc(&total_small_buf_alloc_count);
211#endif /* CONFIG_CIFS_STATS2 */213#endif /* CONFIG_CIFS_STATS2 */
212 214
213 return ret_buf;215 return ret_buf;
@@ -223,7 +225,7 @@ cifs_small_buf_release(void *buf_to_free) · 9 unmodified lines
223 }225 }
224 mempool_free(buf_to_free, cifs_sm_req_poolp);226 mempool_free(buf_to_free, cifs_sm_req_poolp);
225 227
226 atomic_dec(&smBufAllocCount);228 atomic_dec(&small_buf_alloc_count);
227 return;229 return;
228}230}
229 231
@@ -400,7 +402,6 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) · 170 unmodified lines
400{402{
401 struct smb_hdr *buf = (struct smb_hdr *)buffer;403 struct smb_hdr *buf = (struct smb_hdr *)buffer;
402 struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;404 struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
403 struct list_head *tmp, *tmp1, *tmp2;
404 struct cifs_ses *ses;405 struct cifs_ses *ses;
405 struct cifs_tcon *tcon;406 struct cifs_tcon *tcon;
406 struct cifsInodeInfo *pCifsInode;407 struct cifsInodeInfo *pCifsInode;
@@ -467,18 +468,14 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) · 60 unmodified lines
467 468
468 /* look up tcon based on tid & uid */469 /* look up tcon based on tid & uid */
469 spin_lock(&cifs_tcp_ses_lock);470 spin_lock(&cifs_tcp_ses_lock);
470 list_for_each(tmp, &srv->smb_ses_list) {471 list_for_each_entry(ses, &srv->smb_ses_list, smb_ses_list) {
471 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);472 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
472 list_for_each(tmp1, &ses->tcon_list) {
473 tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
474 if (tcon->tid != buf->Tid)473 if (tcon->tid != buf->Tid)
475 continue;474 continue;
476 475
477 cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);476 cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
478 spin_lock(&tcon->open_file_lock);477 spin_lock(&tcon->open_file_lock);
479 list_for_each(tmp2, &tcon->openFileList) {478 list_for_each_entry(netfile, &tcon->openFileList, tlist) {
480 netfile = list_entry(tmp2, struct cifsFileInfo,
481 tlist);
482 if (pSMB->Fid != netfile->fid.netfid)479 if (pSMB->Fid != netfile->fid.netfid)
483 continue;480 continue;
484 481
@@ -763,14 +760,12 @@ void · 278 unmodified lines
763cifs_close_all_deferred_files(struct cifs_tcon *tcon)760cifs_close_all_deferred_files(struct cifs_tcon *tcon)
764{761{
765 struct cifsFileInfo *cfile;762 struct cifsFileInfo *cfile;
766 struct list_head *tmp;
767 struct file_list *tmp_list, *tmp_next_list;763 struct file_list *tmp_list, *tmp_next_list;
768 struct list_head file_head;764 struct list_head file_head;
769 765
770 INIT_LIST_HEAD(&file_head);766 INIT_LIST_HEAD(&file_head);
771 spin_lock(&tcon->open_file_lock);767 spin_lock(&tcon->open_file_lock);
772 list_for_each(tmp, &tcon->openFileList) {768 list_for_each_entry(cfile, &tcon->openFileList, tlist) {
773 cfile = list_entry(tmp, struct cifsFileInfo, tlist);
774 if (delayed_work_pending(&cfile->deferred)) {769 if (delayed_work_pending(&cfile->deferred)) {
775 if (cancel_delayed_work(&cfile->deferred)) {770 if (cancel_delayed_work(&cfile->deferred)) {
776 tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);771 tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
@@ -793,7 +788,6 @@ void · 16 unmodified lines
793cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)788cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
794{789{
795 struct cifsFileInfo *cfile;790 struct cifsFileInfo *cfile;
796 struct list_head *tmp;
797 struct file_list *tmp_list, *tmp_next_list;791 struct file_list *tmp_list, *tmp_next_list;
798 struct list_head file_head;792 struct list_head file_head;
799 void *page;793 void *page;
@@ -802,8 +796,7 @@ cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path) · 2 unmodified lines
802 INIT_LIST_HEAD(&file_head);796 INIT_LIST_HEAD(&file_head);
803 page = alloc_dentry_path();797 page = alloc_dentry_path();
804 spin_lock(&tcon->open_file_lock);798 spin_lock(&tcon->open_file_lock);
805 list_for_each(tmp, &tcon->openFileList) {799 list_for_each_entry(cfile, &tcon->openFileList, tlist) {
806 cfile = list_entry(tmp, struct cifsFileInfo, tlist);
807 full_path = build_path_from_dentry(cfile->dentry, page);800 full_path = build_path_from_dentry(cfile->dentry, page);
808 if (strstr(full_path, path)) {801 if (strstr(full_path, path)) {
809 if (delayed_work_pending(&cfile->deferred)) {802 if (delayed_work_pending(&cfile->deferred)) {
fs/cifs/netmisc.c+1−1
@@ -911,7 +911,7 @@ map_and_check_smb_error(struct mid_q_entry *mid, bool logErr) · 910 unmodified lines
911unsigned int911unsigned int
912smbCalcSize(void *buf, struct TCP_Server_Info *server)912smbCalcSize(void *buf, struct TCP_Server_Info *server)
913{913{
914 struct smb_hdr *ptr = (struct smb_hdr *)buf;914 struct smb_hdr *ptr = buf;
915 return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +915 return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
916 2 /* size of the bcc field */ + get_bcc(ptr));916 2 /* size of the bcc field */ + get_bcc(ptr));
917}917}
fs/cifs/sess.c+4−1
@@ -499,6 +499,7 @@ out: · 498 unmodified lines
499 return rc;499 return rc;
500}500}
501 501
502#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
502static __u32 cifs_ssetup_hdr(struct cifs_ses *ses,503static __u32 cifs_ssetup_hdr(struct cifs_ses *ses,
503 struct TCP_Server_Info *server,504 struct TCP_Server_Info *server,
504 SESSION_SETUP_ANDX *pSMB)505 SESSION_SETUP_ANDX *pSMB)
@@ -591,7 +592,6 @@ static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses, · 86 unmodified lines
591 *pbcc_area = bcc_ptr;592 *pbcc_area = bcc_ptr;
592}593}
593 594
594
595static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,595static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
596 const struct nls_table *nls_cp)596 const struct nls_table *nls_cp)
597{597{
@@ -753,6 +753,7 @@ static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft, · 155 unmodified lines
753 for it later, but it is not very important */753 for it later, but it is not very important */
754 cifs_dbg(FYI, "ascii: bytes left %d\n", bleft);754 cifs_dbg(FYI, "ascii: bytes left %d\n", bleft);
755}755}
756#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
756 757
757int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,758int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
758 struct cifs_ses *ses)759 struct cifs_ses *ses)
@@ -1170,6 +1171,7 @@ struct sess_data { · 411 unmodified lines
1170 struct kvec iov[3];1171 struct kvec iov[3];
1171};1172};
1172 1173
1174#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1173static int1175static int
1174sess_alloc_buffer(struct sess_data *sess_data, int wct)1176sess_alloc_buffer(struct sess_data *sess_data, int wct)
1175{1177{
@@ -1846,3 +1848,4 @@ out: · 670 unmodified lines
1846 kfree(sess_data);1848 kfree(sess_data);
1847 return rc;1849 return rc;
1848}1850}
1851#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
fs/cifs/smb1ops.c+5−5
@@ -92,17 +92,17 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buffer) · 91 unmodified lines
92 struct smb_hdr *buf = (struct smb_hdr *)buffer;92 struct smb_hdr *buf = (struct smb_hdr *)buffer;
93 struct mid_q_entry *mid;93 struct mid_q_entry *mid;
94 94
95 spin_lock(&GlobalMid_Lock);95 spin_lock(&server->mid_lock);
96 list_for_each_entry(mid, &server->pending_mid_q, qhead) {96 list_for_each_entry(mid, &server->pending_mid_q, qhead) {
97 if (compare_mid(mid->mid, buf) &&97 if (compare_mid(mid->mid, buf) &&
98 mid->mid_state == MID_REQUEST_SUBMITTED &&98 mid->mid_state == MID_REQUEST_SUBMITTED &&
99 le16_to_cpu(mid->command) == buf->Command) {99 le16_to_cpu(mid->command) == buf->Command) {
100 kref_get(&mid->refcount);100 kref_get(&mid->refcount);
101 spin_unlock(&GlobalMid_Lock);101 spin_unlock(&server->mid_lock);
102 return mid;102 return mid;
103 }103 }
104 }104 }
105 spin_unlock(&GlobalMid_Lock);105 spin_unlock(&server->mid_lock);
106 return NULL;106 return NULL;
107}107}
108 108
@@ -166,7 +166,7 @@ cifs_get_next_mid(struct TCP_Server_Info *server) · 57 unmodified lines
166 __u16 last_mid, cur_mid;166 __u16 last_mid, cur_mid;
167 bool collision, reconnect = false;167 bool collision, reconnect = false;
168 168
169 spin_lock(&GlobalMid_Lock);169 spin_lock(&server->mid_lock);
170 170
171 /* mid is 16 bit only for CIFS/SMB */171 /* mid is 16 bit only for CIFS/SMB */
172 cur_mid = (__u16)((server->CurrentMid) & 0xffff);172 cur_mid = (__u16)((server->CurrentMid) & 0xffff);
@@ -225,7 +225,7 @@ cifs_get_next_mid(struct TCP_Server_Info *server) · 52 unmodified lines
225 }225 }
226 cur_mid++;226 cur_mid++;
227 }227 }
228 spin_unlock(&GlobalMid_Lock);228 spin_unlock(&server->mid_lock);
229 229
230 if (reconnect) {230 if (reconnect) {
231 cifs_signal_cifsd_for_reconnect(server, false);231 cifs_signal_cifsd_for_reconnect(server, false);
fs/cifs/smb2misc.c+29−20
@@ -132,15 +132,15 @@ static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len, · 131 unmodified lines
132}132}
133 133
134int134int
135smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)135smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
136{136{
137 struct smb2_hdr *shdr = (struct smb2_hdr *)buf;137 struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
138 struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;138 struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;
139 __u64 mid;
140 __u32 clc_len; /* calculated length */
141 int command;
142 int pdu_size = sizeof(struct smb2_pdu);
143 int hdr_size = sizeof(struct smb2_hdr);139 int hdr_size = sizeof(struct smb2_hdr);
140 int pdu_size = sizeof(struct smb2_pdu);
141 int command;
142 __u32 calc_len; /* calculated length */
143 __u64 mid;
144 144
145 /*145 /*
146 * Add function to do table lookup of StructureSize by command146 * Add function to do table lookup of StructureSize by command
@@ -154,7 +154,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr) · 7 unmodified lines
154 154
155 /* decrypt frame now that it is completely read in */155 /* decrypt frame now that it is completely read in */
156 spin_lock(&cifs_tcp_ses_lock);156 spin_lock(&cifs_tcp_ses_lock);
157 list_for_each_entry(iter, &srvr->smb_ses_list, smb_ses_list) {157 list_for_each_entry(iter, &server->smb_ses_list, smb_ses_list) {
158 if (iter->Suid == le64_to_cpu(thdr->SessionId)) {158 if (iter->Suid == le64_to_cpu(thdr->SessionId)) {
159 ses = iter;159 ses = iter;
160 break;160 break;
@@ -221,30 +221,33 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr) · 60 unmodified lines
221 }221 }
222 }222 }
223 223
224 clc_len = smb2_calc_size(buf, srvr);224 calc_len = smb2_calc_size(buf, server);
225
226 /* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
227 * be 0, and not a real miscalculation */
228 if (command == SMB2_IOCTL_HE && calc_len == 0)
229 return 0;
225 230
226 if (shdr->Command == SMB2_NEGOTIATE)231 if (command == SMB2_NEGOTIATE_HE)
227 clc_len += get_neg_ctxt_len(shdr, len, clc_len);232 calc_len += get_neg_ctxt_len(shdr, len, calc_len);
228 233
229 if (len != clc_len) {234 if (len != calc_len) {
230 cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
231 clc_len, len, mid);
232 /* create failed on symlink */235 /* create failed on symlink */
233 if (command == SMB2_CREATE_HE &&236 if (command == SMB2_CREATE_HE &&
234 shdr->Status == STATUS_STOPPED_ON_SYMLINK)237 shdr->Status == STATUS_STOPPED_ON_SYMLINK)
235 return 0;238 return 0;
236 /* Windows 7 server returns 24 bytes more */239 /* Windows 7 server returns 24 bytes more */
237 if (clc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)240 if (calc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)
238 return 0;241 return 0;
239 /* server can return one byte more due to implied bcc[0] */242 /* server can return one byte more due to implied bcc[0] */
240 if (clc_len == len + 1)243 if (calc_len == len + 1)
241 return 0;244 return 0;
242 245
243 /*246 /*
244 * Some windows servers (win2016) will pad also the final247 * Some windows servers (win2016) will pad also the final
245 * PDU in a compound to 8 bytes.248 * PDU in a compound to 8 bytes.
246 */249 */
247 if (((clc_len + 7) & ~7) == len)250 if (((calc_len + 7) & ~7) == len)
248 return 0;251 return 0;
249 252
250 /*253 /*
@@ -253,12 +256,18 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr) · 2 unmodified lines
253 * SMB2/SMB3 frame length (header + smb2 response specific data)256 * SMB2/SMB3 frame length (header + smb2 response specific data)
254 * Some windows servers also pad up to 8 bytes when compounding.257 * Some windows servers also pad up to 8 bytes when compounding.
255 */258 */
256 if (clc_len < len)259 if (calc_len < len)
257 return 0;260 return 0;
258 261
259 pr_warn_once(262 /* Only log a message if len was really miscalculated */
260 "srv rsp too short, len %d not %d. cmd:%d mid:%llu\n",263 if (unlikely(cifsFYI))
261 len, clc_len, command, mid);264 cifs_dbg(FYI, "Server response too short: calculated "
265 "length %u doesn't match read length %u (cmd=%d, mid=%llu)\n",
266 calc_len, len, command, mid);
267 else
268 pr_warn("Server response too short: calculated length "
269 "%u doesn't match read length %u (cmd=%d, mid=%llu)\n",
270 calc_len, len, command, mid);
262 271
263 return 1;272 return 1;
264 }273 }
@@ -402,7 +411,7 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr) · 137 unmodified lines
402unsigned int411unsigned int
403smb2_calc_size(void *buf, struct TCP_Server_Info *srvr)412smb2_calc_size(void *buf, struct TCP_Server_Info *srvr)
404{413{
405 struct smb2_pdu *pdu = (struct smb2_pdu *)buf;414 struct smb2_pdu *pdu = buf;
406 struct smb2_hdr *shdr = &pdu->hdr;415 struct smb2_hdr *shdr = &pdu->hdr;
407 int offset; /* the offset from the beginning of SMB to data area */416 int offset; /* the offset from the beginning of SMB to data area */
408 int data_length; /* the length of the variable length data area */417 int data_length; /* the length of the variable length data area */
fs/cifs/smb2ops.c+32−29
@@ -126,13 +126,13 @@ smb2_add_credits(struct TCP_Server_Info *server, · 125 unmodified lines
126 optype, scredits, add);126 optype, scredits, add);
127 }127 }
128 128
129 spin_lock(&cifs_tcp_ses_lock);129 spin_lock(&server->srv_lock);
130 if (server->tcpStatus == CifsNeedReconnect130 if (server->tcpStatus == CifsNeedReconnect
131 || server->tcpStatus == CifsExiting) {131 || server->tcpStatus == CifsExiting) {
132 spin_unlock(&cifs_tcp_ses_lock);132 spin_unlock(&server->srv_lock);
133 return;133 return;
134 }134 }
135 spin_unlock(&cifs_tcp_ses_lock);135 spin_unlock(&server->srv_lock);
136 136
137 switch (rc) {137 switch (rc) {
138 case -1:138 case -1:
@@ -218,12 +218,12 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, · 79 unmodified lines
218 spin_lock(&server->req_lock);218 spin_lock(&server->req_lock);
219 } else {219 } else {
220 spin_unlock(&server->req_lock);220 spin_unlock(&server->req_lock);
221 spin_lock(&cifs_tcp_ses_lock);221 spin_lock(&server->srv_lock);
222 if (server->tcpStatus == CifsExiting) {222 if (server->tcpStatus == CifsExiting) {
223 spin_unlock(&cifs_tcp_ses_lock);223 spin_unlock(&server->srv_lock);
224 return -ENOENT;224 return -ENOENT;
225 }225 }
226 spin_unlock(&cifs_tcp_ses_lock);226 spin_unlock(&server->srv_lock);
227 227
228 spin_lock(&server->req_lock);228 spin_lock(&server->req_lock);
229 scredits = server->credits;229 scredits = server->credits;
@@ -319,19 +319,19 @@ smb2_get_next_mid(struct TCP_Server_Info *server) · 89 unmodified lines
319{319{
320 __u64 mid;320 __u64 mid;
321 /* for SMB2 we need the current value */321 /* for SMB2 we need the current value */
322 spin_lock(&GlobalMid_Lock);322 spin_lock(&server->mid_lock);
323 mid = server->CurrentMid++;323 mid = server->CurrentMid++;
324 spin_unlock(&GlobalMid_Lock);324 spin_unlock(&server->mid_lock);
325 return mid;325 return mid;
326}326}
327 327
328static void328static void
329smb2_revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)329smb2_revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)
330{330{
331 spin_lock(&GlobalMid_Lock);331 spin_lock(&server->mid_lock);
332 if (server->CurrentMid >= val)332 if (server->CurrentMid >= val)
333 server->CurrentMid -= val;333 server->CurrentMid -= val;
334 spin_unlock(&GlobalMid_Lock);334 spin_unlock(&server->mid_lock);
335}335}
336 336
337static struct mid_q_entry *337static struct mid_q_entry *
@@ -346,7 +346,7 @@ __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue) · 8 unmodified lines
346 return NULL;346 return NULL;
347 }347 }
348 348
349 spin_lock(&GlobalMid_Lock);349 spin_lock(&server->mid_lock);
350 list_for_each_entry(mid, &server->pending_mid_q, qhead) {350 list_for_each_entry(mid, &server->pending_mid_q, qhead) {
351 if ((mid->mid == wire_mid) &&351 if ((mid->mid == wire_mid) &&
352 (mid->mid_state == MID_REQUEST_SUBMITTED) &&352 (mid->mid_state == MID_REQUEST_SUBMITTED) &&
@@ -356,11 +356,11 @@ __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue) · 3 unmodified lines
356 list_del_init(&mid->qhead);356 list_del_init(&mid->qhead);
357 mid->mid_flags |= MID_DELETED;357 mid->mid_flags |= MID_DELETED;
358 }358 }
359 spin_unlock(&GlobalMid_Lock);359 spin_unlock(&server->mid_lock);
360 return mid;360 return mid;
361 }361 }
362 }362 }
363 spin_unlock(&GlobalMid_Lock);363 spin_unlock(&server->mid_lock);
364 return NULL;364 return NULL;
365}365}
366 366
@@ -403,9 +403,9 @@ smb2_negotiate(const unsigned int xid, · 36 unmodified lines
403{403{
404 int rc;404 int rc;
405 405
406 spin_lock(&GlobalMid_Lock);406 spin_lock(&server->mid_lock);
407 server->CurrentMid = 0;407 server->CurrentMid = 0;
408 spin_unlock(&GlobalMid_Lock);408 spin_unlock(&server->mid_lock);
409 rc = SMB2_negotiate(xid, ses, server);409 rc = SMB2_negotiate(xid, ses, server);
410 /* BB we probably don't need to retry with modern servers */410 /* BB we probably don't need to retry with modern servers */
411 if (rc == -EAGAIN)411 if (rc == -EAGAIN)
@@ -1145,9 +1145,7 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size, · 733 unmodified lines
1145 size_t name_len, value_len, user_name_len;1145 size_t name_len, value_len, user_name_len;
1146 1146
1147 while (src_size > 0) {1147 while (src_size > 0) {
1148 name = &src->ea_data[0];
1149 name_len = (size_t)src->ea_name_length;1148 name_len = (size_t)src->ea_name_length;
1150 value = &src->ea_data[src->ea_name_length + 1];
1151 value_len = (size_t)le16_to_cpu(src->ea_value_length);1149 value_len = (size_t)le16_to_cpu(src->ea_value_length);
1152 1150
1153 if (name_len == 0)1151 if (name_len == 0)
@@ -1159,6 +1157,9 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size, · 5 unmodified lines
1159 goto out;1157 goto out;
1160 }1158 }
1161 1159
1160 name = &src->ea_data[0];
1161 value = &src->ea_data[src->ea_name_length + 1];
1162
1162 if (ea_name) {1163 if (ea_name) {
1163 if (ea_name_len == name_len &&1164 if (ea_name_len == name_len &&
1164 memcmp(ea_name, name, name_len) == 0) {1165 memcmp(ea_name, name, name_len) == 0) {
@@ -2574,7 +2575,6 @@ static void · 1409 unmodified lines
2574smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)2575smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)
2575{2576{
2576 struct smb2_hdr *shdr = (struct smb2_hdr *)buf;2577 struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
2577 struct list_head *tmp, *tmp1;
2578 struct cifs_ses *ses;2578 struct cifs_ses *ses;
2579 struct cifs_tcon *tcon;2579 struct cifs_tcon *tcon;
2580 2580
@@ -2582,12 +2582,12 @@ smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server) · 1 unmodified line
2582 return;2582 return;
2583 2583
2584 spin_lock(&cifs_tcp_ses_lock);2584 spin_lock(&cifs_tcp_ses_lock);
2585 list_for_each(tmp, &server->smb_ses_list) {2585 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
2586 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);2586 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
2587 list_for_each(tmp1, &ses->tcon_list) {
2588 tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
2589 if (tcon->tid == le32_to_cpu(shdr->Id.SyncId.TreeId)) {2587 if (tcon->tid == le32_to_cpu(shdr->Id.SyncId.TreeId)) {
2588 spin_lock(&tcon->tc_lock);
2590 tcon->need_reconnect = true;2589 tcon->need_reconnect = true;
2590 spin_unlock(&tcon->tc_lock);
2591 spin_unlock(&cifs_tcp_ses_lock);2591 spin_unlock(&cifs_tcp_ses_lock);
2592 pr_warn_once("Server share %s deleted.\n",2592 pr_warn_once("Server share %s deleted.\n",
2593 tcon->treeName);2593 tcon->treeName);
@@ -4563,9 +4563,11 @@ smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key) · 1969 unmodified lines
4563 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {4563 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
4564 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {4564 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
4565 if (ses->Suid == ses_id) {4565 if (ses->Suid == ses_id) {
4566 spin_lock(&ses->ses_lock);
4566 ses_enc_key = enc ? ses->smb3encryptionkey :4567 ses_enc_key = enc ? ses->smb3encryptionkey :
4567 ses->smb3decryptionkey;4568 ses->smb3decryptionkey;
4568 memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);4569 memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
4570 spin_unlock(&ses->ses_lock);
4569 spin_unlock(&cifs_tcp_ses_lock);4571 spin_unlock(&cifs_tcp_ses_lock);
4570 return 0;4572 return 0;
4571 }4573 }
@@ -5080,23 +5082,24 @@ static void smb2_decrypt_offload(struct work_struct *work) · 508 unmodified lines
5080 5082
5081 mid->callback(mid);5083 mid->callback(mid);
5082 } else {5084 } else {
5083 spin_lock(&cifs_tcp_ses_lock);5085 spin_lock(&dw->server->srv_lock);
5084 spin_lock(&GlobalMid_Lock);
5085 if (dw->server->tcpStatus == CifsNeedReconnect) {5086 if (dw->server->tcpStatus == CifsNeedReconnect) {
5087 spin_lock(&dw->server->mid_lock);
5086 mid->mid_state = MID_RETRY_NEEDED;5088 mid->mid_state = MID_RETRY_NEEDED;
5087 spin_unlock(&GlobalMid_Lock);5089 spin_unlock(&dw->server->mid_lock);
5088 spin_unlock(&cifs_tcp_ses_lock);5090 spin_unlock(&dw->server->srv_lock);
5089 mid->callback(mid);5091 mid->callback(mid);
5090 } else {5092 } else {
5093 spin_lock(&dw->server->mid_lock);
5091 mid->mid_state = MID_REQUEST_SUBMITTED;5094 mid->mid_state = MID_REQUEST_SUBMITTED;
5092 mid->mid_flags &= ~(MID_DELETED);5095 mid->mid_flags &= ~(MID_DELETED);
5093 list_add_tail(&mid->qhead,5096 list_add_tail(&mid->qhead,
5094 &dw->server->pending_mid_q);5097 &dw->server->pending_mid_q);
5095 spin_unlock(&GlobalMid_Lock);5098 spin_unlock(&dw->server->mid_lock);
5096 spin_unlock(&cifs_tcp_ses_lock);5099 spin_unlock(&dw->server->srv_lock);
5097 }5100 }
5098 }5101 }
5099 cifs_mid_q_entry_release(mid);5102 release_mid(mid);
5100 }5103 }
5101 5104
5102free_pages:5105free_pages:
fs/cifs/smb2pdu.c+16−16
@@ -162,7 +162,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, · 161 unmodified lines
162 if (smb2_command == SMB2_TREE_CONNECT || smb2_command == SMB2_IOCTL)162 if (smb2_command == SMB2_TREE_CONNECT || smb2_command == SMB2_IOCTL)
163 return 0;163 return 0;
164 164
165 spin_lock(&cifs_tcp_ses_lock);165 spin_lock(&tcon->tc_lock);
166 if (tcon->status == TID_EXITING) {166 if (tcon->status == TID_EXITING) {
167 /*167 /*
168 * only tree disconnect, open, and write,168 * only tree disconnect, open, and write,
@@ -172,13 +172,13 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, · 3 unmodified lines
172 if ((smb2_command != SMB2_WRITE) &&172 if ((smb2_command != SMB2_WRITE) &&
173 (smb2_command != SMB2_CREATE) &&173 (smb2_command != SMB2_CREATE) &&
174 (smb2_command != SMB2_TREE_DISCONNECT)) {174 (smb2_command != SMB2_TREE_DISCONNECT)) {
175 spin_unlock(&cifs_tcp_ses_lock);175 spin_unlock(&tcon->tc_lock);
176 cifs_dbg(FYI, "can not send cmd %d while umounting\n",176 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
177 smb2_command);177 smb2_command);
178 return -ENODEV;178 return -ENODEV;
179 }179 }
180 }180 }
181 spin_unlock(&cifs_tcp_ses_lock);181 spin_unlock(&tcon->tc_lock);
182 if ((!tcon->ses) || (tcon->ses->ses_status == SES_EXITING) ||182 if ((!tcon->ses) || (tcon->ses->ses_status == SES_EXITING) ||
183 (!tcon->ses->server) || !server)183 (!tcon->ses->server) || !server)
184 return -EIO;184 return -EIO;
@@ -217,12 +217,12 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, · 32 unmodified lines
217 }217 }
218 218
219 /* are we still trying to reconnect? */219 /* are we still trying to reconnect? */
220 spin_lock(&cifs_tcp_ses_lock);220 spin_lock(&server->srv_lock);
221 if (server->tcpStatus != CifsNeedReconnect) {221 if (server->tcpStatus != CifsNeedReconnect) {
222 spin_unlock(&cifs_tcp_ses_lock);222 spin_unlock(&server->srv_lock);
223 break;223 break;
224 }224 }
225 spin_unlock(&cifs_tcp_ses_lock);225 spin_unlock(&server->srv_lock);
226 226
227 if (retries && --retries)227 if (retries && --retries)
228 continue;228 continue;
@@ -256,13 +256,13 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, · 27 unmodified lines
256 * and the server never sends an answer the socket will be closed256 * and the server never sends an answer the socket will be closed
257 * and tcpStatus set to reconnect.257 * and tcpStatus set to reconnect.
258 */258 */
259 spin_lock(&cifs_tcp_ses_lock);259 spin_lock(&server->srv_lock);
260 if (server->tcpStatus == CifsNeedReconnect) {260 if (server->tcpStatus == CifsNeedReconnect) {
261 spin_unlock(&cifs_tcp_ses_lock);261 spin_unlock(&server->srv_lock);
262 rc = -EHOSTDOWN;262 rc = -EHOSTDOWN;
263 goto out;263 goto out;
264 }264 }
265 spin_unlock(&cifs_tcp_ses_lock);265 spin_unlock(&server->srv_lock);
266 266
267 /*267 /*
268 * need to prevent multiple threads trying to simultaneously268 * need to prevent multiple threads trying to simultaneously
@@ -354,7 +354,7 @@ fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon, · 85 unmodified lines
354 void *buf,354 void *buf,
355 unsigned int *total_len)355 unsigned int *total_len)
356{356{
357 struct smb2_pdu *spdu = (struct smb2_pdu *)buf;357 struct smb2_pdu *spdu = buf;
358 /* lookup word count ie StructureSize from table */358 /* lookup word count ie StructureSize from table */
359 __u16 parmsize = smb2_req_struct_sizes[le16_to_cpu(smb2_command)];359 __u16 parmsize = smb2_req_struct_sizes[le16_to_cpu(smb2_command)];
360 360
@@ -3776,7 +3776,7 @@ smb2_echo_callback(struct mid_q_entry *mid) · 3415 unmodified lines
3776 credits.instance = server->reconnect_instance;3776 credits.instance = server->reconnect_instance;
3777 }3777 }
3778 3778
3779 DeleteMidQEntry(mid);3779 release_mid(mid);
3780 add_credits(server, &credits, CIFS_ECHO_OP);3780 add_credits(server, &credits, CIFS_ECHO_OP);
3781}3781}
3782 3782
@@ -3911,15 +3911,15 @@ SMB2_echo(struct TCP_Server_Info *server) · 128 unmodified lines
3911 3911
3912 cifs_dbg(FYI, "In echo request for conn_id %lld\n", server->conn_id);3912 cifs_dbg(FYI, "In echo request for conn_id %lld\n", server->conn_id);
3913 3913
3914 spin_lock(&cifs_tcp_ses_lock);3914 spin_lock(&server->srv_lock);
3915 if (server->ops->need_neg &&3915 if (server->ops->need_neg &&
3916 server->ops->need_neg(server)) {3916 server->ops->need_neg(server)) {
3917 spin_unlock(&cifs_tcp_ses_lock);3917 spin_unlock(&server->srv_lock);
3918 /* No need to send echo on newly established connections */3918 /* No need to send echo on newly established connections */
3919 mod_delayed_work(cifsiod_wq, &server->reconnect, 0);3919 mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
3920 return rc;3920 return rc;
3921 }3921 }
3922 spin_unlock(&cifs_tcp_ses_lock);3922 spin_unlock(&server->srv_lock);
3923 3923
3924 rc = smb2_plain_req_init(SMB2_ECHO, NULL, server,3924 rc = smb2_plain_req_init(SMB2_ECHO, NULL, server,
3925 (void **)&req, &total_len);3925 (void **)&req, &total_len);
@@ -4201,7 +4201,7 @@ smb2_readv_callback(struct mid_q_entry *mid) · 275 unmodified lines
4201 rdata->offset, rdata->got_bytes);4201 rdata->offset, rdata->got_bytes);
4202 4202
4203 queue_work(cifsiod_wq, &rdata->work);4203 queue_work(cifsiod_wq, &rdata->work);
4204 DeleteMidQEntry(mid);4204 release_mid(mid);
4205 add_credits(server, &credits, 0);4205 add_credits(server, &credits, 0);
4206}4206}
4207 4207
@@ -4440,7 +4440,7 @@ smb2_writev_callback(struct mid_q_entry *mid) · 232 unmodified lines
4440 wdata->offset, wdata->bytes);4440 wdata->offset, wdata->bytes);
4441 4441
4442 queue_work(cifsiod_wq, &wdata->work);4442 queue_work(cifsiod_wq, &wdata->work);
4443 DeleteMidQEntry(mid);4443 release_mid(mid);
4444 add_credits(server, &credits, 0);4444 add_credits(server, &credits, 0);
4445}4445}
4446 4446
fs/cifs/smb2transport.c+20−18
@@ -640,13 +640,13 @@ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 639 unmodified lines
640 640
641 if (!is_signed)641 if (!is_signed)
642 return 0;642 return 0;
643 spin_lock(&cifs_tcp_ses_lock);643 spin_lock(&server->srv_lock);
644 if (server->ops->need_neg &&644 if (server->ops->need_neg &&
645 server->ops->need_neg(server)) {645 server->ops->need_neg(server)) {
646 spin_unlock(&cifs_tcp_ses_lock);646 spin_unlock(&server->srv_lock);
647 return 0;647 return 0;
648 }648 }
649 spin_unlock(&cifs_tcp_ses_lock);649 spin_unlock(&server->srv_lock);
650 if (!is_binding && !server->session_estab) {650 if (!is_binding && !server->session_estab) {
651 strncpy(shdr->Signature, "BSRSPYL", 8);651 strncpy(shdr->Signature, "BSRSPYL", 8);
652 return 0;652 return 0;
@@ -750,7 +750,7 @@ smb2_mid_entry_alloc(const struct smb2_hdr *shdr, · 97 unmodified lines
750 temp->callback = cifs_wake_up_task;750 temp->callback = cifs_wake_up_task;
751 temp->callback_data = current;751 temp->callback_data = current;
752 752
753 atomic_inc(&midCount);753 atomic_inc(&mid_count);
754 temp->mid_state = MID_REQUEST_ALLOCATED;754 temp->mid_state = MID_REQUEST_ALLOCATED;
755 trace_smb3_cmd_enter(le32_to_cpu(shdr->Id.SyncId.TreeId),755 trace_smb3_cmd_enter(le32_to_cpu(shdr->Id.SyncId.TreeId),
756 le64_to_cpu(shdr->SessionId),756 le64_to_cpu(shdr->SessionId),
@@ -762,28 +762,30 @@ static int · 5 unmodified lines
762smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,762smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
763 struct smb2_hdr *shdr, struct mid_q_entry **mid)763 struct smb2_hdr *shdr, struct mid_q_entry **mid)
764{764{
765 spin_lock(&cifs_tcp_ses_lock);765 spin_lock(&server->srv_lock);
766 if (server->tcpStatus == CifsExiting) {766 if (server->tcpStatus == CifsExiting) {
767 spin_unlock(&cifs_tcp_ses_lock);767 spin_unlock(&server->srv_lock);
768 return -ENOENT;768 return -ENOENT;
769 }769 }
770 770
771 if (server->tcpStatus == CifsNeedReconnect) {771 if (server->tcpStatus == CifsNeedReconnect) {
772 spin_unlock(&cifs_tcp_ses_lock);772 spin_unlock(&server->srv_lock);
773 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");773 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
774 return -EAGAIN;774 return -EAGAIN;
775 }775 }
776 776
777 if (server->tcpStatus == CifsNeedNegotiate &&777 if (server->tcpStatus == CifsNeedNegotiate &&
778 shdr->Command != SMB2_NEGOTIATE) {778 shdr->Command != SMB2_NEGOTIATE) {
779 spin_unlock(&cifs_tcp_ses_lock);779 spin_unlock(&server->srv_lock);
780 return -EAGAIN;780 return -EAGAIN;
781 }781 }
782 spin_unlock(&server->srv_lock);
782 783
784 spin_lock(&ses->ses_lock);
783 if (ses->ses_status == SES_NEW) {785 if (ses->ses_status == SES_NEW) {
784 if ((shdr->Command != SMB2_SESSION_SETUP) &&786 if ((shdr->Command != SMB2_SESSION_SETUP) &&
785 (shdr->Command != SMB2_NEGOTIATE)) {787 (shdr->Command != SMB2_NEGOTIATE)) {
786 spin_unlock(&cifs_tcp_ses_lock);788 spin_unlock(&ses->ses_lock);
787 return -EAGAIN;789 return -EAGAIN;
788 }790 }
789 /* else ok - we are setting up session */791 /* else ok - we are setting up session */
@@ -791,19 +793,19 @@ smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server, · 1 unmodified line
791 793
792 if (ses->ses_status == SES_EXITING) {794 if (ses->ses_status == SES_EXITING) {
793 if (shdr->Command != SMB2_LOGOFF) {795 if (shdr->Command != SMB2_LOGOFF) {
794 spin_unlock(&cifs_tcp_ses_lock);796 spin_unlock(&ses->ses_lock);
795 return -EAGAIN;797 return -EAGAIN;
796 }798 }
797 /* else ok - we are shutting down the session */799 /* else ok - we are shutting down the session */
798 }800 }
799 spin_unlock(&cifs_tcp_ses_lock);801 spin_unlock(&ses->ses_lock);
800 802
801 *mid = smb2_mid_entry_alloc(shdr, server);803 *mid = smb2_mid_entry_alloc(shdr, server);
802 if (*mid == NULL)804 if (*mid == NULL)
803 return -ENOMEM;805 return -ENOMEM;
804 spin_lock(&GlobalMid_Lock);806 spin_lock(&server->mid_lock);
805 list_add_tail(&(*mid)->qhead, &server->pending_mid_q);807 list_add_tail(&(*mid)->qhead, &server->pending_mid_q);
806 spin_unlock(&GlobalMid_Lock);808 spin_unlock(&server->mid_lock);
807 809
808 return 0;810 return 0;
809}811}
@@ -854,7 +856,7 @@ smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server, · 44 unmodified lines
854 rc = smb2_sign_rqst(rqst, server);856 rc = smb2_sign_rqst(rqst, server);
855 if (rc) {857 if (rc) {
856 revert_current_mid_from_hdr(server, shdr);858 revert_current_mid_from_hdr(server, shdr);
857 cifs_delete_mid(mid);859 delete_mid(mid);
858 return ERR_PTR(rc);860 return ERR_PTR(rc);
859 }861 }
860 862
@@ -869,13 +871,13 @@ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst) · 8 unmodified lines
869 (struct smb2_hdr *)rqst->rq_iov[0].iov_base;871 (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
870 struct mid_q_entry *mid;872 struct mid_q_entry *mid;
871 873
872 spin_lock(&cifs_tcp_ses_lock);874 spin_lock(&server->srv_lock);
873 if (server->tcpStatus == CifsNeedNegotiate &&875 if (server->tcpStatus == CifsNeedNegotiate &&
874 shdr->Command != SMB2_NEGOTIATE) {876 shdr->Command != SMB2_NEGOTIATE) {
875 spin_unlock(&cifs_tcp_ses_lock);877 spin_unlock(&server->srv_lock);
876 return ERR_PTR(-EAGAIN);878 return ERR_PTR(-EAGAIN);
877 }879 }
878 spin_unlock(&cifs_tcp_ses_lock);880 spin_unlock(&server->srv_lock);
879 881
880 smb2_seq_num_into_buf(server, shdr);882 smb2_seq_num_into_buf(server, shdr);
881 883
@@ -888,7 +890,7 @@ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst) · 6 unmodified lines
888 rc = smb2_sign_rqst(rqst, server);890 rc = smb2_sign_rqst(rqst, server);
889 if (rc) {891 if (rc) {
890 revert_current_mid_from_hdr(server, shdr);892 revert_current_mid_from_hdr(server, shdr);
891 DeleteMidQEntry(mid);893 release_mid(mid);
892 return ERR_PTR(rc);894 return ERR_PTR(rc);
893 }895 }
894 896
fs/cifs/transport.c+255−79
@@ -21,6 +21,7 @@ · 20 unmodified lines
21#include <asm/processor.h>21#include <asm/processor.h>
22#include <linux/mempool.h>22#include <linux/mempool.h>
23#include <linux/sched/signal.h>23#include <linux/sched/signal.h>
24#include <linux/task_io_accounting_ops.h>
24#include "cifspdu.h"25#include "cifspdu.h"
25#include "cifsglob.h"26#include "cifsglob.h"
26#include "cifsproto.h"27#include "cifsproto.h"
@@ -37,13 +38,13 @@ cifs_wake_up_task(struct mid_q_entry *mid) · 10 unmodified lines
37 wake_up_process(mid->callback_data);38 wake_up_process(mid->callback_data);
38}39}
39 40
40struct mid_q_entry *41static struct mid_q_entry *
41AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)42alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
42{43{
43 struct mid_q_entry *temp;44 struct mid_q_entry *temp;
44 45
45 if (server == NULL) {46 if (server == NULL) {
46 cifs_dbg(VFS, "Null TCP session in AllocMidQEntry\n");47 cifs_dbg(VFS, "%s: null TCP session\n", __func__);
47 return NULL;48 return NULL;
48 }49 }
49 50
@@ -68,12 +69,12 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) · 18 unmodified lines
68 temp->callback = cifs_wake_up_task;69 temp->callback = cifs_wake_up_task;
69 temp->callback_data = current;70 temp->callback_data = current;
70 71
71 atomic_inc(&midCount);72 atomic_inc(&mid_count);
72 temp->mid_state = MID_REQUEST_ALLOCATED;73 temp->mid_state = MID_REQUEST_ALLOCATED;
73 return temp;74 return temp;
74}75}
75 76
76static void _cifs_mid_q_entry_release(struct kref *refcount)77static void __release_mid(struct kref *refcount)
77{78{
78 struct mid_q_entry *midEntry =79 struct mid_q_entry *midEntry =
79 container_of(refcount, struct mid_q_entry, refcount);80 container_of(refcount, struct mid_q_entry, refcount);
@@ -91,7 +92,7 @@ static void _cifs_mid_q_entry_release(struct kref *refcount) · 11 unmodified lines
91 server->ops->handle_cancelled_mid(midEntry, server);92 server->ops->handle_cancelled_mid(midEntry, server);
92 93
93 midEntry->mid_state = MID_FREE;94 midEntry->mid_state = MID_FREE;
94 atomic_dec(&midCount);95 atomic_dec(&mid_count);
95 if (midEntry->large_buf)96 if (midEntry->large_buf)
96 cifs_buf_release(midEntry->resp_buf);97 cifs_buf_release(midEntry->resp_buf);
97 else98 else
@@ -152,29 +153,26 @@ static void _cifs_mid_q_entry_release(struct kref *refcount) · 54 unmodified lines
152 mempool_free(midEntry, cifs_mid_poolp);153 mempool_free(midEntry, cifs_mid_poolp);
153}154}
154 155
155void cifs_mid_q_entry_release(struct mid_q_entry *midEntry)156void release_mid(struct mid_q_entry *mid)
156{157{
157 spin_lock(&GlobalMid_Lock);158 struct TCP_Server_Info *server = mid->server;
158 kref_put(&midEntry->refcount, _cifs_mid_q_entry_release);
159 spin_unlock(&GlobalMid_Lock);
160}
161 159
162void DeleteMidQEntry(struct mid_q_entry *midEntry)160 spin_lock(&server->mid_lock);
163{161 kref_put(&mid->refcount, __release_mid);
164 cifs_mid_q_entry_release(midEntry);162 spin_unlock(&server->mid_lock);
165}163}
166 164
167void165void
168cifs_delete_mid(struct mid_q_entry *mid)166delete_mid(struct mid_q_entry *mid)
169{167{
170 spin_lock(&GlobalMid_Lock);168 spin_lock(&mid->server->mid_lock);
171 if (!(mid->mid_flags & MID_DELETED)) {169 if (!(mid->mid_flags & MID_DELETED)) {
172 list_del_init(&mid->qhead);170 list_del_init(&mid->qhead);
173 mid->mid_flags |= MID_DELETED;171 mid->mid_flags |= MID_DELETED;
174 }172 }
175 spin_unlock(&GlobalMid_Lock);173 spin_unlock(&mid->server->mid_lock);
176 174
177 DeleteMidQEntry(mid);175 release_mid(mid);
178}176}
179 177
180/*178/*
@@ -577,12 +575,12 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, · 396 unmodified lines
577 } else {575 } else {
578 spin_unlock(&server->req_lock);576 spin_unlock(&server->req_lock);
579 577
580 spin_lock(&cifs_tcp_ses_lock);578 spin_lock(&server->srv_lock);
581 if (server->tcpStatus == CifsExiting) {579 if (server->tcpStatus == CifsExiting) {
582 spin_unlock(&cifs_tcp_ses_lock);580 spin_unlock(&server->srv_lock);
583 return -ENOENT;581 return -ENOENT;
584 }582 }
585 spin_unlock(&cifs_tcp_ses_lock);583 spin_unlock(&server->srv_lock);
586 584
587 /*585 /*
588 * For normal commands, reserve the last MAX_COMPOUND586 * For normal commands, reserve the last MAX_COMPOUND
@@ -725,11 +723,11 @@ cifs_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, · 136 unmodified lines
725static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,723static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
726 struct mid_q_entry **ppmidQ)724 struct mid_q_entry **ppmidQ)
727{725{
728 spin_lock(&cifs_tcp_ses_lock);726 spin_lock(&ses->ses_lock);
729 if (ses->ses_status == SES_NEW) {727 if (ses->ses_status == SES_NEW) {
730 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&728 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
731 (in_buf->Command != SMB_COM_NEGOTIATE)) {729 (in_buf->Command != SMB_COM_NEGOTIATE)) {
732 spin_unlock(&cifs_tcp_ses_lock);730 spin_unlock(&ses->ses_lock);
733 return -EAGAIN;731 return -EAGAIN;
734 }732 }
735 /* else ok - we are setting up session */733 /* else ok - we are setting up session */
@@ -738,19 +736,19 @@ static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf, · 2 unmodified lines
738 if (ses->ses_status == SES_EXITING) {736 if (ses->ses_status == SES_EXITING) {
739 /* check if SMB session is bad because we are setting it up */737 /* check if SMB session is bad because we are setting it up */
740 if (in_buf->Command != SMB_COM_LOGOFF_ANDX) {738 if (in_buf->Command != SMB_COM_LOGOFF_ANDX) {
741 spin_unlock(&cifs_tcp_ses_lock);739 spin_unlock(&ses->ses_lock);
742 return -EAGAIN;740 return -EAGAIN;
743 }741 }
744 /* else ok - we are shutting down session */742 /* else ok - we are shutting down session */
745 }743 }
746 spin_unlock(&cifs_tcp_ses_lock);744 spin_unlock(&ses->ses_lock);
747 745
748 *ppmidQ = AllocMidQEntry(in_buf, ses->server);746 *ppmidQ = alloc_mid(in_buf, ses->server);
749 if (*ppmidQ == NULL)747 if (*ppmidQ == NULL)
750 return -ENOMEM;748 return -ENOMEM;
751 spin_lock(&GlobalMid_Lock);749 spin_lock(&ses->server->mid_lock);
752 list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);750 list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
753 spin_unlock(&GlobalMid_Lock);751 spin_unlock(&ses->server->mid_lock);
754 return 0;752 return 0;
755}753}
756 754
@@ -782,13 +780,13 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst) · 25 unmodified lines
782 if (server->sign)780 if (server->sign)
783 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;781 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
784 782
785 mid = AllocMidQEntry(hdr, server);783 mid = alloc_mid(hdr, server);
786 if (mid == NULL)784 if (mid == NULL)
787 return ERR_PTR(-ENOMEM);785 return ERR_PTR(-ENOMEM);
788 786
789 rc = cifs_sign_rqst(rqst, server, &mid->sequence_number);787 rc = cifs_sign_rqst(rqst, server, &mid->sequence_number);
790 if (rc) {788 if (rc) {
791 DeleteMidQEntry(mid);789 release_mid(mid);
792 return ERR_PTR(rc);790 return ERR_PTR(rc);
793 }791 }
794 792
@@ -849,9 +847,9 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, · 54 unmodified lines
849 mid->mid_state = MID_REQUEST_SUBMITTED;847 mid->mid_state = MID_REQUEST_SUBMITTED;
850 848
851 /* put it on the pending_mid_q */849 /* put it on the pending_mid_q */
852 spin_lock(&GlobalMid_Lock);850 spin_lock(&server->mid_lock);
853 list_add_tail(&mid->qhead, &server->pending_mid_q);851 list_add_tail(&mid->qhead, &server->pending_mid_q);
854 spin_unlock(&GlobalMid_Lock);852 spin_unlock(&server->mid_lock);
855 853
856 /*854 /*
857 * Need to store the time in mid before calling I/O. For call_async,855 * Need to store the time in mid before calling I/O. For call_async,
@@ -865,7 +863,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, · 7 unmodified lines
865 if (rc < 0) {863 if (rc < 0) {
866 revert_current_mid(server, mid->credits);864 revert_current_mid(server, mid->credits);
867 server->sequence_number -= 2;865 server->sequence_number -= 2;
868 cifs_delete_mid(mid);866 delete_mid(mid);
869 }867 }
870 868
871 cifs_server_unlock(server);869 cifs_server_unlock(server);
@@ -912,10 +910,10 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) · 40 unmodified lines
912 cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",910 cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",
913 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);911 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);
914 912
915 spin_lock(&GlobalMid_Lock);913 spin_lock(&server->mid_lock);
916 switch (mid->mid_state) {914 switch (mid->mid_state) {
917 case MID_RESPONSE_RECEIVED:915 case MID_RESPONSE_RECEIVED:
918 spin_unlock(&GlobalMid_Lock);916 spin_unlock(&server->mid_lock);
919 return rc;917 return rc;
920 case MID_RETRY_NEEDED:918 case MID_RETRY_NEEDED:
921 rc = -EAGAIN;919 rc = -EAGAIN;
@@ -935,9 +933,9 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) · 13 unmodified lines
935 __func__, mid->mid, mid->mid_state);933 __func__, mid->mid, mid->mid_state);
936 rc = -EIO;934 rc = -EIO;
937 }935 }
938 spin_unlock(&GlobalMid_Lock);936 spin_unlock(&server->mid_lock);
939 937
940 DeleteMidQEntry(mid);938 release_mid(mid);
941 return rc;939 return rc;
942}940}
943 941
@@ -997,7 +995,7 @@ cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored, · 53 unmodified lines
997 return ERR_PTR(rc);995 return ERR_PTR(rc);
998 rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number);996 rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number);
999 if (rc) {997 if (rc) {
1000 cifs_delete_mid(mid);998 delete_mid(mid);
1001 return ERR_PTR(rc);999 return ERR_PTR(rc);
1002 }1000 }
1003 return mid;1001 return mid;
@@ -1026,7 +1024,7 @@ static void · 22 unmodified lines
1026cifs_cancelled_callback(struct mid_q_entry *mid)1024cifs_cancelled_callback(struct mid_q_entry *mid)
1027{1025{
1028 cifs_compound_callback(mid);1026 cifs_compound_callback(mid);
1029 DeleteMidQEntry(mid);1027 release_mid(mid);
1030}1028}
1031 1029
1032/*1030/*
@@ -1078,12 +1076,12 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 45 unmodified lines
1078 return -EIO;1076 return -EIO;
1079 }1077 }
1080 1078
1081 spin_lock(&cifs_tcp_ses_lock);1079 spin_lock(&server->srv_lock);
1082 if (server->tcpStatus == CifsExiting) {1080 if (server->tcpStatus == CifsExiting) {
1083 spin_unlock(&cifs_tcp_ses_lock);1081 spin_unlock(&server->srv_lock);
1084 return -ENOENT;1082 return -ENOENT;
1085 }1083 }
1086 spin_unlock(&cifs_tcp_ses_lock);1084 spin_unlock(&server->srv_lock);
1087 1085
1088 /*1086 /*
1089 * Wait for all the requests to become available.1087 * Wait for all the requests to become available.
@@ -1130,7 +1128,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 40 unmodified lines
1130 if (IS_ERR(midQ[i])) {1128 if (IS_ERR(midQ[i])) {
1131 revert_current_mid(server, i);1129 revert_current_mid(server, i);
1132 for (j = 0; j < i; j++)1130 for (j = 0; j < i; j++)
1133 cifs_delete_mid(midQ[j]);1131 delete_mid(midQ[j]);
1134 cifs_server_unlock(server);1132 cifs_server_unlock(server);
1135 1133
1136 /* Update # of requests on wire to server */1134 /* Update # of requests on wire to server */
@@ -1186,17 +1184,17 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 49 unmodified lines
1186 /*1184 /*
1187 * Compounding is never used during session establish.1185 * Compounding is never used during session establish.
1188 */1186 */
1189 spin_lock(&cifs_tcp_ses_lock);1187 spin_lock(&ses->ses_lock);
1190 if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) {1188 if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) {
1191 spin_unlock(&cifs_tcp_ses_lock);1189 spin_unlock(&ses->ses_lock);
1192 1190
1193 cifs_server_lock(server);1191 cifs_server_lock(server);
1194 smb311_update_preauth_hash(ses, server, rqst[0].rq_iov, rqst[0].rq_nvec);1192 smb311_update_preauth_hash(ses, server, rqst[0].rq_iov, rqst[0].rq_nvec);
1195 cifs_server_unlock(server);1193 cifs_server_unlock(server);
1196 1194
1197 spin_lock(&cifs_tcp_ses_lock);1195 spin_lock(&ses->ses_lock);
1198 }1196 }
1199 spin_unlock(&cifs_tcp_ses_lock);1197 spin_unlock(&ses->ses_lock);
1200 1198
1201 for (i = 0; i < num_rqst; i++) {1199 for (i = 0; i < num_rqst; i++) {
1202 rc = wait_for_response(server, midQ[i]);1200 rc = wait_for_response(server, midQ[i]);
@@ -1208,14 +1206,14 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 5 unmodified lines
1208 cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n",1206 cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n",
1209 midQ[i]->mid, le16_to_cpu(midQ[i]->command));1207 midQ[i]->mid, le16_to_cpu(midQ[i]->command));
1210 send_cancel(server, &rqst[i], midQ[i]);1208 send_cancel(server, &rqst[i], midQ[i]);
1211 spin_lock(&GlobalMid_Lock);1209 spin_lock(&server->mid_lock);
1212 midQ[i]->mid_flags |= MID_WAIT_CANCELLED;1210 midQ[i]->mid_flags |= MID_WAIT_CANCELLED;
1213 if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) {1211 if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) {
1214 midQ[i]->callback = cifs_cancelled_callback;1212 midQ[i]->callback = cifs_cancelled_callback;
1215 cancelled_mid[i] = true;1213 cancelled_mid[i] = true;
1216 credits[i].value = 0;1214 credits[i].value = 0;
1217 }1215 }
1218 spin_unlock(&GlobalMid_Lock);1216 spin_unlock(&server->mid_lock);
1219 }1217 }
1220 }1218 }
1221 1219
@@ -1250,7 +1248,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 28 unmodified lines
1250 rc = server->ops->check_receive(midQ[i], server,1248 rc = server->ops->check_receive(midQ[i], server,
1251 flags & CIFS_LOG_ERROR);1249 flags & CIFS_LOG_ERROR);
1252 1250
1253 /* mark it so buf will not be freed by cifs_delete_mid */1251 /* mark it so buf will not be freed by delete_mid */
1254 if ((flags & CIFS_NO_RSP_BUF) == 0)1252 if ((flags & CIFS_NO_RSP_BUF) == 0)
1255 midQ[i]->resp_buf = NULL;1253 midQ[i]->resp_buf = NULL;
1256 1254
@@ -1259,19 +1257,19 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 2 unmodified lines
1259 /*1257 /*
1260 * Compounding is never used during session establish.1258 * Compounding is never used during session establish.
1261 */1259 */
1262 spin_lock(&cifs_tcp_ses_lock);1260 spin_lock(&ses->ses_lock);
1263 if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) {1261 if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) {
1264 struct kvec iov = {1262 struct kvec iov = {
1265 .iov_base = resp_iov[0].iov_base,1263 .iov_base = resp_iov[0].iov_base,
1266 .iov_len = resp_iov[0].iov_len1264 .iov_len = resp_iov[0].iov_len
1267 };1265 };
1268 spin_unlock(&cifs_tcp_ses_lock);1266 spin_unlock(&ses->ses_lock);
1269 cifs_server_lock(server);1267 cifs_server_lock(server);
1270 smb311_update_preauth_hash(ses, server, &iov, 1);1268 smb311_update_preauth_hash(ses, server, &iov, 1);
1271 cifs_server_unlock(server);1269 cifs_server_unlock(server);
1272 spin_lock(&cifs_tcp_ses_lock);1270 spin_lock(&ses->ses_lock);
1273 }1271 }
1274 spin_unlock(&cifs_tcp_ses_lock);1272 spin_unlock(&ses->ses_lock);
1275 1273
1276out:1274out:
1277 /*1275 /*
@@ -1282,7 +1280,7 @@ out: · 4 unmodified lines
1282 */1280 */
1283 for (i = 0; i < num_rqst; i++) {1281 for (i = 0; i < num_rqst; i++) {
1284 if (!cancelled_mid[i])1282 if (!cancelled_mid[i])
1285 cifs_delete_mid(midQ[i]);1283 delete_mid(midQ[i]);
1286 }1284 }
1287 1285
1288 return rc;1286 return rc;
@@ -1360,12 +1358,12 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, · 71 unmodified lines
1360 return -EIO;1358 return -EIO;
1361 }1359 }
1362 1360
1363 spin_lock(&cifs_tcp_ses_lock);1361 spin_lock(&server->srv_lock);
1364 if (server->tcpStatus == CifsExiting) {1362 if (server->tcpStatus == CifsExiting) {
1365 spin_unlock(&cifs_tcp_ses_lock);1363 spin_unlock(&server->srv_lock);
1366 return -ENOENT;1364 return -ENOENT;
1367 }1365 }
1368 spin_unlock(&cifs_tcp_ses_lock);1366 spin_unlock(&server->srv_lock);
1369 1367
1370 /* Ensure that we do not send more than 50 overlapping requests1368 /* Ensure that we do not send more than 50 overlapping requests
1371 to the same server. We may make this configurable later or1369 to the same server. We may make this configurable later or
@@ -1419,15 +1417,15 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, · 47 unmodified lines
1419 rc = wait_for_response(server, midQ);1417 rc = wait_for_response(server, midQ);
1420 if (rc != 0) {1418 if (rc != 0) {
1421 send_cancel(server, &rqst, midQ);1419 send_cancel(server, &rqst, midQ);
1422 spin_lock(&GlobalMid_Lock);1420 spin_lock(&server->mid_lock);
1423 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {1421 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1424 /* no longer considered to be "in-flight" */1422 /* no longer considered to be "in-flight" */
1425 midQ->callback = DeleteMidQEntry;1423 midQ->callback = release_mid;
1426 spin_unlock(&GlobalMid_Lock);1424 spin_unlock(&server->mid_lock);
1427 add_credits(server, &credits, 0);1425 add_credits(server, &credits, 0);
1428 return rc;1426 return rc;
1429 }1427 }
1430 spin_unlock(&GlobalMid_Lock);1428 spin_unlock(&server->mid_lock);
1431 }1429 }
1432 1430
1433 rc = cifs_sync_mid_result(midQ, server);1431 rc = cifs_sync_mid_result(midQ, server);
@@ -1447,7 +1445,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, · 13 unmodified lines
1447 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);1445 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1448 rc = cifs_check_receive(midQ, server, 0);1446 rc = cifs_check_receive(midQ, server, 0);
1449out:1447out:
1450 cifs_delete_mid(midQ);1448 delete_mid(midQ);
1451 add_credits(server, &credits, 0);1449 add_credits(server, &credits, 0);
1452 1450
1453 return rc;1451 return rc;
@@ -1505,12 +1503,12 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 51 unmodified lines
1505 return -EIO;1503 return -EIO;
1506 }1504 }
1507 1505
1508 spin_lock(&cifs_tcp_ses_lock);1506 spin_lock(&server->srv_lock);
1509 if (server->tcpStatus == CifsExiting) {1507 if (server->tcpStatus == CifsExiting) {
1510 spin_unlock(&cifs_tcp_ses_lock);1508 spin_unlock(&server->srv_lock);
1511 return -ENOENT;1509 return -ENOENT;
1512 }1510 }
1513 spin_unlock(&cifs_tcp_ses_lock);1511 spin_unlock(&server->srv_lock);
1514 1512
1515 /* Ensure that we do not send more than 50 overlapping requests1513 /* Ensure that we do not send more than 50 overlapping requests
1516 to the same server. We may make this configurable later or1514 to the same server. We may make this configurable later or
@@ -1540,7 +1538,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 23 unmodified lines
1540 1538
1541 rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number);1539 rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number);
1542 if (rc) {1540 if (rc) {
1543 cifs_delete_mid(midQ);1541 delete_mid(midQ);
1544 cifs_server_unlock(server);1542 cifs_server_unlock(server);
1545 return rc;1543 return rc;
1546 }1544 }
@@ -1557,7 +1555,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 10 unmodified lines
1557 cifs_server_unlock(server);1555 cifs_server_unlock(server);
1558 1556
1559 if (rc < 0) {1557 if (rc < 0) {
1560 cifs_delete_mid(midQ);1558 delete_mid(midQ);
1561 return rc;1559 return rc;
1562 }1560 }
1563 1561
@@ -1568,19 +1566,19 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 4 unmodified lines
1568 (server->tcpStatus != CifsNew)));1566 (server->tcpStatus != CifsNew)));
1569 1567
1570 /* Were we interrupted by a signal ? */1568 /* Were we interrupted by a signal ? */
1571 spin_lock(&cifs_tcp_ses_lock);1569 spin_lock(&server->srv_lock);
1572 if ((rc == -ERESTARTSYS) &&1570 if ((rc == -ERESTARTSYS) &&
1573 (midQ->mid_state == MID_REQUEST_SUBMITTED) &&1571 (midQ->mid_state == MID_REQUEST_SUBMITTED) &&
1574 ((server->tcpStatus == CifsGood) ||1572 ((server->tcpStatus == CifsGood) ||
1575 (server->tcpStatus == CifsNew))) {1573 (server->tcpStatus == CifsNew))) {
1576 spin_unlock(&cifs_tcp_ses_lock);1574 spin_unlock(&server->srv_lock);
1577 1575
1578 if (in_buf->Command == SMB_COM_TRANSACTION2) {1576 if (in_buf->Command == SMB_COM_TRANSACTION2) {
1579 /* POSIX lock. We send a NT_CANCEL SMB to cause the1577 /* POSIX lock. We send a NT_CANCEL SMB to cause the
1580 blocking lock to return. */1578 blocking lock to return. */
1581 rc = send_cancel(server, &rqst, midQ);1579 rc = send_cancel(server, &rqst, midQ);
1582 if (rc) {1580 if (rc) {
1583 cifs_delete_mid(midQ);1581 delete_mid(midQ);
1584 return rc;1582 return rc;
1585 }1583 }
1586 } else {1584 } else {
@@ -1592,7 +1590,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 5 unmodified lines
1592 /* If we get -ENOLCK back the lock may have1590 /* If we get -ENOLCK back the lock may have
1593 already been removed. Don't exit in this case. */1591 already been removed. Don't exit in this case. */
1594 if (rc && rc != -ENOLCK) {1592 if (rc && rc != -ENOLCK) {
1595 cifs_delete_mid(midQ);1593 delete_mid(midQ);
1596 return rc;1594 return rc;
1597 }1595 }
1598 }1596 }
@@ -1600,21 +1598,21 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 1 unmodified line
1600 rc = wait_for_response(server, midQ);1598 rc = wait_for_response(server, midQ);
1601 if (rc) {1599 if (rc) {
1602 send_cancel(server, &rqst, midQ);1600 send_cancel(server, &rqst, midQ);
1603 spin_lock(&GlobalMid_Lock);1601 spin_lock(&server->mid_lock);
1604 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {1602 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1605 /* no longer considered to be "in-flight" */1603 /* no longer considered to be "in-flight" */
1606 midQ->callback = DeleteMidQEntry;1604 midQ->callback = release_mid;
1607 spin_unlock(&GlobalMid_Lock);1605 spin_unlock(&server->mid_lock);
1608 return rc;1606 return rc;
1609 }1607 }
1610 spin_unlock(&GlobalMid_Lock);1608 spin_unlock(&server->mid_lock);
1611 }1609 }
1612 1610
1613 /* We got the response - restart system call. */1611 /* We got the response - restart system call. */
1614 rstart = 1;1612 rstart = 1;
1615 spin_lock(&cifs_tcp_ses_lock);1613 spin_lock(&server->srv_lock);
1616 }1614 }
1617 spin_unlock(&cifs_tcp_ses_lock);1615 spin_unlock(&server->srv_lock);
1618 1616
1619 rc = cifs_sync_mid_result(midQ, server);1617 rc = cifs_sync_mid_result(midQ, server);
1620 if (rc != 0)1618 if (rc != 0)
@@ -1631,8 +1629,186 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 10 unmodified lines
1631 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);1629 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1632 rc = cifs_check_receive(midQ, server, 0);1630 rc = cifs_check_receive(midQ, server, 0);
1633out:1631out:
1634 cifs_delete_mid(midQ);1632 delete_mid(midQ);
1635 if (rstart && rc == -EACCES)1633 if (rstart && rc == -EACCES)
1636 return -ERESTARTSYS;1634 return -ERESTARTSYS;
1637 return rc;1635 return rc;
1638}1636}
1637
1638/*
1639 * Discard any remaining data in the current SMB. To do this, we borrow the
1640 * current bigbuf.
1641 */
1642int
1643cifs_discard_remaining_data(struct TCP_Server_Info *server)
1644{
1645 unsigned int rfclen = server->pdu_size;
1646 int remaining = rfclen + server->vals->header_preamble_size -
1647 server->total_read;
1648
1649 while (remaining > 0) {
1650 int length;
1651
1652 length = cifs_discard_from_socket(server,
1653 min_t(size_t, remaining,
1654 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1655 if (length < 0)
1656 return length;
1657 server->total_read += length;
1658 remaining -= length;
1659 }
1660
1661 return 0;
1662}
1663
1664static int
1665__cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
1666 bool malformed)
1667{
1668 int length;
1669
1670 length = cifs_discard_remaining_data(server);
1671 dequeue_mid(mid, malformed);
1672 mid->resp_buf = server->smallbuf;
1673 server->smallbuf = NULL;
1674 return length;
1675}
1676
1677static int
1678cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1679{
1680 struct cifs_readdata *rdata = mid->callback_data;
1681
1682 return __cifs_readv_discard(server, mid, rdata->result);
1683}
1684
1685int
1686cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1687{
1688 int length, len;
1689 unsigned int data_offset, data_len;
1690 struct cifs_readdata *rdata = mid->callback_data;
1691 char *buf = server->smallbuf;
1692 unsigned int buflen = server->pdu_size +
1693 server->vals->header_preamble_size;
1694 bool use_rdma_mr = false;
1695
1696 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
1697 __func__, mid->mid, rdata->offset, rdata->bytes);
1698
1699 /*
1700 * read the rest of READ_RSP header (sans Data array), or whatever we
1701 * can if there's not enough data. At this point, we've read down to
1702 * the Mid.
1703 */
1704 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1705 HEADER_SIZE(server) + 1;
1706
1707 length = cifs_read_from_socket(server,
1708 buf + HEADER_SIZE(server) - 1, len);
1709 if (length < 0)
1710 return length;
1711 server->total_read += length;
1712
1713 if (server->ops->is_session_expired &&
1714 server->ops->is_session_expired(buf)) {
1715 cifs_reconnect(server, true);
1716 return -1;
1717 }
1718
1719 if (server->ops->is_status_pending &&
1720 server->ops->is_status_pending(buf, server)) {
1721 cifs_discard_remaining_data(server);
1722 return -1;
1723 }
1724
1725 /* set up first two iov for signature check and to get credits */
1726 rdata->iov[0].iov_base = buf;
1727 rdata->iov[0].iov_len = server->vals->header_preamble_size;
1728 rdata->iov[1].iov_base = buf + server->vals->header_preamble_size;
1729 rdata->iov[1].iov_len =
1730 server->total_read - server->vals->header_preamble_size;
1731 cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
1732 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1733 cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
1734 rdata->iov[1].iov_base, rdata->iov[1].iov_len);
1735
1736 /* Was the SMB read successful? */
1737 rdata->result = server->ops->map_error(buf, false);
1738 if (rdata->result != 0) {
1739 cifs_dbg(FYI, "%s: server returned error %d\n",
1740 __func__, rdata->result);
1741 /* normal error on read response */
1742 return __cifs_readv_discard(server, mid, false);
1743 }
1744
1745 /* Is there enough to get to the rest of the READ_RSP header? */
1746 if (server->total_read < server->vals->read_rsp_size) {
1747 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
1748 __func__, server->total_read,
1749 server->vals->read_rsp_size);
1750 rdata->result = -EIO;
1751 return cifs_readv_discard(server, mid);
1752 }
1753
1754 data_offset = server->ops->read_data_offset(buf) +
1755 server->vals->header_preamble_size;
1756 if (data_offset < server->total_read) {
1757 /*
1758 * win2k8 sometimes sends an offset of 0 when the read
1759 * is beyond the EOF. Treat it as if the data starts just after
1760 * the header.
1761 */
1762 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
1763 __func__, data_offset);
1764 data_offset = server->total_read;
1765 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
1766 /* data_offset is beyond the end of smallbuf */
1767 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
1768 __func__, data_offset);
1769 rdata->result = -EIO;
1770 return cifs_readv_discard(server, mid);
1771 }
1772
1773 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
1774 __func__, server->total_read, data_offset);
1775
1776 len = data_offset - server->total_read;
1777 if (len > 0) {
1778 /* read any junk before data into the rest of smallbuf */
1779 length = cifs_read_from_socket(server,
1780 buf + server->total_read, len);
1781 if (length < 0)
1782 return length;
1783 server->total_read += length;
1784 }
1785
1786 /* how much data is in the response? */
1787#ifdef CONFIG_CIFS_SMB_DIRECT
1788 use_rdma_mr = rdata->mr;
1789#endif
1790 data_len = server->ops->read_data_length(buf, use_rdma_mr);
1791 if (!use_rdma_mr && (data_offset + data_len > buflen)) {
1792 /* data_len is corrupt -- discard frame */
1793 rdata->result = -EIO;
1794 return cifs_readv_discard(server, mid);
1795 }
1796
1797 length = rdata->read_into_pages(server, rdata, data_len);
1798 if (length < 0)
1799 return length;
1800
1801 server->total_read += length;
1802
1803 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n",
1804 server->total_read, buflen, data_len);
1805
1806 /* discard anything left over */
1807 if (server->total_read < buflen)
1808 return cifs_readv_discard(server, mid);
1809
1810 dequeue_mid(mid, false);
1811 mid->resp_buf = server->smallbuf;
1812 server->smallbuf = NULL;
1813 return length;
1814}
fs/cifs/xattr.c+4−1
@@ -201,6 +201,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler, · 200 unmodified lines
201 break;201 break;
202 }202 }
203 203
204#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
204 case XATTR_ACL_ACCESS:205 case XATTR_ACL_ACCESS:
205#ifdef CONFIG_CIFS_POSIX206#ifdef CONFIG_CIFS_POSIX
206 if (!value)207 if (!value)
@@ -224,6 +225,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler, · 17 unmodified lines
224 cifs_remap(cifs_sb));225 cifs_remap(cifs_sb));
225#endif /* CONFIG_CIFS_POSIX */226#endif /* CONFIG_CIFS_POSIX */
226 break;227 break;
228#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
227 }229 }
228 230
229out:231out:
@@ -364,7 +366,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler, · 134 unmodified lines
364 }366 }
365 break;367 break;
366 }368 }
367 369#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
368 case XATTR_ACL_ACCESS:370 case XATTR_ACL_ACCESS:
369#ifdef CONFIG_CIFS_POSIX371#ifdef CONFIG_CIFS_POSIX
370 if (sb->s_flags & SB_POSIXACL)372 if (sb->s_flags & SB_POSIXACL)
@@ -384,6 +386,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler, · 13 unmodified lines
384 cifs_remap(cifs_sb));386 cifs_remap(cifs_sb));
385#endif /* CONFIG_CIFS_POSIX */387#endif /* CONFIG_CIFS_POSIX */
386 break;388 break;
389#endif /* ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
387 }390 }
388 391
389 /* We could add an additional check for streams ie392 /* We could add an additional check for streams ie