Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Ubuntu Kernel Team (http://www.linux-archive.org/ubuntu-kernel-team/)
-   -   splice: fix infinite loop in generic_file_splice_read() (http://www.linux-archive.org/ubuntu-kernel-team/567497-splice-fix-infinite-loop-generic_file_splice_read.html)

Jens Axboe 04-10-2008 06:24 AM

splice: fix infinite loop in generic_file_splice_read()
 
BugLink: http://bugs.launchpad.net/bugs/790557

There's a quirky loop in generic_file_splice_read() that could go
on indefinitely, if the file splice returns 0 permanently (and not
just as a temporary condition). Get rid of the loop and pass
back -EAGAIN correctly from __generic_file_splice_read(), so we
handle that condition properly as well.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
(cherry picked from commit 8191ecd1d14c6914c660dfa007154860a7908857)

Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
---
fs/splice.c | 31 ++++++-------------------------
1 files changed, 6 insertions(+), 25 deletions(-)

diff --git a/fs/splice.c b/fs/splice.c
index ef9fc8f..b2872d7 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -364,8 +364,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);

@@ -473,9 +475,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))
@@ -485,29 +486,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;
}
--
1.7.5.4




--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team


All times are GMT. The time now is 12:00 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.