Merge branch 'iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Feb 2015 23:48:33 +0000 (15:48 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Feb 2015 23:48:33 +0000 (15:48 -0800)
Pull iov_iter updates from Al Viro:
 "More iov_iter work - missing counterpart of iov_iter_init() for
  bvec-backed ones and vfs_read_iter()/vfs_write_iter() - wrappers for
  sync calls of ->read_iter()/->write_iter()"

* 'iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  fs: add vfs_iter_{read,write} helpers
  new helper: iov_iter_bvec()

1  2 
fs/read_write.c
include/linux/fs.h
include/linux/uio.h

diff --combined fs/read_write.c
index 4060691e78f78ab734986a1347c1d81d117c4b90,ab4f26a7d5cb55dfc1bee45f2cb2b51755c55814..8e1b68786d663d4be5551efcd7b0bf7d5ed8b192
@@@ -333,6 -333,52 +333,52 @@@ out_putf
  }
  #endif
  
+ ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos)
+ {
+       struct kiocb kiocb;
+       ssize_t ret;
+       if (!file->f_op->read_iter)
+               return -EINVAL;
+       init_sync_kiocb(&kiocb, file);
+       kiocb.ki_pos = *ppos;
+       kiocb.ki_nbytes = iov_iter_count(iter);
+       iter->type |= READ;
+       ret = file->f_op->read_iter(&kiocb, iter);
+       if (ret == -EIOCBQUEUED)
+               ret = wait_on_sync_kiocb(&kiocb);
+       if (ret > 0)
+               *ppos = kiocb.ki_pos;
+       return ret;
+ }
+ EXPORT_SYMBOL(vfs_iter_read);
+ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos)
+ {
+       struct kiocb kiocb;
+       ssize_t ret;
+       if (!file->f_op->write_iter)
+               return -EINVAL;
+       init_sync_kiocb(&kiocb, file);
+       kiocb.ki_pos = *ppos;
+       kiocb.ki_nbytes = iov_iter_count(iter);
+       iter->type |= WRITE;
+       ret = file->f_op->write_iter(&kiocb, iter);
+       if (ret == -EIOCBQUEUED)
+               ret = wait_on_sync_kiocb(&kiocb);
+       if (ret > 0)
+               *ppos = kiocb.ki_pos;
+       return ret;
+ }
+ EXPORT_SYMBOL(vfs_iter_write);
  /*
   * rw_verify_area doesn't like huge counts. We limit
   * them to something that fits in "int" so that others
@@@ -358,7 -404,7 +404,7 @@@ int rw_verify_area(int read_write, stru
                        return retval;
        }
  
 -      if (unlikely(inode->i_flock && mandatory_lock(inode))) {
 +      if (unlikely(inode->i_flctx && mandatory_lock(inode))) {
                retval = locks_mandatory_area(
                        read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE,
                        inode, file, pos, count);
diff --combined include/linux/fs.h
index a9250b2a11ba89b4fd2e4a8d533a7b805e7bf25c,1f3c4395254093aaf57ddb14e33f8c289d6add3e..0b5b146d049000991c3e43cdbfaa6baa0dbf208c
@@@ -34,7 -34,6 +34,7 @@@
  #include <asm/byteorder.h>
  #include <uapi/linux/fs.h>
  
 +struct backing_dev_info;
  struct export_operations;
  struct hd_geometry;
  struct iovec;
@@@ -51,7 -50,6 +51,7 @@@ struct swap_info_struct
  struct seq_file;
  struct workqueue_struct;
  struct iov_iter;
 +struct vm_fault;
  
  extern void __init inode_init(void);
  extern void __init inode_init_early(void);
@@@ -362,6 -360,8 +362,6 @@@ struct address_space_operations 
        int (*releasepage) (struct page *, gfp_t);
        void (*freepage)(struct page *);
        ssize_t (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, loff_t offset);
 -      int (*get_xip_mem)(struct address_space *, pgoff_t, int,
 -                                              void **, unsigned long *);
        /*
         * migrate the contents of a page to the specified target. If
         * migrate_mode is MIGRATE_ASYNC, it must not block.
@@@ -394,12 -394,14 +394,12 @@@ int pagecache_write_end(struct file *, 
                                loff_t pos, unsigned len, unsigned copied,
                                struct page *page, void *fsdata);
  
 -struct backing_dev_info;
  struct address_space {
        struct inode            *host;          /* owner: inode, block_device */
        struct radix_tree_root  page_tree;      /* radix tree of all pages */
        spinlock_t              tree_lock;      /* and lock protecting it */
        atomic_t                i_mmap_writable;/* count VM_SHARED mappings */
        struct rb_root          i_mmap;         /* tree of private and shared mappings */
 -      struct list_head        i_mmap_nonlinear;/*list VM_NONLINEAR mappings */
        struct rw_semaphore     i_mmap_rwsem;   /* protect tree, count, list */
        /* Protected by tree_lock together with the radix tree */
        unsigned long           nrpages;        /* number of total pages */
        pgoff_t                 writeback_index;/* writeback starts here */
        const struct address_space_operations *a_ops;   /* methods */
        unsigned long           flags;          /* error bits/gfp mask */
 -      struct backing_dev_info *backing_dev_info; /* device readahead, etc */
        spinlock_t              private_lock;   /* for use by the address_space */
        struct list_head        private_list;   /* ditto */
        void                    *private_data;  /* ditto */
