Skip to content

Commit f56fc7b

Browse files
committed
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 handling
2 parents 59372bb + 1741937 commit f56fc7b

File tree

4 files changed

+25
-18
lines changed

4 files changed

+25
-18
lines changed

fs/nfs/direct.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
537537

538538
if (put_dreq(dreq))
539539
nfs_direct_complete(dreq);
540-
return 0;
540+
return requested_bytes;
541541
}
542542

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

@@ -600,14 +600,19 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
600600
nfs_start_io_direct(inode);
601601

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

605605
nfs_end_io_direct(inode);
606606

607-
if (!result) {
607+
if (requested > 0) {
608608
result = nfs_direct_wait(dreq);
609-
if (result > 0)
609+
if (result > 0) {
610+
requested -= result;
610611
iocb->ki_pos += result;
612+
}
613+
iov_iter_revert(iter, requested);
614+
} else {
615+
result = requested;
611616
}
612617

613618
out_release:
@@ -954,7 +959,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
954959

955960
if (put_dreq(dreq))
956961
nfs_direct_write_complete(dreq);
957-
return 0;
962+
return requested_bytes;
958963
}
959964

960965
/**
@@ -979,7 +984,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
979984
*/
980985
ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
981986
{
982-
ssize_t result = -EINVAL;
987+
ssize_t result = -EINVAL, requested;
983988
size_t count;
984989
struct file *file = iocb->ki_filp;
985990
struct address_space *mapping = file->f_mapping;
@@ -1022,7 +1027,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
10221027

10231028
nfs_start_io_direct(inode);
10241029

1025-
result = nfs_direct_write_schedule_iovec(dreq, iter, pos);
1030+
requested = nfs_direct_write_schedule_iovec(dreq, iter, pos);
10261031

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

10321037
nfs_end_io_direct(inode);
10331038

1034-
if (!result) {
1039+
if (requested > 0) {
10351040
result = nfs_direct_wait(dreq);
10361041
if (result > 0) {
1042+
requested -= result;
10371043
iocb->ki_pos = pos + result;
10381044
/* XXX: should check the generic_write_sync retval */
10391045
generic_write_sync(iocb, result);
10401046
}
1047+
iov_iter_revert(iter, requested);
1048+
} else {
1049+
result = requested;
10411050
}
10421051
out_release:
10431052
nfs_direct_req_release(dreq);

fs/orangefs/orangefs-bufmap.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -521,13 +521,11 @@ int orangefs_bufmap_copy_from_iovec(struct iov_iter *iter,
521521
size_t n = size;
522522
if (n > PAGE_SIZE)
523523
n = PAGE_SIZE;
524-
n = copy_page_from_iter(page, 0, n, iter);
525-
if (!n)
524+
if (copy_page_from_iter(page, 0, n, iter) != n)
526525
return -EFAULT;
527526
size -= n;
528527
}
529528
return 0;
530-
531529
}
532530

533531
/*

include/uapi/linux/stat.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,13 @@
4848
* tv_sec holds the number of seconds before (negative) or after (positive)
4949
* 00:00:00 1st January 1970 UTC.
5050
*
51-
* tv_nsec holds a number of nanoseconds before (0..-999,999,999 if tv_sec is
52-
* negative) or after (0..999,999,999 if tv_sec is positive) the tv_sec time.
53-
*
54-
* Note that if both tv_sec and tv_nsec are non-zero, then the two values must
55-
* either be both positive or both negative.
51+
* tv_nsec holds a number of nanoseconds (0..999,999,999) after the tv_sec time.
5652
*
5753
* __reserved is held in case we need a yet finer resolution.
5854
*/
5955
struct statx_timestamp {
6056
__s64 tv_sec;
61-
__s32 tv_nsec;
57+
__u32 tv_nsec;
6258
__s32 __reserved;
6359
};
6460

net/9p/client.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,6 +2101,10 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
21012101
trace_9p_protocol_dump(clnt, req->rc);
21022102
goto free_and_error;
21032103
}
2104+
if (rsize < count) {
2105+
pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize);
2106+
count = rsize;
2107+
}
21042108

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

0 commit comments

Comments
 (0)