]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - fs/ubifs/io.c
UBIFS: introduce more I/O helpers
[mirror_ubuntu-artful-kernel.git] / fs / ubifs / io.c
index 3be645e012c9358170ad45a87af3b83b8fbd72ca..239899d7bf3fbc512cdaaecd379831b30893c652 100644 (file)
@@ -86,8 +86,125 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
                c->no_chk_data_crc = 0;
                c->vfs_sb->s_flags |= MS_RDONLY;
                ubifs_warn("switched to read-only mode, error %d", err);
+               dump_stack();
+       }
+}
+
+/*
+ * 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;
 }
 
 /**