@@@ -490,7 -493,8 +490,7 @@@ static inline void i_mmap_unlock_read(s
   */
  static inline int mapping_mapped(struct address_space *mapping)
  {
 -      return  !RB_EMPTY_ROOT(&mapping->i_mmap) ||
 -              !list_empty(&mapping->i_mmap_nonlinear);
 +      return  !RB_EMPTY_ROOT(&mapping->i_mmap);
  }
  
  /*
@@@ -621,7 -625,7 +621,7 @@@ struct inode 
        atomic_t                i_readcount; /* struct files open RO */
  #endif
        const struct file_operations    *i_fop; /* former ->i_op->default_file_ops */
 -      struct file_lock        *i_flock;
 +      struct file_lock_context        *i_flctx;
        struct address_space    i_data;
        struct list_head        i_devices;
        union {
@@@ -871,7 -875,6 +871,7 @@@ static inline struct file *get_file(str
  #define FL_DOWNGRADE_PENDING  256 /* Lease is being downgraded */
  #define FL_UNLOCK_PENDING     512 /* Lease is being broken */
  #define FL_OFDLCK     1024    /* lock is "owned" by struct file */
 +#define FL_LAYOUT     2048    /* outstanding pNFS layout */
  
  /*
   * Special return value from posix_lock_file() and vfs_lock_file() for
  /* legacy typedef, should eventually be removed */
  typedef void *fl_owner_t;
  
 +struct file_lock;
 +
  struct file_lock_operations {
        void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
        void (*fl_release_private)(struct file_lock *);
@@@ -897,7 -898,7 +897,7 @@@ struct lock_manager_operations 
        void (*lm_notify)(struct file_lock *);  /* unblock callback */
        int (*lm_grant)(struct file_lock *, int);
        bool (*lm_break)(struct file_lock *);
 -      int (*lm_change)(struct file_lock **, int, struct list_head *);
 +      int (*lm_change)(struct file_lock *, int, struct list_head *);
        void (*lm_setup)(struct file_lock *, void **);
  };
  
@@@ -922,17 -923,17 +922,17 @@@ int locks_in_grace(struct net *)
   * FIXME: should we create a separate "struct lock_request" to help distinguish
   * these two uses?
   *
 - * The i_flock list is ordered by:
 + * The varous i_flctx lists are ordered by:
   *
 - * 1) lock type -- FL_LEASEs first, then FL_FLOCK, and finally FL_POSIX
 - * 2) lock owner
 - * 3) lock range start
 - * 4) lock range end
 + * 1) lock owner
 + * 2) lock range start
 + * 3) lock range end
   *
   * Obviously, the last two criteria only matter for POSIX locks.
   */
  struct file_lock {
        struct file_lock *fl_next;      /* singly linked list for this inode  */
 +      struct list_head fl_list;       /* link into file_lock_context */
        struct hlist_node fl_link;      /* node in global lists */
        struct list_head fl_block;      /* circular list of blocked processes */
        fl_owner_t fl_owner;
        } fl_u;
  };
  
 +struct file_lock_context {
 +      spinlock_t              flc_lock;
 +      struct list_head        flc_flock;
 +      struct list_head        flc_posix;
 +      struct list_head        flc_lease;
 +      int                     flc_flock_cnt;
 +      int                     flc_posix_cnt;
 +      int                     flc_lease_cnt;
 +};
 +
  /* The following constant reflects the upper bound of the file/locking space */
  #ifndef OFFSET_MAX
  #define INT_LIMIT(x)  (~((x)1 << (sizeof(x)*8 - 1)))
