]> Git Repo - J-linux.git/commitdiff
Merge tag 'nfsd-5.4' of git://linux-nfs.org/~bfields/linux
authorLinus Torvalds <[email protected]>
Sat, 28 Sep 2019 00:00:27 +0000 (17:00 -0700)
committerLinus Torvalds <[email protected]>
Sat, 28 Sep 2019 00:00:27 +0000 (17:00 -0700)
Pull nfsd updates from Bruce Fields:
 "Highlights:

   - Add a new knfsd file cache, so that we don't have to open and close
     on each (NFSv2/v3) READ or WRITE. This can speed up read and write
     in some cases. It also replaces our readahead cache.

   - Prevent silent data loss on write errors, by treating write errors
     like server reboots for the purposes of write caching, thus forcing
     clients to resend their writes.

   - Tweak the code that allocates sessions to be more forgiving, so
     that NFSv4.1 mounts are less likely to hang when a server already
     has a lot of clients.

   - Eliminate an arbitrary limit on NFSv4 ACL sizes; they should now be
     limited only by the backend filesystem and the maximum RPC size.

   - Allow the server to enforce use of the correct kerberos credentials
     when a client reclaims state after a reboot.

  And some miscellaneous smaller bugfixes and cleanup"

* tag 'nfsd-5.4' of git://linux-nfs.org/~bfields/linux: (34 commits)
  sunrpc: clean up indentation issue
  nfsd: fix nfs read eof detection
  nfsd: Make nfsd_reset_boot_verifier_locked static
  nfsd: degraded slot-count more gracefully as allocation nears exhaustion.
  nfsd: handle drc over-allocation gracefully.
  nfsd: add support for upcall version 2
  nfsd: add a "GetVersion" upcall for nfsdcld
  nfsd: Reset the boot verifier on all write I/O errors
  nfsd: Don't garbage collect files that might contain write errors
  nfsd: Support the server resetting the boot verifier
  nfsd: nfsd_file cache entries should be per net namespace
  nfsd: eliminate an unnecessary acl size limit
  Deprecate nfsd fault injection
  nfsd: remove duplicated include from filecache.c
  nfsd: Fix the documentation for svcxdr_tmpalloc()
  nfsd: Fix up some unused variable warnings
  nfsd: close cached files prior to a REMOVE or RENAME that would replace target
  nfsd: rip out the raparms cache
  nfsd: have nfsd_test_lock use the nfsd_file cache
  nfsd: hook up nfs4_preprocess_stateid_op to the nfsd_file cache
  ...

1  2 
fs/locks.c
fs/nfsd/nfsctl.c
include/linux/fs.h
net/sunrpc/xprtrdma/svc_rdma_transport.c

