diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-06-03 06:45:09 -0400 |
---|---|---|
committer | Artem Bityutskiy <dedekind1@gmail.com> | 2011-07-04 03:54:33 -0400 |
commit | 83cef708c606f46a2b527af025acb3d24555f0c4 (patch) | |
tree | f5f91da8f13a7f013304ae596e56e7d52a5dcd76 /fs/ubifs | |
parent | d033c98b17ecf30d64d83d96938ce7bfb47f7520 (diff) |
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>
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/debug.h | 16 | ||||
-rw-r--r-- | fs/ubifs/io.c | 117 | ||||
-rw-r--r-- | fs/ubifs/misc.h | 80 | ||||
-rw-r--r-- | fs/ubifs/recovery.c | 9 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 13 |
5 files changed, 148 insertions, 87 deletions
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index e1dcfd29c9aa..b0b005b97279 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h | |||
@@ -244,6 +244,10 @@ static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) | |||
244 | { | 244 | { |
245 | return !!(ubifs_dbg.tst_rcvry || c->dbg->tst_rcvry); | 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 | int ubifs_debugging_init(struct ubifs_info *c); | 252 | int ubifs_debugging_init(struct ubifs_info *c); |
249 | void ubifs_debugging_exit(struct ubifs_info *c); | 253 | void ubifs_debugging_exit(struct ubifs_info *c); |
@@ -445,12 +449,24 @@ static inline int | |||
445 | dbg_check_nondata_nodes_order(struct ubifs_info *c, | 449 | dbg_check_nondata_nodes_order(struct ubifs_info *c, |
446 | struct list_head *head) { return 0; } | 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 | static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; } | 463 | static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; } |
449 | static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; } | 464 | static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; } |
450 | static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; } | 465 | static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; } |
451 | static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; } | 466 | static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; } |
452 | static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; } | 467 | static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; } |
453 | static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { return 0; } | 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 | static inline int dbg_debugfs_init(void) { return 0; } | 471 | static inline int dbg_debugfs_init(void) { return 0; } |
456 | static inline void dbg_debugfs_exit(void) { return; } | 472 | static inline void dbg_debugfs_exit(void) { return; } |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 48e16804ca57..239899d7bf3f 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -90,6 +90,123 @@ void ubifs_ro_mode(struct ubifs_info *c, int err) | |||
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 | * ubifs_check_node - check node. | 211 | * ubifs_check_node - check node. |
95 | * @c: UBIFS file-system description object | 212 | * @c: UBIFS file-system description object |
diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h index 160cd909e957..ee7cb5ebb6e8 100644 --- a/fs/ubifs/misc.h +++ b/fs/ubifs/misc.h | |||
@@ -145,86 +145,6 @@ static inline int ubifs_wbuf_sync(struct ubifs_wbuf *wbuf) | |||
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 | * ubifs_encode_dev - encode device node IDs. | 148 | * ubifs_encode_dev - encode device node IDs. |
229 | * @dev: UBIFS device node information | 149 | * @dev: UBIFS device node information |
230 | * @rdev: device IDs to encode | 150 | * @rdev: device IDs to encode |
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 783d8e0beb76..c59154980719 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -919,8 +919,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, | |||
919 | * | 919 | * |
920 | * This function returns %0 on success and a negative error code on failure. | 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, | 922 | static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf) |
923 | void *sbuf) | ||
924 | { | 923 | { |
925 | int len = c->max_write_size, err; | 924 | int len = c->max_write_size, err; |
926 | 925 | ||
@@ -962,7 +961,7 @@ static int recover_head(const struct ubifs_info *c, int lnum, int offs, | |||
962 | * | 961 | * |
963 | * This function returns %0 on success and a negative error code on failure. | 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 | int err; | 966 | int err; |
968 | 967 | ||
@@ -993,7 +992,7 @@ int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf) | |||
993 | * | 992 | * |
994 | * This function returns %0 on success and a negative error code on failure. | 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 | struct ubifs_unclean_leb *ucleb, void *sbuf) | 996 | struct ubifs_unclean_leb *ucleb, void *sbuf) |
998 | { | 997 | { |
999 | int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1; | 998 | int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1; |
@@ -1089,7 +1088,7 @@ static int clean_an_unclean_leb(const struct ubifs_info *c, | |||
1089 | * | 1088 | * |
1090 | * This function returns %0 on success and a negative error code on failure. | 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 | dbg_rcvry("recovery"); | 1093 | dbg_rcvry("recovery"); |
1095 | while (!list_empty(&c->unclean_leb_list)) { | 1094 | while (!list_empty(&c->unclean_leb_list)) { |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 3304aad04885..702b79258e30 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -1468,6 +1468,15 @@ extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; | |||
1468 | 1468 | ||
1469 | /* io.c */ | 1469 | /* io.c */ |
1470 | void ubifs_ro_mode(struct ubifs_info *c, int err); | 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 | int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len); | 1480 | int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len); |
1472 | int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, | 1481 | int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, |
1473 | int dtype); | 1482 | int dtype); |
@@ -1747,8 +1756,8 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
1747 | int offs, void *sbuf, int jhead); | 1756 | int offs, void *sbuf, int jhead); |
1748 | struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, | 1757 | struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, |
1749 | int offs, void *sbuf); | 1758 | int offs, void *sbuf); |
1750 | int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf); | 1759 | int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf); |
1751 | int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf); | 1760 | int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf); |
1752 | int ubifs_rcvry_gc_commit(struct ubifs_info *c); | 1761 | int ubifs_rcvry_gc_commit(struct ubifs_info *c); |
1753 | int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, | 1762 | int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, |
1754 | int deletion, loff_t new_size); | 1763 | int deletion, loff_t new_size); |