@@@ -999,7 -990,6 +999,7 @@@ extern int fcntl_setlease(unsigned int 
  extern int fcntl_getlease(struct file *filp);
  
  /* fs/locks.c */
 +void locks_free_lock_context(struct file_lock_context *ctx);
  void locks_free_lock(struct file_lock *fl);
  extern void locks_init_lock(struct file_lock *);
  extern struct file_lock * locks_alloc_lock(void);
@@@ -1020,7 -1010,7 +1020,7 @@@ extern int __break_lease(struct inode *
  extern void lease_get_mtime(struct inode *, struct timespec *time);
  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 *);
 +extern int lease_modify(struct file_lock *, int, struct list_head *);
  #else /* !CONFIG_FILE_LOCKING */
  static inline int fcntl_getlk(struct file *file, unsigned int cmd,
                              struct flock __user *user)
@@@ -1057,11 -1047,6 +1057,11 @@@ static inline int fcntl_getlease(struc
        return F_UNLCK;
  }
  
 +static inline void
 +locks_free_lock_context(struct file_lock_context *ctx)
 +{
 +}
 +
  static inline void locks_init_lock(struct file_lock *fl)
  {
        return;
@@@ -1152,7 -1137,7 +1152,7 @@@ static inline int vfs_setlease(struct f
        return -EINVAL;
  }
  
 -static inline int lease_modify(struct file_lock **before, int arg,
 +static inline int lease_modify(struct file_lock *fl, int arg,
                               struct list_head *dispose)
  {
        return -EINVAL;
@@@ -1199,6 -1184,8 +1199,6 @@@ struct mm_struct
  #define UMOUNT_NOFOLLOW       0x00000008      /* Don't follow symlink on umount */
  #define UMOUNT_UNUSED 0x80000000      /* Flag guaranteed to be unused */
  
 -extern struct list_head super_blocks;
 -extern spinlock_t sb_lock;
  
  /* Possible states of 'frozen' field */
  enum {
@@@ -1515,26 -1502,6 +1515,26 @@@ struct block_device_operations
  #define HAVE_COMPAT_IOCTL 1
  #define HAVE_UNLOCKED_IOCTL 1
  
 +/*
 + * These flags let !MMU mmap() govern direct device mapping vs immediate
 + * copying more easily for MAP_PRIVATE, especially for ROM filesystems.
 + *
 + * NOMMU_MAP_COPY:    Copy can be mapped (MAP_PRIVATE)
 + * NOMMU_MAP_DIRECT:  Can be mapped directly (MAP_SHARED)
 + * NOMMU_MAP_READ:    Can be mapped for reading
 + * NOMMU_MAP_WRITE:   Can be mapped for writing
 + * NOMMU_MAP_EXEC:    Can be mapped for execution
 + */
 +#define NOMMU_MAP_COPY                0x00000001
 +#define NOMMU_MAP_DIRECT      0x00000008
 +#define NOMMU_MAP_READ                VM_MAYREAD
 +#define NOMMU_MAP_WRITE               VM_MAYWRITE
 +#define NOMMU_MAP_EXEC                VM_MAYEXEC
 +
 +#define NOMMU_VMFLAGS \
 +      (NOMMU_MAP_READ | NOMMU_MAP_WRITE | NOMMU_MAP_EXEC)
 +
 +
  struct iov_iter;
  
  struct file_operations {
        long (*fallocate)(struct file *file, int mode, loff_t offset,
                          loff_t len);
        void (*show_fdinfo)(struct seq_file *m, struct file *f);
 +#ifndef CONFIG_MMU
 +      unsigned (*mmap_capabilities)(struct file *);
 +#endif
  };
  
  struct inode_operations {
@@@ -1654,10 -1618,8 +1654,10 @@@ struct super_operations 
        struct dquot **(*get_dquots)(struct inode *);
  #endif
        int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
 -      long (*nr_cached_objects)(struct super_block *, int);
 -      long (*free_cached_objects)(struct super_block *, long, int);
 +      long (*nr_cached_objects)(struct super_block *,
 +                                struct shrink_control *);
 +      long (*free_cached_objects)(struct super_block *,
 +                                  struct shrink_control *);
  };
  
  /*
  #define S_IMA         1024    /* Inode has an associated IMA struct */
  #define S_AUTOMOUNT   2048    /* Automount/referral quasi-directory */
  #define S_NOSEC               4096    /* no suid or xattr security attributes */
 +#ifdef CONFIG_FS_DAX
 +#define S_DAX         8192    /* Direct Access, avoiding the page cache */
 +#else
 +#define S_DAX         0       /* Make all the DAX code disappear */
 +#endif
  
  /*
   * Note that nosuid etc flags are inode-specific: setting some file-system
  #define IS_IMA(inode)         ((inode)->i_flags & S_IMA)
  #define IS_AUTOMOUNT(inode)   ((inode)->i_flags & S_AUTOMOUNT)
  #define IS_NOSEC(inode)               ((inode)->i_flags & S_NOSEC)
 +#define IS_DAX(inode)         ((inode)->i_flags & S_DAX)
  
  #define IS_WHITEOUT(inode)    (S_ISCHR(inode->i_mode) && \
                                 (inode)->i_rdev == WHITEOUT_DEV)
@@@ -2003,7 -1959,7 +2003,7 @@@ static inline int locks_verify_truncate
                                    struct file *filp,
                                    loff_t size)
  {
 -      if (inode->i_flock && mandatory_lock(inode))
 +      if (inode->i_flctx && mandatory_lock(inode))
                return locks_mandatory_area(
                        FLOCK_VERIFY_WRITE, inode, filp,
                        size < inode->i_size ? size : inode->i_size,
@@@ -2017,12 -1973,11 +2017,12 @@@ static inline int break_lease(struct in
  {
        /*
         * Since this check is lockless, we must ensure that any refcounts
 -       * taken are done before checking inode->i_flock. Otherwise, we could
 -       * end up racing with tasks trying to set a new lease on this file.
 +       * taken are done before checking i_flctx->flc_lease. Otherwise, we
 +       * could end up racing with tasks trying to set a new lease on this
 +       * file.
         */
        smp_mb();
 -      if (inode->i_flock)
 +      if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease))
                return __break_lease(inode, mode, FL_LEASE);
        return 0;
  }
@@@ -2031,12 -1986,11 +2031,12 @@@ static inline int break_deleg(struct in
  {
        /*
         * Since this check is lockless, we must ensure that any refcounts
 -       * taken are done before checking inode->i_flock. Otherwise, we could
 -       * end up racing with tasks trying to set a new lease on this file.
 +       * taken are done before checking i_flctx->flc_lease. Otherwise, we
 +       * could end up racing with tasks trying to set a new lease on this
 +       * file.
         */
        smp_mb();
 -      if (inode->i_flock)
 +      if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease))
                return __break_lease(inode, mode, FL_DELEG);
        return 0;
  }
@@@ -2063,16 -2017,6 +2063,16 @@@ static inline int break_deleg_wait(stru
        return ret;
  }
  
 +static inline int break_layout(struct inode *inode, bool wait)
 +{
 +      smp_mb();
 +      if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease))
 +              return __break_lease(inode,
 +                              wait ? O_WRONLY : O_WRONLY | O_NONBLOCK,
 +                              FL_LAYOUT);
 +      return 0;
 +}
 +
  #else /* !CONFIG_FILE_LOCKING */
  static inline int locks_mandatory_locked(struct file *file)
  {
@@@ -2128,11 -2072,6 +2128,11 @@@ static inline int break_deleg_wait(stru
        return 0;
  }
  
 +static inline int break_layout(struct inode *inode, bool wait)
 +{
 +      return 0;
 +}
 +
  #endif /* CONFIG_FILE_LOCKING */
  
  /* fs/open.c */
@@@ -2141,7 -2080,6 +2141,7 @@@ struct filename 
        const char              *name;  /* pointer to actual string */
        const __user char       *uptr;  /* original userland pointer */
        struct audit_names      *aname;
 +      int                     refcnt;
        bool                    separate; /* should "name" be freed? */
  };
  
