24 Aug, 2020

1 commit

  • Replace the existing /* fall through */ comments and its variants with
    the new pseudo-keyword macro fallthrough[1]. Also, remove unnecessary
    fall-through markings when it is the case.

    [1] https://www.kernel.org/doc/html/v5.7/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through

    Signed-off-by: Gustavo A. R. Silva

    Gustavo A. R. Silva
     

03 Aug, 2020

2 commits


01 Jun, 2020

4 commits

  • Joe Perches pointed out that we were missing a newline
    at the end of two debug messages

    Reported-by: Joe Perches
    Signed-off-by: Steve French

    Steve French
     
  • Use pr_fmt to standardize all logging for fs/cifs.

    Some logging output had no CIFS: specific prefix.

    Now all output has one of three prefixes:

    o CIFS:
    o CIFS: VFS:
    o Root-CIFS:

    Miscellanea:

    o Convert printks to pr_
    o Neaten macro definitions
    o Remove embedded CIFS: prefixes from formats
    o Convert "illegal" to "invalid"
    o Coalesce formats
    o Add missing '\n' format terminations
    o Consolidate multiple cifs_dbg continuations into single calls
    o More consistent use of upper case first word output logging
    o Multiline statement argument alignment and wrapping

    Signed-off-by: Joe Perches
    Signed-off-by: Steve French

    Joe Perches
     
  • In order to support reconnect to hostnames that resolve to same ip
    address, besides relying on the currently set hostname to match DFS
    targets, attempt to resolve the targets and then match their addresses
    with the reconnected server ip address.

    For instance, if we have two hostnames "FOO" and "BAR", and both
    resolve to the same ip address, we would be able to handle failover in
    DFS paths like

    \\FOO\dfs\link1 -> [ \BAZ\share2 (*), \BAR\share1 ]
    \\FOO\dfs\link2 -> [ \BAZ\share2 (*), \FOO\share1 ]

    so when "BAZ" is no longer accessible, link1 and link2 would get
    reconnected despite having different target hostnames.

    Signed-off-by: Paulo Alcantara (SUSE)
    Reviewed-by: Aurelien Aptel
    Signed-off-by: Steve French

    Paulo Alcantara
     
  • The variable rc is being initialized with a value that is never read
    and it is being updated later with a new value. The initialization is
    redundant and can be removed.

    Addresses-Coverity: ("Unused value")
    Signed-off-by: Colin Ian King
    Signed-off-by: Steve French

    Colin Ian King
     

15 May, 2020

1 commit

  • Failed async writes that are requeued may not clean up a refcount
    on the file, which can result in a leaked open. This scenario arises
    very reliably when using persistent handles and a reconnect occurs
    while writing.

    cifs_writev_requeue only releases the reference if the write fails
    (rc != 0). The server->ops->async_writev operation will take its own
    reference, so the initial reference can always be released.

    Signed-off-by: Adam McCoy
    Signed-off-by: Steve French
    CC: Stable
    Reviewed-by: Pavel Shilovsky

    Adam McCoy
     

16 Apr, 2020