diff --combined fs/locks.c
index a364ebc5cec3b1b974da670c72e9af0a42e07c2a,c31674d105670317d125652506d321ac3aea2bfe..6970f55daf54341f307a5052eb44b9e2d039ead8
@@@ -212,6 -212,7 +212,7 @@@ struct file_lock_list_struct 
  static DEFINE_PER_CPU(struct file_lock_list_struct, file_lock_list);
  DEFINE_STATIC_PERCPU_RWSEM(file_rwsem);
  
  /*
   * The blocked_hash is used to find POSIX lock loops for deadlock detection.
   * It is protected by blocked_lock_lock.
@@@ -1592,7 -1593,7 +1593,7 @@@ int __break_lease(struct inode *inode, 
        ctx = smp_load_acquire(&inode->i_flctx);
        if (!ctx) {
                WARN_ON_ONCE(1);
 -              return error;
 +              goto free_lock;
        }
  
        percpu_down_read(&file_rwsem);
@@@ -1672,7 -1673,6 +1673,7 @@@ out
        spin_unlock(&ctx->flc_lock);
        percpu_up_read(&file_rwsem);
        locks_dispose_list(&dispose);
 +free_lock:
        locks_free_lock(new_fl);
        return error;
  }
@@@ -1991,6 -1991,64 +1992,64 @@@ int generic_setlease(struct file *filp
  }
  EXPORT_SYMBOL(generic_setlease);
  
+ #if IS_ENABLED(CONFIG_SRCU)
+ /*
+  * Kernel subsystems can register to be notified on any attempt to set
+  * a new lease with the lease_notifier_chain. This is used by (e.g.) nfsd
+  * to close files that it may have cached when there is an attempt to set a
+  * conflicting lease.
+  */
+ static struct srcu_notifier_head lease_notifier_chain;
+ static inline void
+ lease_notifier_chain_init(void)
+ {
+       srcu_init_notifier_head(&lease_notifier_chain);
+ }
+ static inline void
+ setlease_notifier(long arg, struct file_lock *lease)
+ {
+       if (arg != F_UNLCK)
+               srcu_notifier_call_chain(&lease_notifier_chain, arg, lease);
+ }
+ int lease_register_notifier(struct notifier_block *nb)
+ {
+       return srcu_notifier_chain_register(&lease_notifier_chain, nb);
+ }
+ EXPORT_SYMBOL_GPL(lease_register_notifier);
+ void lease_unregister_notifier(struct notifier_block *nb)
+ {
+       srcu_notifier_chain_unregister(&lease_notifier_chain, nb);
+ }
+ EXPORT_SYMBOL_GPL(lease_unregister_notifier);
+ #else /* !IS_ENABLED(CONFIG_SRCU) */
+ static inline void
+ lease_notifier_chain_init(void)
+ {
+ }
+ static inline void
+ setlease_notifier(long arg, struct file_lock *lease)
+ {
+ }
+ int lease_register_notifier(struct notifier_block *nb)
+ {
+       return 0;
+ }
+ EXPORT_SYMBOL_GPL(lease_register_notifier);
+ void lease_unregister_notifier(struct notifier_block *nb)
+ {
+ }
+ EXPORT_SYMBOL_GPL(lease_unregister_notifier);
+ #endif /* IS_ENABLED(CONFIG_SRCU) */
  /**
   * vfs_setlease        -       sets a lease on an open file
   * @filp:     file pointer
  int
  vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv)
  {
+       if (lease)
+               setlease_notifier(arg, *lease);
        if (filp->f_op->setlease)
                return filp->f_op->setlease(filp, arg, lease, priv);
        else
@@@ -2785,10 -2845,10 +2846,10 @@@ static void lock_get_status(struct seq_
                               ? (fl->fl_type & LOCK_WRITE) ? "RW   " : "READ "
                               : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE ");
        } else {
 -              seq_printf(f, "%s ",
 -                             (lease_breaking(fl))
 -                             ? (fl->fl_type == F_UNLCK) ? "UNLCK" : "READ "
 -                             : (fl->fl_type == F_WRLCK) ? "WRITE" : "READ ");
 +              int type = IS_LEASE(fl) ? target_leasetype(fl) : fl->fl_type;
 +
 +              seq_printf(f, "%s ", (type == F_WRLCK) ? "WRITE" :
 +                                   (type == F_RDLCK) ? "READ" : "UNLCK");
        }
        if (inode) {
                /* userspace relies on this representation of dev_t */
@@@ -2924,6 -2984,7 +2985,7 @@@ static int __init filelock_init(void
                INIT_HLIST_HEAD(&fll->hlist);
        }
  
+       lease_notifier_chain_init();
        return 0;
  }
  core_initcall(filelock_init);
