From: Suparna Bhattacharya Might fix a BUG which was seen in testing. fs/aio.c | 13 ++++++------- 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 2003-06-16 23:16:39.000000000 -0700 +++ 25-akpm/fs/aio.c 2003-06-16 23:16:39.000000000 -0700 @@ -1287,18 +1287,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); + 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 2003-06-16 23:16:39.000000000 -0700 +++ 25-akpm/mm/page-writeback.c 2003-06-16 23:16:39.000000000 -0700 @@ -576,9 +576,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))) { @@ -593,10 +596,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; @@ -608,9 +609,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) _