From: Boaz Harrosh Date: Sat, 27 Aug 2011 04:00:32 +0000 (-0700) Subject: exofs: Support for short read/writes X-Git-Tag: firefly_0821_release~3680^2~4299^2~10 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=154a9300cd87eee7538f356c9d339f06b0b1d257;p=firefly-linux-kernel-4.4.55.git exofs: Support for short read/writes If at read/write_done the actual IO was shorter then requested, reported in returned ios->length. It is not an error. The reminder of the pages should just be unlocked but not marked uptodate or end_page_writeback. They will be re issued later by the VFS. Signed-off-by: Boaz Harrosh --- diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index d87c1f7562fb..96366a1d7eae 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -149,14 +149,17 @@ static int pcol_add_page(struct page_collect *pcol, struct page *page, return 0; } +enum {PAGE_WAS_NOT_IN_IO = 17}; static int update_read_page(struct page *page, int ret) { - if (ret == 0) { + switch (ret) { + case 0: /* Everything is OK */ SetPageUptodate(page); if (PageError(page)) ClearPageError(page); - } else if (ret == -EFAULT) { + break; + case -EFAULT: /* In this case we were trying to read something that wasn't on * disk yet - return a page full of zeroes. This should be OK, * because the object should be empty (if there was a write @@ -167,16 +170,22 @@ static int update_read_page(struct page *page, int ret) SetPageUptodate(page); if (PageError(page)) ClearPageError(page); - ret = 0; /* recovered error */ EXOFS_DBGMSG("recovered read error\n"); - } else /* Error */ + /* fall through */ + case PAGE_WAS_NOT_IN_IO: + ret = 0; /* recovered error */ + break; + default: SetPageError(page); - + } return ret; } static void update_write_page(struct page *page, int ret) { + if (unlikely(ret == PAGE_WAS_NOT_IN_IO)) + return; /* don't pass start don't collect $200 */ + if (ret) { mapping_set_error(page->mapping, ret); SetPageError(page); @@ -195,10 +204,14 @@ static int __readpages_done(struct page_collect *pcol) u64 length = 0; int ret = ore_check_io(pcol->ios, &resid); - if (likely(!ret)) + if (likely(!ret)) { good_bytes = pcol->length; - else + ret = PAGE_WAS_NOT_IN_IO; + } else { good_bytes = pcol->length - resid; + } + if (good_bytes > pcol->ios->length) + good_bytes = pcol->ios->length; EXOFS_DBGMSG2("readpages_done(0x%lx) good_bytes=0x%llx" " length=0x%lx nr_pages=%u\n", @@ -518,10 +531,14 @@ static void writepages_done(struct ore_io_state *ios, void *p) atomic_dec(&pcol->sbi->s_curr_pending); - if (likely(!ret)) + if (likely(!ret)) { good_bytes = pcol->length; - else + ret = PAGE_WAS_NOT_IN_IO; + } else { good_bytes = pcol->length - resid; + } + if (good_bytes > pcol->ios->length) + good_bytes = pcol->ios->length; EXOFS_DBGMSG2("writepages_done(0x%lx) good_bytes=0x%llx" " length=0x%lx nr_pages=%u\n",