Merge tag '5.3-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 8 Aug 2019 16:57:50 +0000 (09:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 8 Aug 2019 16:57:50 +0000 (09:57 -0700)
Pull cifs fixes from Steve French:
 "Six small SMB3 fixes, two for stable"

* tag '5.3-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  SMB3: Kernel oops mounting a encryptData share with CONFIG_DEBUG_VIRTUAL
  smb3: update TODO list of missing features
  smb3: send CAP_DFS capability during session setup
  SMB3: Fix potential memory leak when processing compound chain
  SMB3: Fix deadlock in validate negotiate hits reconnect
  cifs: fix rmmod regression in cifs.ko caused by force_sig changes

Documentation/filesystems/cifs/TODO
fs/cifs/connect.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c

index 9267f3fb131f9b5cf0e027ba9bdd9ff51a93d5b8..edbbccda1942e4c84bf5b3dd3e5d3c1bd7959b32 100644 (file)
@@ -13,7 +13,8 @@ a) SMB3 (and SMB3.1.1) missing optional features:
    - T10 copy offload ie "ODX" (copy chunk, and "Duplicate Extents" ioctl
      currently the only two server side copy mechanisms supported)
 
-b) improved sparse file support
+b) improved sparse file support (fiemap and SEEK_HOLE are implemented
+but additional features would be supportable by the protocol).
 
 c) Directory entry caching relies on a 1 second timer, rather than
 using Directory Leases, currently only the root file handle is cached longer
@@ -21,9 +22,13 @@ using Directory Leases, currently only the root file handle is cached longer
 d) quota support (needs minor kernel change since quota calls
 to make it to network filesystems or deviceless filesystems)
 
-e) Additional use cases where we use "compoounding" (e.g. open/query/close
-and open/setinfo/close) to reduce the number of roundtrips, and also
-open to reduce redundant opens (using deferred close and reference counts more).
+e) Additional use cases can be optimized to use "compounding"
+(e.g. open/query/close and open/setinfo/close) to reduce the number
+of roundtrips to the server and improve performance. Various cases
+(stat, statfs, create, unlink, mkdir) already have been improved by
+using compounding but more can be done.  In addition we could significantly
+reduce redundant opens by using deferred close (with handle caching leases)
+and better using reference counters on file handles.
 
 f) Finish inotify support so kde and gnome file list windows
 will autorefresh (partially complete by Asser). Needs minor kernel
@@ -43,18 +48,17 @@ mount or a per server basis to client UIDs or nobody if no mapping
 exists. Also better integration with winbind for resolving SID owners
 
 k) Add tools to take advantage of more smb3 specific ioctls and features
-(passthrough ioctl/fsctl for sending various SMB3 fsctls to the server
-is in progress, and a passthrough query_info call is already implemented
-in cifs.ko to allow smb3 info levels queries to be sent from userspace)
+(passthrough ioctl/fsctl is now implemented in cifs.ko to allow sending
+various SMB3 fsctls and query info and set info calls directly from user space)
+Add tools to make setting various non-POSIX metadata attributes easier
+from tools (e.g. extending what was done in smb-info tool).
 
 l) encrypted file support
 
 m) improved stats gathering tools (perhaps integration with nfsometer?)
 to extend and make easier to use what is currently in /proc/fs/cifs/Stats
 
-n) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed
-file attribute via chflags) and improve user space tools for managing and
-viewing them.
+n) Add support for claims based ACLs ("DAC")
 
 o) mount helper GUI (to simplify the various configuration options on mount)
 
@@ -82,6 +86,8 @@ so far).
 w) Add support for additional strong encryption types, and additional spnego
 authentication mechanisms (see MS-SMB2)
 
+x) Finish support for SMB3.1.1 compression
+
 KNOWN BUGS
 ====================================
 See http://bugzilla.samba.org - search on product "CifsVFS" for
