ubifs: Store read superblock node
authorSascha Hauer <s.hauer@pengutronix.de>
Fri, 7 Sep 2018 12:36:29 +0000 (14:36 +0200)
committerRichard Weinberger <richard@nod.at>
Tue, 23 Oct 2018 11:48:29 +0000 (13:48 +0200)
The superblock node is read/modified/written several times throughout
the UBIFS code. Instead of reading it from the device each time just
keep a copy in memory and write back the modified copy when necessary.
This patch helps for authentication support, here we not only have to
read the superblock node, but also have to authenticate it, which
is easier if we do it once during initialization.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Richard Weinberger <richard@nod.at>
fs/ubifs/sb.c
fs/ubifs/super.c
fs/ubifs/ubifs.h

index cf7ee2880c571ff917d360acf79065bf6a5f92c1..7e08c81433165b49192bc4eb60cdda0551de409c 100644 (file)
@@ -497,7 +497,7 @@ failed:
  * code. Note, the user of this function is responsible of kfree()'ing the
  * returned superblock buffer.
  */
-struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c)
+static struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c)
 {
        struct ubifs_sb_node *sup;
        int err;
@@ -554,6 +554,8 @@ int ubifs_read_superblock(struct ubifs_info *c)
        if (IS_ERR(sup))
                return PTR_ERR(sup);
 
+       c->sup_node = sup;
+
        c->fmt_version = le32_to_cpu(sup->fmt_version);
        c->ro_compat_version = le32_to_cpu(sup->ro_compat_version);
 
@@ -685,7 +687,6 @@ int ubifs_read_superblock(struct ubifs_info *c)
 
        err = validate_sb(c, sup);
 out:
-       kfree(sup);
        return err;
 }
 
@@ -814,7 +815,7 @@ out:
 int ubifs_fixup_free_space(struct ubifs_info *c)
 {
        int err;
-       struct ubifs_sb_node *sup;
+       struct ubifs_sb_node *sup = c->sup_node;
 
        ubifs_assert(c, c->space_fixup);
        ubifs_assert(c, !c->ro_mount);
@@ -825,16 +826,11 @@ int ubifs_fixup_free_space(struct ubifs_info *c)
        if (err)
                return err;
 
-       sup = ubifs_read_sb_node(c);
-       if (IS_ERR(sup))
-               return PTR_ERR(sup);
-
        /* Free-space fixup is no longer required */
        c->space_fixup = 0;
        sup->flags &= cpu_to_le32(~UBIFS_FLG_SPACE_FIXUP);
 
        err = ubifs_write_sb_node(c, sup);
-       kfree(sup);
        if (err)
                return err;
 
@@ -845,7 +841,7 @@ int ubifs_fixup_free_space(struct ubifs_info *c)
 int ubifs_enable_encryption(struct ubifs_info *c)
 {
        int err;
-       struct ubifs_sb_node *sup;
+       struct ubifs_sb_node *sup = c->sup_node;
 
        if (c->encrypted)
                return 0;
@@ -858,16 +854,11 @@ int ubifs_enable_encryption(struct ubifs_info *c)
                return -EINVAL;
        }
 
-       sup = ubifs_read_sb_node(c);
-       if (IS_ERR(sup))
-               return PTR_ERR(sup);
-
        sup->flags |= cpu_to_le32(UBIFS_FLG_ENCRYPTION);
 
        err = ubifs_write_sb_node(c, sup);
        if (!err)
                c->encrypted = 1;
-       kfree(sup);
 
        return err;
 }
index fec62e9dfbe6a6c639d7f61879bf21ac84ef4a6c..70a64e00f0a8384f6133a693c365f44d10ab9ec1 100644 (file)
@@ -1605,16 +1605,10 @@ static int ubifs_remount_rw(struct ubifs_info *c)
                goto out;
 
        if (c->old_leb_cnt != c->leb_cnt) {
-               struct ubifs_sb_node *sup;
+               struct ubifs_sb_node *sup = c->sup_node;
 
-               sup = ubifs_read_sb_node(c);
-               if (IS_ERR(sup)) {
-                       err = PTR_ERR(sup);
-                       goto out;
-               }
                sup->leb_cnt = cpu_to_le32(c->leb_cnt);
                err = ubifs_write_sb_node(c, sup);
-               kfree(sup);
                if (err)
                        goto out;
        }
index 306cc7a4f72590a6cb8fe860b2ac4c857ee5189a..93e1c34c097f3c52611fac0ded2a4c14ffd6918b 100644 (file)
@@ -983,6 +983,7 @@ struct ubifs_debug_info;
  * struct ubifs_info - UBIFS file-system description data structure
  * (per-superblock).
  * @vfs_sb: VFS @struct super_block object
+ * @sup_node: The super block node as read from the device
  *
  * @highest_inum: highest used inode number
  * @max_sqnum: current global sequence number
@@ -1230,6 +1231,7 @@ struct ubifs_debug_info;
  */
 struct ubifs_info {
        struct super_block *vfs_sb;
+       struct ubifs_sb_node *sup_node;
 
        ino_t highest_inum;
        unsigned long long max_sqnum;
@@ -1664,7 +1666,6 @@ int ubifs_write_master(struct ubifs_info *c);
 
 /* sb.c */
 int ubifs_read_superblock(struct ubifs_info *c);
-struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c);
 int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup);
 int ubifs_fixup_free_space(struct ubifs_info *c);
 int ubifs_enable_encryption(struct ubifs_info *c);