mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
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);
|
||||
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
|
||||
logfs_buf_recover(area, ofs, NULL, 0);
|
||||
return 0;
|
||||
return logfs_buf_recover(area, ofs, NULL, 0);
|
||||
}
|
||||
|
||||
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));
|
||||
break;
|
||||
case JE_AREA:
|
||||
read_area(sb, unpack(jh, scratch));
|
||||
err = read_area(sb, unpack(jh, scratch));
|
||||
break;
|
||||
case JE_OBJ_ALIAS:
|
||||
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);
|
||||
void logfs_cleanup_areas(struct super_block *sb);
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
__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)
|
||||
{
|
||||
__logfs_buf_write(area, ofs, buf, len, 1);
|
||||
return __logfs_buf_write(area, ofs, buf, len, 1);
|
||||
}
|
||||
|
||||
/* super.c */
|
||||
|
@ -67,7 +67,7 @@ static struct page *get_mapping_page(struct super_block *sb, pgoff_t index,
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
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 */
|
||||
SetPageUptodate(page);
|
||||
memcpy(page_address(page) + offset, buf, copylen);
|
||||
SetPagePrivate(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;
|
||||
index++;
|
||||
} while (len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pad_partial_page(struct logfs_area *area)
|
||||
|
Loading…
Reference in New Issue
Block a user