Commit 154a9300 authored by Boaz Harrosh's avatar Boaz Harrosh

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: default avatarBoaz Harrosh <bharrosh@panasas.com>
parent 6851a5e5
...@@ -149,14 +149,17 @@ static int pcol_add_page(struct page_collect *pcol, struct page *page, ...@@ -149,14 +149,17 @@ static int pcol_add_page(struct page_collect *pcol, struct page *page,
return 0; return 0;
} }
enum {PAGE_WAS_NOT_IN_IO = 17};
static int update_read_page(struct page *page, int ret) static int update_read_page(struct page *page, int ret)
{ {
if (ret == 0) { switch (ret) {
case 0:
/* Everything is OK */ /* Everything is OK */
SetPageUptodate(page); SetPageUptodate(page);
if (PageError(page)) if (PageError(page))
ClearPageError(page); ClearPageError(page);
} else if (ret == -EFAULT) { break;
case -EFAULT:
/* In this case we were trying to read something that wasn't on /* 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, * disk yet - return a page full of zeroes. This should be OK,
* because the object should be empty (if there was a write * 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) ...@@ -167,16 +170,22 @@ static int update_read_page(struct page *page, int ret)
SetPageUptodate(page); SetPageUptodate(page);
if (PageError(page)) if (PageError(page))
ClearPageError(page); ClearPageError(page);
ret = 0; /* recovered error */
EXOFS_DBGMSG("recovered read error\n"); EXOFS_DBGMSG("recovered read error\n");
} else /* Error */ /* fall through */
case PAGE_WAS_NOT_IN_IO:
ret = 0; /* recovered error */
break;
default:
SetPageError(page); SetPageError(page);
}
return ret; return ret;
} }
static void update_write_page(struct page *page, int 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) { if (ret) {
mapping_set_error(page->mapping, ret); mapping_set_error(page->mapping, ret);
SetPageError(page); SetPageError(page);
...@@ -195,10 +204,14 @@ static int __readpages_done(struct page_collect *pcol) ...@@ -195,10 +204,14 @@ static int __readpages_done(struct page_collect *pcol)
u64 length = 0; u64 length = 0;
int ret = ore_check_io(pcol->ios, &resid); int ret = ore_check_io(pcol->ios, &resid);
if (likely(!ret)) if (likely(!ret)) {
good_bytes = pcol->length; good_bytes = pcol->length;
else ret = PAGE_WAS_NOT_IN_IO;
} else {
good_bytes = pcol->length - resid; 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" EXOFS_DBGMSG2("readpages_done(0x%lx) good_bytes=0x%llx"
" length=0x%lx nr_pages=%u\n", " length=0x%lx nr_pages=%u\n",
...@@ -518,10 +531,14 @@ static void writepages_done(struct ore_io_state *ios, void *p) ...@@ -518,10 +531,14 @@ static void writepages_done(struct ore_io_state *ios, void *p)
atomic_dec(&pcol->sbi->s_curr_pending); atomic_dec(&pcol->sbi->s_curr_pending);
if (likely(!ret)) if (likely(!ret)) {
good_bytes = pcol->length; good_bytes = pcol->length;
else ret = PAGE_WAS_NOT_IN_IO;
} else {
good_bytes = pcol->length - resid; 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" EXOFS_DBGMSG2("writepages_done(0x%lx) good_bytes=0x%llx"
" length=0x%lx nr_pages=%u\n", " length=0x%lx nr_pages=%u\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment