]> Git Repo - linux.git/commitdiff
Merge tag '5.20-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <[email protected]>
Sun, 14 Aug 2022 00:31:18 +0000 (17:31 -0700)
committerLinus Torvalds <[email protected]>
Sun, 14 Aug 2022 00:31:18 +0000 (17:31 -0700)
Pull more cifs updates from Steve French:

 - two fixes for stable, one for a lock length miscalculation, and
   another fixes a lease break timeout bug

 - improvement to handle leases, allows the close timeout to be
   configured more safely

 - five restructuring/cleanup patches

* tag '5.20-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: Do not access tcon->cfids->cfid directly from is_path_accessible
  cifs: Add constructor/destructors for tcon->cfid
  SMB3: fix lease break timeout when multiple deferred close handles for the same file.
  smb3: allow deferred close timeout to be configurable
  cifs: Do not use tcon->cfid directly, use the cfid we get from open_cached_dir
  cifs: Move cached-dir functions into a separate file
  cifs: Remove {cifs,nfs}_fscache_release_page()
  cifs: fix lock length calculation

1  2 
fs/cifs/file.c
fs/cifs/misc.c

diff --combined fs/cifs/file.c
index d5a434176ce5e85f82c52e7676e979c244ef3791,c00f71884b82b5d1878ebc20274ff59bb883ff77..fa738adc031f728d2cd553f0dcaababf2fc275ac
@@@ -34,6 -34,7 +34,7 @@@
  #include "smbdirect.h"
  #include "fs_context.h"
  #include "cifs_ioctl.h"
+ #include "cached_dir.h"
  
  /*
   * Mark as invalid, all open files on tree connections since they
@@@ -64,13 -65,7 +65,7 @@@ cifs_mark_open_files_invalid(struct cif
        }
        spin_unlock(&tcon->open_file_lock);
  
-       mutex_lock(&tcon->crfid.fid_mutex);
-       tcon->crfid.is_valid = false;
-       /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
-       close_cached_dir_lease_locked(&tcon->crfid);
-       memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
-       mutex_unlock(&tcon->crfid.fid_mutex);
+       invalidate_all_cached_dirs(tcon);
        spin_lock(&tcon->tc_lock);
        if (tcon->status == TID_IN_FILES_INVALIDATE)
                tcon->status = TID_NEED_TCON;
@@@ -969,12 -964,12 +964,12 @@@ int cifs_close(struct inode *inode, str
                                 * So, Increase the ref count to avoid use-after-free.
                                 */
                                if (!mod_delayed_work(deferredclose_wq,
-                                               &cfile->deferred, cifs_sb->ctx->acregmax))
+                                               &cfile->deferred, cifs_sb->ctx->closetimeo))
                                        cifsFileInfo_get(cfile);
                        } else {
                                /* Deferred close for files */
                                queue_delayed_work(deferredclose_wq,
-                                               &cfile->deferred, cifs_sb->ctx->acregmax);
+                                               &cfile->deferred, cifs_sb->ctx->closetimeo);
                                cfile->deferred_close_scheduled = true;
                                spin_unlock(&cinode->deferred_lock);
                                return 0;
