[PATCH] splice: cleanup the SPLICE_F_NONBLOCK handling
- generic_file_splice_read() more readable and correct - Don't bail on page allocation with NONBLOCK set, just don't allow direct blocking on IO (eg lock_page). Signed-off-by: Jens Axboe <axboe@suse.de>
This commit is contained in:
parent
91ad66ef44
commit
c4f895cbe1
1 changed files with 16 additions and 14 deletions
30
fs/splice.c
30
fs/splice.c
|
@ -278,14 +278,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
|
|||
*/
|
||||
page = find_get_page(mapping, index);
|
||||
if (!page) {
|
||||
/*
|
||||
* If in nonblock mode then dont block on
|
||||
* readpage (we've kicked readahead so there
|
||||
* will be asynchronous progress):
|
||||
*/
|
||||
if (flags & SPLICE_F_NONBLOCK)
|
||||
break;
|
||||
|
||||
/*
|
||||
* page didn't exist, allocate one
|
||||
*/
|
||||
|
@ -307,6 +299,13 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
|
|||
* If the page isn't uptodate, we may need to start io on it
|
||||
*/
|
||||
if (!PageUptodate(page)) {
|
||||
/*
|
||||
* If in nonblock mode then dont block on waiting
|
||||
* for an in-flight io page
|
||||
*/
|
||||
if (flags & SPLICE_F_NONBLOCK)
|
||||
break;
|
||||
|
||||
lock_page(page);
|
||||
|
||||
/*
|
||||
|
@ -400,17 +399,20 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
|
|||
while (len) {
|
||||
ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
|
||||
|
||||
if (ret <= 0)
|
||||
if (ret < 0)
|
||||
break;
|
||||
else if (!ret) {
|
||||
if (spliced)
|
||||
break;
|
||||
if (flags & SPLICE_F_NONBLOCK) {
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*ppos += ret;
|
||||
len -= ret;
|
||||
spliced += ret;
|
||||
|
||||
if (!(flags & SPLICE_F_NONBLOCK))
|
||||
continue;
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (spliced)
|
||||
|
|
Loading…
Reference in a new issue