From: Linus Torvalds Date: Fri, 7 Oct 2016 22:36:58 +0000 (-0700) Subject: Merge branch 'work.splice_read' of git://git.kernel.org/pub/scm/linux/kernel/git... X-Git-Tag: v4.9-rc1~85 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d1f5323370fceaed43a7ee38f4c7bfc7e70f28d0;p=platform%2Fkernel%2Flinux-exynos.git Merge branch 'work.splice_read' of git://git./linux/kernel/git/viro/vfs Pull VFS splice updates from Al Viro: "There's a bunch of branches this cycle, both mine and from other folks and I'd rather send pull requests separately. This one is the conversion of ->splice_read() to ITER_PIPE iov_iter (and introduction of such). Gets rid of a lot of code in fs/splice.c and elsewhere; there will be followups, but these are for the next cycle... Some pipe/splice-related cleanups from Miklos in the same branch as well" * 'work.splice_read' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: pipe: fix comment in pipe_buf_operations pipe: add pipe_buf_steal() helper pipe: add pipe_buf_confirm() helper pipe: add pipe_buf_release() helper pipe: add pipe_buf_get() helper relay: simplify relay_file_read() switch default_file_splice_read() to use of pipe-backed iov_iter switch generic_file_splice_read() to use of ->read_iter() new iov_iter flavour: pipe-backed fuse_dev_splice_read(): switch to add_to_pipe() skb_splice_bits(): get rid of callback new helper: add_to_pipe() splice: lift pipe_lock out of splice_to_pipe() splice: switch get_iovec_page_array() to iov_iter splice_to_pipe(): don't open-code wakeup_pipe_readers() consistent treatment of EFAULT on O_DIRECT read/write --- d1f5323370fceaed43a7ee38f4c7bfc7e70f28d0 diff --cc drivers/staging/lustre/lustre/llite/file.c index 6e3a188,2567b09..d56863f --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@@ -1130,59 -1150,26 +1130,45 @@@ restart if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) { struct vvp_io *vio = vvp_env_io(env); - int write_mutex_locked = 0; + bool range_locked = false; + + if (file->f_flags & O_APPEND) + range_lock_init(&range, 0, LUSTRE_EOF); + else + range_lock_init(&range, *ppos, *ppos + count - 1); vio->vui_fd = LUSTRE_FPRIVATE(file); - vio->vui_io_subtype = args->via_io_subtype; + vio->vui_iter = args->u.normal.via_iter; + vio->vui_iocb = args->u.normal.via_iocb; - if ((iot == CIT_WRITE) && ++ /* ++ * Direct IO reads must also take range lock, ++ * or multiple reads will try to work on the same pages ++ * See LU-6227 for details. ++ */ ++ if (((iot == CIT_WRITE) || ++ (iot == CIT_READ && (file->f_flags & O_DIRECT))) && + !(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { - if (mutex_lock_interruptible(&lli->lli_write_mutex)) { - result = -ERESTARTSYS; ++ CDEBUG(D_VFSTRACE, "Range lock [%llu, %llu]\n", ++ range.rl_node.in_extent.start, ++ range.rl_node.in_extent.end); ++ result = range_lock(&lli->lli_write_tree, ++ &range); ++ if (result < 0) + goto out; - } - write_mutex_locked = 1; + - switch (vio->vui_io_subtype) { - case IO_NORMAL: - vio->vui_iter = args->u.normal.via_iter; - vio->vui_iocb = args->u.normal.via_iocb; - /* - * Direct IO reads must also take range lock, - * or multiple reads will try to work on the same pages - * See LU-6227 for details. - */ - if (((iot == CIT_WRITE) || - (iot == CIT_READ && (file->f_flags & O_DIRECT))) && - !(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { - CDEBUG(D_VFSTRACE, "Range lock [%llu, %llu]\n", - range.rl_node.in_extent.start, - range.rl_node.in_extent.end); - result = range_lock(&lli->lli_write_tree, - &range); - if (result < 0) - goto out; - - range_locked = true; - } - down_read(&lli->lli_trunc_sem); - break; - case IO_SPLICE: - vio->u.splice.vui_pipe = args->u.splice.via_pipe; - vio->u.splice.vui_flags = args->u.splice.via_flags; - break; - default: - CERROR("Unknown IO type - %u\n", vio->vui_io_subtype); - LBUG(); ++ range_locked = true; } + down_read(&lli->lli_trunc_sem); ll_cl_add(file, env, io); result = cl_io_loop(env, io); ll_cl_remove(file, env); - if (args->via_io_subtype == IO_NORMAL) - up_read(&lli->lli_trunc_sem); + up_read(&lli->lli_trunc_sem); - if (write_mutex_locked) - mutex_unlock(&lli->lli_write_mutex); + if (range_locked) { + CDEBUG(D_VFSTRACE, "Range unlock [%llu, %llu]\n", + range.rl_node.in_extent.start, + range.rl_node.in_extent.end); + range_unlock(&lli->lli_write_tree, &range); + } } else { /* cl_io_rw_init() handled IO */ result = io->ci_result; @@@ -1269,31 -1256,88 +1255,6 @@@ static ssize_t ll_file_write_iter(struc return result; } - /* - * Send file content (through pagecache) somewhere with helper - */ - static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos, - struct pipe_inode_info *pipe, size_t count, - unsigned int flags) -static int ll_lov_recreate(struct inode *inode, struct ost_id *oi, u32 ost_idx) --{ - struct lu_env *env; - struct vvp_io_args *args; - ssize_t result; - int refcheck; - struct obd_export *exp = ll_i2dtexp(inode); - struct obd_trans_info oti = { 0 }; - struct obdo *oa = NULL; - int lsm_size; - int rc = 0; - struct lov_stripe_md *lsm = NULL, *lsm2; -- - env = cl_env_get(&refcheck); - if (IS_ERR(env)) - return PTR_ERR(env); - oa = kmem_cache_zalloc(obdo_cachep, GFP_NOFS); - if (!oa) - return -ENOMEM; -- - args = ll_env_args(env, IO_SPLICE); - args->u.splice.via_pipe = pipe; - args->u.splice.via_flags = flags; - lsm = ccc_inode_lsm_get(inode); - if (!lsm_has_objects(lsm)) { - rc = -ENOENT; - goto out; - } -- - result = ll_file_io_generic(env, args, in_file, CIT_READ, ppos, count); - cl_env_put(env, &refcheck); - return result; - lsm_size = sizeof(*lsm) + (sizeof(struct lov_oinfo) * - (lsm->lsm_stripe_count)); - - lsm2 = libcfs_kvzalloc(lsm_size, GFP_NOFS); - if (!lsm2) { - rc = -ENOMEM; - goto out; - } - - oa->o_oi = *oi; - oa->o_nlink = ost_idx; - oa->o_flags |= OBD_FL_RECREATE_OBJS; - oa->o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS | OBD_MD_FLGROUP; - obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME | - OBD_MD_FLMTIME | OBD_MD_FLCTIME); - obdo_set_parent_fid(oa, &ll_i2info(inode)->lli_fid); - memcpy(lsm2, lsm, lsm_size); - ll_inode_size_lock(inode); - rc = obd_create(NULL, exp, oa, &lsm2, &oti); - ll_inode_size_unlock(inode); - - kvfree(lsm2); - goto out; -out: - ccc_inode_lsm_put(inode, lsm); - kmem_cache_free(obdo_cachep, oa); - return rc; -} - -static int ll_lov_recreate_obj(struct inode *inode, unsigned long arg) -{ - struct ll_recreate_obj ucreat; - struct ost_id oi; - - if (!capable(CFS_CAP_SYS_ADMIN)) - return -EPERM; - - if (copy_from_user(&ucreat, (struct ll_recreate_obj __user *)arg, - sizeof(ucreat))) - return -EFAULT; - - ostid_set_seq_mdt0(&oi); - ostid_set_id(&oi, ucreat.lrc_id); - return ll_lov_recreate(inode, &oi, ucreat.lrc_ost_idx); -} - -static int ll_lov_recreate_fid(struct inode *inode, unsigned long arg) -{ - struct lu_fid fid; - struct ost_id oi; - u32 ost_idx; - - if (!capable(CFS_CAP_SYS_ADMIN)) - return -EPERM; - - if (copy_from_user(&fid, (struct lu_fid __user *)arg, sizeof(fid))) - return -EFAULT; - - fid_to_ostid(&fid, &oi); - ost_idx = (fid_seq(&fid) >> 16) & 0xffff; - return ll_lov_recreate(inode, &oi, ost_idx); --} -- int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry, __u64 flags, struct lov_user_md *lum, int lum_size)