Commit 83cef708c606f46a2b527af025acb3d24555f0c4
Committed by
Artem Bityutskiy
1 parent
d033c98b17
Exists in
master
and in
4 other branches
UBIFS: introduce more I/O helpers
Introduce the following I/O helper functions: 'ubifs_leb_read()', 'ubifs_leb_write()', 'ubifs_leb_change()', 'ubifs_leb_unmap()', 'ubifs_leb_map()', 'ubifs_is_mapped(). The idea is to wrap all UBI I/O functions in order to encapsulate various assertions and error path handling (error message, stack dump, switching to R/O mode). And there are some other benefits of this which will be used in the following patches. This patch does not switch whole UBIFS to use these functions yet. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Showing 5 changed files with 148 additions and 87 deletions Side-by-side Diff
fs/ubifs/debug.h
... | ... | @@ -244,6 +244,10 @@ |
244 | 244 | { |
245 | 245 | return !!(ubifs_dbg.tst_rcvry || c->dbg->tst_rcvry); |
246 | 246 | } |
247 | +static inline int dbg_is_power_cut(const struct ubifs_info *c) | |
248 | +{ | |
249 | + return !!c->dbg->failure_mode; | |
250 | +} | |
247 | 251 | |
248 | 252 | int ubifs_debugging_init(struct ubifs_info *c); |
249 | 253 | void ubifs_debugging_exit(struct ubifs_info *c); |
250 | 254 | |
... | ... | @@ -445,12 +449,24 @@ |
445 | 449 | dbg_check_nondata_nodes_order(struct ubifs_info *c, |
446 | 450 | struct list_head *head) { return 0; } |
447 | 451 | |
452 | +static inline int dbg_leb_write(struct ubi_volume_desc *desc, | |
453 | + int lnum, const void *buf, | |
454 | + int offset, int len, int dtype) { return 0; } | |
455 | +static inline int dbg_leb_change(struct ubi_volume_desc *desc, | |
456 | + int lnum, const void *buf, | |
457 | + int len, int dtype) { return 0; } | |
458 | +static inline int dbg_leb_unmap(struct ubi_volume_desc *desc, | |
459 | + int lnum) { return 0; } | |
460 | +static inline int dbg_leb_map(struct ubi_volume_desc *desc, | |
461 | + int lnum, int dtype) { return 0; } | |
462 | + | |
448 | 463 | static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; } |
449 | 464 | static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; } |
450 | 465 | static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; } |
451 | 466 | static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; } |
452 | 467 | static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; } |
453 | 468 | static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { return 0; } |
469 | +static inline int dbg_is_power_cut(const struct ubifs_info *c) { return 0; } | |
454 | 470 | |
455 | 471 | static inline int dbg_debugfs_init(void) { return 0; } |
456 | 472 | static inline void dbg_debugfs_exit(void) { return; } |
fs/ubifs/io.c
... | ... | @@ -90,6 +90,123 @@ |
90 | 90 | } |
91 | 91 | } |
92 | 92 | |
93 | +/* | |
94 | + * Below are simple wrappers over UBI I/O functions which include some | |
95 | + * additional checks and UBIFS debugging stuff. See corresponding UBI function | |
96 | + * for more information. | |
97 | + */ | |
98 | + | |
99 | +int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs, | |
100 | + int len, int even_ebadmsg) | |
101 | +{ | |
102 | + int err; | |
103 | + | |
104 | + err = ubi_read(c->ubi, lnum, buf, offs, len); | |
105 | + /* | |
106 | + * In case of %-EBADMSG print the error message only if the | |
107 | + * @even_ebadmsg is true. | |
108 | + */ | |
109 | + if (err && (err != -EBADMSG || even_ebadmsg)) { | |
110 | + ubifs_err("reading %d bytes from LEB %d:%d failed, error %d", | |
111 | + len, lnum, offs, err); | |
112 | + dbg_dump_stack(); | |
113 | + } | |
114 | + return err; | |
115 | +} | |
116 | + | |
117 | +int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, | |
118 | + int len, int dtype) | |
119 | +{ | |
120 | + int err; | |
121 | + | |
122 | + ubifs_assert(!c->ro_media && !c->ro_mount); | |
123 | + if (c->ro_error) | |
124 | + return -EROFS; | |
125 | + if (!dbg_is_tst_rcvry(c)) | |
126 | + err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype); | |
127 | + else | |
128 | + err = dbg_leb_write(c->ubi, lnum, buf, offs, len, dtype); | |
129 | + if (err) { | |
130 | + ubifs_err("writing %d bytes to LEB %d:%d failed, error %d", | |
131 | + len, lnum, offs, err); | |
132 | + ubifs_ro_mode(c, err); | |
133 | + dbg_dump_stack(); | |
134 | + } | |
135 | + return err; | |
136 | +} | |
137 | + | |
138 | +int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len, | |
139 | + int dtype) | |
140 | +{ | |
141 | + int err; | |
142 | + | |
143 | + ubifs_assert(!c->ro_media && !c->ro_mount); | |
144 | + if (c->ro_error) | |
145 | + return -EROFS; | |
146 | + if (!dbg_is_tst_rcvry(c)) | |
147 | + err = ubi_leb_change(c->ubi, lnum, buf, len, dtype); | |
148 | + else | |
149 | + err = dbg_leb_change(c->ubi, lnum, buf, len, dtype); | |
150 | + if (err) { | |
151 | + ubifs_err("changing %d bytes in LEB %d failed, error %d", | |
152 | + len, lnum, err); | |
153 | + ubifs_ro_mode(c, err); | |
154 | + dbg_dump_stack(); | |
155 | + } | |
156 | + return err; | |
157 | +} | |
158 | + | |
159 | +int ubifs_leb_unmap(struct ubifs_info *c, int lnum) | |
160 | +{ | |
161 | + int err; | |
162 | + | |
163 | + ubifs_assert(!c->ro_media && !c->ro_mount); | |
164 | + if (c->ro_error) | |
165 | + return -EROFS; | |
166 | + if (!dbg_is_tst_rcvry(c)) | |
167 | + err = ubi_leb_unmap(c->ubi, lnum); | |
168 | + else | |
169 | + err = dbg_leb_unmap(c->ubi, lnum); | |
170 | + if (err) { | |
171 | + ubifs_err("unmap LEB %d failed, error %d", lnum, err); | |
172 | + ubifs_ro_mode(c, err); | |
173 | + dbg_dump_stack(); | |
174 | + } | |
175 | + return err; | |
176 | +} | |
177 | + | |
178 | +int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype) | |
179 | +{ | |
180 | + int err; | |
181 | + | |
182 | + ubifs_assert(!c->ro_media && !c->ro_mount); | |
183 | + if (c->ro_error) | |
184 | + return -EROFS; | |
185 | + if (!dbg_is_tst_rcvry(c)) | |
186 | + err = ubi_leb_map(c->ubi, lnum, dtype); | |
187 | + else | |
188 | + err = dbg_leb_map(c->ubi, lnum, dtype); | |
189 | + if (err) { | |
190 | + ubifs_err("mapping LEB %d failed, error %d", lnum, err); | |
191 | + ubifs_ro_mode(c, err); | |
192 | + dbg_dump_stack(); | |
193 | + } | |
194 | + return err; | |
195 | +} | |
196 | + | |
197 | +int ubifs_is_mapped(const struct ubifs_info *c, int lnum) | |
198 | +{ | |
199 | + int err; | |
200 | + | |
201 | + err = ubi_is_mapped(c->ubi, lnum); | |
202 | + if (err < 0) { | |
203 | + ubifs_err("ubi_is_mapped failed for LEB %d, error %d", | |
204 | + lnum, err); | |
205 | + dbg_dump_stack(); | |
206 | + } | |
207 | + return err; | |
208 | +} | |
209 | + | |
93 | 210 | /** |
94 | 211 | * ubifs_check_node - check node. |
95 | 212 | * @c: UBIFS file-system description object |
fs/ubifs/misc.h
... | ... | @@ -145,86 +145,6 @@ |
145 | 145 | } |
146 | 146 | |
147 | 147 | /** |
148 | - * ubifs_leb_unmap - unmap an LEB. | |
149 | - * @c: UBIFS file-system description object | |
150 | - * @lnum: LEB number to unmap | |
151 | - * | |
152 | - * This function returns %0 on success and a negative error code on failure. | |
153 | - */ | |
154 | -static inline int ubifs_leb_unmap(const struct ubifs_info *c, int lnum) | |
155 | -{ | |
156 | - int err; | |
157 | - | |
158 | - ubifs_assert(!c->ro_media && !c->ro_mount); | |
159 | - if (c->ro_error) | |
160 | - return -EROFS; | |
161 | - err = ubi_leb_unmap(c->ubi, lnum); | |
162 | - if (err) { | |
163 | - ubifs_err("unmap LEB %d failed, error %d", lnum, err); | |
164 | - return err; | |
165 | - } | |
166 | - | |
167 | - return 0; | |
168 | -} | |
169 | - | |
170 | -/** | |
171 | - * ubifs_leb_write - write to a LEB. | |
172 | - * @c: UBIFS file-system description object | |
173 | - * @lnum: LEB number to write | |
174 | - * @buf: buffer to write from | |
175 | - * @offs: offset within LEB to write to | |
176 | - * @len: length to write | |
177 | - * @dtype: data type | |
178 | - * | |
179 | - * This function returns %0 on success and a negative error code on failure. | |
180 | - */ | |
181 | -static inline int ubifs_leb_write(const struct ubifs_info *c, int lnum, | |
182 | - const void *buf, int offs, int len, int dtype) | |
183 | -{ | |
184 | - int err; | |
185 | - | |
186 | - ubifs_assert(!c->ro_media && !c->ro_mount); | |
187 | - if (c->ro_error) | |
188 | - return -EROFS; | |
189 | - err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype); | |
190 | - if (err) { | |
191 | - ubifs_err("writing %d bytes at %d:%d, error %d", | |
192 | - len, lnum, offs, err); | |
193 | - return err; | |
194 | - } | |
195 | - | |
196 | - return 0; | |
197 | -} | |
198 | - | |
199 | -/** | |
200 | - * ubifs_leb_change - atomic LEB change. | |
201 | - * @c: UBIFS file-system description object | |
202 | - * @lnum: LEB number to write | |
203 | - * @buf: buffer to write from | |
204 | - * @len: length to write | |
205 | - * @dtype: data type | |
206 | - * | |
207 | - * This function returns %0 on success and a negative error code on failure. | |
208 | - */ | |
209 | -static inline int ubifs_leb_change(const struct ubifs_info *c, int lnum, | |
210 | - const void *buf, int len, int dtype) | |
211 | -{ | |
212 | - int err; | |
213 | - | |
214 | - ubifs_assert(!c->ro_media && !c->ro_mount); | |
215 | - if (c->ro_error) | |
216 | - return -EROFS; | |
217 | - err = ubi_leb_change(c->ubi, lnum, buf, len, dtype); | |
218 | - if (err) { | |
219 | - ubifs_err("changing %d bytes in LEB %d, error %d", | |
220 | - len, lnum, err); | |
221 | - return err; | |
222 | - } | |
223 | - | |
224 | - return 0; | |
225 | -} | |
226 | - | |
227 | -/** | |
228 | 148 | * ubifs_encode_dev - encode device node IDs. |
229 | 149 | * @dev: UBIFS device node information |
230 | 150 | * @rdev: device IDs to encode |
fs/ubifs/recovery.c
... | ... | @@ -919,8 +919,7 @@ |
919 | 919 | * |
920 | 920 | * This function returns %0 on success and a negative error code on failure. |
921 | 921 | */ |
922 | -static int recover_head(const struct ubifs_info *c, int lnum, int offs, | |
923 | - void *sbuf) | |
922 | +static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf) | |
924 | 923 | { |
925 | 924 | int len = c->max_write_size, err; |
926 | 925 | |
... | ... | @@ -962,7 +961,7 @@ |
962 | 961 | * |
963 | 962 | * This function returns %0 on success and a negative error code on failure. |
964 | 963 | */ |
965 | -int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf) | |
964 | +int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf) | |
966 | 965 | { |
967 | 966 | int err; |
968 | 967 | |
... | ... | @@ -993,7 +992,7 @@ |
993 | 992 | * |
994 | 993 | * This function returns %0 on success and a negative error code on failure. |
995 | 994 | */ |
996 | -static int clean_an_unclean_leb(const struct ubifs_info *c, | |
995 | +static int clean_an_unclean_leb(struct ubifs_info *c, | |
997 | 996 | struct ubifs_unclean_leb *ucleb, void *sbuf) |
998 | 997 | { |
999 | 998 | int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1; |
... | ... | @@ -1089,7 +1088,7 @@ |
1089 | 1088 | * |
1090 | 1089 | * This function returns %0 on success and a negative error code on failure. |
1091 | 1090 | */ |
1092 | -int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf) | |
1091 | +int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf) | |
1093 | 1092 | { |
1094 | 1093 | dbg_rcvry("recovery"); |
1095 | 1094 | while (!list_empty(&c->unclean_leb_list)) { |
fs/ubifs/ubifs.h
... | ... | @@ -1468,6 +1468,15 @@ |
1468 | 1468 | |
1469 | 1469 | /* io.c */ |
1470 | 1470 | void ubifs_ro_mode(struct ubifs_info *c, int err); |
1471 | +int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs, | |
1472 | + int len, int even_ebadmsg); | |
1473 | +int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, | |
1474 | + int len, int dtype); | |
1475 | +int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len, | |
1476 | + int dtype); | |
1477 | +int ubifs_leb_unmap(struct ubifs_info *c, int lnum); | |
1478 | +int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype); | |
1479 | +int ubifs_is_mapped(const struct ubifs_info *c, int lnum); | |
1471 | 1480 | int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len); |
1472 | 1481 | int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, |
1473 | 1482 | int dtype); |
... | ... | @@ -1747,8 +1756,8 @@ |
1747 | 1756 | int offs, void *sbuf, int jhead); |
1748 | 1757 | struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, |
1749 | 1758 | int offs, void *sbuf); |
1750 | -int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf); | |
1751 | -int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf); | |
1759 | +int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf); | |
1760 | +int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf); | |
1752 | 1761 | int ubifs_rcvry_gc_commit(struct ubifs_info *c); |
1753 | 1762 | int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, |
1754 | 1763 | int deletion, loff_t new_size); |