1 commit

  • Found a read performance issue when linux kernel page size is 64KB.
    If linux kernel page size is 64KB and mount options cache=strict &
    vers=2.1+, it does not support cifs_readpages(). Instead, it is using
    cifs_readpage() and cifs_read() with maximum read IO size 16KB, which is
    much slower than read IO size 1MB when negotiated SMB 2.1+. Since modern
    SMB server supported SMB 2.1+ and Max Read Size can reach more than 64KB
    (for example 1MB ~ 8MB), this patch check max_read instead of maxBuf to
    determine whether server support readpages() and improve read performance
    for page size 64KB & cache=strict & vers=2.1+, and for SMB1 it is more
    cleaner to initialize server->max_read to server->maxBuf.

    The client is a linux box with linux kernel 4.2.8,
    page size 64KB (CONFIG_ARM64_64K_PAGES=y),
    cpu arm 1.7GHz, and use mount.cifs as smb client.
    The server is another linux box with linux kernel 4.2.8,
    share a file '10G.img' with size 10GB,
    and use samba-4.7.12 as smb server.

    The client mount a share from the server with different
    cache options: cache=strict and cache=none,
    mount -tcifs ///Public /cache_strict -overs=3.0,cache=strict,username=,password=
    mount -tcifs ///Public /cache_none -overs=3.0,cache=none,username=,password=

    The client download a 10GbE file from the server across 1GbE network,
    dd if=/cache_strict/10G.img of=/dev/null bs=1M count=10240
    dd if=/cache_none/10G.img of=/dev/null bs=1M count=10240

    Found that cache=strict (without patch) is slower read throughput and
    smaller read IO size than cache=none.
    cache=strict (without patch): read throughput 40MB/s, read IO size is 16KB
    cache=strict (with patch): read throughput 113MB/s, read IO size is 1MB
    cache=none: read throughput 109MB/s, read IO size is 1MB

    Looks like if page size is 64KB,
    cifs_set_ops() would use cifs_addr_ops_smallbuf instead of cifs_addr_ops,

    /* check if server can support readpages */
    if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
    PAGE_SIZE + MAX_CIFS_HDR_SIZE)
    inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
    else
    inode->i_data.a_ops = &cifs_addr_ops;

    maxBuf is came from 2 places, SMB2_negotiate() and CIFSSMBNegotiate(),
    (SMB2_MAX_BUFFER_SIZE is 64KB)
    SMB2_negotiate():
    /* set it to the maximum buffer size value we can send with 1 credit */
    server->maxBuf = min_t(unsigned int, le32_to_cpu(rsp->MaxTransactSize),
          SMB2_MAX_BUFFER_SIZE);
    CIFSSMBNegotiate():
    server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);

    Page size 64KB and cache=strict lead to read_pages() use cifs_readpage()
    instead of cifs_readpages(), and then cifs_read() using maximum read IO
    size 16KB, which is much slower than maximum read IO size 1MB.
    (CIFSMaxBufSize is 16KB by default)

    /* FIXME: set up handlers for larger reads and/or convert to async */
    rsize = min_t(unsigned int, cifs_sb->rsize, CIFSMaxBufSize);
    Reviewed-by: Pavel Shilovsky
    Signed-off-by: Jones Syue
    Signed-off-by: Steve French

    Jones Syue
     

23 Mar, 2020

3 commits


25 Feb, 2020

1 commit

  • To rename a file in SMB2 we open it with the DELETE access and do a
    special SetInfo on it. If the handle is missing the DELETE bit the
    server will fail the SetInfo with STATUS_ACCESS_DENIED.

    We currently try to reuse any existing opened handle we have with
    cifs_get_writable_path(). That function looks for handles with WRITE
    access but doesn't check for DELETE, making rename() fail if it finds
    a handle to reuse. Simple reproducer below.

    To select handles with the DELETE bit, this patch adds a flag argument
    to cifs_get_writable_path() and find_writable_file() and the existing
    'bool fsuid_only' argument is converted to a flag.

    The cifsFileInfo struct only stores the UNIX open mode but not the
    original SMB access flags. Since the DELETE bit is not mapped in that
    mode, this patch stores the access mask in cifs_fid on file open,
    which is accessible from cifsFileInfo.

    Simple reproducer:

    #include
    #include
    #include
    #include
    #include
    #include
    #define E(s) perror(s), exit(1)

    int main(int argc, char *argv[])
    {
    int fd, ret;
    if (argc != 3) {
    fprintf(stderr, "Usage: %s A B\n"
    "create&open A in write mode, "
    "rename A to B, close A\n", argv[0]);
    return 0;
    }

    fd = openat(AT_FDCWD, argv[1], O_WRONLY|O_CREAT|O_SYNC, 0666);
    if (fd == -1) E("openat()");

    ret = rename(argv[1], argv[2]);
    if (ret) E("rename()");

    ret = close(fd);
    if (ret) E("close()");

    return ret;
    }

    $ gcc -o bugrename bugrename.c
    $ ./bugrename /mnt/a /mnt/b
    rename(): Permission denied

    Fixes: 8de9e86c67ba ("cifs: create a helper to find a writeable handle by path name")
    CC: Stable
    Signed-off-by: Aurelien Aptel
    Signed-off-by: Steve French
    Reviewed-by: Pavel Shilovsky
    Reviewed-by: Paulo Alcantara (SUSE)

    Aurelien Aptel
     

06 Feb, 2020

