From: Suparna Bhattacharya Might fix a BUG which was seen in testing. 25-akpm/fs/aio.c | 13 ++++++------- 25-akpm/mm/page-writeback.c | 16 +++++++++------- 2 files changed, 15 insertions(+), 14 deletions(-) diff -puN fs/aio.c~aio-10-BUG-fix fs/aio.c --- 25/fs/aio.c~aio-10-BUG-fix Tue Jul 8 16:07:30 2003 +++ 25-akpm/fs/aio.c Tue Jul 8 16:07:30 2003 @@ -1286,18 +1286,17 @@ retry_osync: ssize_t err; err = sync_page_range(inode, mapping, iocb->ki_pos, ret); - if (err < 0) + if (err <= 0) { ret = err; - else { - printk("synced %d bytes\n", err); + } else { + BUG_ON(err > iocb->ki_left); iocb->ki_pos += err; iocb->ki_left -= err; - if ((iocb->ki_left) && (err != 0)) - ret = -EIOCBRETRY; - else - ret = iocb->ki_nbytes; + ret = -EIOCBRETRY; } } + if (ret == 0) + ret = iocb->ki_nbytes - iocb->ki_left; return ret; } diff -puN mm/page-writeback.c~aio-10-BUG-fix mm/page-writeback.c --- 25/mm/page-writeback.c~aio-10-BUG-fix Tue Jul 8 16:07:30 2003 +++ 25-akpm/mm/page-writeback.c Tue Jul 8 16:07:30 2003 @@ -577,9 +577,12 @@ static ssize_t operate_on_page_range(str pgoff_t last = (pos + count - 1) >> PAGE_CACHE_SHIFT; /* inclusive */ pgoff_t next = first; struct pagevec pvec; - ssize_t ret = 0; + ssize_t ret = 0, bytes = 0; int i; + if (count == 0) + return 0; + pagevec_init(&pvec, 0); while (pagevec_lookup(&pvec, mapping, next, min((pgoff_t)PAGEVEC_SIZE, last - next + 1))) { @@ -594,10 +597,8 @@ static ssize_t operate_on_page_range(str } next = page->index + 1; ret = (*operator)(page); - if (ret == -EIOCBRETRY) { - next--; + if (ret == -EIOCBRETRY) break; - } if (PageError(page)) { if (!ret) ret = -EIO; @@ -609,9 +610,10 @@ static ssize_t operate_on_page_range(str if ((next > last) || (ret == -EIOCBRETRY)) break; } - if (!ret || (ret == -EIOCBRETRY)) - ret = (next << PAGE_CACHE_SHIFT) - pos; - return ret; + bytes = (next << PAGE_CACHE_SHIFT) - pos; + if (bytes > count) + bytes = count; + return (bytes && (!ret || (ret == -EIOCBRETRY))) ? bytes : ret; } static int page_waiter(struct page *page) _