[XFS] Put the correct offset in dirent d_off
[safe/jmp/linux-2.6] / fs / ext4 / ialloc.c
index e45dbd6..c61f37f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/fs/ext3/ialloc.c
+ *  linux/fs/ext4/ialloc.c
  *
  * Copyright (C) 1992, 1993, 1994, 1995
  * Remy Card (card@masi.ibp.fr)
 
 #include <linux/time.h>
 #include <linux/fs.h>
-#include <linux/jbd.h>
-#include <linux/ext3_fs.h>
-#include <linux/ext3_jbd.h>
+#include <linux/jbd2.h>
+#include <linux/ext4_fs.h>
+#include <linux/ext4_jbd2.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
 #include <linux/random.h>
 #include <linux/bitops.h>
-
+#include <linux/blkdev.h>
 #include <asm/byteorder.h>
 
 #include "xattr.h"
 #include "acl.h"
+#include "group.h"
 
 /*
  * ialloc.c contains the inodes allocation and deallocation routines
  * the free blocks count in the block.
  */
 
+/*
+ * To avoid calling the atomic setbit hundreds or thousands of times, we only
+ * need to use it within a single byte (to ensure we get endianness right).
+ * We can use memset for the rest of the bitmap as there are no other users.
+ */
+void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+{
+       int i;
+
+       if (start_bit >= end_bit)
+               return;
+
+       ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit);
+       for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
+               ext4_set_bit(i, bitmap);
+       if (i < end_bit)
+               memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+}
+
+/* Initializes an uninitialized inode bitmap */
+unsigned ext4_init_inode_bitmap(struct super_block *sb,
+                               struct buffer_head *bh, int block_group,
+                               struct ext4_group_desc *gdp)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+       J_ASSERT_BH(bh, buffer_locked(bh));
+
+       /* If checksum is bad mark all blocks and inodes use to prevent
+        * allocation, essentially implementing a per-group read-only flag. */
+       if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
+               ext4_error(sb, __FUNCTION__, "Checksum bad for group %u\n",
+                          block_group);
+               gdp->bg_free_blocks_count = 0;
+               gdp->bg_free_inodes_count = 0;
+               gdp->bg_itable_unused = 0;
+               memset(bh->b_data, 0xff, sb->s_blocksize);
+               return 0;
+       }
+
+       memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
+       mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb),
+                       bh->b_data);
+
+       return EXT4_INODES_PER_GROUP(sb);
+}
 
 /*
  * Read the inode allocation bitmap for a given block_group, reading
 static struct buffer_head *
 read_inode_bitmap(struct super_block * sb, unsigned long block_group)
 {
-       struct ext3_group_desc *desc;
+       struct ext4_group_desc *desc;
        struct buffer_head *bh = NULL;
 
-       desc = ext3_get_group_desc(sb, block_group, NULL);
+       desc = ext4_get_group_desc(sb, block_group, NULL);
        if (!desc)
                goto error_out;
-
-       bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap));
+       if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+               bh = sb_getblk(sb, ext4_inode_bitmap(sb, desc));
+               if (!buffer_uptodate(bh)) {
+                       lock_buffer(bh);
+                       if (!buffer_uptodate(bh)) {
+                               ext4_init_inode_bitmap(sb, bh, block_group,
+                                                      desc);
+                               set_buffer_uptodate(bh);
+                       }
+                       unlock_buffer(bh);
+               }
+       } else {
+               bh = sb_bread(sb, ext4_inode_bitmap(sb, desc));
+       }
        if (!bh)
-               ext3_error(sb, "read_inode_bitmap",
+               ext4_error(sb, "read_inode_bitmap",
                            "Cannot read inode bitmap - "
-                           "block_group = %lu, inode_bitmap = %u",
-                           block_group, le32_to_cpu(desc->bg_inode_bitmap));
+                           "block_group = %lu, inode_bitmap = %llu",
+                           block_group, ext4_inode_bitmap(sb, desc));
 error_out:
        return bh;
 }
@@ -86,7 +145,7 @@ error_out:
  * though), and then we'd have two inodes sharing the
  * same inode number and space on the harddisk.
  */
