Commit 20503664b008e17976bff1fdbc693c77ebd6f6c9

Authored by Joern Engel
1 parent ccc0197b02

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

... ... @@ -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),
... ... @@ -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 */
... ... @@ -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)