@@@ -2163,7 -2101,6 +2163,7 @@@ extern int filp_close(struct file *, fl
  extern struct filename *getname_flags(const char __user *, int, int *);
  extern struct filename *getname(const char __user *);
  extern struct filename *getname_kernel(const char *);
 +extern void putname(struct filename *name);
  
  enum {
        FILE_CREATED = 1,
@@@ -2184,8 -2121,15 +2184,8 @@@ extern void __init vfs_caches_init(unsi
  
  extern struct kmem_cache *names_cachep;
  
 -extern void final_putname(struct filename *name);
 -
  #define __getname()           kmem_cache_alloc(names_cachep, GFP_KERNEL)
  #define __putname(name)               kmem_cache_free(names_cachep, (void *)(name))
 -#ifndef CONFIG_AUDITSYSCALL
 -#define putname(name)         final_putname(name)
 -#else
 -extern void putname(struct filename *name);
 -#endif
  
  #ifdef CONFIG_BLOCK
  extern int register_blkdev(unsigned int, const char *);
@@@ -2537,6 -2481,8 +2537,6 @@@ extern int sb_min_blocksize(struct supe
  
  extern int generic_file_mmap(struct file *, struct vm_area_struct *);
  extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
 -extern int generic_file_remap_pages(struct vm_area_struct *, unsigned long addr,
 -              unsigned long size, pgoff_t pgoff);
  int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
  extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *);
  extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *);
@@@ -2548,6 -2494,9 +2548,9 @@@ extern ssize_t do_sync_write(struct fil
  extern ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
  extern ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
  
+ ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos);
+ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos);
  /* fs/block_dev.c */
  extern ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to);
  extern ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from);