@@@ -1936,9 -1931,9 +1931,9 @@@ int cifs_lock(struct file *file, int cm
        rc = -EACCES;
        xid = get_xid();
  
-       cifs_dbg(FYI, "Lock parm: 0x%x flockflags: 0x%x flocktype: 0x%x start: %lld end: %lld\n",
-                cmd, flock->fl_flags, flock->fl_type,
-                flock->fl_start, flock->fl_end);
+       cifs_dbg(FYI, "%s: %pD2 cmd=0x%x type=0x%x flags=0x%x r=%lld:%lld\n", __func__, file, cmd,
+                flock->fl_flags, flock->fl_type, (long long)flock->fl_start,
+                (long long)flock->fl_end);
  
        cfile = (struct cifsFileInfo *)file->private_data;
        tcon = tlink_tcon(cfile->tlink);
@@@ -3276,7 -3271,7 +3271,7 @@@ cifs_write_from_iter(loff_t offset, siz
                if (ctx->direct_io) {
                        ssize_t result;
  
 -                      result = iov_iter_get_pages_alloc(
 +                      result = iov_iter_get_pages_alloc2(
                                from, &pagevec, cur_len, &start);
                        if (result < 0) {
                                cifs_dbg(VFS,
                                break;
                        }
                        cur_len = (size_t)result;
 -                      iov_iter_advance(from, cur_len);
  
                        nr_pages =
                                (cur_len + start + PAGE_SIZE - 1) / PAGE_SIZE;
@@@ -4011,7 -4007,7 +4006,7 @@@ cifs_send_async_read(loff_t offset, siz
                if (ctx->direct_io) {
                        ssize_t result;
  
 -                      result = iov_iter_get_pages_alloc(
 +                      result = iov_iter_get_pages_alloc2(
                                        &direct_iov, &pagevec,
                                        cur_len, &start);
                        if (result < 0) {
                                break;
                        }
                        cur_len = (size_t)result;
 -                      iov_iter_advance(&direct_iov, cur_len);
  
                        rdata = cifs_readdata_direct_alloc(
                                        pagevec, cifs_uncached_readv_complete);
@@@ -4256,7 -4253,7 +4251,7 @@@ static ssize_t __cifs_readv
        if (!is_sync_kiocb(iocb))
                ctx->iocb = iocb;
  
 -      if (iter_is_iovec(to))
 +      if (user_backed_iter(to))
                ctx->should_dirty = true;
  
        if (direct) {
@@@ -5064,8 -5061,6 +5059,6 @@@ void cifs_oplock_break(struct work_stru
        struct TCP_Server_Info *server = tcon->ses->server;
        int rc = 0;
        bool purge_cache = false;
-       bool is_deferred = false;
-       struct cifs_deferred_close *dclose;
  
        wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
                        TASK_UNINTERRUPTIBLE);
                cifs_dbg(VFS, "Push locks rc = %d\n", rc);
  
  oplock_break_ack:
-       /*
-        * When oplock break is received and there are no active
-        * file handles but cached, then schedule deferred close immediately.
-        * So, new open will not use cached handle.
-        */
-       spin_lock(&CIFS_I(inode)->deferred_lock);
-       is_deferred = cifs_is_deferred_close(cfile, &dclose);
-       spin_unlock(&CIFS_I(inode)->deferred_lock);
-       if (is_deferred &&
-           cfile->deferred_close_scheduled &&
-           delayed_work_pending(&cfile->deferred)) {
-               if (cancel_delayed_work(&cfile->deferred)) {
-                       _cifsFileInfo_put(cfile, false, false);
-                       goto oplock_break_done;
-               }
-       }
        /*
         * releasing stale oplock after recent reconnect of smb session using
         * a now incorrect file handle is not a data integrity issue but do
                                                             cinode);
                cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
        }
- oplock_break_done:
        _cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
        cifs_done_oplock_break(cinode);
  }
diff --combined fs/cifs/misc.c
index 987f47f665d546c44d57a5c76cf67248b1f404d1,3f4f3d1a378f1c850865eed94b775682212b25b2..34d990f06fd6a4dddc03d3270955986671d3534c
@@@ -23,6 -23,7 +23,7 @@@
  #include "dns_resolve.h"
  #endif
  #include "fs_context.h"
+ #include "cached_dir.h"
  
  extern mempool_t *cifs_sm_req_poolp;
  extern mempool_t *cifs_req_poolp;
@@@ -116,13 -117,11 +117,11 @@@ tconInfoAlloc(void
        ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL);
        if (!ret_buf)
                return NULL;
-       ret_buf->crfid.fid = kzalloc(sizeof(*ret_buf->crfid.fid), GFP_KERNEL);
-       if (!ret_buf->crfid.fid) {
+       ret_buf->cfid = init_cached_dir();
+       if (!ret_buf->cfid) {
                kfree(ret_buf);
                return NULL;
        }
-       INIT_LIST_HEAD(&ret_buf->crfid.dirents.entries);
-       mutex_init(&ret_buf->crfid.dirents.de_mutex);
  
        atomic_inc(&tconInfoAllocCount);
        ret_buf->status = TID_NEW;
        INIT_LIST_HEAD(&ret_buf->openFileList);
        INIT_LIST_HEAD(&ret_buf->tcon_list);
        spin_lock_init(&ret_buf->open_file_lock);
-       mutex_init(&ret_buf->crfid.fid_mutex);
        spin_lock_init(&ret_buf->stat_lock);
        atomic_set(&ret_buf->num_local_opens, 0);
        atomic_set(&ret_buf->num_remote_opens, 0);
  }
  
  void
- tconInfoFree(struct cifs_tcon *buf_to_free)
+ tconInfoFree(struct cifs_tcon *tcon)
  {
-       if (buf_to_free == NULL) {
+       if (tcon == NULL) {
                cifs_dbg(FYI, "Null buffer passed to tconInfoFree\n");
                return;
        }
+       free_cached_dir(tcon);
        atomic_dec(&tconInfoAllocCount);
-       kfree(buf_to_free->nativeFileSystem);
-       kfree_sensitive(buf_to_free->password);
-       kfree(buf_to_free->crfid.fid);
-       kfree(buf_to_free);
+       kfree(tcon->nativeFileSystem);
+       kfree_sensitive(tcon->password);
+       kfree(tcon);
  }
  
  struct smb_hdr *
@@@ -1022,7 -1020,7 +1020,7 @@@ setup_aio_ctx_iter(struct cifs_aio_ctx 
        saved_len = count;
  
        while (count && npages < max_pages) {
 -              rc = iov_iter_get_pages(iter, pages, count, max_pages, &start);
 +              rc = iov_iter_get_pages2(iter, pages, count, max_pages, &start);
                if (rc < 0) {
                        cifs_dbg(VFS, "Couldn't get user pages (rc=%zd)\n", rc);
                        break;
                        break;
                }
  
 -              iov_iter_advance(iter, rc);
                count -= rc;
                rc += start;
                cur_npages = DIV_ROUND_UP(rc, PAGE_SIZE);
This page took 0.071186 seconds and 4 git commands to generate.