aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-06-03 06:45:09 -0400
committerArtem Bityutskiy <dedekind1@gmail.com>2011-07-04 03:54:33 -0400
commit83cef708c606f46a2b527af025acb3d24555f0c4 (patch)
treef5f91da8f13a7f013304ae596e56e7d52a5dcd76 /fs/ubifs
parentd033c98b17ecf30d64d83d96938ce7bfb47f7520 (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.h16
-rw-r--r--fs/ubifs/io.c117
-rw-r--r--fs/ubifs/misc.h80
-rw-r--r--fs/ubifs/recovery.c9
-rw-r--r--fs/ubifs/ubifs.h13
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}
247static inline int dbg_is_power_cut(const struct ubifs_info *c)
248{
249 return !!c->dbg->failure_mode;
250}
247 251
248int ubifs_debugging_init(struct ubifs_info *c); 252int ubifs_debugging_init(struct ubifs_info *c);
249void ubifs_debugging_exit(struct ubifs_info *c); 253void ubifs_debugging_exit(struct ubifs_info *c);
@@ -445,12 +449,24 @@ static inline int
445dbg_check_nondata_nodes_order(struct ubifs_info *c, 449dbg_check_nondata_nodes_order(struct ubifs_info *c,
446 struct list_head *head) { return 0; } 450 struct list_head *head) { return 0; }
447 451
452static 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; }
455static inline int dbg_leb_change(struct ubi_volume_desc *desc,
456 int lnum, const void *buf,
457 int len, int dtype) { return 0; }
458static inline int dbg_leb_unmap(struct ubi_volume_desc *desc,
459 int lnum) { return 0; }
460static inline int dbg_leb_map(struct ubi_volume_desc *desc,
461 int lnum, int dtype) { return 0; }
462
448static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; } 463static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; }
449static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; } 464static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; }
450static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; } 465static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; }
451static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; } 466static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; }
452static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; } 467static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; }
453static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { return 0; } 468static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { return 0; }
469static inline int dbg_is_power_cut(const struct ubifs_info *c) { return 0; }
454 470
455static inline int dbg_debugfs_init(void) { return 0; } 471static inline int dbg_debugfs_init(void) { return 0; }
456static inline void dbg_debugfs_exit(void) { return; } 472static 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
99int 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
117int 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
138int 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
159int 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
178int 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
197int 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 */
154static 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 */
181static 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 */
209static 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 */
922static int recover_head(const struct ubifs_info *c, int lnum, int offs, 922static 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 */
965int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf) 964int 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 */
996static int clean_an_unclean_leb(const struct ubifs_info *c, 995static 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 */
1092int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf) 1091int 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 */
1470void ubifs_ro_mode(struct ubifs_info *c, int err); 1470void ubifs_ro_mode(struct ubifs_info *c, int err);
1471int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
1472 int len, int even_ebadmsg);
1473int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
1474 int len, int dtype);
1475int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
1476 int dtype);
1477int ubifs_leb_unmap(struct ubifs_info *c, int lnum);
1478int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype);
1479int ubifs_is_mapped(const struct ubifs_info *c, int lnum);
1471int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len); 1480int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len);
1472int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, 1481int 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);
1748struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, 1757struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
1749 int offs, void *sbuf); 1758 int offs, void *sbuf);
1750int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf); 1759int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf);
1751int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf); 1760int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf);
1752int ubifs_rcvry_gc_commit(struct ubifs_info *c); 1761int ubifs_rcvry_gc_commit(struct ubifs_info *c);
1753int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, 1762int 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);