diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-10 13:39:07 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-10 13:39:07 -0700 |
commit | 999646e3f953c734f8eced551fc1ea28719ba7a7 (patch) | |
tree | 303e37c8a848534331640d7a5c7fd177537534b1 /fs | |
parent | 76b0c26af2736b7e5b87e6ed7ab63901483d5736 (diff) | |
parent | 4faa3c8150c1d4f7b38d962eda7851083e218e3f (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
cfq-iosched: do not leak ioc_data across iosched switches
splice: fix infinite loop in generic_file_splice_read()
Diffstat (limited to 'fs')
-rw-r--r-- | fs/splice.c | 31 |
1 files changed, 6 insertions, 25 deletions
diff --git a/fs/splice.c b/fs/splice.c index a861bb318ac..eeb1a86a701 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -370,8 +370,10 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, * for an in-flight io page */ if (flags & SPLICE_F_NONBLOCK) { - if (TestSetPageLocked(page)) + if (TestSetPageLocked(page)) { + error = -EAGAIN; break; + } } else lock_page(page); @@ -479,9 +481,8 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags) { - ssize_t spliced; - int ret; loff_t isize, left; + int ret; isize = i_size_read(in->f_mapping->host); if (unlikely(*ppos >= isize)) @@ -491,29 +492,9 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, if (unlikely(left < len)) len = left; - ret = 0; - spliced = 0; - while (len && !spliced) { - ret = __generic_file_splice_read(in, ppos, pipe, len, flags); - - if (ret < 0) - break; - else if (!ret) { - if (spliced) - break; - if (flags & SPLICE_F_NONBLOCK) { - ret = -EAGAIN; - break; - } - } - + ret = __generic_file_splice_read(in, ppos, pipe, len, flags); + if (ret > 0) *ppos += ret; - len -= ret; - spliced += ret; - } - - if (spliced) - return spliced; return ret; } |