Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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()
  ...
  • Loading branch information
torvalds committed Jun 12, 2014
2 parents 5c02c39 + c2338f2 commit 16b9057
Show file tree
Hide file tree
Showing 102 changed files with 1,796 additions and 2,028 deletions.
5 changes: 3 additions & 2 deletions Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,7 @@ prototypes:
void (*invalidatepage) (struct page *, unsigned int, unsigned int);
int (*releasepage) (struct page *, int);
void (*freepage)(struct page *);
int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
int (*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 *);
int (*migratepage)(struct address_space *, struct page *, struct page *);
Expand Down Expand Up @@ -431,6 +430,8 @@ prototypes:
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);
Expand Down
13 changes: 9 additions & 4 deletions Documentation/filesystems/vfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -589,8 +589,7 @@ struct address_space_operations {
void (*invalidatepage) (struct page *, unsigned int, unsigned int);
int (*releasepage) (struct page *, int);
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);
struct page* (*get_xip_page)(struct address_space *, sector_t,
int);
/* migrate the contents of a page to the specified target */
Expand Down Expand Up @@ -807,6 +806,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);
Expand Down Expand Up @@ -837,11 +838,15 @@ otherwise noted.

read: called by read(2) and related system calls

aio_read: called by io_submit(2) and other asynchronous I/O operations
aio_read: vectored, possibly asynchronous read

read_iter: possibly asynchronous read with iov_iter as destination

write: called by write(2) and related system calls

aio_write: called by io_submit(2) and other asynchronous I/O operations
aio_write: vectored, possibly asynchronous write

write_iter: possibly asynchronous write with iov_iter as source

iterate: called when the VFS needs to read the directory contents

Expand Down
8 changes: 4 additions & 4 deletions drivers/char/raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,10 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd,
#endif

