struct bmap *bmp;
        struct dbmap_disk *dbmp_le;
        struct metapage *mp;
-       int i;
+       int i, err;
 
        /*
         * allocate/initialize the in-memory bmap descriptor
                           BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage,
                           PSIZE, 0);
        if (mp == NULL) {
-               kfree(bmp);
-               return -EIO;
+               err = -EIO;
+               goto err_kfree_bmp;
        }
 
        /* copy the on-disk bmap descriptor to its in-memory version. */
        bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
        bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
        if (!bmp->db_numag) {
-               release_metapage(mp);
-               kfree(bmp);
-               return -EINVAL;
+               err = -EINVAL;
+               goto err_release_metapage;
        }
 
        bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
        bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
        bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
        bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
+       if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) {
+               err = -EINVAL;
+               goto err_release_metapage;
+       }
+
        for (i = 0; i < MAXAG; i++)
                bmp->db_agfree[i] = le64_to_cpu(dbmp_le->dn_agfree[i]);
        bmp->db_agsize = le64_to_cpu(dbmp_le->dn_agsize);
        BMAP_LOCK_INIT(bmp);
 
        return (0);
+
+err_release_metapage:
+       release_metapage(mp);
+err_kfree_bmp:
+       kfree(bmp);
+       return err;
 }