index a4830ced0f9899c35c89609b2ea25330a06693bd..a15a6e738eb5321dcde574c848f9a6435ffcd9aa 100644 (file)
@@ -1113,6 +1113,7 @@ cifs_demultiplex_thread(void *p)
                mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
 
        set_freezable();
+       allow_signal(SIGKILL);
        while (server->tcpStatus != CifsExiting) {
                if (try_to_freeze())
                        continue;
index a5bc1b671c126579a7161853ad0ef352e01f8c39..64a5864127be9154fead53d4188a15d3f7ddaf17 100644 (file)
@@ -3489,7 +3489,15 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len,
 static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
                                   unsigned int buflen)
 {
-       sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
+       void *addr;
+       /*
+        * VMAP_STACK (at least) puts stack into the vmalloc address space
+        */
+       if (is_vmalloc_addr(buf))
+               addr = vmalloc_to_page(buf);
+       else
+               addr = virt_to_page(buf);
+       sg_set_page(sg, addr, buflen, offset_in_page(buf));
 }
 
 /* Assumes the first rqst has a transform header as the first iov.
@@ -4070,7 +4078,6 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
 {
        int ret, length;
        char *buf = server->smallbuf;
-       char *tmpbuf;
        struct smb2_sync_hdr *shdr;
        unsigned int pdu_length = server->pdu_size;
        unsigned int buf_size;
@@ -4100,18 +4107,15 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
                return length;
 
        next_is_large = server->large_buf;
- one_more:
+one_more:
        shdr = (struct smb2_sync_hdr *)buf;
        if (shdr->NextCommand) {
-               if (next_is_large) {
-                       tmpbuf = server->bigbuf;
+               if (next_is_large)
                        next_buffer = (char *)cifs_buf_get();
-               } else {
-                       tmpbuf = server->smallbuf;
+               else
                        next_buffer = (char *)cifs_small_buf_get();
-               }
                memcpy(next_buffer,
-                      tmpbuf + le32_to_cpu(shdr->NextCommand),
+                      buf + le32_to_cpu(shdr->NextCommand),
                       pdu_length - le32_to_cpu(shdr->NextCommand));
        }
 
@@ -4140,12 +4144,21 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
                pdu_length -= le32_to_cpu(shdr->NextCommand);
                server->large_buf = next_is_large;
                if (next_is_large)
-                       server->bigbuf = next_buffer;
+                       server->bigbuf = buf = next_buffer;
                else
-                       server->smallbuf = next_buffer;
-
-               buf += le32_to_cpu(shdr->NextCommand);
+                       server->smallbuf = buf = next_buffer;
                goto one_more;
+       } else if (ret != 0) {
+               /*
+                * ret != 0 here means that we didn't get to handle_mid() thus
+                * server->smallbuf and server->bigbuf are still valid. We need
+                * to free next_buffer because it is not going to be used
+                * anywhere.
+                */
+               if (next_is_large)
+                       free_rsp_buf(CIFS_LARGE_BUFFER, next_buffer);
+               else
+                       free_rsp_buf(CIFS_SMALL_BUFFER, next_buffer);
        }
 
        return ret;
index c8cd7b6cdda2a5c93b0c6a5cf374d6b29291726e..31e4a1b0b1704b90e9ed8f0cdb123477933fb369 100644 (file)
@@ -252,7 +252,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon)
        if (tcon == NULL)
                return 0;
 
-       if (smb2_command == SMB2_TREE_CONNECT)
+       if (smb2_command == SMB2_TREE_CONNECT || smb2_command == SMB2_IOCTL)
                return 0;
 
        if (tcon->tidStatus == CifsExiting) {
@@ -1196,7 +1196,12 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data)
        else
                req->SecurityMode = 0;
 
+#ifdef CONFIG_CIFS_DFS_UPCALL
+       req->Capabilities = cpu_to_le32(SMB2_GLOBAL_CAP_DFS);
+#else
        req->Capabilities = 0;
+#endif /* DFS_UPCALL */
+
        req->Channel = 0; /* MBZ */
 
        sess_data->iov[0].iov_base = (char *)req;