aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoern Engel <joern@logfs.org>2010-05-03 14:54:34 -0400
committerJoern Engel <joern@logfs.org>2010-05-04 13:37:04 -0400
commit20503664b008e17976bff1fdbc693c77ebd6f6c9 (patch)
tree7cff886995e42d0b90dd3ebe86993f0277e9345c
parentccc0197b02178f7e1707e659cbc5242fc94b499a (diff)
logfs: survive logfs_buf_recover read errors
Refusing to mount beats a kernel crash. Signed-off-by: Joern Engel <joern@logfs.org>
-rw-r--r--fs/logfs/journal.c7
-rw-r--r--fs/logfs/logfs.h10
-rw-r--r--fs/logfs/segment.c7
3 files changed, 13 insertions, 11 deletions
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c
index fb0a613f885b..4b0e0616b357 100644
--- a/fs/logfs/journal.c
+++ b/fs/logfs/journal.c
@@ -132,10 +132,9 @@ static int read_area(struct super_block *sb, struct logfs_je_area *a)
132 132
133 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes); 133 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
134 if (super->s_writesize > 1) 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 else 136 else
137 logfs_buf_recover(area, ofs, NULL, 0); 137 return logfs_buf_recover(area, ofs, NULL, 0);
138 return 0;
139} 138}
140 139
141static void *unpack(void *from, void *to) 140static void *unpack(void *from, void *to)
@@ -245,7 +244,7 @@ static int read_je(struct super_block *sb, u64 ofs)
245 read_erasecount(sb, unpack(jh, scratch)); 244 read_erasecount(sb, unpack(jh, scratch));
246 break; 245 break;
247 case JE_AREA: 246 case JE_AREA:
248 read_area(sb, unpack(jh, scratch)); 247 err = read_area(sb, unpack(jh, scratch));
249 break; 248 break;
250 case JE_OBJ_ALIAS: 249 case JE_OBJ_ALIAS:
251 err = logfs_load_object_aliases(sb, unpack(jh, scratch), 250 err = logfs_load_object_aliases(sb, unpack(jh, scratch),
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h
index 0a3df1a0c936..32bf55616e56 100644
--- a/fs/logfs/logfs.h
+++ b/fs/logfs/logfs.h
@@ -598,19 +598,19 @@ void freeseg(struct super_block *sb, u32 segno);
598int logfs_init_areas(struct super_block *sb); 598int logfs_init_areas(struct super_block *sb);
599void logfs_cleanup_areas(struct super_block *sb); 599void logfs_cleanup_areas(struct super_block *sb);
600int logfs_open_area(struct logfs_area *area, size_t bytes); 600int logfs_open_area(struct logfs_area *area, size_t bytes);
601void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, 601int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
602 int use_filler); 602 int use_filler);
603 603
604static inline void logfs_buf_write(struct logfs_area *area, u64 ofs, 604static inline int logfs_buf_write(struct logfs_area *area, u64 ofs,
605 void *buf, size_t len) 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
610static inline void logfs_buf_recover(struct logfs_area *area, u64 ofs, 610static inline int logfs_buf_recover(struct logfs_area *area, u64 ofs,
611 void *buf, size_t len) 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/* super.c */ 616/* super.c */
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c
index f77ce2b470ba..a9657afb70ad 100644
--- a/fs/logfs/segment.c
+++ b/fs/logfs/segment.c
@@ -67,7 +67,7 @@ static struct page *get_mapping_page(struct super_block *sb, pgoff_t index,
67 return page; 67 return page;
68} 68}
69 69
70void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, 70int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
71 int use_filler) 71 int use_filler)
72{ 72{
73 pgoff_t index = ofs >> PAGE_SHIFT; 73 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 copylen = min((ulong)len, PAGE_SIZE - offset); 81 copylen = min((ulong)len, PAGE_SIZE - offset);
82 82
83 page = get_mapping_page(area->a_sb, index, use_filler); 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 BUG_ON(!page); /* FIXME: reserve a pool */ 86 BUG_ON(!page); /* FIXME: reserve a pool */
87 SetPageUptodate(page);
86 memcpy(page_address(page) + offset, buf, copylen); 88 memcpy(page_address(page) + offset, buf, copylen);
87 SetPagePrivate(page); 89 SetPagePrivate(page);
88 page_cache_release(page); 90 page_cache_release(page);
@@ -92,6 +94,7 @@ void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
92 offset = 0; 94 offset = 0;
93 index++; 95 index++;
94 } while (len); 96 } while (len);
97 return 0;
95} 98}
96 99
97static void pad_partial_page(struct logfs_area *area) 100static void pad_partial_page(struct logfs_area *area)