static const struct file_operations raw_fops = {
.read = do_sync_read,
.aio_read = generic_file_aio_read,
.write = do_sync_write,
.aio_write = blkdev_aio_write,
.read = new_sync_read,
.read_iter = generic_file_read_iter,
.write = new_sync_write,
.write_iter = blkdev_write_iter,
.fsync = blkdev_fsync,
.open = raw_open,
.release = raw_release,
Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/nand/nandsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,12 +575,12 @@ static int alloc_device(struct nandsim *ns)
cfile = filp_open(cache_file, O_CREAT | O_RDWR | O_LARGEFILE, 0600);
if (IS_ERR(cfile))
return PTR_ERR(cfile);
if (!cfile->f_op->read && !cfile->f_op->aio_read) {
if (!(cfile->f_mode & FMODE_CAN_READ)) {
NS_ERR("alloc_device: cache file not readable\n");
err = -EINVAL;
goto err_close;
}
if (!cfile->f_op->write && !cfile->f_op->aio_write) {
if (!(cfile->f_mode & FMODE_CAN_WRITE)) {
NS_ERR("alloc_device: cache file not writeable\n");
err = -EINVAL;
goto err_close;
Expand Down
11 changes: 1 addition & 10 deletions drivers/staging/lustre/lustre/include/lclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,7 @@ struct ccc_io {
/**
* I/O vector information to or from which read/write is going.
*/
struct iovec *cui_iov;
unsigned long cui_nrsegs;
/**
* Total iov count for left IO.
*/
unsigned long cui_tot_nrsegs;
/**
* Old length for iov that was truncated partially.
*/
size_t cui_iov_olen;
struct iov_iter *cui_iter;
/**
* Total size for the left IO.
*/
Expand Down
48 changes: 3 additions & 45 deletions drivers/staging/lustre/lustre/lclient/lcommon_cl.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,31 +720,12 @@ int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io,
void ccc_io_update_iov(const struct lu_env *env,
struct ccc_io *cio, struct cl_io *io)
{
int i;
size_t size = io->u.ci_rw.crw_count;

cio->cui_iov_olen = 0;
if (!cl_is_normalio(env, io) || cio->cui_tot_nrsegs == 0)
if (!cl_is_normalio(env, io) || cio->cui_iter == NULL)
return;

for (i = 0; i < cio->cui_tot_nrsegs; i++) {
struct iovec *iv = &cio->cui_iov[i];

if (iv->iov_len < size)
size -= iv->iov_len;
else {
if (iv->iov_len > size) {
cio->cui_iov_olen = iv->iov_len;
iv->iov_len = size;
}
break;
}
}

cio->cui_nrsegs = i + 1;
LASSERTF(cio->cui_tot_nrsegs >= cio->cui_nrsegs,
"tot_nrsegs: %lu, nrsegs: %lu\n",
cio->cui_tot_nrsegs, cio->cui_nrsegs);
iov_iter_truncate(cio->cui_iter, size);
}

int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io,
Expand Down Expand Up @@ -775,30 +756,7 @@ void ccc_io_advance(const struct lu_env *env,
if (!cl_is_normalio(env, io))
return;

LASSERT(cio->cui_tot_nrsegs >= cio->cui_nrsegs);
LASSERT(cio->cui_tot_count >= nob);

cio->cui_iov += cio->cui_nrsegs;
cio->cui_tot_nrsegs -= cio->cui_nrsegs;
cio->cui_tot_count -= nob;

/* update the iov */
if (cio->cui_iov_olen > 0) {
struct iovec *iv;

cio->cui_iov--;
cio->cui_tot_nrsegs++;
iv = &cio->cui_iov[0];
if (io->ci_continue) {
iv->iov_base += iv->iov_len;
LASSERT(cio->cui_iov_olen > iv->iov_len);
iv->iov_len = cio->cui_iov_olen - iv->iov_len;
} else {
/* restore the iov_len, in case of restart io. */
iv->iov_len = cio->cui_iov_olen;
}
cio->cui_iov_olen = 0;
}
iov_iter_reexpand(cio->cui_iter, cio->cui_tot_count -= nob);
}

/**
Expand Down
112 changes: 19 additions & 93 deletions drivers/staging/lustre/lustre/llite/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1114,9 +1114,7 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,

switch (vio->cui_io_subtype) {
case IO_NORMAL:
cio->cui_iov = args->u.normal.via_iov;
cio->cui_nrsegs = args->u.normal.via_nrsegs;
cio->cui_tot_nrsegs = cio->cui_nrsegs;
cio->cui_iter = args->u.normal.via_iter;
cio->cui_iocb = args->u.normal.via_iocb;
if ((iot == CIT_WRITE) &&
!(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
Expand Down Expand Up @@ -1180,123 +1178,51 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
return result;
}

static ssize_t ll_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
struct lu_env *env;
struct vvp_io_args *args;
size_t count = 0;
ssize_t result;
int refcheck;

result = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE);
if (result)
return result;

env = cl_env_get(&refcheck);
if (IS_ERR(env))
return PTR_ERR(env);

args = vvp_env_args(env, IO_NORMAL);
args->u.normal.via_iov = (struct iovec *)iov;
args->u.normal.via_nrsegs = nr_segs;
args->u.normal.via_iter = to;
args->u.normal.via_iocb = iocb;

result = ll_file_io_generic(env, args, iocb->ki_filp, CIT_READ,
&iocb->ki_pos, count);
cl_env_put(env, &refcheck);
return result;
}

static ssize_t ll_file_read(struct file *file, char *buf, size_t count,
loff_t *ppos)
{
struct lu_env *env;
struct iovec *local_iov;
struct kiocb *kiocb;
ssize_t result;
int refcheck;

env = cl_env_get(&refcheck);
if (IS_ERR(env))
return PTR_ERR(env);

local_iov = &vvp_env_info(env)->vti_local_iov;
kiocb = &vvp_env_info(env)->vti_kiocb;
local_iov->iov_base = (void __user *)buf;
local_iov->iov_len = count;
init_sync_kiocb(kiocb, file);
kiocb->ki_pos = *ppos;
kiocb->ki_nbytes = count;

result = ll_file_aio_read(kiocb, local_iov, 1, kiocb->ki_pos);
*ppos = kiocb->ki_pos;

&iocb->ki_pos, iov_iter_count(to));
cl_env_put(env, &refcheck);
return result;
}

/*
* Write to a file (through the page cache).
*/
static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
struct lu_env *env;
struct vvp_io_args *args;
size_t count = 0;
ssize_t result;
int refcheck;

result = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ);
if (result)
return result;

env = cl_env_get(&refcheck);
if (IS_ERR(env))
return PTR_ERR(env);

args = vvp_env_args(env, IO_NORMAL);
args->u.normal.via_iov = (struct iovec *)iov;
args->u.normal.via_nrsegs = nr_segs;
args->u.normal.via_iter = from;
args->u.normal.via_iocb = iocb;

result = ll_file_io_generic(env, args, iocb->ki_filp, CIT_WRITE,
&iocb->ki_pos, count);
&iocb->ki_pos, iov_iter_count(from));
cl_env_put(env, &refcheck);
return result;
}

static ssize_t ll_file_write(struct file *file, const char *buf, size_t count,
loff_t *ppos)
{
struct lu_env *env;
struct iovec *local_iov;
struct kiocb *kiocb;
ssize_t result;
int refcheck;

env = cl_env_get(&refcheck);
if (IS_ERR(env))
return PTR_ERR(env);

local_iov = &vvp_env_info(env)->vti_local_iov;
kiocb = &vvp_env_info(env)->vti_kiocb;
local_iov->iov_base = (void __user *)buf;
local_iov->iov_len = count;
init_sync_kiocb(kiocb, file);
kiocb->ki_pos = *ppos;
kiocb->ki_nbytes = count;

result = ll_file_aio_write(kiocb, local_iov, 1, kiocb->ki_pos);
*ppos = kiocb->ki_pos;

cl_env_put(env, &refcheck);
return result;
}



/*
* Send file content (through pagecache) somewhere with helper
*/
Expand Down Expand Up @@ -3143,10 +3069,10 @@ int ll_inode_permission(struct inode *inode, int mask)

/* -o localflock - only provides locally consistent flock locks */
struct file_operations ll_file_operations = {
.read = ll_file_read,
.aio_read = ll_file_aio_read,
.write = ll_file_write,
.aio_write = ll_file_aio_write,
.read = new_sync_read,
.read_iter = ll_file_read_iter,
.write = new_sync_write,
.write_iter = ll_file_write_iter,
.unlocked_ioctl = ll_file_ioctl,
.open = ll_file_open,
.release = ll_file_release,
Expand All @@ -3158,10 +3084,10 @@ struct file_operations ll_file_operations = {
};

struct file_operations ll_file_operations_flock = {
.read = ll_file_read,
.aio_read = ll_file_aio_read,
.write = ll_file_write,
.aio_write = ll_file_aio_write,
.read = new_sync_read,
.read_iter = ll_file_read_iter,
.write = new_sync_write,
.write_iter = ll_file_write_iter,
.unlocked_ioctl = ll_file_ioctl,
.open = ll_file_open,
.release = ll_file_release,
Expand All @@ -3176,10 +3102,10 @@ struct file_operations ll_file_operations_flock = {

/* These are for -o noflock - to return ENOSYS on flock calls */
struct file_operations ll_file_operations_noflock = {
.read = ll_file_read,
.aio_read = ll_file_aio_read,
.write = ll_file_write,
.aio_write = ll_file_aio_write,
.read = new_sync_read,
.read_iter = ll_file_read_iter,
.write = new_sync_write,
.write_iter = ll_file_write_iter,
.unlocked_ioctl = ll_file_ioctl,
.open = ll_file_open,
.release = ll_file_release,
Expand Down
3 changes: 1 addition & 2 deletions drivers/staging/lustre/lustre/llite/llite_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -917,8 +917,7 @@ struct vvp_io_args {
union {
struct {
struct kiocb *via_iocb;
struct iovec *via_iov;
unsigned long via_nrsegs;
struct iov_iter *via_iter;
} normal;
struct {
struct pipe_inode_info *via_pipe;
Expand Down
3 changes: 1 addition & 2 deletions drivers/staging/lustre/lustre/llite/rw.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ static struct ll_cl_context *ll_cl_init(struct file *file,
result = cl_io_rw_init(env, io, CIT_WRITE, pos, PAGE_CACHE_SIZE);
if (result == 0) {
cio->cui_fd = LUSTRE_FPRIVATE(file);
cio->cui_iov = NULL;
cio->cui_nrsegs = 0;
cio->cui_iter = NULL;
result = cl_io_iter_init(env, io);
if (result == 0) {
result = cl_io_lock(env, io);
Expand Down
Loading

0 comments on commit 16b9057

Please sign in to comment.