1 commit

  • RHBZ: 1795423

    This is the SMB1 version of a patch we already have for SMB2

    In recent DFS updates we have a new variable controlling how many times we will
    retry to reconnect the share.
    If DFS is not used, then this variable is initialized to 0 in:

    static inline int
    dfs_cache_get_nr_tgts(const struct dfs_cache_tgt_list *tl)
    {
    return tl ? tl->tl_numtgts : 0;
    }

    This means that in the reconnect loop in smb2_reconnect() we will immediately wrap retries to -1
    and never actually get to pass this conditional:

    if (--retries)
    continue;

    The effect is that we no longer reach the point where we fail the commands with -EHOSTDOWN
    and basically the kernel threads are virtually hung and unkillable.

    Signed-off-by: Ronnie Sahlberg
    Signed-off-by: Steve French
    Reviewed-by: Aurelien Aptel
    Reviewed-by: Paulo Alcantara (SUSE)

    Ronnie Sahlberg
     

27 Jan, 2020

1 commit


13 Dec, 2019

1 commit

  • SMB2_tdis() checks if a root handle is valid in order to decide
    whether it needs to close the handle or not. However if another
    thread has reference for the handle, it may end up with putting
    the reference twice. The extra reference that we want to put
    during the tree disconnect is the reference that has a directory
    lease. So, track the fact that we have a directory lease and
    close the handle only in that case.

    Signed-off-by: Pavel Shilovsky
    Reviewed-by: Ronnie Sahlberg
    Signed-off-by: Steve French

    Pavel Shilovsky
     

26 Sep, 2019

1 commit

  • We need to populate an ACL (security descriptor open context)
    on file and directory correct. This patch passes in the
    mode. Followon patch will build the open context and the
    security descriptor (from the mode) that goes in the open
    context.

    Signed-off-by: Steve French
    Reviewed-by: Aurelien Aptel

    Steve French
     

17 Sep, 2019

1 commit


28 Aug, 2019

1 commit

  • Using strscpy is cleaner, and avoids some problems with
    handling maximum length strings. Linus noticed the
    original problem and Aurelien pointed out some additional
    problems. Fortunately most of this is SMB1 code (and
    in particular the ASCII string handling older, which
    is less common).

    Reported-by: Linus Torvalds
    Reviewed-by: Aurelien Aptel
    Signed-off-by: Ronnie Sahlberg
    Signed-off-by: Steve French

    Ronnie Sahlberg
     

08 Jul, 2019

2 commits


08 May, 2019

2 commits

  • The flags were named confusingly.
    CIFS_ASYNC_OP now just means that we will not block waiting for credits
    to become available so we thus rename this to be CIFS_NON_BLOCKING.

    Change CIFS_NO_RESP to CIFS_NO_RSP_BUF to clarify that we will actually get a
    response from the server but we will not get/do not want a response buffer.

    Delete CIFSSMBNotify. This is an SMB1 function that is not used.

    Signed-off-by: Ronnie Sahlberg
    Signed-off-by: Steve French
    Reviewed-by: Pavel Shilovsky

    Ronnie Sahlberg
     
  • For SMB1 oplock breaks we would grab one credit while sending the PDU
    but we would never relese the credit back since we will never receive a
    response to this from the server. Eventuallt this would lead to a hang
    once all credits are leaked.

    Fix this by defining a new flag CIFS_NO_SRV_RSP which indicates that there
    is no server response to this command and thus we need to add any credits back
    immediately after sending the PDU.

    CC: Stable #v5.0+
    Signed-off-by: Ronnie Sahlberg
    Reviewed-by: Pavel Shilovsky
    Signed-off-by: Steve French

    Ronnie Sahlberg
     

06 Mar, 2019

3 commits


05 Mar, 2019

4 commits

  • There are a couple places where we still account for 4 bytes
    in the beginning of SMB2 packet which is not true in the current
    code. Fix this to use a header preamble size where possible.

    Signed-off-by: Pavel Shilovsky
    Signed-off-by: Steve French

    Pavel Shilovsky
     
  • Even if a response is malformed, we should count credits
    granted by the server to avoid miscalculations and unnecessary
    reconnects due to client or server bugs. If the response has
    been received partially, the session will be reconnected anyway
    on the next iteration of the demultiplex thread, so counting
    credits for such cases shouldn't break things.

    Signed-off-by: Pavel Shilovsky
    Signed-off-by: Steve French

    Pavel Shilovsky
     
  • a trivial patch that replaces all use of snprintf with scnprintf.
    scnprintf() is generally seen as a safer function to use than
    snprintf for many use cases.

    In our case, there is no actual difference between the two since we never
    look at the return value. Thus we did not have any of the bugs that
    scnprintf protects against and the patch does nothing.

    However, for people reading our code it will be a receipt that we
    have done our due dilligence and checked our code for this type of bugs.

    See the presentation "Making C Less Dangerous In The Linux Kernel"
    at this years LCA

    Signed-off-by: Ronnie Sahlberg
    Signed-off-by: Steve French

    Ronnie Sahlberg
     
  • If we don't find a writable file handle when retrying writepages
    we break of the loop and do not unlock and put pages neither from
    wdata2 nor from the original wdata. Fix this by walking through
    all the remaining pages and cleanup them properly.

    Cc:
    Signed-off-by: Pavel Shilovsky
    Signed-off-by: Steve French

    Pavel Shilovsky
     