diff --combined fs/nfsd/nfsctl.c
index 2c215171c0eb65584cc461c0cc64c587daa53bc5,33cbe2e5d937aafb4492ac4b2535140d0e1969f1..11b42c523f045b15875a98c988a737c6107797fc
@@@ -1385,7 -1385,8 +1385,7 @@@ static int nfsd_fill_super(struct super
  
  static int nfsd_fs_get_tree(struct fs_context *fc)
  {
 -      fc->s_fs_info = get_net(fc->net_ns);
 -      return vfs_get_super(fc, vfs_get_keyed_super, nfsd_fill_super);
 +      return get_tree_keyed(fc, nfsd_fill_super, get_net(fc->net_ns));
  }
  
  static void nfsd_fs_free_fc(struct fs_context *fc)
@@@ -1476,6 -1477,7 +1476,7 @@@ static __net_init int nfsd_init_net(str
  
        atomic_set(&nn->ntf_refcnt, 0);
        init_waitqueue_head(&nn->ntf_wq);
+       seqlock_init(&nn->boot_lock);
  
        mnt =  vfs_kern_mount(&nfsd_fs_type, SB_KERNMOUNT, "nfsd", NULL);
        if (IS_ERR(mnt)) {
diff --combined include/linux/fs.h
index b0c6b0d34d0213569c88c9bd83280c46ecaf2be2,0f106c7f4bb9f7e07a837dc28cc03ecc4eca83df..e0d909d357634bb26a9adfa65ddbcc9bce5364f6
@@@ -64,8 -64,6 +64,8 @@@ struct workqueue_struct
  struct iov_iter;
  struct fscrypt_info;
  struct fscrypt_operations;
 +struct fsverity_info;
 +struct fsverity_operations;
  struct fs_context;
  struct fs_parameter_description;
  
@@@ -429,7 -427,6 +429,7 @@@ int pagecache_write_end(struct file *, 
   * @i_pages: Cached pages.
   * @gfp_mask: Memory allocation flags to use for allocating pages.
   * @i_mmap_writable: Number of VM_SHARED mappings.
 + * @nr_thps: Number of THPs in the pagecache (non-shmem only).
   * @i_mmap: Tree of private and shared mappings.
   * @i_mmap_rwsem: Protects @i_mmap and @i_mmap_writable.
   * @nrpages: Number of page entries, protected by the i_pages lock.
@@@ -447,10 -444,6 +447,10 @@@ struct address_space 
        struct xarray           i_pages;
        gfp_t                   gfp_mask;
        atomic_t                i_mmap_writable;
 +#ifdef CONFIG_READ_ONLY_THP_FOR_FS
 +      /* number of thp, only for non-shmem files */
 +      atomic_t                nr_thps;
 +#endif
        struct rb_root_cached   i_mmap;
        struct rw_semaphore     i_mmap_rwsem;
        unsigned long           nrpages;
@@@ -730,15 -723,9 +730,15 @@@ struct inode 
        struct fscrypt_info     *i_crypt_info;
  #endif
  
 +#ifdef CONFIG_FS_VERITY
 +      struct fsverity_info    *i_verity_info;
 +#endif
 +
        void                    *i_private; /* fs or device private pointer */
  } __randomize_layout;
  
 +struct timespec64 timestamp_truncate(struct timespec64 t, struct inode *inode);
 +
  static inline unsigned int i_blocksize(const struct inode *node)
  {
        return (1 << node->i_blkbits);
@@@ -1168,6 -1155,11 +1168,11 @@@ extern void lease_get_mtime(struct inod
  extern int generic_setlease(struct file *, long, struct file_lock **, void **priv);
  extern int vfs_setlease(struct file *, long, struct file_lock **, void **);
  extern int lease_modify(struct file_lock *, int, struct list_head *);
+ struct notifier_block;
+ extern int lease_register_notifier(struct notifier_block *);
+ extern void lease_unregister_notifier(struct notifier_block *);
  struct files_struct;
  extern void show_fd_locks(struct seq_file *f,
                         struct file *filp, struct files_struct *files);
@@@ -1440,10 -1432,6 +1445,10 @@@ struct super_block 
        const struct xattr_handler **s_xattr;
  #ifdef CONFIG_FS_ENCRYPTION
        const struct fscrypt_operations *s_cop;
 +      struct key              *s_master_keys; /* master crypto keys in use */
 +#endif
 +#ifdef CONFIG_FS_VERITY
 +      const struct fsverity_operations *s_vop;
  #endif
        struct hlist_bl_head    s_roots;        /* alternate root dentries for NFS */
        struct list_head        s_mounts;       /* list of mounts; _not_ for fs use */
  
        /* Granularity of c/m/atime in ns (cannot be worse than a second) */
        u32                     s_time_gran;
 +      /* Time limits for c/m/atime in seconds */
 +      time64_t                   s_time_min;
 +      time64_t                   s_time_max;
  #ifdef CONFIG_FSNOTIFY
        __u32                   s_fsnotify_mask;
        struct fsnotify_mark_connector __rcu    *s_fsnotify_marks;
@@@ -1985,7 -1970,6 +1990,7 @@@ struct super_operations 
  #endif
  #define S_ENCRYPTED   16384   /* Encrypted file (using fs/crypto/) */
  #define S_CASEFOLD    32768   /* Casefolded file */
 +#define S_VERITY      65536   /* Verity file (using fs/verity/) */
  
  /*
   * Note that nosuid etc flags are inode-specific: setting some file-system
@@@ -2027,7 -2011,6 +2032,7 @@@ static inline bool sb_rdonly(const stru
  #define IS_DAX(inode)         ((inode)->i_flags & S_DAX)
  #define IS_ENCRYPTED(inode)   ((inode)->i_flags & S_ENCRYPTED)
  #define IS_CASEFOLDED(inode)  ((inode)->i_flags & S_CASEFOLD)
 +#define IS_VERITY(inode)      ((inode)->i_flags & S_VERITY)
  
  #define IS_WHITEOUT(inode)    (S_ISCHR(inode->i_mode) && \
                                 (inode)->i_rdev == WHITEOUT_DEV)
@@@ -2620,12 -2603,6 +2625,12 @@@ extern struct block_device *blkdev_get_
                                               void *holder);
  extern struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode,
                                              void *holder);
 +extern struct block_device *bd_start_claiming(struct block_device *bdev,
 +                                            void *holder);
 +extern void bd_finish_claiming(struct block_device *bdev,
 +                             struct block_device *whole, void *holder);
 +extern void bd_abort_claiming(struct block_device *bdev,
 +                            struct block_device *whole, void *holder);
  extern void blkdev_put(struct block_device *bdev, fmode_t mode);
  extern int __blkdev_reread_part(struct block_device *bdev);
  extern int blkdev_reread_part(struct block_device *bdev);
@@@ -2803,33 -2780,6 +2808,33 @@@ static inline errseq_t filemap_sample_w
        return errseq_sample(&mapping->wb_err);
  }
  
 +static inline int filemap_nr_thps(struct address_space *mapping)
 +{
 +#ifdef CONFIG_READ_ONLY_THP_FOR_FS
 +      return atomic_read(&mapping->nr_thps);
 +#else
 +      return 0;
 +#endif
 +}
 +
 +static inline void filemap_nr_thps_inc(struct address_space *mapping)
 +{
 +#ifdef CONFIG_READ_ONLY_THP_FOR_FS
 +      atomic_inc(&mapping->nr_thps);
 +#else
 +      WARN_ON_ONCE(1);
 +#endif
 +}
 +
 +static inline void filemap_nr_thps_dec(struct address_space *mapping)
 +{
 +#ifdef CONFIG_READ_ONLY_THP_FOR_FS
 +      atomic_dec(&mapping->nr_thps);
 +#else
 +      WARN_ON_ONCE(1);
 +#endif
 +}
 +
  extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
                           int datasync);
  extern int vfs_fsync(struct file *file, int datasync);
@@@ -3580,8 -3530,6 +3585,8 @@@ extern void inode_nohighmem(struct inod
  /* mm/fadvise.c */
  extern int vfs_fadvise(struct file *file, loff_t offset, loff_t len,
                       int advice);
 +extern int generic_fadvise(struct file *file, loff_t offset, loff_t len,
 +                         int advice);
  
  #if defined(CONFIG_IO_URING)
  extern struct sock *io_uring_get_socket(struct file *file);
@@@ -3604,15 -3552,4 +3609,15 @@@ static inline void simple_fill_fsxattr(
        fa->fsx_xflags = xflags;
  }
  
 +/*
 + * Flush file data before changing attributes.  Caller must hold any locks
 + * required to prevent further writes to this file until we're done setting
 + * flags.
 + */
 +static inline int inode_drain_writes(struct inode *inode)
 +{
 +      inode_dio_wait(inode);
 +      return filemap_write_and_wait(inode->i_mapping);
 +}
 +
  #endif /* _LINUX_FS_H */
index 4d3db6ee7f09ca7eae3d4ac239e5dbac452851cc,4182d569b5cfe199d391908465394806c3d52dc0..145a3615c319366fbcc9815f76d59f4e271dc6ff
@@@ -140,14 -140,13 +140,13 @@@ static struct svcxprt_rdma *svc_rdma_cr
        INIT_LIST_HEAD(&cma_xprt->sc_rq_dto_q);
        INIT_LIST_HEAD(&cma_xprt->sc_read_complete_q);
        INIT_LIST_HEAD(&cma_xprt->sc_send_ctxts);
-       INIT_LIST_HEAD(&cma_xprt->sc_recv_ctxts);
+       init_llist_head(&cma_xprt->sc_recv_ctxts);
        INIT_LIST_HEAD(&cma_xprt->sc_rw_ctxts);
        init_waitqueue_head(&cma_xprt->sc_send_wait);
  
        spin_lock_init(&cma_xprt->sc_lock);
        spin_lock_init(&cma_xprt->sc_rq_dto_lock);
        spin_lock_init(&cma_xprt->sc_send_lock);
-       spin_lock_init(&cma_xprt->sc_recv_lock);
        spin_lock_init(&cma_xprt->sc_rw_ctxt_lock);
  
        /*
@@@ -454,14 -453,14 +453,14 @@@ static struct svc_xprt *svc_rdma_accept
                dprintk("svcrdma: error creating PD for connect request\n");
                goto errout;
        }
 -      newxprt->sc_sq_cq = ib_alloc_cq(dev, newxprt, newxprt->sc_sq_depth,
 -                                      0, IB_POLL_WORKQUEUE);
 +      newxprt->sc_sq_cq = ib_alloc_cq_any(dev, newxprt, newxprt->sc_sq_depth,
 +                                          IB_POLL_WORKQUEUE);
        if (IS_ERR(newxprt->sc_sq_cq)) {
                dprintk("svcrdma: error creating SQ CQ for connect request\n");
                goto errout;
        }
 -      newxprt->sc_rq_cq = ib_alloc_cq(dev, newxprt, rq_depth,
 -                                      0, IB_POLL_WORKQUEUE);
 +      newxprt->sc_rq_cq =
 +              ib_alloc_cq_any(dev, newxprt, rq_depth, IB_POLL_WORKQUEUE);
        if (IS_ERR(newxprt->sc_rq_cq)) {
                dprintk("svcrdma: error creating RQ CQ for connect request\n");
                goto errout;
@@@ -630,8 -629,9 +629,9 @@@ static void svc_rdma_free(struct svc_xp
  {
        struct svcxprt_rdma *rdma =
                container_of(xprt, struct svcxprt_rdma, sc_xprt);
        INIT_WORK(&rdma->sc_work, __svc_rdma_free);
-       queue_work(svc_rdma_wq, &rdma->sc_work);
+       schedule_work(&rdma->sc_work);
  }
  
  static int svc_rdma_has_wspace(struct svc_xprt *xprt)
This page took 0.13494 seconds and 4 git commands to generate.