Merge tag 'upstream-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw...
[linux-2.6-block.git] / fs / ubifs / super.c
index 6cfc494050bef21a675ab9aa2f3e5020379781cf..2c0803b0ac3aa21190ca84ca65f59f2e5de1069b 100644 (file)
@@ -566,6 +566,8 @@ static int init_constants_early(struct ubifs_info *c)
        c->ranges[UBIFS_AUTH_NODE].min_len = UBIFS_AUTH_NODE_SZ;
        c->ranges[UBIFS_AUTH_NODE].max_len = UBIFS_AUTH_NODE_SZ +
                                UBIFS_MAX_HMAC_LEN;
+       c->ranges[UBIFS_SIG_NODE].min_len = UBIFS_SIG_NODE_SZ;
+       c->ranges[UBIFS_SIG_NODE].max_len = c->leb_size - UBIFS_SB_NODE_SZ;
 
        c->ranges[UBIFS_INO_NODE].min_len  = UBIFS_INO_NODE_SZ;
        c->ranges[UBIFS_INO_NODE].max_len  = UBIFS_MAX_INO_NODE_SZ;
@@ -1043,6 +1045,8 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
                                c->mount_opts.compr_type = UBIFS_COMPR_LZO;
                        else if (!strcmp(name, "zlib"))
                                c->mount_opts.compr_type = UBIFS_COMPR_ZLIB;
+                       else if (!strcmp(name, "zstd"))
+                               c->mount_opts.compr_type = UBIFS_COMPR_ZSTD;
                        else {
                                ubifs_err(c, "unknown compressor \"%s\"", name); //FIXME: is c ready?
                                kfree(name);
@@ -1296,8 +1300,7 @@ static int mount_ubifs(struct ubifs_info *c)
        if (err)
                goto out_free;
 
-       sz = ALIGN(c->max_idx_node_sz, c->min_io_size);
-       sz = ALIGN(sz + c->max_idx_node_sz, c->min_io_size);
+       sz = ALIGN(c->max_idx_node_sz, c->min_io_size) * 2;
        c->cbuf = kmalloc(sz, GFP_NOFS);
        if (!c->cbuf) {
                err = -ENOMEM;
@@ -1360,6 +1363,26 @@ static int mount_ubifs(struct ubifs_info *c)
                        goto out_lpt;
        }
 
+       /*
+        * Handle offline signed images: Now that the master node is
+        * written and its validation no longer depends on the hash
+        * in the superblock, we can update the offline signed
+        * superblock with a HMAC version,
+        */
+       if (ubifs_authenticated(c) && ubifs_hmac_zero(c, c->sup_node->hmac)) {
+               err = ubifs_hmac_wkm(c, c->sup_node->hmac_wkm);
+               if (err)
+                       goto out_lpt;
+               c->superblock_need_write = 1;
+       }
+
+       if (!c->ro_mount && c->superblock_need_write) {
+               err = ubifs_write_sb_node(c, c->sup_node);
+               if (err)
+                       goto out_lpt;
+               c->superblock_need_write = 0;
+       }
+
        err = dbg_check_idx_size(c, c->bi.old_idx_sz);
        if (err)
                goto out_lpt;
@@ -1465,9 +1488,7 @@ static int mount_ubifs(struct ubifs_info *c)
        if (err)
                goto out_infos;
 
-       err = dbg_debugfs_init_fs(c);
-       if (err)
-               goto out_infos;
+       dbg_debugfs_init_fs(c);
 
        c->mounting = 0;
 
@@ -1644,15 +1665,6 @@ static int ubifs_remount_rw(struct ubifs_info *c)
        if (err)
                goto out;
 
-       if (c->old_leb_cnt != c->leb_cnt) {
-               struct ubifs_sb_node *sup = c->sup_node;
-
-               sup->leb_cnt = cpu_to_le32(c->leb_cnt);
-               err = ubifs_write_sb_node(c, sup);
-               if (err)
-                       goto out;
-       }
-
        if (c->need_recovery) {
                ubifs_msg(c, "completing deferred recovery");
                err = ubifs_write_rcvrd_mst_node(c);
@@ -1684,6 +1696,16 @@ static int ubifs_remount_rw(struct ubifs_info *c)
                        goto out;
        }
 
+       if (c->superblock_need_write) {
+               struct ubifs_sb_node *sup = c->sup_node;
+
+               err = ubifs_write_sb_node(c, sup);
+               if (err)
+                       goto out;
+
+               c->superblock_need_write = 0;
+       }
+
        c->ileb_buf = vmalloc(c->leb_size);
        if (!c->ileb_buf) {
                err = -ENOMEM;
@@ -2352,9 +2374,7 @@ static int __init ubifs_init(void)
        if (err)
                goto out_shrinker;
 
-       err = dbg_debugfs_init();
-       if (err)
-               goto out_compr;
+       dbg_debugfs_init();
 
        err = register_filesystem(&ubifs_fs_type);
        if (err) {
@@ -2366,7 +2386,6 @@ static int __init ubifs_init(void)
 
 out_dbg:
        dbg_debugfs_exit();
-out_compr:
        ubifs_compressors_exit();
 out_shrinker:
        unregister_shrinker(&ubifs_shrinker_info);