Commit 20503664b008e17976bff1fdbc693c77ebd6f6c9
1 parent
ccc0197b02
Exists in
master
and in
7 other branches
logfs: survive logfs_buf_recover read errors
Refusing to mount beats a kernel crash. Signed-off-by: Joern Engel <joern@logfs.org>
Showing 3 changed files with 13 additions and 11 deletions Side-by-side Diff
fs/logfs/journal.c
... | ... | @@ -132,10 +132,9 @@ |
132 | 132 | |
133 | 133 | ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes); |
134 | 134 | if (super->s_writesize > 1) |
135 | - logfs_buf_recover(area, ofs, a + 1, super->s_writesize); | |
135 | + return logfs_buf_recover(area, ofs, a + 1, super->s_writesize); | |
136 | 136 | else |
137 | - logfs_buf_recover(area, ofs, NULL, 0); | |
138 | - return 0; | |
137 | + return logfs_buf_recover(area, ofs, NULL, 0); | |
139 | 138 | } |
140 | 139 | |
141 | 140 | static void *unpack(void *from, void *to) |
... | ... | @@ -245,7 +244,7 @@ |
245 | 244 | read_erasecount(sb, unpack(jh, scratch)); |
246 | 245 | break; |
247 | 246 | case JE_AREA: |
248 | - read_area(sb, unpack(jh, scratch)); | |
247 | + err = read_area(sb, unpack(jh, scratch)); | |
249 | 248 | break; |
250 | 249 | case JE_OBJ_ALIAS: |
251 | 250 | err = logfs_load_object_aliases(sb, unpack(jh, scratch), |
fs/logfs/logfs.h
... | ... | @@ -598,19 +598,19 @@ |
598 | 598 | int logfs_init_areas(struct super_block *sb); |
599 | 599 | void logfs_cleanup_areas(struct super_block *sb); |
600 | 600 | int logfs_open_area(struct logfs_area *area, size_t bytes); |
601 | -void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, | |
601 | +int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, | |
602 | 602 | int use_filler); |
603 | 603 | |
604 | -static inline void logfs_buf_write(struct logfs_area *area, u64 ofs, | |
604 | +static inline int logfs_buf_write(struct logfs_area *area, u64 ofs, | |
605 | 605 | void *buf, size_t len) |
606 | 606 | { |
607 | - __logfs_buf_write(area, ofs, buf, len, 0); | |
607 | + return __logfs_buf_write(area, ofs, buf, len, 0); | |
608 | 608 | } |
609 | 609 | |
610 | -static inline void logfs_buf_recover(struct logfs_area *area, u64 ofs, | |
610 | +static inline int logfs_buf_recover(struct logfs_area *area, u64 ofs, | |
611 | 611 | void *buf, size_t len) |
612 | 612 | { |
613 | - __logfs_buf_write(area, ofs, buf, len, 1); | |
613 | + return __logfs_buf_write(area, ofs, buf, len, 1); | |
614 | 614 | } |
615 | 615 | |
616 | 616 | /* super.c */ |
fs/logfs/segment.c
... | ... | @@ -67,7 +67,7 @@ |
67 | 67 | return page; |
68 | 68 | } |
69 | 69 | |
70 | -void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, | |
70 | +int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, | |
71 | 71 | int use_filler) |
72 | 72 | { |
73 | 73 | pgoff_t index = ofs >> PAGE_SHIFT; |
74 | 74 | |
... | ... | @@ -81,8 +81,10 @@ |
81 | 81 | copylen = min((ulong)len, PAGE_SIZE - offset); |
82 | 82 | |
83 | 83 | page = get_mapping_page(area->a_sb, index, use_filler); |
84 | - SetPageUptodate(page); | |
84 | + if (IS_ERR(page)) | |
85 | + return PTR_ERR(page); | |
85 | 86 | BUG_ON(!page); /* FIXME: reserve a pool */ |
87 | + SetPageUptodate(page); | |
86 | 88 | memcpy(page_address(page) + offset, buf, copylen); |
87 | 89 | SetPagePrivate(page); |
88 | 90 | page_cache_release(page); |
... | ... | @@ -92,6 +94,7 @@ |
92 | 94 | offset = 0; |
93 | 95 | index++; |
94 | 96 | } while (len); |
97 | + return 0; | |
95 | 98 | } |
96 | 99 | |
97 | 100 | static void pad_partial_page(struct logfs_area *area) |