diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-12 17:49:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-12 17:49:50 -0400 |
commit | 5166701b368caea89d57b14bf41cf39e819dad51 (patch) | |
tree | c73b9d4860809e3afa9359be9d03ba2d8d98a18e /include | |
parent | 0a7418f5f569512e98789c439198eed4b507cce3 (diff) | |
parent | a786c06d9f2719203c00b3d97b21f9a96980d0b5 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro:
"The first vfs pile, with deep apologies for being very late in this
window.
Assorted cleanups and fixes, plus a large preparatory part of iov_iter
work. There's a lot more of that, but it'll probably go into the next
merge window - it *does* shape up nicely, removes a lot of
boilerplate, gets rid of locking inconsistencie between aio_write and
splice_write and I hope to get Kent's direct-io rewrite merged into
the same queue, but some of the stuff after this point is having
(mostly trivial) conflicts with the things already merged into
mainline and with some I want more testing.
This one passes LTP and xfstests without regressions, in addition to
usual beating. BTW, readahead02 in ltp syscalls testsuite has started
giving failures since "mm/readahead.c: fix readahead failure for
memoryless NUMA nodes and limit readahead pages" - might be a false
positive, might be a real regression..."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits)
missing bits of "splice: fix racy pipe->buffers uses"
cifs: fix the race in cifs_writev()
ceph_sync_{,direct_}write: fix an oops on ceph_osdc_new_request() failure
kill generic_file_buffered_write()
ocfs2_file_aio_write(): switch to generic_perform_write()
ceph_aio_write(): switch to generic_perform_write()
xfs_file_buffered_aio_write(): switch to generic_perform_write()
export generic_perform_write(), start getting rid of generic_file_buffer_write()
generic_file_direct_write(): get rid of ppos argument
btrfs_file_aio_write(): get rid of ppos
kill the 5th argument of generic_file_buffered_write()
kill the 4th argument of __generic_file_aio_write()
lustre: don't open-code kernel_recvmsg()
ocfs2: don't open-code kernel_recvmsg()
drbd: don't open-code kernel_recvmsg()
constify blk_rq_map_user_iov() and friends
lustre: switch to kernel_sendmsg()
ocfs2: don't open-code kernel_sendmsg()
take iov_iter stuff to mm/iov_iter.c
process_vm_access: tidy up a bit
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/bio.h | 5 | ||||
-rw-r--r-- | include/linux/blkdev.h | 4 | ||||
-rw-r--r-- | include/linux/buffer_head.h | 4 | ||||
-rw-r--r-- | include/linux/fdtable.h | 2 | ||||
-rw-r--r-- | include/linux/fs.h | 97 | ||||
-rw-r--r-- | include/linux/mount.h | 3 | ||||
-rw-r--r-- | include/linux/nbd.h | 3 | ||||
-rw-r--r-- | include/linux/pipe_fs_i.h | 19 | ||||
-rw-r--r-- | include/linux/uio.h | 52 |
9 files changed, 71 insertions, 118 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h index 5aa372a7380c..bba550826921 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -388,7 +388,7 @@ struct sg_iovec; | |||
388 | struct rq_map_data; | 388 | struct rq_map_data; |
389 | extern struct bio *bio_map_user_iov(struct request_queue *, | 389 | extern struct bio *bio_map_user_iov(struct request_queue *, |
390 | struct block_device *, | 390 | struct block_device *, |
391 | struct sg_iovec *, int, int, gfp_t); | 391 | const struct sg_iovec *, int, int, gfp_t); |
392 | extern void bio_unmap_user(struct bio *); | 392 | extern void bio_unmap_user(struct bio *); |
393 | extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int, | 393 | extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int, |
394 | gfp_t); | 394 | gfp_t); |
@@ -414,7 +414,8 @@ extern int bio_alloc_pages(struct bio *bio, gfp_t gfp); | |||
414 | extern struct bio *bio_copy_user(struct request_queue *, struct rq_map_data *, | 414 | extern struct bio *bio_copy_user(struct request_queue *, struct rq_map_data *, |
415 | unsigned long, unsigned int, int, gfp_t); | 415 | unsigned long, unsigned int, int, gfp_t); |
416 | extern struct bio *bio_copy_user_iov(struct request_queue *, | 416 | extern struct bio *bio_copy_user_iov(struct request_queue *, |
417 | struct rq_map_data *, struct sg_iovec *, | 417 | struct rq_map_data *, |
418 | const struct sg_iovec *, | ||
418 | int, int, gfp_t); | 419 | int, int, gfp_t); |
419 | extern int bio_uncopy_user(struct bio *); | 420 | extern int bio_uncopy_user(struct bio *); |
420 | void zero_fill_bio(struct bio *bio); | 421 | void zero_fill_bio(struct bio *bio); |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 99617cf7dd1a..0d84981ee03f 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -835,8 +835,8 @@ extern int blk_rq_map_user(struct request_queue *, struct request *, | |||
835 | extern int blk_rq_unmap_user(struct bio *); | 835 | extern int blk_rq_unmap_user(struct bio *); |
836 | extern int blk_rq_map_kern(struct request_queue *, struct request *, void *, unsigned int, gfp_t); | 836 | extern int blk_rq_map_kern(struct request_queue *, struct request *, void *, unsigned int, gfp_t); |
837 | extern int blk_rq_map_user_iov(struct request_queue *, struct request *, | 837 | extern int blk_rq_map_user_iov(struct request_queue *, struct request *, |
838 | struct rq_map_data *, struct sg_iovec *, int, | 838 | struct rq_map_data *, const struct sg_iovec *, |
839 | unsigned int, gfp_t); | 839 | int, unsigned int, gfp_t); |
840 | extern int blk_execute_rq(struct request_queue *, struct gendisk *, | 840 | extern int blk_execute_rq(struct request_queue *, struct gendisk *, |
841 | struct request *, int); | 841 | struct request *, int); |
842 | extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, | 842 | extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, |
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index d77797a52b7b..c40302f909ce 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h | |||
@@ -210,8 +210,8 @@ int block_write_full_page(struct page *page, get_block_t *get_block, | |||
210 | int block_write_full_page_endio(struct page *page, get_block_t *get_block, | 210 | int block_write_full_page_endio(struct page *page, get_block_t *get_block, |
211 | struct writeback_control *wbc, bh_end_io_t *handler); | 211 | struct writeback_control *wbc, bh_end_io_t *handler); |
212 | int block_read_full_page(struct page*, get_block_t*); | 212 | int block_read_full_page(struct page*, get_block_t*); |
213 | int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc, | 213 | int block_is_partially_uptodate(struct page *page, unsigned long from, |
214 | unsigned long from); | 214 | unsigned long count); |
215 | int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len, | 215 | int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len, |
216 | unsigned flags, struct page **pagep, get_block_t *get_block); | 216 | unsigned flags, struct page **pagep, get_block_t *get_block); |
217 | int __block_write_begin(struct page *page, loff_t pos, unsigned len, | 217 | int __block_write_begin(struct page *page, loff_t pos, unsigned len, |
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 70e8e21c0a30..230f87bdf5ad 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h | |||
@@ -63,8 +63,6 @@ struct file_operations; | |||
63 | struct vfsmount; | 63 | struct vfsmount; |
64 | struct dentry; | 64 | struct dentry; |
65 | 65 | ||
66 | extern void __init files_defer_init(void); | ||
67 | |||
68 | #define rcu_dereference_check_fdtable(files, fdtfd) \ | 66 | #define rcu_dereference_check_fdtable(files, fdtfd) \ |
69 | rcu_dereference_check((fdtfd), lockdep_is_held(&(files)->file_lock)) | 67 | rcu_dereference_check((fdtfd), lockdep_is_held(&(files)->file_lock)) |
70 | 68 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 81048f9bc783..7a9c5bca2b76 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -48,6 +48,7 @@ struct cred; | |||
48 | struct swap_info_struct; | 48 | struct swap_info_struct; |
49 | struct seq_file; | 49 | struct seq_file; |
50 | struct workqueue_struct; | 50 | struct workqueue_struct; |
51 | struct iov_iter; | ||
51 | 52 | ||
52 | extern void __init inode_init(void); | 53 | extern void __init inode_init(void); |
53 | extern void __init inode_init_early(void); | 54 | extern void __init inode_init_early(void); |
@@ -125,6 +126,8 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, | |||
125 | 126 | ||
126 | /* File needs atomic accesses to f_pos */ | 127 | /* File needs atomic accesses to f_pos */ |
127 | #define FMODE_ATOMIC_POS ((__force fmode_t)0x8000) | 128 | #define FMODE_ATOMIC_POS ((__force fmode_t)0x8000) |
129 | /* Write access to underlying fs */ | ||
130 | #define FMODE_WRITER ((__force fmode_t)0x10000) | ||
128 | 131 | ||
129 | /* File was opened by fanotify and shouldn't generate fanotify events */ | 132 | /* File was opened by fanotify and shouldn't generate fanotify events */ |
130 | #define FMODE_NONOTIFY ((__force fmode_t)0x1000000) | 133 | #define FMODE_NONOTIFY ((__force fmode_t)0x1000000) |
@@ -293,38 +296,6 @@ struct page; | |||
293 | struct address_space; | 296 | struct address_space; |
294 | struct writeback_control; | 297 | struct writeback_control; |
295 | 298 | ||
296 | struct iov_iter { | ||
297 | const struct iovec *iov; | ||
298 | unsigned long nr_segs; | ||
299 | size_t iov_offset; | ||
300 | size_t count; | ||
301 | }; | ||
302 | |||
303 | size_t iov_iter_copy_from_user_atomic(struct page *page, | ||
304 | struct iov_iter *i, unsigned long offset, size_t bytes); | ||
305 | size_t iov_iter_copy_from_user(struct page *page, | ||
306 | struct iov_iter *i, unsigned long offset, size_t bytes); | ||
307 | void iov_iter_advance(struct iov_iter *i, size_t bytes); | ||
308 | int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); | ||
309 | size_t iov_iter_single_seg_count(const struct iov_iter *i); | ||
310 | |||
311 | static inline void iov_iter_init(struct iov_iter *i, | ||
312 | const struct iovec *iov, unsigned long nr_segs, | ||
313 | size_t count, size_t written) | ||
314 | { | ||
315 | i->iov = iov; | ||
316 | i->nr_segs = nr_segs; | ||
317 | i->iov_offset = 0; | ||
318 | i->count = count + written; | ||
319 | |||
320 | iov_iter_advance(i, written); | ||
321 | } | ||
322 | |||
323 | static inline size_t iov_iter_count(struct iov_iter *i) | ||
324 | { | ||
325 | return i->count; | ||
326 | } | ||
327 | |||
328 | /* | 299 | /* |
329 | * "descriptor" for what we're up to with a read. | 300 | * "descriptor" for what we're up to with a read. |
330 | * This allows us to use the same read code yet | 301 | * This allows us to use the same read code yet |
@@ -383,7 +354,7 @@ struct address_space_operations { | |||
383 | int (*migratepage) (struct address_space *, | 354 | int (*migratepage) (struct address_space *, |
384 | struct page *, struct page *, enum migrate_mode); | 355 | struct page *, struct page *, enum migrate_mode); |
385 | int (*launder_page) (struct page *); | 356 | int (*launder_page) (struct page *); |
386 | int (*is_partially_uptodate) (struct page *, read_descriptor_t *, | 357 | int (*is_partially_uptodate) (struct page *, unsigned long, |
387 | unsigned long); | 358 | unsigned long); |
388 | void (*is_dirty_writeback) (struct page *, bool *, bool *); | 359 | void (*is_dirty_writeback) (struct page *, bool *, bool *); |
389 | int (*error_remove_page)(struct address_space *, struct page *); | 360 | int (*error_remove_page)(struct address_space *, struct page *); |
@@ -770,9 +741,6 @@ static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index) | |||
770 | index < ra->start + ra->size); | 741 | index < ra->start + ra->size); |
771 | } | 742 | } |
772 | 743 | ||
773 | #define FILE_MNT_WRITE_TAKEN 1 | ||
774 | #define FILE_MNT_WRITE_RELEASED 2 | ||
775 | |||
776 | struct file { | 744 | struct file { |
777 | union { | 745 | union { |
778 | struct llist_node fu_llist; | 746 | struct llist_node fu_llist; |
@@ -810,9 +778,6 @@ struct file { | |||
810 | struct list_head f_tfile_llink; | 778 | struct list_head f_tfile_llink; |
811 | #endif /* #ifdef CONFIG_EPOLL */ | 779 | #endif /* #ifdef CONFIG_EPOLL */ |
812 | struct address_space *f_mapping; | 780 | struct address_space *f_mapping; |
813 | #ifdef CONFIG_DEBUG_WRITECOUNT | ||
814 | unsigned long f_mnt_write_state; | ||
815 | #endif | ||
816 | } __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */ | 781 | } __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */ |
817 | 782 | ||
818 | struct file_handle { | 783 | struct file_handle { |
@@ -830,49 +795,6 @@ static inline struct file *get_file(struct file *f) | |||
830 | #define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1) | 795 | #define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1) |
831 | #define file_count(x) atomic_long_read(&(x)->f_count) | 796 | #define file_count(x) atomic_long_read(&(x)->f_count) |
832 | 797 | ||
833 | #ifdef CONFIG_DEBUG_WRITECOUNT | ||
834 | static inline void file_take_write(struct file *f) | ||
835 | { | ||
836 | WARN_ON(f->f_mnt_write_state != 0); | ||
837 | f->f_mnt_write_state = FILE_MNT_WRITE_TAKEN; | ||
838 | } | ||
839 | static inline void file_release_write(struct file *f) | ||
840 | { | ||
841 | f->f_mnt_write_state |= FILE_MNT_WRITE_RELEASED; | ||
842 | } | ||
843 | static inline void file_reset_write(struct file *f) | ||
844 | { | ||
845 | f->f_mnt_write_state = 0; | ||
846 | } | ||
847 | static inline void file_check_state(struct file *f) | ||
848 | { | ||
849 | /* | ||
850 | * At this point, either both or neither of these bits | ||
851 | * should be set. | ||
852 | */ | ||
853 | WARN_ON(f->f_mnt_write_state == FILE_MNT_WRITE_TAKEN); | ||
854 | WARN_ON(f->f_mnt_write_state == FILE_MNT_WRITE_RELEASED); | ||
855 | } | ||
856 | static inline int file_check_writeable(struct file *f) | ||
857 | { | ||
858 | if (f->f_mnt_write_state == FILE_MNT_WRITE_TAKEN) | ||
859 | return 0; | ||
860 | printk(KERN_WARNING "writeable file with no " | ||
861 | "mnt_want_write()\n"); | ||
862 | WARN_ON(1); | ||
863 | return -EINVAL; | ||
864 | } | ||
865 | #else /* !CONFIG_DEBUG_WRITECOUNT */ | ||
866 | static inline void file_take_write(struct file *filp) {} | ||
867 | static inline void file_release_write(struct file *filp) {} | ||
868 | static inline void file_reset_write(struct file *filp) {} | ||
869 | static inline void file_check_state(struct file *filp) {} | ||
870 | static inline int file_check_writeable(struct file *filp) | ||
871 | { | ||
872 | return 0; | ||
873 | } | ||
874 | #endif /* CONFIG_DEBUG_WRITECOUNT */ | ||
875 | |||
876 | #define MAX_NON_LFS ((1UL<<31) - 1) | 798 | #define MAX_NON_LFS ((1UL<<31) - 1) |
877 | 799 | ||
878 | /* Page cache limit. The filesystems should put that into their s_maxbytes | 800 | /* Page cache limit. The filesystems should put that into their s_maxbytes |
@@ -2481,16 +2403,13 @@ extern int generic_file_mmap(struct file *, struct vm_area_struct *); | |||
2481 | extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); | 2403 | extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); |
2482 | extern int generic_file_remap_pages(struct vm_area_struct *, unsigned long addr, | 2404 | extern int generic_file_remap_pages(struct vm_area_struct *, unsigned long addr, |
2483 | unsigned long size, pgoff_t pgoff); | 2405 | unsigned long size, pgoff_t pgoff); |
2484 | extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size); | ||
2485 | int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk); | 2406 | int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk); |
2486 | extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t); | 2407 | extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t); |
2487 | extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, | 2408 | extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long); |
2488 | loff_t *); | ||
2489 | extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); | 2409 | extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); |
2490 | extern ssize_t generic_file_direct_write(struct kiocb *, const struct iovec *, | 2410 | extern ssize_t generic_file_direct_write(struct kiocb *, const struct iovec *, |
2491 | unsigned long *, loff_t, loff_t *, size_t, size_t); | 2411 | unsigned long *, loff_t, size_t, size_t); |
2492 | extern ssize_t generic_file_buffered_write(struct kiocb *, const struct iovec *, | 2412 | extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t); |
2493 | unsigned long, loff_t, loff_t *, size_t, ssize_t); | ||
2494 | extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos); | 2413 | extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos); |
2495 | extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); | 2414 | extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); |
2496 | extern int generic_segment_checks(const struct iovec *iov, | 2415 | extern int generic_segment_checks(const struct iovec *iov, |
@@ -2582,7 +2501,7 @@ extern const struct file_operations generic_ro_fops; | |||
2582 | 2501 | ||
2583 | #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) | 2502 | #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) |
2584 | 2503 | ||
2585 | extern int vfs_readlink(struct dentry *, char __user *, int, const char *); | 2504 | extern int readlink_copy(char __user *, int, const char *); |
2586 | extern int page_readlink(struct dentry *, char __user *, int); | 2505 | extern int page_readlink(struct dentry *, char __user *, int); |
2587 | extern void *page_follow_link_light(struct dentry *, struct nameidata *); | 2506 | extern void *page_follow_link_light(struct dentry *, struct nameidata *); |
2588 | extern void page_put_link(struct dentry *, struct nameidata *, void *); | 2507 | extern void page_put_link(struct dentry *, struct nameidata *, void *); |
diff --git a/include/linux/mount.h b/include/linux/mount.h index 371d346fa270..839bac270904 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h | |||
@@ -44,6 +44,8 @@ struct mnt_namespace; | |||
44 | #define MNT_SHARED_MASK (MNT_UNBINDABLE) | 44 | #define MNT_SHARED_MASK (MNT_UNBINDABLE) |
45 | #define MNT_PROPAGATION_MASK (MNT_SHARED | MNT_UNBINDABLE) | 45 | #define MNT_PROPAGATION_MASK (MNT_SHARED | MNT_UNBINDABLE) |
46 | 46 | ||
47 | #define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \ | ||
48 | MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED) | ||
47 | 49 | ||
48 | #define MNT_INTERNAL 0x4000 | 50 | #define MNT_INTERNAL 0x4000 |
49 | 51 | ||
@@ -51,6 +53,7 @@ struct mnt_namespace; | |||
51 | #define MNT_LOCKED 0x800000 | 53 | #define MNT_LOCKED 0x800000 |
52 | #define MNT_DOOMED 0x1000000 | 54 | #define MNT_DOOMED 0x1000000 |
53 | #define MNT_SYNC_UMOUNT 0x2000000 | 55 | #define MNT_SYNC_UMOUNT 0x2000000 |
56 | #define MNT_MARKED 0x4000000 | ||
54 | 57 | ||
55 | struct vfsmount { | 58 | struct vfsmount { |
56 | struct dentry *mnt_root; /* root of the mounted tree */ | 59 | struct dentry *mnt_root; /* root of the mounted tree */ |
diff --git a/include/linux/nbd.h b/include/linux/nbd.h index ae4981ebd18e..f62f78aef4ac 100644 --- a/include/linux/nbd.h +++ b/include/linux/nbd.h | |||
@@ -24,8 +24,7 @@ struct request; | |||
24 | struct nbd_device { | 24 | struct nbd_device { |
25 | int flags; | 25 | int flags; |
26 | int harderror; /* Code of hard error */ | 26 | int harderror; /* Code of hard error */ |
27 | struct socket * sock; | 27 | struct socket * sock; /* If == NULL, device is not ready, yet */ |
28 | struct file * file; /* If == NULL, device is not ready, yet */ | ||
29 | int magic; | 28 | int magic; |
30 | 29 | ||
31 | spinlock_t queue_lock; | 30 | spinlock_t queue_lock; |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 4d9389c79e61..eb8b8ac6df3c 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
@@ -83,23 +83,6 @@ struct pipe_buf_operations { | |||
83 | int can_merge; | 83 | int can_merge; |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * ->map() returns a virtual address mapping of the pipe buffer. | ||
87 | * The last integer flag reflects whether this should be an atomic | ||
88 | * mapping or not. The atomic map is faster, however you can't take | ||
89 | * page faults before calling ->unmap() again. So if you need to eg | ||
90 | * access user data through copy_to/from_user(), then you must get | ||
91 | * a non-atomic map. ->map() uses the kmap_atomic slot for | ||
92 | * atomic maps, you have to be careful if mapping another page as | ||
93 | * source or destination for a copy. | ||
94 | */ | ||
95 | void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int); | ||
96 | |||
97 | /* | ||
98 | * Undoes ->map(), finishes the virtual mapping of the pipe buffer. | ||
99 | */ | ||
100 | void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *); | ||
101 | |||
102 | /* | ||
103 | * ->confirm() verifies that the data in the pipe buffer is there | 86 | * ->confirm() verifies that the data in the pipe buffer is there |
104 | * and that the contents are good. If the pages in the pipe belong | 87 | * and that the contents are good. If the pages in the pipe belong |
105 | * to a file system, we may need to wait for IO completion in this | 88 | * to a file system, we may need to wait for IO completion in this |
@@ -150,8 +133,6 @@ struct pipe_inode_info *alloc_pipe_info(void); | |||
150 | void free_pipe_info(struct pipe_inode_info *); | 133 | void free_pipe_info(struct pipe_inode_info *); |
151 | 134 | ||
152 | /* Generic pipe buffer ops functions */ | 135 | /* Generic pipe buffer ops functions */ |
153 | void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int); | ||
154 | void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *); | ||
155 | void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); | 136 | void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); |
156 | int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *); | 137 | int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *); |
157 | int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); | 138 | int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); |
diff --git a/include/linux/uio.h b/include/linux/uio.h index c55ce243cc09..199bcc34241b 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h | |||
@@ -9,14 +9,23 @@ | |||
9 | #ifndef __LINUX_UIO_H | 9 | #ifndef __LINUX_UIO_H |
10 | #define __LINUX_UIO_H | 10 | #define __LINUX_UIO_H |
11 | 11 | ||
12 | #include <linux/kernel.h> | ||
12 | #include <uapi/linux/uio.h> | 13 | #include <uapi/linux/uio.h> |
13 | 14 | ||
15 | struct page; | ||
14 | 16 | ||
15 | struct kvec { | 17 | struct kvec { |
16 | void *iov_base; /* and that should *never* hold a userland pointer */ | 18 | void *iov_base; /* and that should *never* hold a userland pointer */ |
17 | size_t iov_len; | 19 | size_t iov_len; |
18 | }; | 20 | }; |
19 | 21 | ||
22 | struct iov_iter { | ||
23 | const struct iovec *iov; | ||
24 | unsigned long nr_segs; | ||
25 | size_t iov_offset; | ||
26 | size_t count; | ||
27 | }; | ||
28 | |||
20 | /* | 29 | /* |
21 | * Total number of bytes covered by an iovec. | 30 | * Total number of bytes covered by an iovec. |
22 | * | 31 | * |
@@ -34,8 +43,51 @@ static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs) | |||
34 | return ret; | 43 | return ret; |
35 | } | 44 | } |
36 | 45 | ||
46 | static inline struct iovec iov_iter_iovec(const struct iov_iter *iter) | ||
47 | { | ||
48 | return (struct iovec) { | ||
49 | .iov_base = iter->iov->iov_base + iter->iov_offset, | ||
50 | .iov_len = min(iter->count, | ||
51 | iter->iov->iov_len - iter->iov_offset), | ||
52 | }; | ||
53 | } | ||
54 | |||
55 | #define iov_for_each(iov, iter, start) \ | ||
56 | for (iter = (start); \ | ||
57 | (iter).count && \ | ||
58 | ((iov = iov_iter_iovec(&(iter))), 1); \ | ||
59 | iov_iter_advance(&(iter), (iov).iov_len)) | ||
60 | |||
37 | unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to); | 61 | unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to); |
38 | 62 | ||
63 | size_t iov_iter_copy_from_user_atomic(struct page *page, | ||
64 | struct iov_iter *i, unsigned long offset, size_t bytes); | ||
65 | size_t iov_iter_copy_from_user(struct page *page, | ||
66 | struct iov_iter *i, unsigned long offset, size_t bytes); | ||
67 | void iov_iter_advance(struct iov_iter *i, size_t bytes); | ||
68 | int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); | ||
69 | size_t iov_iter_single_seg_count(const struct iov_iter *i); | ||
70 | size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, | ||
71 | struct iov_iter *i); | ||
72 | |||
73 | static inline void iov_iter_init(struct iov_iter *i, | ||
74 | const struct iovec *iov, unsigned long nr_segs, | ||
75 | size_t count, size_t written) | ||
76 | { | ||
77 | i->iov = iov; | ||
78 | i->nr_segs = nr_segs; | ||
79 | i->iov_offset = 0; | ||
80 | i->count = count + written; | ||
81 | |||
82 | iov_iter_advance(i, written); | ||
83 | } | ||
84 | |||
85 | static inline size_t iov_iter_count(struct iov_iter *i) | ||
86 | { | ||
87 | return i->count; | ||
88 | } | ||
89 | |||
39 | int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); | 90 | int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); |
40 | int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); | 91 | int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); |
92 | |||
41 | #endif | 93 | #endif |