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

Commit f56fc7bd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull vfs fixes from Al Viro:

 - fix orangefs handling of faults on write() - I'd missed that one back
   when orangefs was going through review.

 - readdir counterpart of "9p: cope with bogus responses from server in
   p9_client_{read,write}" - server might be lying or broken, and we'd
   better not overrun the kmalloc'ed buffer we are copying the results
   into.

 - NFS O_DIRECT read/write can leave iov_iter advanced by too much;
   that's what had been causing iov_iter_pipe() warnings davej had been
   seeing.

 - statx_timestamp.tv_nsec type fix (s32 -> u32). That one really should
   go in before 4.11.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  uapi: change the type of struct statx_timestamp.tv_nsec to unsigned
  fix nfs O_DIRECT advancing iov_iter too much
  p9_client_readdir() fix
  orangefs_bufmap_copy_from_iovec(): fix EFAULT handling
parents 59372bbf 1741937d
Loading
Loading
Loading
Loading
+18 −9
Original line number Diff line number Diff line
@@ -537,7 +537,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,

	if (put_dreq(dreq))
		nfs_direct_complete(dreq);
	return 0;
	return requested_bytes;
}

/**
@@ -566,7 +566,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
	struct inode *inode = mapping->host;
	struct nfs_direct_req *dreq;
	struct nfs_lock_context *l_ctx;
	ssize_t result = -EINVAL;
	ssize_t result = -EINVAL, requested;
	size_t count = iov_iter_count(iter);
	nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count);

@@ -600,15 +600,20 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
	nfs_start_io_direct(inode);

	NFS_I(inode)->read_io += count;
	result = nfs_direct_read_schedule_iovec(dreq, iter, iocb->ki_pos);
	requested = nfs_direct_read_schedule_iovec(dreq, iter, iocb->ki_pos);

	nfs_end_io_direct(inode);

	if (!result) {
	if (requested > 0) {
		result = nfs_direct_wait(dreq);
		if (result > 0)
		if (result > 0) {
			requested -= result;
			iocb->ki_pos += result;
		}
		iov_iter_revert(iter, requested);
	} else {
		result = requested;
	}

out_release:
	nfs_direct_req_release(dreq);
@@ -954,7 +959,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,

	if (put_dreq(dreq))
		nfs_direct_write_complete(dreq);
	return 0;
	return requested_bytes;
}

/**
@@ -979,7 +984,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
 */
ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
{
	ssize_t result = -EINVAL;
	ssize_t result = -EINVAL, requested;
	size_t count;
	struct file *file = iocb->ki_filp;
	struct address_space *mapping = file->f_mapping;
@@ -1022,7 +1027,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)

	nfs_start_io_direct(inode);

	result = nfs_direct_write_schedule_iovec(dreq, iter, pos);
	requested = nfs_direct_write_schedule_iovec(dreq, iter, pos);

	if (mapping->nrpages) {
		invalidate_inode_pages2_range(mapping,
@@ -1031,13 +1036,17 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)

	nfs_end_io_direct(inode);

	if (!result) {
	if (requested > 0) {
		result = nfs_direct_wait(dreq);
		if (result > 0) {
			requested -= result;
			iocb->ki_pos = pos + result;
			/* XXX: should check the generic_write_sync retval */
			generic_write_sync(iocb, result);
		}
		iov_iter_revert(iter, requested);
	} else {
		result = requested;
	}
out_release:
	nfs_direct_req_release(dreq);
+1 −3
Original line number Diff line number Diff line
@@ -521,13 +521,11 @@ int orangefs_bufmap_copy_from_iovec(struct iov_iter *iter,
		size_t n = size;
		if (n > PAGE_SIZE)
			n = PAGE_SIZE;
		n = copy_page_from_iter(page, 0, n, iter);
		if (!n)
		if (copy_page_from_iter(page, 0, n, iter) != n)
			return -EFAULT;
		size -= n;
	}
	return 0;

}

/*
+2 −6
Original line number Diff line number Diff line
@@ -48,17 +48,13 @@
 * tv_sec holds the number of seconds before (negative) or after (positive)
 * 00:00:00 1st January 1970 UTC.
 *
 * tv_nsec holds a number of nanoseconds before (0..-999,999,999 if tv_sec is
 * negative) or after (0..999,999,999 if tv_sec is positive) the tv_sec time.
 *
 * Note that if both tv_sec and tv_nsec are non-zero, then the two values must
 * either be both positive or both negative.
 * tv_nsec holds a number of nanoseconds (0..999,999,999) after the tv_sec time.
 *
 * __reserved is held in case we need a yet finer resolution.
 */
struct statx_timestamp {
	__s64	tv_sec;
	__s32	tv_nsec;
	__u32	tv_nsec;
	__s32	__reserved;
};

+4 −0
Original line number Diff line number Diff line
@@ -2101,6 +2101,10 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
		trace_9p_protocol_dump(clnt, req->rc);
		goto free_and_error;
	}
	if (rsize < count) {
		pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize);
		count = rsize;
	}

	p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);