Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
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 handlinghifive-unleashed-5.1
commit
f56fc7bdaa
|
@ -537,7 +537,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
|
||||||
|
|
||||||
if (put_dreq(dreq))
|
if (put_dreq(dreq))
|
||||||
nfs_direct_complete(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 inode *inode = mapping->host;
|
||||||
struct nfs_direct_req *dreq;
|
struct nfs_direct_req *dreq;
|
||||||
struct nfs_lock_context *l_ctx;
|
struct nfs_lock_context *l_ctx;
|
||||||
ssize_t result = -EINVAL;
|
ssize_t result = -EINVAL, requested;
|
||||||
size_t count = iov_iter_count(iter);
|
size_t count = iov_iter_count(iter);
|
||||||
nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count);
|
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_start_io_direct(inode);
|
||||||
|
|
||||||
NFS_I(inode)->read_io += count;
|
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);
|
nfs_end_io_direct(inode);
|
||||||
|
|
||||||
if (!result) {
|
if (requested > 0) {
|
||||||
result = nfs_direct_wait(dreq);
|
result = nfs_direct_wait(dreq);
|
||||||
if (result > 0)
|
if (result > 0) {
|
||||||
|
requested -= result;
|
||||||
iocb->ki_pos += result;
|
iocb->ki_pos += result;
|
||||||
}
|
}
|
||||||
|
iov_iter_revert(iter, requested);
|
||||||
|
} else {
|
||||||
|
result = requested;
|
||||||
|
}
|
||||||
|
|
||||||
out_release:
|
out_release:
|
||||||
nfs_direct_req_release(dreq);
|
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))
|
if (put_dreq(dreq))
|
||||||
nfs_direct_write_complete(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 nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
|
||||||
{
|
{
|
||||||
ssize_t result = -EINVAL;
|
ssize_t result = -EINVAL, requested;
|
||||||
size_t count;
|
size_t count;
|
||||||
struct file *file = iocb->ki_filp;
|
struct file *file = iocb->ki_filp;
|
||||||
struct address_space *mapping = file->f_mapping;
|
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);
|
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) {
|
if (mapping->nrpages) {
|
||||||
invalidate_inode_pages2_range(mapping,
|
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);
|
nfs_end_io_direct(inode);
|
||||||
|
|
||||||
if (!result) {
|
if (requested > 0) {
|
||||||
result = nfs_direct_wait(dreq);
|
result = nfs_direct_wait(dreq);
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
|
requested -= result;
|
||||||
iocb->ki_pos = pos + result;
|
iocb->ki_pos = pos + result;
|
||||||
/* XXX: should check the generic_write_sync retval */
|
/* XXX: should check the generic_write_sync retval */
|
||||||
generic_write_sync(iocb, result);
|
generic_write_sync(iocb, result);
|
||||||
}
|
}
|
||||||
|
iov_iter_revert(iter, requested);
|
||||||
|
} else {
|
||||||
|
result = requested;
|
||||||
}
|
}
|
||||||
out_release:
|
out_release:
|
||||||
nfs_direct_req_release(dreq);
|
nfs_direct_req_release(dreq);
|
||||||
|
|
|
@ -521,13 +521,11 @@ int orangefs_bufmap_copy_from_iovec(struct iov_iter *iter,
|
||||||
size_t n = size;
|
size_t n = size;
|
||||||
if (n > PAGE_SIZE)
|
if (n > PAGE_SIZE)
|
||||||
n = PAGE_SIZE;
|
n = PAGE_SIZE;
|
||||||
n = copy_page_from_iter(page, 0, n, iter);
|
if (copy_page_from_iter(page, 0, n, iter) != n)
|
||||||
if (!n)
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
size -= n;
|
size -= n;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -48,17 +48,13 @@
|
||||||
* tv_sec holds the number of seconds before (negative) or after (positive)
|
* tv_sec holds the number of seconds before (negative) or after (positive)
|
||||||
* 00:00:00 1st January 1970 UTC.
|
* 00:00:00 1st January 1970 UTC.
|
||||||
*
|
*
|
||||||
* tv_nsec holds a number of nanoseconds before (0..-999,999,999 if tv_sec is
|
* tv_nsec holds a number of nanoseconds (0..999,999,999) after the tv_sec time.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* __reserved is held in case we need a yet finer resolution.
|
* __reserved is held in case we need a yet finer resolution.
|
||||||
*/
|
*/
|
||||||
struct statx_timestamp {
|
struct statx_timestamp {
|
||||||
__s64 tv_sec;
|
__s64 tv_sec;
|
||||||
__s32 tv_nsec;
|
__u32 tv_nsec;
|
||||||
__s32 __reserved;
|
__s32 __reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
trace_9p_protocol_dump(clnt, req->rc);
|
||||||
goto free_and_error;
|
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);
|
p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue