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:
parent
ccc0197b02
commit
20503664b0
@ -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),
|
||||||
|
@ -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,
|
|||||||
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user