25 Jan, 2019

1 commit

  • Currently we mark MID as malformed if we get an error from server
    in a read response. This leads to not properly processing credits
    in the readv callback. Fix this by marking such a response as
    normal received response and process it appropriately.

    Cc:
    Signed-off-by: Pavel Shilovsky
    Reviewed-by: Ronnie Sahlberg
    Signed-off-by: Steve French

    Pavel Shilovsky
     

11 Jan, 2019

2 commits


29 Dec, 2018

1 commit


24 Oct, 2018

2 commits


09 Sep, 2018

1 commit

  • A powerpc build of cifs with gcc v8.2.0 produces this warning:

    fs/cifs/cifssmb.c: In function ‘CIFSSMBNegotiate’:
    fs/cifs/cifssmb.c:605:3: warning: ‘strncpy’ writing 16 bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
    strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Since we are already doing a strlen() on the source, change the strncpy
    to a memcpy().

    Signed-off-by: Stephen Rothwell
    Signed-off-by: Steve French

    Stephen Rothwell
     

08 Aug, 2018

1 commit

  • In cifs, the timestamps are stored in memory in the cifs_fattr structure,
    which uses the deprecated 'timespec' structure. Now that the VFS code
    has moved on to 'timespec64', the next step is to change over the fattr
    as well.

    This also makes 32-bit and 64-bit systems behave the same way, and
    no longer overflow the 32-bit time_t in year 2038.

    Signed-off-by: Arnd Bergmann
    Reviewed-by: Paulo Alcantara
    Signed-off-by: Steve French

    Arnd Bergmann
     

06 Jul, 2018

1 commit

  • For every request we send, whether it is SMB1 or SMB2+, we attempt to
    reconnect tcon (cifs_reconnect_tcon or smb2_reconnect) before carrying
    out the request.

    So, while server->tcpStatus != CifsNeedReconnect, we wait for the
    reconnection to succeed on wait_event_interruptible_timeout(). If it
    returns, that means that either the condition was evaluated to true, or
    timeout elapsed, or it was interrupted by a signal.

    Since we're not handling the case where the process woke up due to a
    received signal (-ERESTARTSYS), the next call to
    wait_event_interruptible_timeout() will _always_ fail and we end up
    looping forever inside either cifs_reconnect_tcon() or smb2_reconnect().

    Here's an example of how to trigger that:

    $ mount.cifs //foo/share /mnt/test -o
    username=foo,password=foo,vers=1.0,hard

    (break connection to server before executing bellow cmd)
    $ stat -f /mnt/test & sleep 140
    [1] 2511

    $ ps -aux -q 2511
    USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
    root 2511 0.0 0.0 12892 1008 pts/0 S 12:24 0:00 stat -f
    /mnt/test

    $ kill -9 2511

    (wait for a while; process is stuck in the kernel)
    $ ps -aux -q 2511
    USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
    root 2511 83.2 0.0 12892 1008 pts/0 R 12:24 30:01 stat -f
    /mnt/test

    By using 'hard' mount point means that cifs.ko will keep retrying
    indefinitely, however we must allow the process to be killed otherwise
    it would hang the system.

    Signed-off-by: Paulo Alcantara
    Cc: stable@vger.kernel.org
    Reviewed-by: Aurelien Aptel
    Signed-off-by: Steve French

    Paulo Alcantara
     

15 Jun, 2018

1 commit

  • Use a read lease for the cached root fid so that we can detect
    when the content of the directory changes (via a break) at which time
    we close the handle. On next access to the root the handle will be reopened
    and cached again.

    Signed-off-by: Ronnie Sahlberg
    Signed-off-by: Steve French

    Ronnie Sahlberg