-void ext3_free_inode (handle_t *handle, struct inode * inode)
+void ext4_free_inode (handle_t *handle, struct inode * inode)
 {
        struct super_block * sb = inode->i_sb;
        int is_directory;
@@ -95,36 +154,36 @@ void ext3_free_inode (handle_t *handle, struct inode * inode)
        struct buffer_head *bh2;
        unsigned long block_group;
        unsigned long bit;
-       struct ext3_group_desc * gdp;
-       struct ext3_super_block * es;
-       struct ext3_sb_info *sbi;
+       struct ext4_group_desc * gdp;
+       struct ext4_super_block * es;
+       struct ext4_sb_info *sbi;
        int fatal = 0, err;
 
        if (atomic_read(&inode->i_count) > 1) {
-               printk ("ext3_free_inode: inode has count=%d\n",
+               printk ("ext4_free_inode: inode has count=%d\n",
                                        atomic_read(&inode->i_count));
                return;
        }
        if (inode->i_nlink) {
-               printk ("ext3_free_inode: inode has nlink=%d\n",
+               printk ("ext4_free_inode: inode has nlink=%d\n",
                        inode->i_nlink);
                return;
        }
        if (!sb) {
-               printk("ext3_free_inode: inode on nonexistent device\n");
+               printk("ext4_free_inode: inode on nonexistent device\n");
                return;
        }
-       sbi = EXT3_SB(sb);
+       sbi = EXT4_SB(sb);
 
        ino = inode->i_ino;
-       ext3_debug ("freeing inode %lu\n", ino);
+       ext4_debug ("freeing inode %lu\n", ino);
 
        /*
         * Note: we must free any quota before locking the superblock,
         * as writing the quota to disk may need the lock as well.
         */
        DQUOT_INIT(inode);
-       ext3_xattr_delete_inode(handle, inode);
+       ext4_xattr_delete_inode(handle, inode);
        DQUOT_FREE_INODE(inode);
        DQUOT_DROP(inode);
 
@@ -133,33 +192,33 @@ void ext3_free_inode (handle_t *handle, struct inode * inode)
        /* Do this BEFORE marking the inode not in use or returning an error */
        clear_inode (inode);
 
-       es = EXT3_SB(sb)->s_es;
-       if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
-               ext3_error (sb, "ext3_free_inode",
+       es = EXT4_SB(sb)->s_es;
+       if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
+               ext4_error (sb, "ext4_free_inode",
                            "reserved or nonexistent inode %lu", ino);
                goto error_return;
        }
-       block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb);
-       bit = (ino - 1) % EXT3_INODES_PER_GROUP(sb);
+       block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
+       bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
        bitmap_bh = read_inode_bitmap(sb, block_group);
        if (!bitmap_bh)
                goto error_return;
 
        BUFFER_TRACE(bitmap_bh, "get_write_access");
-       fatal = ext3_journal_get_write_access(handle, bitmap_bh);
+       fatal = ext4_journal_get_write_access(handle, bitmap_bh);
        if (fatal)
                goto error_return;
 
        /* Ok, now we can actually update the inode bitmaps.. */
-       if (!ext3_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
+       if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
                                        bit, bitmap_bh->b_data))
-               ext3_error (sb, "ext3_free_inode",
+               ext4_error (sb, "ext4_free_inode",
                              "bit already cleared for inode %lu", ino);
        else {
-               gdp = ext3_get_group_desc (sb, block_group, &bh2);
+               gdp = ext4_get_group_desc (sb, block_group, &bh2);
 
                BUFFER_TRACE(bh2, "get_write_access");
-               fatal = ext3_journal_get_write_access(handle, bh2);
+               fatal = ext4_journal_get_write_access(handle, bh2);
                if (fatal) goto error_return;
 
                if (gdp) {
@@ -169,24 +228,26 @@ void ext3_free_inode (handle_t *handle, struct inode * inode)
                        if (is_directory)
                                gdp->bg_used_dirs_count = cpu_to_le16(
                                  le16_to_cpu(gdp->bg_used_dirs_count) - 1);
+                       gdp->bg_checksum = ext4_group_desc_csum(sbi,
+                                                       block_group, gdp);
                        spin_unlock(sb_bgl_lock(sbi, block_group));
                        percpu_counter_inc(&sbi->s_freeinodes_counter);
                        if (is_directory)
                                percpu_counter_dec(&sbi->s_dirs_counter);
 
                }
-               BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata");
-               err = ext3_journal_dirty_metadata(handle, bh2);
+               BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
+               err = ext4_journal_dirty_metadata(handle, bh2);
                if (!fatal) fatal = err;
        }
-       BUFFER_TRACE(bitmap_bh, "call ext3_journal_dirty_metadata");
-       err = ext3_journal_dirty_metadata(handle, bitmap_bh);
+       BUFFER_TRACE(bitmap_bh, "call ext4_journal_dirty_metadata");
+       err = ext4_journal_dirty_metadata(handle, bitmap_bh);
        if (!fatal)
                fatal = err;
        sb->s_dirt = 1;
 error_return:
        brelse(bitmap_bh);
-       ext3_std_error(sb, fatal);
+       ext4_std_error(sb, fatal);
 }
 
 /*
@@ -201,17 +262,16 @@ error_return:
  */
 static int find_group_dir(struct super_block *sb, struct inode *parent)
 {
-       int ngroups = EXT3_SB(sb)->s_groups_count;
+       int ngroups = EXT4_SB(sb)->s_groups_count;
        unsigned int freei, avefreei;
-       struct ext3_group_desc *desc, *best_desc = NULL;
-       struct buffer_head *bh;
+       struct ext4_group_desc *desc, *best_desc = NULL;
        int group, best_group = -1;
 
-       freei = percpu_counter_read_positive(&EXT3_SB(sb)->s_freeinodes_counter);
+       freei = percpu_counter_read_positive(&EXT4_SB(sb)->s_freeinodes_counter);
        avefreei = freei / ngroups;
 
        for (group = 0; group < ngroups; group++) {
-               desc = ext3_get_group_desc (sb, group, &bh);
+               desc = ext4_get_group_desc (sb, group, NULL);
                if (!desc || !desc->bg_free_inodes_count)
                        continue;
                if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
@@ -256,29 +316,29 @@ static int find_group_dir(struct super_block *sb, struct inode *parent)
 
 static int find_group_orlov(struct super_block *sb, struct inode *parent)
 {
-       int parent_group = EXT3_I(parent)->i_block_group;
-       struct ext3_sb_info *sbi = EXT3_SB(sb);
-       struct ext3_super_block *es = sbi->s_es;
+       int parent_group = EXT4_I(parent)->i_block_group;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_super_block *es = sbi->s_es;
        int ngroups = sbi->s_groups_count;
-       int inodes_per_group = EXT3_INODES_PER_GROUP(sb);
+       int inodes_per_group = EXT4_INODES_PER_GROUP(sb);
        unsigned int freei, avefreei;
-       ext3_fsblk_t freeb, avefreeb;
-       ext3_fsblk_t blocks_per_dir;
+       ext4_fsblk_t freeb, avefreeb;
+       ext4_fsblk_t blocks_per_dir;
        unsigned int ndirs;
        int max_debt, max_dirs, min_inodes;
-       ext3_grpblk_t min_blocks;
+       ext4_grpblk_t min_blocks;
        int group = -1, i;
-       struct ext3_group_desc *desc;
-       struct buffer_head *bh;
+       struct ext4_group_desc *desc;
 
        freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
        avefreei = freei / ngroups;
        freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
-       avefreeb = freeb / ngroups;
+       avefreeb = freeb;
+       do_div(avefreeb, ngroups);
        ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
 
        if ((parent == sb->s_root->d_inode) ||
-           (EXT3_I(parent)->i_flags & EXT3_TOPDIR_FL)) {
+           (EXT4_I(parent)->i_flags & EXT4_TOPDIR_FL)) {
                int best_ndir = inodes_per_group;
                int best_group = -1;
 
@@ -286,7 +346,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
                parent_group = (unsigned)group % ngroups;
                for (i = 0; i < ngroups; i++) {
                        group = (parent_group + i) % ngroups;
-                       desc = ext3_get_group_desc (sb, group, &bh);
+                       desc = ext4_get_group_desc (sb, group, NULL);
                        if (!desc || !desc->bg_free_inodes_count)
                                continue;
                        if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir)
@@ -303,13 +363,15 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
                goto fallback;
        }
 
-       blocks_per_dir = (le32_to_cpu(es->s_blocks_count) - freeb) / ndirs;
+       blocks_per_dir = ext4_blocks_count(es) - freeb;
+       do_div(blocks_per_dir, ndirs);
 
        max_dirs = ndirs / ngroups + inodes_per_group / 16;
        min_inodes = avefreei - inodes_per_group / 4;
-       min_blocks = avefreeb - EXT3_BLOCKS_PER_GROUP(sb) / 4;
+       min_blocks = avefreeb - EXT4_BLOCKS_PER_GROUP(sb) / 4;
 
-       max_debt = EXT3_BLOCKS_PER_GROUP(sb) / max(blocks_per_dir, (ext3_fsblk_t)BLOCK_COST);
+       max_debt = EXT4_BLOCKS_PER_GROUP(sb);
+       max_debt /= max_t(int, blocks_per_dir, BLOCK_COST);
        if (max_debt * INODE_COST > inodes_per_group)
                max_debt = inodes_per_group / INODE_COST;
        if (max_debt > 255)
@@ -319,7 +381,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
 
        for (i = 0; i < ngroups; i++) {
                group = (parent_group + i) % ngroups;
-               desc = ext3_get_group_desc (sb, group, &bh);
+               desc = ext4_get_group_desc (sb, group, NULL);
                if (!desc || !desc->bg_free_inodes_count)
                        continue;
                if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs)
@@ -334,7 +396,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
 fallback:
        for (i = 0; i < ngroups; i++) {
                group = (parent_group + i) % ngroups;
-               desc = ext3_get_group_desc (sb, group, &bh);
+               desc = ext4_get_group_desc (sb, group, NULL);
                if (!desc || !desc->bg_free_inodes_count)
                        continue;
                if (le16_to_cpu(desc->bg_free_inodes_count) >= avefreei)
@@ -355,17 +417,16 @@ fallback:
 
 static int find_group_other(struct super_block *sb, struct inode *parent)
 {
-       int parent_group = EXT3_I(parent)->i_block_group;
-       int ngroups = EXT3_SB(sb)->s_groups_count;
-       struct ext3_group_desc *desc;
-       struct buffer_head *bh;
+       int parent_group = EXT4_I(parent)->i_block_group;
+       int ngroups = EXT4_SB(sb)->s_groups_count;
+       struct ext4_group_desc *desc;
        int group, i;
 
        /*
         * Try to place the inode in its parent directory
         */
        group = parent_group;
-       desc = ext3_get_group_desc (sb, group, &bh);
+       desc = ext4_get_group_desc (sb, group, NULL);
        if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
                        le16_to_cpu(desc->bg_free_blocks_count))
                return group;
@@ -389,7 +450,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
                group += i;
                if (group >= ngroups)
                        group -= ngroups;
-               desc = ext3_get_group_desc (sb, group, &bh);
+               desc = ext4_get_group_desc (sb, group, NULL);
                if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
                                le16_to_cpu(desc->bg_free_blocks_count))
                        return group;
@@ -403,7 +464,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
        for (i = 0; i < ngroups; i++) {
                if (++group >= ngroups)
                        group = 0;
-               desc = ext3_get_group_desc (sb, group, &bh);
+               desc = ext4_get_group_desc (sb, group, NULL);
                if (desc && le16_to_cpu(desc->bg_free_inodes_count))
                        return group;
        }
@@ -421,7 +482,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
  * For other inodes, search forward from the parent directory's block
  * group to find a free inode.
  */
-struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
+struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
 {
        struct super_block *sb;
        struct buffer_head *bitmap_bh = NULL;
@@ -429,13 +490,13 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
        int group;
        unsigned long ino = 0;
        struct inode * inode;
-       struct ext3_group_desc * gdp = NULL;
-       struct ext3_super_block * es;
-       struct ext3_inode_info *ei;
-       struct ext3_sb_info *sbi;
+       struct ext4_group_desc * gdp = NULL;
+       struct ext4_super_block * es;
+       struct ext4_inode_info *ei;
+       struct ext4_sb_info *sbi;
        int err = 0;
        struct inode *ret;
-       int i;
+       int i, free = 0;
 
        /* Cannot create files in a deleted directory */
        if (!dir || !dir->i_nlink)
@@ -445,9 +506,9 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
        inode = new_inode(sb);
        if (!inode)
                return ERR_PTR(-ENOMEM);
-       ei = EXT3_I(inode);
+       ei = EXT4_I(inode);
 
-       sbi = EXT3_SB(sb);
+       sbi = EXT4_SB(sb);
        es = sbi->s_es;
        if (S_ISDIR(mode)) {
                if (test_opt (sb, OLDALLOC))
@@ -464,7 +525,7 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
        for (i = 0; i < sbi->s_groups_count; i++) {
                err = -EIO;
 
-               gdp = ext3_get_group_desc(sb, group, &bh2);
+               gdp = ext4_get_group_desc(sb, group, &bh2);
                if (!gdp)
                        goto fail;
 
@@ -476,30 +537,30 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
                ino = 0;
 
 repeat_in_this_group:
-               ino = ext3_find_next_zero_bit((unsigned long *)
-                               bitmap_bh->b_data, EXT3_INODES_PER_GROUP(sb), ino);
-               if (ino < EXT3_INODES_PER_GROUP(sb)) {
+               ino = ext4_find_next_zero_bit((unsigned long *)
+                               bitmap_bh->b_data, EXT4_INODES_PER_GROUP(sb), ino);
+               if (ino < EXT4_INODES_PER_GROUP(sb)) {
 
                        BUFFER_TRACE(bitmap_bh, "get_write_access");
-                       err = ext3_journal_get_write_access(handle, bitmap_bh);
+                       err = ext4_journal_get_write_access(handle, bitmap_bh);
                        if (err)
                                goto fail;
 
-                       if (!ext3_set_bit_atomic(sb_bgl_lock(sbi, group),
+                       if (!ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
                                                ino, bitmap_bh->b_data)) {
                                /* we won it */
                                BUFFER_TRACE(bitmap_bh,
-                                       "call ext3_journal_dirty_metadata");
-                               err = ext3_journal_dirty_metadata(handle,
+                                       "call ext4_journal_dirty_metadata");
+                               err = ext4_journal_dirty_metadata(handle,
                                                                bitmap_bh);
                                if (err)
                                        goto fail;
                                goto got;
                        }
                        /* we lost it */
-                       journal_release_buffer(handle, bitmap_bh);
+                       jbd2_journal_release_buffer(handle, bitmap_bh);
 
-                       if (++ino < EXT3_INODES_PER_GROUP(sb))
+                       if (++ino < EXT4_INODES_PER_GROUP(sb))
                                goto repeat_in_this_group;
                }
 
@@ -517,28 +578,95 @@ repeat_in_this_group:
        goto out;
 
 got:
-       ino += group * EXT3_INODES_PER_GROUP(sb) + 1;
-       if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
-               ext3_error (sb, "ext3_new_inode",
-                           "reserved inode or inode > inodes count - "
-                           "block_group = %d, inode=%lu", group, ino);
+       ino++;
+       if ((group == 0 && ino < EXT4_FIRST_INO(sb)) ||
+           ino > EXT4_INODES_PER_GROUP(sb)) {
+               ext4_error(sb, __FUNCTION__,
+                          "reserved inode or inode > inodes count - "
+                          "block_group = %d, inode=%lu", group,
+                          ino + group * EXT4_INODES_PER_GROUP(sb));
                err = -EIO;
                goto fail;
        }
 
        BUFFER_TRACE(bh2, "get_write_access");
-       err = ext3_journal_get_write_access(handle, bh2);
+       err = ext4_journal_get_write_access(handle, bh2);
        if (err) goto fail;
+
+       /* We may have to initialize the block bitmap if it isn't already */
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM) &&
+           gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+               struct buffer_head *block_bh = read_block_bitmap(sb, group);
+
+               BUFFER_TRACE(block_bh, "get block bitmap access");
+               err = ext4_journal_get_write_access(handle, block_bh);
+               if (err) {
+                       brelse(block_bh);
+                       goto fail;
+               }
+
+               free = 0;
+               spin_lock(sb_bgl_lock(sbi, group));
+               /* recheck and clear flag under lock if we still need to */
+               if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+                       gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
+                       free = ext4_free_blocks_after_init(sb, group, gdp);
+                       gdp->bg_free_blocks_count = cpu_to_le16(free);
+               }
+               spin_unlock(sb_bgl_lock(sbi, group));
+
+               /* Don't need to dirty bitmap block if we didn't change it */
+               if (free) {
+                       BUFFER_TRACE(block_bh, "dirty block bitmap");
+                       err = ext4_journal_dirty_metadata(handle, block_bh);
+               }
+
+               brelse(block_bh);
+               if (err)
+                       goto fail;
+       }
+
        spin_lock(sb_bgl_lock(sbi, group));
+       /* If we didn't allocate from within the initialized part of the inode
+        * table then we need to initialize up to this inode. */
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+               if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+                       gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
+
+                       /* When marking the block group with
+                        * ~EXT4_BG_INODE_UNINIT we don't want to depend
+                        * on the value of bg_itable_unsed even though
+                        * mke2fs could have initialized the same for us.
+                        * Instead we calculated the value below
+                        */
+
+                       free = 0;
+               } else {
+                       free = EXT4_INODES_PER_GROUP(sb) -
+                               le16_to_cpu(gdp->bg_itable_unused);
+               }
+
+               /*
+                * Check the relative inode number against the last used
+                * relative inode number in this group. if it is greater
+                * we need to  update the bg_itable_unused count
+                *
+                */
+               if (ino > free)
+                       gdp->bg_itable_unused =
+                               cpu_to_le16(EXT4_INODES_PER_GROUP(sb) - ino);
+       }
+
        gdp->bg_free_inodes_count =
                cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1);
        if (S_ISDIR(mode)) {
                gdp->bg_used_dirs_count =
                        cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1);
        }
+       gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
        spin_unlock(sb_bgl_lock(sbi, group));
-       BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata");
-       err = ext3_journal_dirty_metadata(handle, bh2);
+       BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
+       err = ext4_journal_dirty_metadata(handle, bh2);
        if (err) goto fail;
 
        percpu_counter_dec(&sbi->s_freeinodes_counter);
@@ -557,33 +685,29 @@ got:
                inode->i_gid = current->fsgid;
        inode->i_mode = mode;
 
-       inode->i_ino = ino;
+       inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
        /* This is the optimal IO size (for stat), not the fs block size */
        inode->i_blocks = 0;
-       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
+       inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
+                                                      ext4_current_time(inode);
 
        memset(ei->i_data, 0, sizeof(ei->i_data));
        ei->i_dir_start_lookup = 0;
        ei->i_disksize = 0;
 
-       ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL;
+       ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL;
        if (S_ISLNK(mode))
-               ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
+               ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL);
        /* dirsync only applies to directories */
        if (!S_ISDIR(mode))
-               ei->i_flags &= ~EXT3_DIRSYNC_FL;
-#ifdef EXT3_FRAGMENTS
-       ei->i_faddr = 0;
-       ei->i_frag_no = 0;
-       ei->i_frag_size = 0;
-#endif
+               ei->i_flags &= ~EXT4_DIRSYNC_FL;
        ei->i_file_acl = 0;
        ei->i_dir_acl = 0;
        ei->i_dtime = 0;
        ei->i_block_alloc_info = NULL;
        ei->i_block_group = group;
 
-       ext3_set_inode_flags(inode);
+       ext4_set_inode_flags(inode);
        if (IS_DIRSYNC(inode))
                handle->h_sync = 1;
        insert_inode_hash(inode);
@@ -591,10 +715,9 @@ got:
        inode->i_generation = sbi->s_next_generation++;
        spin_unlock(&sbi->s_next_gen_lock);
 
-       ei->i_state = EXT3_STATE_NEW;
-       ei->i_extra_isize =
-               (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ?
-               sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0;
+       ei->i_state = EXT4_STATE_NEW;
+
+       ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
 
        ret = inode;
        if(DQUOT_ALLOC_INODE(inode)) {
@@ -602,24 +725,35 @@ got:
                goto fail_drop;
        }
 
-       err = ext3_init_acl(handle, inode, dir);
+       err = ext4_init_acl(handle, inode, dir);
        if (err)
                goto fail_free_drop;
 
-       err = ext3_init_security(handle,inode, dir);
+       err = ext4_init_security(handle,inode, dir);
        if (err)
                goto fail_free_drop;
 
-       err = ext3_mark_inode_dirty(handle, inode);
+       err = ext4_mark_inode_dirty(handle, inode);
        if (err) {
-               ext3_std_error(sb, err);
+               ext4_std_error(sb, err);
                goto fail_free_drop;
        }
+       if (test_opt(sb, EXTENTS)) {
+               EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL;
+               ext4_ext_tree_init(handle, inode);
+               if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+                       err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
+                       if (err) goto fail;
+                       EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS);
+                       BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "call ext4_journal_dirty_metadata");
+                       err = ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
+               }
+       }
 
