1. 21 12月, 2019 1 次提交
  2. 13 12月, 2019 1 次提交
    • P
      CIFS: Fix SMB2 oplock break processing · d4785d88
      Pavel Shilovsky 提交于
      commit fa9c2362497fbd64788063288dc4e74daf977ebb upstream.
      
      Even when mounting modern protocol version the server may be
      configured without supporting SMB2.1 leases and the client
      uses SMB2 oplock to optimize IO performance through local caching.
      
      However there is a problem in oplock break handling that leads
      to missing a break notification on the client who has a file
      opened. It latter causes big latencies to other clients that
      are trying to open the same file.
      
      The problem reproduces when there are multiple shares from the
      same server mounted on the client. The processing code tries to
      match persistent and volatile file ids from the break notification
      with an open file but it skips all share besides the first one.
      Fix this by looking up in all shares belonging to the server that
      issued the oplock break.
      
      Cc: Stable <stable@vger.kernel.org>
      Signed-off-by: NPavel Shilovsky <pshilov@microsoft.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d4785d88
  3. 06 11月, 2019 1 次提交
  4. 27 4月, 2019 1 次提交
    • A
      CIFS: keep FileInfo handle live during oplock break · 8092ecc3
      Aurelien Aptel 提交于
      commit b98749cac4a695f084a5ff076f4510b23e353ecd upstream.
      
      In the oplock break handler, writing pending changes from pages puts
      the FileInfo handle. If the refcount reaches zero it closes the handle
      and waits for any oplock break handler to return, thus causing a deadlock.
      
      To prevent this situation:
      
      * We add a wait flag to cifsFileInfo_put() to decide whether we should
        wait for running/pending oplock break handlers
      
      * We keep an additionnal reference of the SMB FileInfo handle so that
        for the rest of the handler putting the handle won't close it.
        - The ref is bumped everytime we queue the handler via the
          cifs_queue_oplock_break() helper.
        - The ref is decremented at the end of the handler
      
      This bug was triggered by xfstest 464.
      
      Also important fix to address the various reports of
      oops in smb2_push_mandatory_locks
      Signed-off-by: NAurelien Aptel <aaptel@suse.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      Reviewed-by: NPavel Shilovsky <pshilov@microsoft.com>
      CC: Stable <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      8092ecc3
  5. 24 3月, 2019 1 次提交
    • P
      CIFS: Do not reset lease state to NONE on lease break · 3ed9f22e
      Pavel Shilovsky 提交于
      commit 7b9b9edb49ad377b1e06abf14354c227e9ac4b06 upstream.
      
      Currently on lease break the client sets a caching level twice:
      when oplock is detected and when oplock is processed. While the
      1st attempt sets the level to the value provided by the server,
      the 2nd one resets the level to None unconditionally.
      This happens because the oplock/lease processing code was changed
      to avoid races between page cache flushes and oplock breaks.
      The commit c11f1df5 ("cifs: Wait for writebacks to complete
      before attempting write.") fixed the races for oplocks but didn't
      apply the same changes for leases resulting in overwriting the
      server granted value to None. Fix this by properly processing
      lease breaks.
      Signed-off-by: NPavel Shilovsky <pshilov@microsoft.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      CC: Stable <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      3ed9f22e
  6. 31 1月, 2019 1 次提交
  7. 03 9月, 2018 1 次提交
    • S
      smb3: minor debugging clarifications in rfc1001 len processing · 25f25735
      Steve French 提交于
      I ran into some cases where server was returning the wrong length
      on frames but I couldn't easily match them to the command in the
      network trace (or server logs) since I need the command and/or
      multiplex id to find the offending SMB2/SMB3 command.  Add these
      two fields to the log message. In the case of padding too much
      it may not be a problem in all cases but might have correlated
      to a network disconnect case in some problems we have been
      looking at. In the case of frame too short is even more important.
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      Reviewed-by: NRonnie Sahlberg <lsahlber@redhat.com>
      25f25735
  8. 24 8月, 2018 1 次提交
  9. 08 8月, 2018 1 次提交
  10. 15 6月, 2018 2 次提交
  11. 07 6月, 2018 1 次提交
  12. 03 6月, 2018 1 次提交
  13. 01 6月, 2018 6 次提交
  14. 31 5月, 2018 1 次提交
  15. 28 5月, 2018 1 次提交
  16. 13 4月, 2018 2 次提交
  17. 03 4月, 2018 2 次提交
  18. 02 4月, 2018 1 次提交
  19. 25 1月, 2018 1 次提交
  20. 03 5月, 2017 1 次提交
    • R
      CIFS: fix oplock break deadlocks · 3998e6b8
      Rabin Vincent 提交于
      When the final cifsFileInfo_put() is called from cifsiod and an oplock
      break work is queued, lockdep complains loudly:
      
       =============================================
       [ INFO: possible recursive locking detected ]
       4.11.0+ #21 Not tainted
       ---------------------------------------------
       kworker/0:2/78 is trying to acquire lock:
        ("cifsiod"){++++.+}, at: flush_work+0x215/0x350
      
       but task is already holding lock:
        ("cifsiod"){++++.+}, at: process_one_work+0x255/0x8e0
      
       other info that might help us debug this:
        Possible unsafe locking scenario:
      
              CPU0
              ----
         lock("cifsiod");
         lock("cifsiod");
      
        *** DEADLOCK ***
      
        May be due to missing lock nesting notation
      
       2 locks held by kworker/0:2/78:
        #0:  ("cifsiod"){++++.+}, at: process_one_work+0x255/0x8e0
        #1:  ((&wdata->work)){+.+...}, at: process_one_work+0x255/0x8e0
      
       stack backtrace:
       CPU: 0 PID: 78 Comm: kworker/0:2 Not tainted 4.11.0+ #21
       Workqueue: cifsiod cifs_writev_complete
       Call Trace:
        dump_stack+0x85/0xc2
        __lock_acquire+0x17dd/0x2260
        ? match_held_lock+0x20/0x2b0
        ? trace_hardirqs_off_caller+0x86/0x130
        ? mark_lock+0xa6/0x920
        lock_acquire+0xcc/0x260
        ? lock_acquire+0xcc/0x260
        ? flush_work+0x215/0x350
        flush_work+0x236/0x350
        ? flush_work+0x215/0x350
        ? destroy_worker+0x170/0x170
        __cancel_work_timer+0x17d/0x210
        ? ___preempt_schedule+0x16/0x18
        cancel_work_sync+0x10/0x20
        cifsFileInfo_put+0x338/0x7f0
        cifs_writedata_release+0x2a/0x40
        ? cifs_writedata_release+0x2a/0x40
        cifs_writev_complete+0x29d/0x850
        ? preempt_count_sub+0x18/0xd0
        process_one_work+0x304/0x8e0
        worker_thread+0x9b/0x6a0
        kthread+0x1b2/0x200
        ? process_one_work+0x8e0/0x8e0
        ? kthread_create_on_node+0x40/0x40
        ret_from_fork+0x31/0x40
      
      This is a real warning.  Since the oplock is queued on the same
      workqueue this can deadlock if there is only one worker thread active
      for the workqueue (which will be the case during memory pressure when
      the rescuer thread is handling it).
      
      Furthermore, there is at least one other kind of hang possible due to
      the oplock break handling if there is only worker.  (This can be
      reproduced without introducing memory pressure by having passing 1 for
      the max_active parameter of cifsiod.) cifs_oplock_break() can wait
      indefintely in the filemap_fdatawait() while the cifs_writev_complete()
      work is blocked:
      
       sysrq: SysRq : Show Blocked State
         task                        PC stack   pid father
       kworker/0:1     D    0    16      2 0x00000000
       Workqueue: cifsiod cifs_oplock_break
       Call Trace:
        __schedule+0x562/0xf40
        ? mark_held_locks+0x4a/0xb0
        schedule+0x57/0xe0
        io_schedule+0x21/0x50
        wait_on_page_bit+0x143/0x190
        ? add_to_page_cache_lru+0x150/0x150
        __filemap_fdatawait_range+0x134/0x190
        ? do_writepages+0x51/0x70
        filemap_fdatawait_range+0x14/0x30
        filemap_fdatawait+0x3b/0x40
        cifs_oplock_break+0x651/0x710
        ? preempt_count_sub+0x18/0xd0
        process_one_work+0x304/0x8e0
        worker_thread+0x9b/0x6a0
        kthread+0x1b2/0x200
        ? process_one_work+0x8e0/0x8e0
        ? kthread_create_on_node+0x40/0x40
        ret_from_fork+0x31/0x40
       dd              D    0   683    171 0x00000000
       Call Trace:
        __schedule+0x562/0xf40
        ? mark_held_locks+0x29/0xb0
        schedule+0x57/0xe0
        io_schedule+0x21/0x50
        wait_on_page_bit+0x143/0x190
        ? add_to_page_cache_lru+0x150/0x150
        __filemap_fdatawait_range+0x134/0x190
        ? do_writepages+0x51/0x70
        filemap_fdatawait_range+0x14/0x30
        filemap_fdatawait+0x3b/0x40
        filemap_write_and_wait+0x4e/0x70
        cifs_flush+0x6a/0xb0
        filp_close+0x52/0xa0
        __close_fd+0xdc/0x150
        SyS_close+0x33/0x60
        entry_SYSCALL_64_fastpath+0x1f/0xbe
      
       Showing all locks held in the system:
       2 locks held by kworker/0:1/16:
        #0:  ("cifsiod"){.+.+.+}, at: process_one_work+0x255/0x8e0
        #1:  ((&cfile->oplock_break)){+.+.+.}, at: process_one_work+0x255/0x8e0
      
       Showing busy workqueues and worker pools:
       workqueue cifsiod: flags=0xc
         pwq 0: cpus=0 node=0 flags=0x0 nice=0 active=1/1
           in-flight: 16:cifs_oplock_break
           delayed: cifs_writev_complete, cifs_echo_request
       pool 0: cpus=0 node=0 flags=0x0 nice=0 hung=0s workers=3 idle: 750 3
      
      Fix these problems by creating a a new workqueue (with a rescuer) for
      the oplock break work.
      Signed-off-by: NRabin Vincent <rabinv@axis.com>
      Signed-off-by: NSteve French <smfrench@gmail.com>
      CC: Stable <stable@vger.kernel.org>
      3998e6b8
  21. 07 4月, 2017 1 次提交
    • S
      Handle mismatched open calls · 38bd4906
      Sachin Prabhu 提交于
      A signal can interrupt a SendReceive call which result in incoming
      responses to the call being ignored. This is a problem for calls such as
      open which results in the successful response being ignored. This
      results in an open file resource on the server.
      
      The patch looks into responses which were cancelled after being sent and
      in case of successful open closes the open fids.
      
      For this patch, the check is only done in SendReceive2()
      
      RH-bz: 1403319
      Signed-off-by: NSachin Prabhu <sprabhu@redhat.com>
      Reviewed-by: NPavel Shilovsky <pshilov@microsoft.com>
      Cc: Stable <stable@vger.kernel.org>
      38bd4906
  22. 02 2月, 2017 1 次提交
  23. 13 10月, 2016 1 次提交
  24. 15 1月, 2016 1 次提交
  25. 16 4月, 2015 1 次提交
  26. 01 4月, 2015 1 次提交
  27. 15 12月, 2014 1 次提交
    • S
      Convert MessageID in smb2_hdr to LE · 9235d098
      Sachin Prabhu 提交于
      We have encountered failures when When testing smb2 mounts on ppc64
      machines when using both Samba as well as Windows 2012.
      
      On poking around, the problem was determined to be caused by the
      high endian MessageID passed in the header for smb2. On checking the
      corresponding MID for smb1 is converted to LE before being sent on the
      wire.
      
      We have tested this patch successfully on a ppc64 machine.
      Signed-off-by: NSachin Prabhu <sprabhu@redhat.com>
      9235d098
  28. 11 12月, 2014 1 次提交
  29. 17 10月, 2014 1 次提交
  30. 16 8月, 2014 1 次提交
    • S
      [CIFS] Workaround MacOS server problem with SMB2.1 write · 754789a1
      Steve French 提交于
       response
      
      Writes fail to Mac servers with SMB2.1 mounts (works with cifs though) due
      to them sending an incorrect RFC1001 length for the SMB2.1 Write response.
      Workaround this problem. MacOS server sends a write response with 3 bytes
      of pad beyond the end of the SMB itself.  The RFC1001 length is 3 bytes
      more than the sum of the SMB2.1 header length + the write reponse.
      
      Incorporate feedback from Jeff and JRA to allow servers to send
      a tcp frame that is even more than three bytes too long
      (ie much longer than the SMB2/SMB3 request that it contains) but
      we do log it once now. In the earlier version of the patch I had
      limited how far off the length field could be before we fail the request.
      Signed-off-by: NSteve French <smfrench@gmail.com>
      754789a1
  31. 03 8月, 2014 1 次提交
  32. 17 4月, 2014 1 次提交
    • S
      cifs: Wait for writebacks to complete before attempting write. · c11f1df5
      Sachin Prabhu 提交于
      Problem reported in Red Hat bz 1040329 for strict writes where we cache
      only when we hold oplock and write direct to the server when we don't.
      
      When we receive an oplock break, we first change the oplock value for
      the inode in cifsInodeInfo->oplock to indicate that we no longer hold
      the oplock before we enqueue a task to flush changes to the backing
      device. Once we have completed flushing the changes, we return the
      oplock to the server.
      
      There are 2 ways here where we can have data corruption
      1) While we flush changes to the backing device as part of the oplock
      break, we can have processes write to the file. These writes check for
      the oplock, find none and attempt to write directly to the server.
      These direct writes made while we are flushing from cache could be
      overwritten by data being flushed from the cache causing data
      corruption.
      2) While a thread runs in cifs_strict_writev, the machine could receive
      and process an oplock break after the thread has checked the oplock and
      found that it allows us to cache and before we have made changes to the
      cache. In that case, we end up with a dirty page in cache when we
      shouldn't have any. This will be flushed later and will overwrite all
      subsequent writes to the part of the file represented by this page.
      
      Before making any writes to the server, we need to confirm that we are
      not in the process of flushing data to the server and if we are, we
      should wait until the process is complete before we attempt the write.
      We should also wait for existing writes to complete before we process
      an oplock break request which changes oplock values.
      
      We add a version specific  downgrade_oplock() operation to allow for
      differences in the oplock values set for the different smb versions.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: NSachin Prabhu <sprabhu@redhat.com>
      Reviewed-by: NJeff Layton <jlayton@redhat.com>
      Reviewed-by: NPavel Shilovsky <piastry@etersoft.ru>
      Signed-off-by: NSteve French <smfrench@gmail.com>
      c11f1df5