logfs: survive logfs_buf_recover read errors

Refusing to mount beats a kernel crash.

Signed-off-by: Joern Engel <joern@logfs.org>
This commit is contained in:
Joern Engel 2010-05-03 20:54:34 +02:00
parent ccc0197b02
commit 20503664b0
3 changed files with 13 additions and 11 deletions

View File

@ -132,10 +132,9 @@ static int read_area(struct super_block *sb, struct logfs_je_area *a)
ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes); ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
if (super->s_writesize > 1) if (super->s_writesize > 1)
logfs_buf_recover(area, ofs, a + 1, super->s_writesize); return logfs_buf_recover(area, ofs, a + 1, super->s_writesize);
else else
logfs_buf_recover(area, ofs, NULL, 0); return logfs_buf_recover(area, ofs, NULL, 0);
return 0;
} }
static void *unpack(void *from, void *to) static void *unpack(void *from, void *to)
@ -245,7 +244,7 @@ static int read_je(struct super_block *sb, u64 ofs)
read_erasecount(sb, unpack(jh, scratch)); read_erasecount(sb, unpack(jh, scratch));
break; break;
case JE_AREA: case JE_AREA:
read_area(sb, unpack(jh, scratch)); err = read_area(sb, unpack(jh, scratch));
break; break;
case JE_OBJ_ALIAS: case JE_OBJ_ALIAS:
err = logfs_load_object_aliases(sb, unpack(jh, scratch), err = logfs_load_object_aliases(sb, unpack(jh, scratch),

View File

@ -598,19 +598,19 @@ void freeseg(struct super_block *sb, u32 segno);
int logfs_init_areas(struct super_block *sb); int logfs_init_areas(struct super_block *sb);
void logfs_cleanup_areas(struct super_block *sb); void logfs_cleanup_areas(struct super_block *sb);
int logfs_open_area(struct logfs_area *area, size_t bytes); int logfs_open_area(struct logfs_area *area, size_t bytes);
void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
int use_filler); int use_filler);
static inline void logfs_buf_write(struct logfs_area *area, u64 ofs, static inline int logfs_buf_write(struct logfs_area *area, u64 ofs,
void *buf, size_t len) void *buf, size_t len)
{ {
__logfs_buf_write(area, ofs, buf, len, 0); return __logfs_buf_write(area, ofs, buf, len, 0);
} }
static inline void logfs_buf_recover(struct logfs_area *area, u64 ofs, static inline int logfs_buf_recover(struct logfs_area *area, u64 ofs,
void *buf, size_t len) void *buf, size_t len)
{ {
__logfs_buf_write(area, ofs, buf, len, 1); return __logfs_buf_write(area, ofs, buf, len, 1);
} }
/* super.c */ /* super.c */

View File

@ -67,7 +67,7 @@ static struct page *get_mapping_page(struct super_block *sb, pgoff_t index,
return page; return page;
} }
void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
int use_filler) int use_filler)
{ {
pgoff_t index = ofs >> PAGE_SHIFT; pgoff_t index = ofs >> PAGE_SHIFT;
@ -81,8 +81,10 @@ void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
copylen = min((ulong)len, PAGE_SIZE - offset); copylen = min((ulong)len, PAGE_SIZE - offset);
page = get_mapping_page(area->a_sb, index, use_filler); page = get_mapping_page(area->a_sb, index, use_filler);
SetPageUptodate(page); if (IS_ERR(page))
return PTR_ERR(page);
BUG_ON(!page); /* FIXME: reserve a pool */ BUG_ON(!page); /* FIXME: reserve a pool */
SetPageUptodate(page);
memcpy(page_address(page) + offset, buf, copylen); memcpy(page_address(page) + offset, buf, copylen);
SetPagePrivate(page); SetPagePrivate(page);
page_cache_release(page); page_cache_release(page);
@ -92,6 +94,7 @@ void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
offset = 0; offset = 0;
index++; index++;
} while (len); } while (len);
return 0;
} }
static void pad_partial_page(struct logfs_area *area) static void pad_partial_page(struct logfs_area *area)