Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro:
"This the bunch that sat in -next + lock_parent() fix. This is the
minimal set; there's more pending stuff.
In particular, I really hope to get acct.c fixes merged this cycle -
we need that to deal sanely with delayed-mntput stuff. In the next
pile, hopefully - that series is fairly short and localized
(kernel/acct.c, fs/super.c and fs/namespace.c). In this pile: more
iov_iter work. Most of prereqs for ->splice_write with sane locking
order are there and Kent's dio rewrite would also fit nicely on top of
this pile"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (70 commits)
lock_parent: don't step on stale ->d_parent of all-but-freed one
kill generic_file_splice_write()
ceph: switch to iter_file_splice_write()
shmem: switch to iter_file_splice_write()
nfs: switch to iter_splice_write_file()
fs/splice.c: remove unneeded exports
ocfs2: switch to iter_file_splice_write()
->splice_write() via ->write_iter()
bio_vec-backed iov_iter
optimize copy_page_{to,from}_iter()
bury generic_file_aio_{read,write}
lustre: get rid of messing with iovecs
ceph: switch to ->write_iter()
ceph_sync_direct_write: stop poking into iov_iter guts
ceph_sync_read: stop poking into iov_iter guts
new helper: copy_page_from_iter()
fuse: switch to ->write_iter()
btrfs: switch to ->write_iter()
ocfs2: switch to ->write_iter()
xfs: switch to ->write_iter()
...
This commit is contained in:
@@ -5,8 +5,6 @@
|
||||
#ifndef __LINUX_BLK_TYPES_H
|
||||
#define __LINUX_BLK_TYPES_H
|
||||
|
||||
#ifdef CONFIG_BLOCK
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct bio_set;
|
||||
@@ -28,6 +26,8 @@ struct bio_vec {
|
||||
unsigned int bv_offset;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_BLOCK
|
||||
|
||||
struct bvec_iter {
|
||||
sector_t bi_sector; /* device address in 512 byte
|
||||
sectors */
|
||||
|
||||
@@ -222,8 +222,6 @@ extern void ceph_copy_to_page_vector(struct page **pages,
|
||||
extern void ceph_copy_from_page_vector(struct page **pages,
|
||||
void *data,
|
||||
loff_t off, size_t len);
|
||||
extern int ceph_copy_page_vector_to_user(struct page **pages, void __user *data,
|
||||
loff_t off, size_t len);
|
||||
extern void ceph_zero_page_vector_range(int off, int len, struct page **pages);
|
||||
|
||||
|
||||
|
||||
+23
-18
@@ -128,6 +128,10 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
|
||||
#define FMODE_ATOMIC_POS ((__force fmode_t)0x8000)
|
||||
/* Write access to underlying fs */
|
||||
#define FMODE_WRITER ((__force fmode_t)0x10000)
|
||||
/* Has read method(s) */
|
||||
#define FMODE_CAN_READ ((__force fmode_t)0x20000)
|
||||
/* Has write method(s) */
|
||||
#define FMODE_CAN_WRITE ((__force fmode_t)0x40000)
|
||||
|
||||
/* File was opened by fanotify and shouldn't generate fanotify events */
|
||||
#define FMODE_NONOTIFY ((__force fmode_t)0x1000000)
|
||||
@@ -343,8 +347,7 @@ struct address_space_operations {
|
||||
void (*invalidatepage) (struct page *, unsigned int, unsigned int);
|
||||
int (*releasepage) (struct page *, gfp_t);
|
||||
void (*freepage)(struct page *);
|
||||
ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
|
||||
loff_t offset, unsigned long nr_segs);
|
||||
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 *);
|
||||
/*
|
||||
@@ -1448,6 +1451,8 @@ struct block_device_operations;
|
||||
#define HAVE_COMPAT_IOCTL 1
|
||||
#define HAVE_UNLOCKED_IOCTL 1
|
||||
|
||||
struct iov_iter;
|
||||
|
||||
struct file_operations {
|
||||
struct module *owner;
|
||||
loff_t (*llseek) (struct file *, loff_t, int);
|
||||
@@ -1455,6 +1460,8 @@ struct file_operations {
|
||||
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
|
||||
ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
||||
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
||||
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
|
||||
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
|
||||
int (*iterate) (struct file *, struct dir_context *);
|
||||
unsigned int (*poll) (struct file *, struct poll_table_struct *);
|
||||
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
|
||||
@@ -2404,20 +2411,18 @@ 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_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
||||
extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long);
|
||||
extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
||||
extern ssize_t generic_file_direct_write(struct kiocb *, const struct iovec *,
|
||||
unsigned long *, loff_t, size_t, size_t);
|
||||
extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *);
|
||||
extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *);
|
||||
extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *);
|
||||
extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *, loff_t);
|
||||
extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t);
|
||||
extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
|
||||
extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
|
||||
extern int generic_segment_checks(const struct iovec *iov,
|
||||
unsigned long *nr_segs, size_t *count, int access_flags);
|
||||
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);
|
||||
|
||||
/* fs/block_dev.c */
|
||||
extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||
unsigned long nr_segs, loff_t pos);
|
||||
extern ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from);
|
||||
extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
|
||||
int datasync);
|
||||
extern void block_sync_page(struct page *page);
|
||||
@@ -2427,7 +2432,7 @@ extern ssize_t generic_file_splice_read(struct file *, loff_t *,
|
||||
struct pipe_inode_info *, size_t, unsigned int);
|
||||
extern ssize_t default_file_splice_read(struct file *, loff_t *,
|
||||
struct pipe_inode_info *, size_t, unsigned int);
|
||||
extern ssize_t generic_file_splice_write(struct pipe_inode_info *,
|
||||
extern ssize_t iter_file_splice_write(struct pipe_inode_info *,
|
||||
struct file *, loff_t *, size_t, unsigned int);
|
||||
extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe,
|
||||
struct file *out, loff_t *, size_t len, unsigned int flags);
|
||||
@@ -2477,16 +2482,16 @@ enum {
|
||||
void dio_end_io(struct bio *bio, int error);
|
||||
|
||||
ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
|
||||
struct block_device *bdev, const struct iovec *iov, loff_t offset,
|
||||
unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
|
||||
struct block_device *bdev, struct iov_iter *iter, loff_t offset,
|
||||
get_block_t get_block, dio_iodone_t end_io,
|
||||
dio_submit_t submit_io, int flags);
|
||||
|
||||
static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
|
||||
struct inode *inode, const struct iovec *iov, loff_t offset,
|
||||
unsigned long nr_segs, get_block_t get_block)
|
||||
struct inode *inode, struct iov_iter *iter, loff_t offset,
|
||||
get_block_t get_block)
|
||||
{
|
||||
return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
|
||||
offset, nr_segs, get_block, NULL, NULL,
|
||||
return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iter,
|
||||
offset, get_block, NULL, NULL,
|
||||
DIO_LOCKING | DIO_SKIP_HOLES);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -459,13 +459,12 @@ extern int nfs3_removexattr (struct dentry *, const char *name);
|
||||
/*
|
||||
* linux/fs/nfs/direct.c
|
||||
*/
|
||||
extern ssize_t nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t,
|
||||
unsigned long);
|
||||
extern ssize_t nfs_direct_IO(int, struct kiocb *, struct iov_iter *, loff_t);
|
||||
extern ssize_t nfs_file_direct_read(struct kiocb *iocb,
|
||||
const struct iovec *iov, unsigned long nr_segs,
|
||||
struct iov_iter *iter,
|
||||
loff_t pos, bool uio);
|
||||
extern ssize_t nfs_file_direct_write(struct kiocb *iocb,
|
||||
const struct iovec *iov, unsigned long nr_segs,
|
||||
struct iov_iter *iter,
|
||||
loff_t pos, bool uio);
|
||||
|
||||
/*
|
||||
|
||||
@@ -70,16 +70,6 @@ extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
|
||||
splice_actor *);
|
||||
extern ssize_t __splice_from_pipe(struct pipe_inode_info *,
|
||||
struct splice_desc *, splice_actor *);
|
||||
extern int splice_from_pipe_feed(struct pipe_inode_info *, struct splice_desc *,
|
||||
splice_actor *);
|
||||
extern int splice_from_pipe_next(struct pipe_inode_info *,
|
||||
struct splice_desc *);
|
||||
extern void splice_from_pipe_begin(struct splice_desc *);
|
||||
extern void splice_from_pipe_end(struct pipe_inode_info *,
|
||||
struct splice_desc *);
|
||||
extern int pipe_to_file(struct pipe_inode_info *, struct pipe_buffer *,
|
||||
struct splice_desc *);
|
||||
|
||||
extern ssize_t splice_to_pipe(struct pipe_inode_info *,
|
||||
struct splice_pipe_desc *);
|
||||
extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
|
||||
|
||||
+39
-16
@@ -19,11 +19,21 @@ struct kvec {
|
||||
size_t iov_len;
|
||||
};
|
||||
|
||||
enum {
|
||||
ITER_IOVEC = 0,
|
||||
ITER_KVEC = 2,
|
||||
ITER_BVEC = 4,
|
||||
};
|
||||
|
||||
struct iov_iter {
|
||||
const struct iovec *iov;
|
||||
unsigned long nr_segs;
|
||||
int type;
|
||||
size_t iov_offset;
|
||||
size_t count;
|
||||
union {
|
||||
const struct iovec *iov;
|
||||
const struct bio_vec *bvec;
|
||||
};
|
||||
unsigned long nr_segs;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -53,6 +63,7 @@ static inline struct iovec iov_iter_iovec(const struct iov_iter *iter)
|
||||
}
|
||||
|
||||
#define iov_for_each(iov, iter, start) \
|
||||
if (!((start).type & ITER_BVEC)) \
|
||||
for (iter = (start); \
|
||||
(iter).count && \
|
||||
((iov = iov_iter_iovec(&(iter))), 1); \
|
||||
@@ -62,32 +73,44 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to);
|
||||
|
||||
size_t iov_iter_copy_from_user_atomic(struct page *page,
|
||||
struct iov_iter *i, unsigned long offset, size_t bytes);
|
||||
size_t iov_iter_copy_from_user(struct page *page,
|
||||
struct iov_iter *i, unsigned long offset, size_t bytes);
|
||||
void iov_iter_advance(struct iov_iter *i, size_t bytes);
|
||||
int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes);
|
||||
size_t iov_iter_single_seg_count(const struct iov_iter *i);
|
||||
size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
|
||||
struct iov_iter *i);
|
||||
|
||||
static inline void iov_iter_init(struct iov_iter *i,
|
||||
const struct iovec *iov, unsigned long nr_segs,
|
||||
size_t count, size_t written)
|
||||
{
|
||||
i->iov = iov;
|
||||
i->nr_segs = nr_segs;
|
||||
i->iov_offset = 0;
|
||||
i->count = count + written;
|
||||
|
||||
iov_iter_advance(i, written);
|
||||
}
|
||||
size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes,
|
||||
struct iov_iter *i);
|
||||
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);
|
||||
ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages,
|
||||
size_t maxsize, size_t *start);
|
||||
ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages,
|
||||
size_t maxsize, size_t *start);
|
||||
int iov_iter_npages(const struct iov_iter *i, int maxpages);
|
||||
|
||||
static inline size_t iov_iter_count(struct iov_iter *i)
|
||||
{
|
||||
return i->count;
|
||||
}
|
||||
|
||||
static inline void iov_iter_truncate(struct iov_iter *i, size_t count)
|
||||
{
|
||||
if (i->count > count)
|
||||
i->count = count;
|
||||
}
|
||||
|
||||
/*
|
||||
* reexpand a previously truncated iterator; count must be no more than how much
|
||||
* we had shrunk it.
|
||||
*/
|
||||
static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
|
||||
{
|
||||
i->count = count;
|
||||
}
|
||||
|
||||
int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
|
||||
int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user