Commit 83cef708c606f46a2b527af025acb3d24555f0c4

Authored by Artem Bityutskiy
Committed by Artem Bityutskiy
1 parent d033c98b17

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

... ... @@ -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; }
... ... @@ -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
... ... @@ -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
... ... @@ -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)) {
... ... @@ -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);