@@@ -2581,13 -2530,19 +2584,13 @@@ extern loff_t fixed_size_llseek(struct 
  extern int generic_file_open(struct inode * inode, struct file * filp);
  extern int nonseekable_open(struct inode * inode, struct file * filp);
  
 -#ifdef CONFIG_FS_XIP
 -extern ssize_t xip_file_read(struct file *filp, char __user *buf, size_t len,
 -                           loff_t *ppos);
 -extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma);
 -extern ssize_t xip_file_write(struct file *filp, const char __user *buf,
 -                            size_t len, loff_t *ppos);
 -extern int xip_truncate_page(struct address_space *mapping, loff_t from);
 -#else
 -static inline int xip_truncate_page(struct address_space *mapping, loff_t from)
 -{
 -      return 0;
 -}
 -#endif
 +ssize_t dax_do_io(int rw, struct kiocb *, struct inode *, struct iov_iter *,
 +              loff_t, get_block_t, dio_iodone_t, int flags);
 +int dax_clear_blocks(struct inode *, sector_t block, long size);
 +int dax_zero_page_range(struct inode *, loff_t from, unsigned len, get_block_t);
 +int dax_truncate_page(struct inode *, loff_t from, get_block_t);
 +int dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t);
 +#define dax_mkwrite(vma, vmf, gb)     dax_fault(vma, vmf, gb)
  
  #ifdef CONFIG_BLOCK
  typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
@@@ -2744,11 -2699,6 +2747,11 @@@ extern int generic_show_options(struct 
  extern void save_mount_options(struct super_block *sb, char *options);
  extern void replace_mount_options(struct super_block *sb, char *options);
  
 +static inline bool io_is_direct(struct file *filp)
 +{
 +      return (filp->f_flags & O_DIRECT) || IS_DAX(file_inode(filp));
 +}
 +
  static inline ino_t parent_ino(struct dentry *dentry)
  {
        ino_t res;
diff --combined include/linux/uio.h
index 3e0cb4ea3905905cd3c6c22082754818f5f7798d,b447402d9737ed8eaa26ac7cb79f150c9489f072..07a022641996f0ccf74cd872ccd9e4bc8aa5f538
@@@ -88,7 -88,9 +88,9 @@@ size_t iov_iter_zero(size_t bytes, stru
  unsigned long iov_iter_alignment(const struct iov_iter *i);
  void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov,
                        unsigned long nr_segs, size_t count);
- void iov_iter_kvec(struct iov_iter *i, int direction, const struct kvec *iov,
+ void iov_iter_kvec(struct iov_iter *i, int direction, const struct kvec *kvec,
+                       unsigned long nr_segs, size_t count);
+ void iov_iter_bvec(struct iov_iter *i, int direction, const struct bio_vec *bvec,
                        unsigned long nr_segs, size_t count);
  ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages,
                        size_t maxsize, unsigned maxpages, size_t *start);
@@@ -135,4 -137,10 +137,4 @@@ static inline void iov_iter_reexpand(st
  size_t csum_and_copy_to_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
  size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
  
 -int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
 -int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
 -                      int offset, int len);
 -int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
 -                    int offset, int len);
 -
  #endif