return ret;
 }
 
+/**
+ * nilfs_get_blocksize - get block size from raw superblock data
+ * @sb: super block instance
+ * @sbp: superblock raw data buffer
+ * @blocksize: place to store block size
+ *
+ * nilfs_get_blocksize() calculates the block size from the block size
+ * exponent information written in @sbp and stores it in @blocksize,
+ * or aborts with an error message if it's too large.
+ *
+ * Return Value: On success, 0 is returned. If the block size is too
+ * large, -EINVAL is returned.
+ */
+static int nilfs_get_blocksize(struct super_block *sb,
+                              struct nilfs_super_block *sbp, int *blocksize)
+{
+       unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size);
+
+       if (unlikely(shift_bits >
+                    ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)) {
+               nilfs_err(sb, "too large filesystem blocksize: 2 ^ %u KiB",
+                         shift_bits);
+               return -EINVAL;
+       }
+       *blocksize = BLOCK_SIZE << shift_bits;
+       return 0;
+}
+
 /**
  * load_nilfs - load and recover the nilfs
  * @nilfs: the_nilfs structure to be released
                nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
 
                /* verify consistency between two super blocks */
-               blocksize = BLOCK_SIZE << le32_to_cpu(sbp[0]->s_log_block_size);
+               err = nilfs_get_blocksize(sb, sbp[0], &blocksize);
+               if (err)
+                       goto scan_error;
+
                if (blocksize != nilfs->ns_blocksize) {
                        nilfs_warn(sb,
                                   "blocksize differs between two super blocks (%d != %d)",
                                   blocksize, nilfs->ns_blocksize);
+                       err = -EINVAL;
                        goto scan_error;
                }
 
        if (err)
                goto failed_sbh;
 
-       blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
-       if (blocksize < NILFS_MIN_BLOCK_SIZE ||
-           blocksize > NILFS_MAX_BLOCK_SIZE) {
+       err = nilfs_get_blocksize(sb, sbp, &blocksize);
+       if (err)
+               goto failed_sbh;
+
+       if (blocksize < NILFS_MIN_BLOCK_SIZE) {
                nilfs_err(sb,
                          "couldn't mount because of unsupported filesystem blocksize %d",
                          blocksize);