Commit 20503664 authored by Joern Engel's avatar Joern Engel

logfs: survive logfs_buf_recover read errors

Refusing to mount beats a kernel crash.
Signed-off-by: default avatarJoern Engel <joern@logfs.org>
parent ccc0197b
...@@ -132,10 +132,9 @@ static int read_area(struct super_block *sb, struct logfs_je_area *a) ...@@ -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) ...@@ -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),
......
...@@ -598,19 +598,19 @@ void freeseg(struct super_block *sb, u32 segno); ...@@ -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 */
......
...@@ -67,7 +67,7 @@ static struct page *get_mapping_page(struct super_block *sb, pgoff_t index, ...@@ -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, ...@@ -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, ...@@ -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)
......
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