-       ext3_debug("allocating inode %lu\n", inode->i_ino);
+       ext4_debug("allocating inode %lu\n", inode->i_ino);
        goto really_out;
 fail:
-       ext3_std_error(sb, err);
+       ext4_std_error(sb, err);
 out:
        iput(inode);
        ret = ERR_PTR(err);
@@ -640,9 +774,9 @@ fail_drop:
 }
 
 /* Verify that we are loading a valid orphan from disk */
-struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
+struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
 {
-       unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
+       unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count);
        unsigned long block_group;
        int bit;
        struct buffer_head *bitmap_bh = NULL;
@@ -650,16 +784,16 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
 
        /* Error cases - e2fsck has already cleaned up for us */
        if (ino > max_ino) {
-               ext3_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __FUNCTION__,
                             "bad orphan ino %lu!  e2fsck was run?", ino);
                goto out;
        }
 
-       block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb);
-       bit = (ino - 1) % EXT3_INODES_PER_GROUP(sb);
+       block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
+       bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
        bitmap_bh = read_inode_bitmap(sb, block_group);
        if (!bitmap_bh) {
-               ext3_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __FUNCTION__,
                             "inode bitmap error for orphan %lu", ino);
                goto out;
        }
@@ -668,14 +802,14 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
         * is a valid orphan (no e2fsck run on fs).  Orphans also include
         * inodes that were being truncated, so we can't check i_nlink==0.
         */
