return err;
 }
 
+/**
+ * inode_fix_size - fix inode size
+ * @c: UBIFS file-system description object
+ * @e: inode size information for recovery
+ */
+static int inode_fix_size(struct ubifs_info *c, struct size_entry *e)
+{
+       struct inode *inode;
+       struct ubifs_inode *ui;
+       int err;
+
+       if (c->ro_mount)
+               ubifs_assert(c, !e->inode);
+
+       if (e->inode) {
+               /* Remounting rw, pick up inode we stored earlier */
+               inode = e->inode;
+       } else {
+               inode = ubifs_iget(c->vfs_sb, e->inum);
+               if (IS_ERR(inode))
+                       return PTR_ERR(inode);
+
+               if (inode->i_size >= e->d_size) {
+                       /*
+                        * The original inode in the index already has a size
+                        * big enough, nothing to do
+                        */
+                       iput(inode);
+                       return 0;
+               }
+
+               dbg_rcvry("ino %lu size %lld -> %lld",
+                         (unsigned long)e->inum,
+                         inode->i_size, e->d_size);
+
+               ui = ubifs_inode(inode);
+
+               inode->i_size = e->d_size;
+               ui->ui_size = e->d_size;
+               ui->synced_i_size = e->d_size;
+
+               e->inode = inode;
+       }
+
+       /*
+        * In readonly mode just keep the inode pinned in memory until we go
+        * readwrite. In readwrite mode write the inode to the journal with the
+        * fixed size.
+        */
+       if (c->ro_mount)
+               return 0;
+
+       err = ubifs_jnl_write_inode(c, inode);
+
+       iput(inode);
+
+       if (err)
+               return err;
+
+       rb_erase(&e->rb, &c->size_tree);
+       kfree(e);
+
+       return 0;
+}
+
 /**
  * ubifs_recover_size - recover inode size.
  * @c: UBIFS file-system description object
+ * @in_place: If true, do a in-place size fixup
  *
  * This function attempts to fix inode size discrepancies identified by the
  * 'ubifs_recover_size_accum()' function.
  *
  * This functions returns %0 on success and a negative error code on failure.
  */
-int ubifs_recover_size(struct ubifs_info *c)
+int ubifs_recover_size(struct ubifs_info *c, bool in_place)
 {
        struct rb_node *this = rb_first(&c->size_tree);
 
                int err;
 
                e = rb_entry(this, struct size_entry, rb);
+
+               this = rb_next(this);
+
                if (!e->exists) {
                        union ubifs_key key;
 
                }
 
                if (e->exists && e->i_size < e->d_size) {
-                       if (c->ro_mount) {
-                               /* Fix the inode size and pin it in memory */
-                               struct inode *inode;
-                               struct ubifs_inode *ui;
-
-                               ubifs_assert(c, !e->inode);
-
-                               inode = ubifs_iget(c->vfs_sb, e->inum);
-                               if (IS_ERR(inode))
-                                       return PTR_ERR(inode);
-
-                               ui = ubifs_inode(inode);
-                               if (inode->i_size < e->d_size) {
-                                       dbg_rcvry("ino %lu size %lld -> %lld",
-                                                 (unsigned long)e->inum,
-                                                 inode->i_size, e->d_size);
-                                       inode->i_size = e->d_size;
-                                       ui->ui_size = e->d_size;
-                                       ui->synced_i_size = e->d_size;
-                                       e->inode = inode;
-                                       this = rb_next(this);
-                                       continue;
-                               }
-                               iput(inode);
-                       } else {
-                               /* Fix the size in place */
+                       ubifs_assert(c, !(c->ro_mount && in_place));
+
+                       /*
+                        * We found data that is outside the found inode size,
+                        * fixup the inode size
+                        */
+
+                       if (in_place) {
                                err = fix_size_in_place(c, e);
                                if (err)
                                        return err;
                                iput(e->inode);
+                       } else {
+                               err = inode_fix_size(c, e);
+                               if (err)
+                                       return err;
+                               continue;
                        }
                }
 
-               this = rb_next(this);
                rb_erase(&e->rb, &c->size_tree);
                kfree(e);
        }
 
                }
 
                if (c->need_recovery) {
-                       err = ubifs_recover_size(c);
-                       if (err)
-                               goto out_orphans;
+                       if (!ubifs_authenticated(c)) {
+                               err = ubifs_recover_size(c, true);
+                               if (err)
+                                       goto out_orphans;
+                       }
+
                        err = ubifs_rcvry_gc_commit(c);
                        if (err)
                                goto out_orphans;
+
+                       if (ubifs_authenticated(c)) {
+                               err = ubifs_recover_size(c, false);
+                               if (err)
+                                       goto out_orphans;
+                       }
                } else {
                        err = take_gc_lnum(c);
                        if (err)
                if (err)
                        goto out_orphans;
        } else if (c->need_recovery) {
-               err = ubifs_recover_size(c);
+               err = ubifs_recover_size(c, false);
                if (err)
                        goto out_orphans;
        } else {
                err = ubifs_write_rcvrd_mst_node(c);
                if (err)
                        goto out;
-               err = ubifs_recover_size(c);
-               if (err)
-                       goto out;
+               if (!ubifs_authenticated(c)) {
+                       err = ubifs_recover_size(c, true);
+                       if (err)
+                               goto out;
+               }
                err = ubifs_clean_lebs(c, c->sbuf);
                if (err)
                        goto out;
                        goto out;
        }
 
-       if (c->need_recovery)
+       if (c->need_recovery) {
                err = ubifs_rcvry_gc_commit(c);
-       else
+               if (err)
+                       goto out;
+
+               if (ubifs_authenticated(c)) {
+                       err = ubifs_recover_size(c, false);
+                       if (err)
+                               goto out;
+               }
+       } else {
                err = ubifs_leb_unmap(c, c->gc_lnum);
+       }
        if (err)
                goto out;