]> Pileus Git - ~andy/linux/blobdiff - fs/ubifs/io.c
UBIFS: introduce more I/O helpers
[~andy/linux] / fs / ubifs / io.c
index 48e16804ca573cbc78dd8dcdea2ba9684581345c..239899d7bf3fbc512cdaaecd379831b30893c652 100644 (file)
@@ -90,6 +90,123 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
        }
 }
 
+/*
+ * Below are simple wrappers over UBI I/O functions which include some
+ * additional checks and UBIFS debugging stuff. See corresponding UBI function
+ * for more information.
+ */
+
+int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
+                  int len, int even_ebadmsg)
+{
+       int err;
+
+       err = ubi_read(c->ubi, lnum, buf, offs, len);
+       /*
+        * In case of %-EBADMSG print the error message only if the
+        * @even_ebadmsg is true.
+        */
+       if (err && (err != -EBADMSG || even_ebadmsg)) {
+               ubifs_err("reading %d bytes from LEB %d:%d failed, error %d",
+                         len, lnum, offs, err);
+               dbg_dump_stack();
+       }
+       return err;
+}
+
+int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
+                   int len, int dtype)
+{
+       int err;
+
+       ubifs_assert(!c->ro_media && !c->ro_mount);
+       if (c->ro_error)
+               return -EROFS;
+       if (!dbg_is_tst_rcvry(c))
+               err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
+       else
+               err = dbg_leb_write(c->ubi, lnum, buf, offs, len, dtype);
+       if (err) {
+               ubifs_err("writing %d bytes to LEB %d:%d failed, error %d",
+                         len, lnum, offs, err);
+               ubifs_ro_mode(c, err);
+               dbg_dump_stack();
+       }
+       return err;
+}
+
+int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
+                    int dtype)
+{
+       int err;
+
+       ubifs_assert(!c->ro_media && !c->ro_mount);
+       if (c->ro_error)
+               return -EROFS;
+       if (!dbg_is_tst_rcvry(c))
+               err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
+       else
+               err = dbg_leb_change(c->ubi, lnum, buf, len, dtype);
+       if (err) {
+               ubifs_err("changing %d bytes in LEB %d failed, error %d",
+                         len, lnum, err);
+               ubifs_ro_mode(c, err);
+               dbg_dump_stack();
+       }
+       return err;
+}
+
+int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
+{
+       int err;
+
+       ubifs_assert(!c->ro_media && !c->ro_mount);
+       if (c->ro_error)
+               return -EROFS;
+       if (!dbg_is_tst_rcvry(c))
+               err = ubi_leb_unmap(c->ubi, lnum);
+       else
+               err = dbg_leb_unmap(c->ubi, lnum);
+       if (err) {
+               ubifs_err("unmap LEB %d failed, error %d", lnum, err);
+               ubifs_ro_mode(c, err);
+               dbg_dump_stack();
+       }
+       return err;
+}
+
+int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype)
+{
+       int err;
+
+       ubifs_assert(!c->ro_media && !c->ro_mount);
+       if (c->ro_error)
+               return -EROFS;
+       if (!dbg_is_tst_rcvry(c))
+               err = ubi_leb_map(c->ubi, lnum, dtype);
+       else
+               err = dbg_leb_map(c->ubi, lnum, dtype);
+       if (err) {
+               ubifs_err("mapping LEB %d failed, error %d", lnum, err);
+               ubifs_ro_mode(c, err);
+               dbg_dump_stack();
+       }
+       return err;
+}
+
+int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
+{
+       int err;
+
+       err = ubi_is_mapped(c->ubi, lnum);
+       if (err < 0) {
+               ubifs_err("ubi_is_mapped failed for LEB %d, error %d",
+                         lnum, err);
+               dbg_dump_stack();
+       }
+       return err;
+}
+
 /**
  * ubifs_check_node - check node.
  * @c: UBIFS file-system description object