-       if (!ext3_test_bit(bit, bitmap_bh->b_data) ||
+       if (!ext4_test_bit(bit, bitmap_bh->b_data) ||
                        !(inode = iget(sb, ino)) || is_bad_inode(inode) ||
                        NEXT_ORPHAN(inode) > max_ino) {
-               ext3_warning(sb, __FUNCTION__,
+               ext4_warning(sb, __FUNCTION__,
                             "bad orphan inode %lu!  e2fsck was run?", ino);
-               printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
+               printk(KERN_NOTICE "ext4_test_bit(bit=%d, block=%llu) = %d\n",
                       bit, (unsigned long long)bitmap_bh->b_blocknr,
-                      ext3_test_bit(bit, bitmap_bh->b_data));
+                      ext4_test_bit(bit, bitmap_bh->b_data));
                printk(KERN_NOTICE "inode=%p\n", inode);
                if (inode) {
                        printk(KERN_NOTICE "is_bad_inode(inode)=%d\n",
@@ -695,22 +829,22 @@ out:
        return inode;
 }
 
-unsigned long ext3_count_free_inodes (struct super_block * sb)
+unsigned long ext4_count_free_inodes (struct super_block * sb)
 {
        unsigned long desc_count;
-       struct ext3_group_desc *gdp;
+       struct ext4_group_desc *gdp;
        int i;
-#ifdef EXT3FS_DEBUG
-       struct ext3_super_block *es;
+#ifdef EXT4FS_DEBUG
+       struct ext4_super_block *es;
        unsigned long bitmap_count, x;
        struct buffer_head *bitmap_bh = NULL;
 
-       es = EXT3_SB(sb)->s_es;
+       es = EXT4_SB(sb)->s_es;
        desc_count = 0;
        bitmap_count = 0;
        gdp = NULL;
-       for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
-               gdp = ext3_get_group_desc (sb, i, NULL);
+       for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
+               gdp = ext4_get_group_desc (sb, i, NULL);
                if (!gdp)
                        continue;
                desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
@@ -719,19 +853,19 @@ unsigned long ext3_count_free_inodes (struct super_block * sb)
                if (!bitmap_bh)
                        continue;
 
-               x = ext3_count_free(bitmap_bh, EXT3_INODES_PER_GROUP(sb) / 8);
+               x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8);
                printk("group %d: stored = %d, counted = %lu\n",
                        i, le16_to_cpu(gdp->bg_free_inodes_count), x);
                bitmap_count += x;
        }
        brelse(bitmap_bh);
-       printk("ext3_count_free_inodes: stored = %u, computed = %lu, %lu\n",
+       printk("ext4_count_free_inodes: stored = %u, computed = %lu, %lu\n",
                le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count);
        return desc_count;
 #else
        desc_count = 0;
-       for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
-               gdp = ext3_get_group_desc (sb, i, NULL);
+       for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
+               gdp = ext4_get_group_desc (sb, i, NULL);
                if (!gdp)
                        continue;
                desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
@@ -742,13 +876,13 @@ unsigned long ext3_count_free_inodes (struct super_block * sb)
 }
 
 /* Called at mount-time, super-block is locked */
-unsigned long ext3_count_dirs (struct super_block * sb)
+unsigned long ext4_count_dirs (struct super_block * sb)
 {
        unsigned long count = 0;
        int i;
 
-       for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
-               struct ext3_group_desc *gdp = ext3_get_group_desc (sb, i, NULL);
+       for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
+               struct ext4_group_desc *gdp = ext4_get_group_desc (sb, i, NULL);
                if (!gdp)
                        continue;
                count += le16_to_cpu(gdp->bg_used_dirs_count);