Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b42b15fd authored by Al Viro's avatar Al Viro
Browse files

lustre: get rid of messing with iovecs



* switch to ->read_iter/->write_iter
* keep a pointer to iov_iter instead of iov/nr_segs
* do not modify iovecs; use iov_iter_truncate()/iov_iter_advance() and
a new primitive - iov_iter_reexpand() (expand previously truncated
iterator) istead.
* (racy) check for lustre VMAs intersecting with iovecs kept for now as
for_each_iov() loop.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 4908b822
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -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.
	 */
+3 −45
Original line number Diff line number Diff line
@@ -721,31 +721,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,
@@ -776,30 +757,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);
}

/**
+19 −87
Original line number Diff line number Diff line
@@ -1105,9 +1105,7 @@ restart:

		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)) {
@@ -1171,56 +1169,23 @@ out:
	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;

	count = iov_length(iov, nr_segs);

	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;
}
@@ -1228,12 +1193,10 @@ static ssize_t ll_file_read(struct file *file, char *buf, size_t count,
/*
 * 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 = iov_length(iov, nr_segs);
	ssize_t	     result;
	int		 refcheck;

@@ -1242,46 +1205,15 @@ static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
		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
 */
@@ -3133,10 +3065,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,
@@ -3148,10 +3080,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,
@@ -3166,10 +3098,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,
+1 −2
Original line number Diff line number Diff line
@@ -974,8 +974,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;
+1 −2
Original line number Diff line number Diff line
@@ -157,8 +157,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);
Loading