1. 25 11月, 2019 5 次提交
    • R
      cifs: move cifsFileInfo_put logic into a work-queue · 32546a95
      Ronnie Sahlberg 提交于
      This patch moves the final part of the cifsFileInfo_put() logic where we
      need a write lock on lock_sem to be processed in a separate thread that
      holds no other locks.
      This is to prevent deadlocks like the one below:
      
      > there are 6 processes looping to while trying to down_write
      > cinode->lock_sem, 5 of them from _cifsFileInfo_put, and one from
      > cifs_new_fileinfo
      >
      > and there are 5 other processes which are blocked, several of them
      > waiting on either PG_writeback or PG_locked (which are both set), all
      > for the same page of the file
      >
      > 2 inode_lock() (inode->i_rwsem) for the file
      > 1 wait_on_page_writeback() for the page
      > 1 down_read(inode->i_rwsem) for the inode of the directory
      > 1 inode_lock()(inode->i_rwsem) for the inode of the directory
      > 1 __lock_page
      >
      >
      > so processes are blocked waiting on:
      >   page flags PG_locked and PG_writeback for one specific page
      >   inode->i_rwsem for the directory
      >   inode->i_rwsem for the file
      >   cifsInodeInflock_sem
      >
      >
      >
      > here are the more gory details (let me know if I need to provide
      > anything more/better):
      >
      > [0 00:48:22.765] [UN]  PID: 8863   TASK: ffff8c691547c5c0  CPU: 3
      > COMMAND: "reopen_file"
      >  #0 [ffff9965007e3ba8] __schedule at ffffffff9b6e6095
      >  #1 [ffff9965007e3c38] schedule at ffffffff9b6e64df
      >  #2 [ffff9965007e3c48] rwsem_down_write_slowpath at ffffffff9af283d7
      >  #3 [ffff9965007e3cb8] legitimize_path at ffffffff9b0f975d
      >  #4 [ffff9965007e3d08] path_openat at ffffffff9b0fe55d
      >  #5 [ffff9965007e3dd8] do_filp_open at ffffffff9b100a33
      >  #6 [ffff9965007e3ee0] do_sys_open at ffffffff9b0eb2d6
      >  #7 [ffff9965007e3f38] do_syscall_64 at ffffffff9ae04315
      > * (I think legitimize_path is bogus)
      >
      > in path_openat
      >         } else {
      >                 const char *s = path_init(nd, flags);
      >                 while (!(error = link_path_walk(s, nd)) &&
      >                         (error = do_last(nd, file, op)) > 0) {  <<<<
      >
      > do_last:
      >         if (open_flag & O_CREAT)
      >                 inode_lock(dir->d_inode);  <<<<
      >         else
      > so it's trying to take inode->i_rwsem for the directory
      >
      >      DENTRY           INODE           SUPERBLK     TYPE PATH
      > ffff8c68bb8e79c0 ffff8c691158ef20 ffff8c6915bf9000 DIR  /mnt/vm1_smb/
      > inode.i_rwsem is ffff8c691158efc0
      >
      > <struct rw_semaphore 0xffff8c691158efc0>:
      >         owner: <struct task_struct 0xffff8c6914275d00> (UN -   8856 -
      > reopen_file), counter: 0x0000000000000003
      >         waitlist: 2
      >         0xffff9965007e3c90     8863   reopen_file      UN 0  1:29:22.926
      >   RWSEM_WAITING_FOR_WRITE
      >         0xffff996500393e00     9802   ls               UN 0  1:17:26.700
      >   RWSEM_WAITING_FOR_READ
      >
      >
      > the owner of the inode.i_rwsem of the directory is:
      >
      > [0 00:00:00.109] [UN]  PID: 8856   TASK: ffff8c6914275d00  CPU: 3
      > COMMAND: "reopen_file"
      >  #0 [ffff99650065b828] __schedule at ffffffff9b6e6095
      >  #1 [ffff99650065b8b8] schedule at ffffffff9b6e64df
      >  #2 [ffff99650065b8c8] schedule_timeout at ffffffff9b6e9f89
      >  #3 [ffff99650065b940] msleep at ffffffff9af573a9
      >  #4 [ffff99650065b948] _cifsFileInfo_put.cold.63 at ffffffffc0a42dd6 [cifs]
      >  #5 [ffff99650065ba38] cifs_writepage_locked at ffffffffc0a0b8f3 [cifs]
      >  #6 [ffff99650065bab0] cifs_launder_page at ffffffffc0a0bb72 [cifs]
      >  #7 [ffff99650065bb30] invalidate_inode_pages2_range at ffffffff9b04d4bd
      >  #8 [ffff99650065bcb8] cifs_invalidate_mapping at ffffffffc0a11339 [cifs]
      >  #9 [ffff99650065bcd0] cifs_revalidate_mapping at ffffffffc0a1139a [cifs]
      > #10 [ffff99650065bcf0] cifs_d_revalidate at ffffffffc0a014f6 [cifs]
      > #11 [ffff99650065bd08] path_openat at ffffffff9b0fe7f7
      > #12 [ffff99650065bdd8] do_filp_open at ffffffff9b100a33
      > #13 [ffff99650065bee0] do_sys_open at ffffffff9b0eb2d6
      > #14 [ffff99650065bf38] do_syscall_64 at ffffffff9ae04315
      >
      > cifs_launder_page is for page 0xffffd1e2c07d2480
      >
      > crash> page.index,mapping,flags 0xffffd1e2c07d2480
      >       index = 0x8
      >       mapping = 0xffff8c68f3cd0db0
      >   flags = 0xfffffc0008095
      >
      >   PAGE-FLAG       BIT  VALUE
      >   PG_locked         0  0000001
      >   PG_uptodate       2  0000004
      >   PG_lru            4  0000010
      >   PG_waiters        7  0000080
      >   PG_writeback     15  0008000
      >
      >
      > inode is ffff8c68f3cd0c40
      > inode.i_rwsem is ffff8c68f3cd0ce0
      >      DENTRY           INODE           SUPERBLK     TYPE PATH
      > ffff8c68a1f1b480 ffff8c68f3cd0c40 ffff8c6915bf9000 REG
      > /mnt/vm1_smb/testfile.8853
      >
      >
      > this process holds the inode->i_rwsem for the parent directory, is
      > laundering a page attached to the inode of the file it's opening, and in
      > _cifsFileInfo_put is trying to down_write the cifsInodeInflock_sem
      > for the file itself.
      >
      >
      > <struct rw_semaphore 0xffff8c68f3cd0ce0>:
      >         owner: <struct task_struct 0xffff8c6914272e80> (UN -   8854 -
      > reopen_file), counter: 0x0000000000000003
      >         waitlist: 1
      >         0xffff9965005dfd80     8855   reopen_file      UN 0  1:29:22.912
      >   RWSEM_WAITING_FOR_WRITE
      >
      > this is the inode.i_rwsem for the file
      >
      > the owner:
      >
      > [0 00:48:22.739] [UN]  PID: 8854   TASK: ffff8c6914272e80  CPU: 2
      > COMMAND: "reopen_file"
      >  #0 [ffff99650054fb38] __schedule at ffffffff9b6e6095
      >  #1 [ffff99650054fbc8] schedule at ffffffff9b6e64df
      >  #2 [ffff99650054fbd8] io_schedule at ffffffff9b6e68e2
      >  #3 [ffff99650054fbe8] __lock_page at ffffffff9b03c56f
      >  #4 [ffff99650054fc80] pagecache_get_page at ffffffff9b03dcdf
      >  #5 [ffff99650054fcc0] grab_cache_page_write_begin at ffffffff9b03ef4c
      >  #6 [ffff99650054fcd0] cifs_write_begin at ffffffffc0a064ec [cifs]
      >  #7 [ffff99650054fd30] generic_perform_write at ffffffff9b03bba4
      >  #8 [ffff99650054fda8] __generic_file_write_iter at ffffffff9b04060a
      >  #9 [ffff99650054fdf0] cifs_strict_writev.cold.70 at ffffffffc0a4469b [cifs]
      > #10 [ffff99650054fe48] new_sync_write at ffffffff9b0ec1dd
      > #11 [ffff99650054fed0] vfs_write at ffffffff9b0eed35
      > #12 [ffff99650054ff00] ksys_write at ffffffff9b0eefd9
      > #13 [ffff99650054ff38] do_syscall_64 at ffffffff9ae04315
      >
      > the process holds the inode->i_rwsem for the file to which it's writing,
      > and is trying to __lock_page for the same page as in the other processes
      >
      >
      > the other tasks:
      > [0 00:00:00.028] [UN]  PID: 8859   TASK: ffff8c6915479740  CPU: 2
      > COMMAND: "reopen_file"
      >  #0 [ffff9965007b39d8] __schedule at ffffffff9b6e6095
      >  #1 [ffff9965007b3a68] schedule at ffffffff9b6e64df
      >  #2 [ffff9965007b3a78] schedule_timeout at ffffffff9b6e9f89
      >  #3 [ffff9965007b3af0] msleep at ffffffff9af573a9
      >  #4 [ffff9965007b3af8] cifs_new_fileinfo.cold.61 at ffffffffc0a42a07 [cifs]
      >  #5 [ffff9965007b3b78] cifs_open at ffffffffc0a0709d [cifs]
      >  #6 [ffff9965007b3cd8] do_dentry_open at ffffffff9b0e9b7a
      >  #7 [ffff9965007b3d08] path_openat at ffffffff9b0fe34f
      >  #8 [ffff9965007b3dd8] do_filp_open at ffffffff9b100a33
      >  #9 [ffff9965007b3ee0] do_sys_open at ffffffff9b0eb2d6
      > #10 [ffff9965007b3f38] do_syscall_64 at ffffffff9ae04315
      >
      > this is opening the file, and is trying to down_write cinode->lock_sem
      >
      >
      > [0 00:00:00.041] [UN]  PID: 8860   TASK: ffff8c691547ae80  CPU: 2
      > COMMAND: "reopen_file"
      > [0 00:00:00.057] [UN]  PID: 8861   TASK: ffff8c6915478000  CPU: 3
      > COMMAND: "reopen_file"
      > [0 00:00:00.059] [UN]  PID: 8858   TASK: ffff8c6914271740  CPU: 2
      > COMMAND: "reopen_file"
      > [0 00:00:00.109] [UN]  PID: 8862   TASK: ffff8c691547dd00  CPU: 6
      > COMMAND: "reopen_file"
      >  #0 [ffff9965007c3c78] __schedule at ffffffff9b6e6095
      >  #1 [ffff9965007c3d08] schedule at ffffffff9b6e64df
      >  #2 [ffff9965007c3d18] schedule_timeout at ffffffff9b6e9f89
      >  #3 [ffff9965007c3d90] msleep at ffffffff9af573a9
      >  #4 [ffff9965007c3d98] _cifsFileInfo_put.cold.63 at ffffffffc0a42dd6 [cifs]
      >  #5 [ffff9965007c3e88] cifs_close at ffffffffc0a07aaf [cifs]
      >  #6 [ffff9965007c3ea0] __fput at ffffffff9b0efa6e
      >  #7 [ffff9965007c3ee8] task_work_run at ffffffff9aef1614
      >  #8 [ffff9965007c3f20] exit_to_usermode_loop at ffffffff9ae03d6f
      >  #9 [ffff9965007c3f38] do_syscall_64 at ffffffff9ae0444c
      >
      > closing the file, and trying to down_write cifsi->lock_sem
      >
      >
      > [0 00:48:22.839] [UN]  PID: 8857   TASK: ffff8c6914270000  CPU: 7
      > COMMAND: "reopen_file"
      >  #0 [ffff9965006a7cc8] __schedule at ffffffff9b6e6095
      >  #1 [ffff9965006a7d58] schedule at ffffffff9b6e64df
      >  #2 [ffff9965006a7d68] io_schedule at ffffffff9b6e68e2
      >  #3 [ffff9965006a7d78] wait_on_page_bit at ffffffff9b03cac6
      >  #4 [ffff9965006a7e10] __filemap_fdatawait_range at ffffffff9b03b028
      >  #5 [ffff9965006a7ed8] filemap_write_and_wait at ffffffff9b040165
      >  #6 [ffff9965006a7ef0] cifs_flush at ffffffffc0a0c2fa [cifs]
      >  #7 [ffff9965006a7f10] filp_close at ffffffff9b0e93f1
      >  #8 [ffff9965006a7f30] __x64_sys_close at ffffffff9b0e9a0e
      >  #9 [ffff9965006a7f38] do_syscall_64 at ffffffff9ae04315
      >
      > in __filemap_fdatawait_range
      >                         wait_on_page_writeback(page);
      > for the same page of the file
      >
      >
      >
      > [0 00:48:22.718] [UN]  PID: 8855   TASK: ffff8c69142745c0  CPU: 7
      > COMMAND: "reopen_file"
      >  #0 [ffff9965005dfc98] __schedule at ffffffff9b6e6095
      >  #1 [ffff9965005dfd28] schedule at ffffffff9b6e64df
      >  #2 [ffff9965005dfd38] rwsem_down_write_slowpath at ffffffff9af283d7
      >  #3 [ffff9965005dfdf0] cifs_strict_writev at ffffffffc0a0c40a [cifs]
      >  #4 [ffff9965005dfe48] new_sync_write at ffffffff9b0ec1dd
      >  #5 [ffff9965005dfed0] vfs_write at ffffffff9b0eed35
      >  #6 [ffff9965005dff00] ksys_write at ffffffff9b0eefd9
      >  #7 [ffff9965005dff38] do_syscall_64 at ffffffff9ae04315
      >
      >         inode_lock(inode);
      >
      >
      > and one 'ls' later on, to see whether the rest of the mount is available
      > (the test file is in the root, so we get blocked up on the directory
      > ->i_rwsem), so the entire mount is unavailable
      >
      > [0 00:36:26.473] [UN]  PID: 9802   TASK: ffff8c691436ae80  CPU: 4
      > COMMAND: "ls"
      >  #0 [ffff996500393d28] __schedule at ffffffff9b6e6095
      >  #1 [ffff996500393db8] schedule at ffffffff9b6e64df
      >  #2 [ffff996500393dc8] rwsem_down_read_slowpath at ffffffff9b6e9421
      >  #3 [ffff996500393e78] down_read_killable at ffffffff9b6e95e2
      >  #4 [ffff996500393e88] iterate_dir at ffffffff9b103c56
      >  #5 [ffff996500393ec8] ksys_getdents64 at ffffffff9b104b0c
      >  #6 [ffff996500393f30] __x64_sys_getdents64 at ffffffff9b104bb6
      >  #7 [ffff996500393f38] do_syscall_64 at ffffffff9ae04315
      >
      > in iterate_dir:
      >         if (shared)
      >                 res = down_read_killable(&inode->i_rwsem);  <<<<
      >         else
      >                 res = down_write_killable(&inode->i_rwsem);
      >
      Reported-by: NFrank Sorenson <sorenson@redhat.com>
      Reviewed-by: NPavel Shilovsky <pshilov@microsoft.com>
      Signed-off-by: NRonnie Sahlberg <lsahlber@redhat.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      32546a95
    • P
      CIFS: Respect O_SYNC and O_DIRECT flags during reconnect · 44805b0e
      Pavel Shilovsky 提交于
      Currently the client translates O_SYNC and O_DIRECT flags
      into corresponding SMB create options when openning a file.
      The problem is that on reconnect when the file is being
      re-opened the client doesn't set those flags and it causes
      a server to reject re-open requests because create options
      don't match. The latter means that any subsequent system
      call against that open file fail until a share is re-mounted.
      
      Fix this by properly setting SMB create options when
      re-openning files after reconnects.
      
      Fixes: 1013e760: ("SMB3: Don't ignore O_SYNC/O_DSYNC and O_DIRECT flags")
      Cc: Stable <stable@vger.kernel.org>
      Signed-off-by: NPavel Shilovsky <pshilov@microsoft.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      44805b0e
    • L
      cifs: smbd: Invalidate and deregister memory registration on re-send for direct I/O · b7a55bbd
      Long Li 提交于
      On re-send, there might be a reconnect and all prevoius memory registrations
      need to be invalidated and deregistered.
      Signed-off-by: NLong Li <longli@microsoft.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      b7a55bbd
    • Y
      CIFS: remove set but not used variables 'cinode' and 'netfid' · f28a2e5e
      YueHaibing 提交于
      Fixes gcc '-Wunused-but-set-variable' warning:
      
      fs/cifs/file.c: In function 'cifs_flock':
      fs/cifs/file.c:1704:8: warning:
       variable 'netfid' set but not used [-Wunused-but-set-variable]
      
      fs/cifs/file.c:1702:24: warning:
       variable 'cinode' set but not used [-Wunused-but-set-variable]
      Reported-by: NHulk Robot <hulkci@huawei.com>
      Signed-off-by: NYueHaibing <yuehaibing@huawei.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      f28a2e5e
    • S
      cifs: add support for flock · d0677992
      Steve French 提交于
      The flock system call locks the whole file rather than a byte
      range and so is currently emulated by various other file systems
      by simply sending a byte range lock for the whole file.
      Add flock handling for cifs.ko in similar way.
      
      xfstest generic/504 passes with this as well
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      Reviewed-by: NPavel Shilovsky <pshilov@microsoft.com>
      Reviewed-by: NRonnie Sahlberg <lsahlber@redhat.com>
      d0677992
  2. 25 10月, 2019 2 次提交
    • D
      cifs: Fix cifsInodeInfo lock_sem deadlock when reconnect occurs · d46b0da7
      Dave Wysochanski 提交于
      There's a deadlock that is possible and can easily be seen with
      a test where multiple readers open/read/close of the same file
      and a disruption occurs causing reconnect.  The deadlock is due
      a reader thread inside cifs_strict_readv calling down_read and
      obtaining lock_sem, and then after reconnect inside
      cifs_reopen_file calling down_read a second time.  If in
      between the two down_read calls, a down_write comes from
      another process, deadlock occurs.
      
              CPU0                    CPU1
              ----                    ----
      cifs_strict_readv()
       down_read(&cifsi->lock_sem);
                                     _cifsFileInfo_put
                                        OR
                                     cifs_new_fileinfo
                                      down_write(&cifsi->lock_sem);
      cifs_reopen_file()
       down_read(&cifsi->lock_sem);
      
      Fix the above by changing all down_write(lock_sem) calls to
      down_write_trylock(lock_sem)/msleep() loop, which in turn
      makes the second down_read call benign since it will never
      block behind the writer while holding lock_sem.
      Signed-off-by: NDave Wysochanski <dwysocha@redhat.com>
      Suggested-by: NRonnie Sahlberg <lsahlber@redhat.com>
      Reviewed--by: NRonnie Sahlberg <lsahlber@redhat.com>
      Reviewed-by: NPavel Shilovsky <pshilov@microsoft.com>
      d46b0da7
    • P
      CIFS: Fix use after free of file info structures · 1a67c415
      Pavel Shilovsky 提交于
      Currently the code assumes that if a file info entry belongs
      to lists of open file handles of an inode and a tcon then
      it has non-zero reference. The recent changes broke that
      assumption when putting the last reference of the file info.
      There may be a situation when a file is being deleted but
      nothing prevents another thread to reference it again
      and start using it. This happens because we do not hold
      the inode list lock while checking the number of references
      of the file info structure. Fix this by doing the proper
      locking when doing the check.
      
      Fixes: 487317c9 ("cifs: add spinlock for the openFileList to cifsInodeInfo")
      Fixes: cb248819 ("cifs: use cifsInodeInfo->open_file_lock while iterating to avoid a panic")
      Cc: Stable <stable@vger.kernel.org>
      Reviewed-by: NRonnie Sahlberg <lsahlber@redhat.com>
      Signed-off-by: NPavel Shilovsky <pshilov@microsoft.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      1a67c415
  3. 07 10月, 2019 2 次提交
    • P
      CIFS: Gracefully handle QueryInfo errors during open · 30573a82
      Pavel Shilovsky 提交于
      Currently if the client identifies problems when processing
      metadata returned in CREATE response, the open handle is being
      leaked. This causes multiple problems like a file missing a lease
      break by that client which causes high latencies to other clients
      accessing the file. Another side-effect of this is that the file
      can't be deleted.
      
      Fix this by closing the file after the client hits an error after
      the file was opened and the open descriptor wasn't returned to
      the user space. Also convert -ESTALE to -EOPENSTALE to allow
      the VFS to revalidate a dentry and retry the open.
      
      Cc: <stable@vger.kernel.org>
      Signed-off-by: NPavel Shilovsky <pshilov@microsoft.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      30573a82
    • D
      cifs: use cifsInodeInfo->open_file_lock while iterating to avoid a panic · cb248819
      Dave Wysochanski 提交于
      Commit 487317c9 ("cifs: add spinlock for the openFileList to
      cifsInodeInfo") added cifsInodeInfo->open_file_lock spin_lock to protect
      the openFileList, but missed a few places where cifs_inode->openFileList
      was enumerated.  Change these remaining tcon->open_file_lock to
      cifsInodeInfo->open_file_lock to avoid panic in is_size_safe_to_change.
      
      [17313.245641] RIP: 0010:is_size_safe_to_change+0x57/0xb0 [cifs]
      [17313.245645] Code: 68 40 48 89 ef e8 19 67 b7 f1 48 8b 43 40 48 8d 4b 40 48 8d 50 f0 48 39 c1 75 0f eb 47 48 8b 42 10 48 8d 50 f0 48 39 c1 74 3a <8b> 80 88 00 00 00 83 c0 01 a8 02 74 e6 48 89 ef c6 07 00 0f 1f 40
      [17313.245649] RSP: 0018:ffff94ae1baefa30 EFLAGS: 00010202
      [17313.245654] RAX: dead000000000100 RBX: ffff88dc72243300 RCX: ffff88dc72243340
      [17313.245657] RDX: dead0000000000f0 RSI: 00000000098f7940 RDI: ffff88dd3102f040
      [17313.245659] RBP: ffff88dd3102f040 R08: 0000000000000000 R09: ffff94ae1baefc40
      [17313.245661] R10: ffffcdc8bb1c4e80 R11: ffffcdc8b50adb08 R12: 00000000098f7940
      [17313.245663] R13: ffff88dc72243300 R14: ffff88dbc8f19600 R15: ffff88dc72243428
      [17313.245667] FS:  00007fb145485700(0000) GS:ffff88dd3e000000(0000) knlGS:0000000000000000
      [17313.245670] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [17313.245672] CR2: 0000026bb46c6000 CR3: 0000004edb110003 CR4: 00000000007606e0
      [17313.245753] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      [17313.245756] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
      [17313.245759] PKRU: 55555554
      [17313.245761] Call Trace:
      [17313.245803]  cifs_fattr_to_inode+0x16b/0x580 [cifs]
      [17313.245838]  cifs_get_inode_info+0x35c/0xa60 [cifs]
      [17313.245852]  ? kmem_cache_alloc_trace+0x151/0x1d0
      [17313.245885]  cifs_open+0x38f/0x990 [cifs]
      [17313.245921]  ? cifs_revalidate_dentry_attr+0x3e/0x350 [cifs]
      [17313.245953]  ? cifsFileInfo_get+0x30/0x30 [cifs]
      [17313.245960]  ? do_dentry_open+0x132/0x330
      [17313.245963]  do_dentry_open+0x132/0x330
      [17313.245969]  path_openat+0x573/0x14d0
      [17313.245974]  do_filp_open+0x93/0x100
      [17313.245979]  ? __check_object_size+0xa3/0x181
      [17313.245986]  ? audit_alloc_name+0x7e/0xd0
      [17313.245992]  do_sys_open+0x184/0x220
      [17313.245999]  do_syscall_64+0x5b/0x1b0
      
      Fixes: 487317c9 ("cifs: add spinlock for the openFileList to cifsInodeInfo")
      
      CC: Stable <stable@vger.kernel.org>
      Signed-off-by: NDave Wysochanski <dwysocha@redhat.com>
      Reviewed-by: NRonnie Sahlberg <lsahlber@redhat.com>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      cb248819
  4. 17 9月, 2019 4 次提交
  5. 14 6月, 2019 1 次提交
  6. 30 5月, 2019 1 次提交
  7. 08 5月, 2019 1 次提交
  8. 25 4月, 2019 1 次提交
    • J
      cifs: fix page reference leak with readv/writev · 13f5938d
      Jérôme Glisse 提交于
      CIFS can leak pages reference gotten through GUP (get_user_pages*()
      through iov_iter_get_pages()). This happen if cifs_send_async_read()
      or cifs_write_from_iter() calls fail from within __cifs_readv() and
      __cifs_writev() respectively. This patch move page unreference to
      cifs_aio_ctx_release() which will happens on all code paths this is
      all simpler to follow for correctness.
      Signed-off-by: NJérôme Glisse <jglisse@redhat.com>
      Cc: Steve French <sfrench@samba.org>
      Cc: linux-cifs@vger.kernel.org
      Cc: samba-technical@lists.samba.org
      Cc: Alexander Viro <viro@zeniv.linux.org.uk>
      Cc: linux-fsdevel@vger.kernel.org
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Stable <stable@vger.kernel.org>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      Reviewed-by: NPavel Shilovsky <pshilov@microsoft.com>
      13f5938d
  9. 16 4月, 2019 1 次提交
    • A
      CIFS: keep FileInfo handle live during oplock break · b98749ca
      Aurelien Aptel 提交于
      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>
      b98749ca
  10. 23 3月, 2019 2 次提交
  11. 15 3月, 2019 1 次提交
    • A
      CIFS: fix POSIX lock leak and invalid ptr deref · bc31d0cd
      Aurelien Aptel 提交于
      We have a customer reporting crashes in lock_get_status() with many
      "Leaked POSIX lock" messages preceeding the crash.
      
       Leaked POSIX lock on dev=0x0:0x56 ...
       Leaked POSIX lock on dev=0x0:0x56 ...
       Leaked POSIX lock on dev=0x0:0x56 ...
       Leaked POSIX lock on dev=0x0:0x53 ...
       Leaked POSIX lock on dev=0x0:0x53 ...
       Leaked POSIX lock on dev=0x0:0x53 ...
       Leaked POSIX lock on dev=0x0:0x53 ...
       POSIX: fl_owner=ffff8900e7b79380 fl_flags=0x1 fl_type=0x1 fl_pid=20709
       Leaked POSIX lock on dev=0x0:0x4b ino...
       Leaked locks on dev=0x0:0x4b ino=0xf911400000029:
       POSIX: fl_owner=ffff89f41c870e00 fl_flags=0x1 fl_type=0x1 fl_pid=19592
       stack segment: 0000 [#1] SMP
       Modules linked in: binfmt_misc msr tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag rpcsec_gss_krb5 arc4 ecb auth_rpcgss nfsv4 md4 nfs nls_utf8 lockd grace cifs sunrpc ccm dns_resolver fscache af_packet iscsi_ibft iscsi_boot_sysfs vmw_vsock_vmci_transport vsock xfs libcrc32c sb_edac edac_core crct10dif_pclmul crc32_pclmul ghash_clmulni_intel drbg ansi_cprng vmw_balloon aesni_intel aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd joydev pcspkr vmxnet3 i2c_piix4 vmw_vmci shpchp fjes processor button ac btrfs xor raid6_pq sr_mod cdrom ata_generic sd_mod ata_piix vmwgfx crc32c_intel drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm serio_raw ahci libahci drm libata vmw_pvscsi sg dm_multipath dm_mod scsi_dh_rdac scsi_dh_emc scsi_dh_alua scsi_mod autofs4
      
       Supported: Yes
       CPU: 6 PID: 28250 Comm: lsof Not tainted 4.4.156-94.64-default #1
       Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/05/2016
       task: ffff88a345f28740 ti: ffff88c74005c000 task.ti: ffff88c74005c000
       RIP: 0010:[<ffffffff8125dcab>]  [<ffffffff8125dcab>] lock_get_status+0x9b/0x3b0
       RSP: 0018:ffff88c74005fd90  EFLAGS: 00010202
       RAX: ffff89bde83e20ae RBX: ffff89e870003d18 RCX: 0000000049534f50
       RDX: ffffffff81a3541f RSI: ffffffff81a3544e RDI: ffff89bde83e20ae
       RBP: 0026252423222120 R08: 0000000020584953 R09: 000000000000ffff
       R10: 0000000000000000 R11: ffff88c74005fc70 R12: ffff89e5ca7b1340
       R13: 00000000000050e5 R14: ffff89e870003d30 R15: ffff89e5ca7b1340
       FS:  00007fafd64be800(0000) GS:ffff89f41fd00000(0000) knlGS:0000000000000000
       CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
       CR2: 0000000001c80018 CR3: 000000a522048000 CR4: 0000000000360670
       DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
       DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
       Stack:
        0000000000000208 ffffffff81a3d6b6 ffff89e870003d30 ffff89e870003d18
        ffff89e5ca7b1340 ffff89f41738d7c0 ffff89e870003d30 ffff89e5ca7b1340
        ffffffff8125e08f 0000000000000000 ffff89bc22b67d00 ffff88c74005ff28
       Call Trace:
        [<ffffffff8125e08f>] locks_show+0x2f/0x70
        [<ffffffff81230ad1>] seq_read+0x251/0x3a0
        [<ffffffff81275bbc>] proc_reg_read+0x3c/0x70
        [<ffffffff8120e456>] __vfs_read+0x26/0x140
        [<ffffffff8120e9da>] vfs_read+0x7a/0x120
        [<ffffffff8120faf2>] SyS_read+0x42/0xa0
        [<ffffffff8161cbc3>] entry_SYSCALL_64_fastpath+0x1e/0xb7
      
      When Linux closes a FD (close(), close-on-exec, dup2(), ...) it calls
      filp_close() which also removes all posix locks.
      
      The lock struct is initialized like so in filp_close() and passed
      down to cifs
      
      	...
              lock.fl_type = F_UNLCK;
              lock.fl_flags = FL_POSIX | FL_CLOSE;
              lock.fl_start = 0;
              lock.fl_end = OFFSET_MAX;
      	...
      
      Note the FL_CLOSE flag, which hints the VFS code that this unlocking
      is done for closing the fd.
      
      filp_close()
        locks_remove_posix(filp, id);
          vfs_lock_file(filp, F_SETLK, &lock, NULL);
            return filp->f_op->lock(filp, cmd, fl) => cifs_lock()
              rc = cifs_setlk(file, flock, type, wait_flag, posix_lck, lock, unlock, xid);
                rc = server->ops->mand_unlock_range(cfile, flock, xid);
                if (flock->fl_flags & FL_POSIX && !rc)
                        rc = locks_lock_file_wait(file, flock)
      
      Notice how we don't call locks_lock_file_wait() which does the
      generic VFS lock/unlock/wait work on the inode if rc != 0.
      
      If we are closing the handle, the SMB server is supposed to remove any
      locks associated with it. Similarly, cifs.ko frees and wakes up any
      lock and lock waiter when closing the file:
      
      cifs_close()
        cifsFileInfo_put(file->private_data)
      	/*
      	 * Delete any outstanding lock records. We'll lose them when the file
      	 * is closed anyway.
      	 */
      	down_write(&cifsi->lock_sem);
      	list_for_each_entry_safe(li, tmp, &cifs_file->llist->locks, llist) {
      		list_del(&li->llist);
      		cifs_del_lock_waiters(li);
      		kfree(li);
      	}
      	list_del(&cifs_file->llist->llist);
      	kfree(cifs_file->llist);
      	up_write(&cifsi->lock_sem);
      
      So we can safely ignore unlocking failures in cifs_lock() if they
      happen with the FL_CLOSE flag hint set as both the server and the
      client take care of it during the actual closing.
      
      This is not a proper fix for the unlocking failure but it's safe and
      it seems to prevent the lock leakages and crashes the customer
      experiences.
      Signed-off-by: NAurelien Aptel <aaptel@suse.com>
      Signed-off-by: NNeilBrown <neil@brown.name>
      Signed-off-by: NSteve French <stfrench@microsoft.com>
      Acked-by: NPavel Shilovsky <pshilov@microsoft.com>
      bc31d0cd
  12. 06 3月, 2019 8 次提交
  13. 05 3月, 2019 1 次提交
  14. 30 1月, 2019 1 次提交
  15. 11 1月, 2019 3 次提交
  16. 05 1月, 2019 1 次提交
  17. 24 12月, 2018 2 次提交
  18. 07 12月, 2018 2 次提交
  19. 01 12月, 2018 1 次提交
    • N
      fs/locks: rename some lists and pointers. · ada5c1da
      NeilBrown 提交于
      struct file lock contains an 'fl_next' pointer which
      is used to point to the lock that this request is blocked
      waiting for.  So rename it to fl_blocker.
      
      The fl_blocked list_head in an active lock is the head of a list of
      blocked requests.  In a request it is a node in that list.
      These are two distinct uses, so replace with two list_heads
      with different names.
      fl_blocked_requests is the head of a list of blocked requests
      fl_blocked_member is a node in a member of that list.
      
      The two different list_heads are never used at the same time, but that
      will change in a future patch.
      
      Note that a tracepoint is changed to report fl_blocker instead
      of fl_next.
      Signed-off-by: NNeilBrown <neilb@suse.com>
      Reviewed-by: NJ. Bruce Fields <bfields@redhat.com>
      Signed-off-by: NJeff Layton <jlayton@kernel.org>
      ada5c1da