ext4: Fix possible lost inode write in no journal mode
[safe/jmp/linux-2.6] / fs / ext4 / namei.c
index c9690b2..0c070fa 100644 (file)
@@ -383,8 +383,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
        if (root->info.hash_version != DX_HASH_TEA &&
            root->info.hash_version != DX_HASH_HALF_MD4 &&
            root->info.hash_version != DX_HASH_LEGACY) {
-               ext4_warning(dir->i_sb, __func__,
-                            "Unrecognised inode hash code %d",
+               ext4_warning(dir->i_sb, "Unrecognised inode hash code %d",
                             root->info.hash_version);
                brelse(bh);
                *err = ERR_BAD_DX_DIR;
@@ -399,8 +398,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
        hash = hinfo->hash;
 
        if (root->info.unused_flags & 1) {
-               ext4_warning(dir->i_sb, __func__,
-                            "Unimplemented inode hash flags: %#06x",
+               ext4_warning(dir->i_sb, "Unimplemented inode hash flags: %#06x",
                             root->info.unused_flags);
                brelse(bh);
                *err = ERR_BAD_DX_DIR;
@@ -408,8 +406,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
        }
 
        if ((indirect = root->info.indirect_levels) > 1) {
-               ext4_warning(dir->i_sb, __func__,
-                            "Unimplemented inode hash depth: %#06x",
+               ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x",
                             root->info.indirect_levels);
                brelse(bh);
                *err = ERR_BAD_DX_DIR;
@@ -421,8 +418,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
 
        if (dx_get_limit(entries) != dx_root_limit(dir,
                                                   root->info.info_length)) {
-               ext4_warning(dir->i_sb, __func__,
-                            "dx entry: limit != root limit");
+               ext4_warning(dir->i_sb, "dx entry: limit != root limit");
                brelse(bh);
                *err = ERR_BAD_DX_DIR;
                goto fail;
@@ -433,7 +429,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
        {
                count = dx_get_count(entries);
                if (!count || count > dx_get_limit(entries)) {
-                       ext4_warning(dir->i_sb, __func__,
+                       ext4_warning(dir->i_sb,
                                     "dx entry: no count or count > limit");
                        brelse(bh);
                        *err = ERR_BAD_DX_DIR;
@@ -478,7 +474,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
                        goto fail2;
                at = entries = ((struct dx_node *) bh->b_data)->entries;
                if (dx_get_limit(entries) != dx_node_limit (dir)) {
-                       ext4_warning(dir->i_sb, __func__,
+                       ext4_warning(dir->i_sb,
                                     "dx entry: limit != node limit");
                        brelse(bh);
                        *err = ERR_BAD_DX_DIR;
@@ -494,7 +490,7 @@ fail2:
        }
 fail:
        if (*err == ERR_BAD_DX_DIR)
-               ext4_warning(dir->i_sb, __func__,
+               ext4_warning(dir->i_sb,
                             "Corrupt dir inode %ld, running e2fsck is "
                             "recommended.", dir->i_ino);
        return NULL;
@@ -749,7 +745,7 @@ static int dx_make_map(struct ext4_dir_entry_2 *de, unsigned blocksize,
                        ext4fs_dirhash(de->name, de->name_len, &h);
                        map_tail--;
                        map_tail->hash = h.hash;
-                       map_tail->offs = (u16) ((char *) de - base);
+                       map_tail->offs = ((char *) de - base)>>2;
                        map_tail->size = le16_to_cpu(de->rec_len);
                        count++;
                        cond_resched();
@@ -947,9 +943,8 @@ restart:
                wait_on_buffer(bh);
                if (!buffer_uptodate(bh)) {
                        /* read error, skip block & hope for the best */
-                       ext4_error(sb, __func__, "reading directory #%lu "
-                                  "offset %lu", dir->i_ino,
-                                  (unsigned long)block);
+                       ext4_error(sb, "reading directory #%lu offset %lu",
+                                  dir->i_ino, (unsigned long)block);
                        brelse(bh);
                        goto next;
                }
@@ -1041,7 +1036,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
                retval = ext4_htree_next_block(dir, hash, frame,
                                               frames, NULL);
                if (retval < 0) {
-                       ext4_warning(sb, __func__,
+                       ext4_warning(sb,
                             "error reading index page in directory #%lu",
                             dir->i_ino);
                        *err = retval;
@@ -1071,14 +1066,13 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru
                __u32 ino = le32_to_cpu(de->inode);
                brelse(bh);
                if (!ext4_valid_inum(dir->i_sb, ino)) {
-                       ext4_error(dir->i_sb, "ext4_lookup",
-                                  "bad inode number: %u", ino);
+                       ext4_error(dir->i_sb, "bad inode number: %u", ino);
                        return ERR_PTR(-EIO);
                }
                inode = ext4_iget(dir->i_sb, ino);
                if (unlikely(IS_ERR(inode))) {
                        if (PTR_ERR(inode) == -ESTALE) {
-                               ext4_error(dir->i_sb, __func__,
+                               ext4_error(dir->i_sb,
                                                "deleted inode referenced: %u",
                                                ino);
                                return ERR_PTR(-EIO);
@@ -1110,7 +1104,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
        brelse(bh);
 
        if (!ext4_valid_inum(child->d_inode->i_sb, ino)) {
-               ext4_error(child->d_inode->i_sb, "ext4_get_parent",
+               ext4_error(child->d_inode->i_sb,
                           "bad inode number: %u", ino);
                return ERR_PTR(-EIO);
        }
@@ -1147,7 +1141,8 @@ dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count,
        unsigned rec_len = 0;
 
        while (count--) {
-               struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) (from + map->offs);
+               struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) 
+                                               (from + (map->offs<<2));
                rec_len = EXT4_DIR_REC_LEN(de->name_len);
                memcpy (to, de, rec_len);
                ((struct ext4_dir_entry_2 *) to)->rec_len =
@@ -1291,9 +1286,6 @@ errout:
  * add_dirent_to_buf will attempt search the directory block for
  * space.  It will return -ENOSPC if no space is available, and -EIO
  * and -EEXIST if directory entry already exists.
- *
- * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
- * all other cases bh is released.
  */
 static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
                             struct inode *inode, struct ext4_dir_entry_2 *de,
@@ -1314,14 +1306,10 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
                top = bh->b_data + blocksize - reclen;
                while ((char *) de <= top) {
                        if (!ext4_check_dir_entry("ext4_add_entry", dir, de,
-                                                 bh, offset)) {
-                               brelse(bh);
+                                                 bh, offset))
                                return -EIO;
-                       }
-                       if (ext4_match(namelen, name, de)) {
-                               brelse(bh);
+                       if (ext4_match(namelen, name, de))
                                return -EEXIST;
-                       }
                        nlen = EXT4_DIR_REC_LEN(de->name_len);
                        rlen = ext4_rec_len_from_disk(de->rec_len, blocksize);
                        if ((de->inode? rlen - nlen: rlen) >= reclen)
@@ -1336,7 +1324,6 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
        err = ext4_journal_get_write_access(handle, bh);
        if (err) {
                ext4_std_error(dir->i_sb, err);
-               brelse(bh);
                return err;
        }
 
@@ -1376,7 +1363,6 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
        err = ext4_handle_dirty_metadata(handle, dir, bh);
        if (err)
                ext4_std_error(dir->i_sb, err);
-       brelse(bh);
        return 0;
 }
 
@@ -1418,7 +1404,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
        de = (struct ext4_dir_entry_2 *)((char *)fde +
                ext4_rec_len_from_disk(fde->rec_len, blocksize));
        if ((char *) de >= (((char *) root) + blocksize)) {
-               ext4_error(dir->i_sb, __func__,
+               ext4_error(dir->i_sb,
                           "invalid rec_len for '..' in inode %lu",
                           dir->i_ino);
                brelse(bh);
@@ -1470,7 +1456,9 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
        if (!(de))
                return retval;
 
-       return add_dirent_to_buf(handle, dentry, inode, de, bh);
+       retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
+       brelse(bh);
+       return retval;
 }
 
 /*
@@ -1513,8 +1501,10 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
                if(!bh)
                        return retval;
                retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
-               if (retval != -ENOSPC)
+               if (retval != -ENOSPC) {
+                       brelse(bh);
                        return retval;
+               }
 
                if (blocks == 1 && !dx_fallback &&
                    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
@@ -1527,7 +1517,9 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
        de = (struct ext4_dir_entry_2 *) bh->b_data;
        de->inode = 0;
        de->rec_len = ext4_rec_len_to_disk(blocksize, blocksize);
-       return add_dirent_to_buf(handle, dentry, inode, de, bh);
+       retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
+       brelse(bh);
+       return retval;
 }
 
 /*
@@ -1560,10 +1552,8 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
                goto journal_error;
 
        err = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
-       if (err != -ENOSPC) {
-               bh = NULL;
+       if (err != -ENOSPC)
                goto cleanup;
-       }
 
        /* Block full, should compress but for now just split */
        dxtrace(printk(KERN_DEBUG "using %u of %u node entries\n",
@@ -1579,8 +1569,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
 
                if (levels && (dx_get_count(frames->entries) ==
                               dx_get_limit(frames->entries))) {
-                       ext4_warning(sb, __func__,
-                                    "Directory index full!");
+                       ext4_warning(sb, "Directory index full!");
                        err = -ENOSPC;
                        goto cleanup;
                }
@@ -1589,9 +1578,9 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
                        goto cleanup;
                node2 = (struct dx_node *)(bh2->b_data);
                entries2 = node2->entries;
+               memset(&node2->fake, 0, sizeof(struct fake_dirent));
                node2->fake.rec_len = ext4_rec_len_to_disk(sb->s_blocksize,
                                                           sb->s_blocksize);
-               node2->fake.inode = 0;
                BUFFER_TRACE(frame->bh, "get_write_access");
                err = ext4_journal_get_write_access(handle, frame->bh);
                if (err)
@@ -1656,7 +1645,6 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
        if (!de)
                goto cleanup;
        err = add_dirent_to_buf(handle, dentry, inode, de, bh);
-       bh = NULL;
        goto cleanup;
 
 journal_error:
@@ -1771,17 +1759,19 @@ static int ext4_create(struct inode *dir, struct dentry *dentry, int mode,
        struct inode *inode;
        int err, retries = 0;
 
+       dquot_initialize(dir);
+
 retry:
        handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
                                        EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-                                       2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+                                       EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
        if (IS_DIRSYNC(dir))
                ext4_handle_sync(handle);
 
-       inode = ext4_new_inode (handle, dir, mode);
+       inode = ext4_new_inode(handle, dir, mode, &dentry->d_name, 0);
        err = PTR_ERR(inode);
        if (!IS_ERR(inode)) {
                inode->i_op = &ext4_file_inode_operations;
@@ -1805,17 +1795,19 @@ static int ext4_mknod(struct inode *dir, struct dentry *dentry,
        if (!new_valid_dev(rdev))
                return -EINVAL;
 
+       dquot_initialize(dir);
+
 retry:
        handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
                                        EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-                                       2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+                                       EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
        if (IS_DIRSYNC(dir))
                ext4_handle_sync(handle);
 
-       inode = ext4_new_inode(handle, dir, mode);
+       inode = ext4_new_inode(handle, dir, mode, &dentry->d_name, 0);
        err = PTR_ERR(inode);
        if (!IS_ERR(inode)) {
                init_special_inode(inode, inode->i_mode, rdev);
@@ -1842,17 +1834,20 @@ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        if (EXT4_DIR_LINK_MAX(dir))
                return -EMLINK;
 
+       dquot_initialize(dir);
+
 retry:
        handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
                                        EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-                                       2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+                                       EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
        if (IS_DIRSYNC(dir))
                ext4_handle_sync(handle);
 
-       inode = ext4_new_inode(handle, dir, S_IFDIR | mode);
+       inode = ext4_new_inode(handle, dir, S_IFDIR | mode,
+                              &dentry->d_name, 0);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_stop;
@@ -1920,11 +1915,11 @@ static int empty_dir(struct inode *inode)
        if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
            !(bh = ext4_bread(NULL, inode, 0, 0, &err))) {
                if (err)
-                       ext4_error(inode->i_sb, __func__,
+                       ext4_error(inode->i_sb,
                                   "error %d reading directory #%lu offset 0",
                                   err, inode->i_ino);
                else
-                       ext4_warning(inode->i_sb, __func__,
+                       ext4_warning(inode->i_sb,
                                     "bad directory (dir #%lu) - no data block",
                                     inode->i_ino);
                return 1;
@@ -1935,7 +1930,7 @@ static int empty_dir(struct inode *inode)
                        !le32_to_cpu(de1->inode) ||
                        strcmp(".", de->name) ||
                        strcmp("..", de1->name)) {
-               ext4_warning(inode->i_sb, "empty_dir",
+               ext4_warning(inode->i_sb,
                             "bad directory (dir #%lu) - no `.' or `..'",
                             inode->i_ino);
                brelse(bh);
@@ -1953,7 +1948,7 @@ static int empty_dir(struct inode *inode)
                                offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err);
                        if (!bh) {
                                if (err)
-                                       ext4_error(sb, __func__,
+                                       ext4_error(sb,
                                                   "error %d reading directory"
                                                   " #%lu offset %u",
                                                   err, inode->i_ino, offset);
@@ -2024,11 +2019,18 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
        err = ext4_reserve_inode_write(handle, inode, &iloc);
        if (err)
                goto out_unlock;
+       /*
+        * Due to previous errors inode may be already a part of on-disk
+        * orphan list. If so skip on-disk list modification.
+        */
+       if (NEXT_ORPHAN(inode) && NEXT_ORPHAN(inode) <=
+               (le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)))
+                       goto mem_insert;
 
        /* Insert this inode at the head of the on-disk orphan list... */
        NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan);
        EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
-       err = ext4_handle_dirty_metadata(handle, inode, EXT4_SB(sb)->s_sbh);
+       err = ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
        rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
        if (!err)
                err = rc;
@@ -2041,6 +2043,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
         *
         * This is safe: on error we're going to ignore the orphan list
         * anyway on the next recovery. */
+mem_insert:
        if (!err)
                list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan);
 
@@ -2066,7 +2069,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
        struct ext4_iloc iloc;
        int err = 0;
 
-       if (!ext4_handle_valid(handle))
+       /* ext4_handle_valid() assumes a valid handle_t pointer */
+       if (handle && !ext4_handle_valid(handle))
                return 0;
 
        mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock);
@@ -2099,7 +2103,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
                if (err)
                        goto out_brelse;
                sbi->s_es->s_last_orphan = cpu_to_le32(ino_next);
-               err = ext4_handle_dirty_metadata(handle, inode, sbi->s_sbh);
+               err = ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh);
        } else {
                struct ext4_iloc iloc2;
                struct inode *i_prev =
@@ -2139,7 +2143,9 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
 
        /* Initialize quotas before so that eventual writes go in
         * separate transaction */
-       vfs_dq_init(dentry->d_inode);
+       dquot_initialize(dir);
+       dquot_initialize(dentry->d_inode);
+
        handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
@@ -2166,7 +2172,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
        if (retval)
                goto end_rmdir;
        if (!EXT4_DIR_LINK_EMPTY(inode))
-               ext4_warning(inode->i_sb, "ext4_rmdir",
+               ext4_warning(inode->i_sb,
                             "empty directory has too many links (%d)",
                             inode->i_nlink);
        inode->i_version++;
@@ -2198,7 +2204,9 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
 
        /* Initialize quotas before so that eventual writes go
         * in separate transaction */
-       vfs_dq_init(dentry->d_inode);
+       dquot_initialize(dir);
+       dquot_initialize(dentry->d_inode);
+
        handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
@@ -2218,7 +2226,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
                goto end_unlink;
 
        if (!inode->i_nlink) {
-               ext4_warning(inode->i_sb, "ext4_unlink",
+               ext4_warning(inode->i_sb,
                             "Deleting nonexistent file (%lu), %d",
                             inode->i_ino, inode->i_nlink);
                inode->i_nlink = 1;
@@ -2253,17 +2261,20 @@ static int ext4_symlink(struct inode *dir,
        if (l > dir->i_sb->s_blocksize)
                return -ENAMETOOLONG;
 
+       dquot_initialize(dir);
+
 retry:
        handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
                                        EXT4_INDEX_EXTRA_TRANS_BLOCKS + 5 +
-                                       2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+                                       EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
        if (IS_DIRSYNC(dir))
                ext4_handle_sync(handle);
 
-       inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO);
+       inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO,
+                              &dentry->d_name, 0);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_stop;
@@ -2307,9 +2318,11 @@ static int ext4_link(struct dentry *old_dentry,
        struct inode *inode = old_dentry->d_inode;
        int err, retries = 0;
 
-       if (EXT4_DIR_LINK_MAX(inode))
+       if (inode->i_nlink >= EXT4_LINK_MAX)
                return -EMLINK;
 
+       dquot_initialize(dir);
+
        /*
         * Return -ENOENT if we've raced with unlink and i_nlink is 0.  Doing
         * otherwise has the potential to corrupt the orphan inode list.
@@ -2360,12 +2373,15 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
        struct ext4_dir_entry_2 *old_de, *new_de;
        int retval, force_da_alloc = 0;
 
+       dquot_initialize(old_dir);
+       dquot_initialize(new_dir);
+
        old_bh = new_bh = dir_bh = NULL;
 
        /* Initialize quotas before so that eventual writes go
         * in separate transaction */
        if (new_dentry->d_inode)
-               vfs_dq_init(new_dentry->d_inode);
+               dquot_initialize(new_dentry->d_inode);
        handle = ext4_journal_start(old_dir, 2 *
                                        EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) +
                                        EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2);
@@ -2410,7 +2426,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
                        goto end_rename;
                retval = -EMLINK;
                if (!new_inode && new_dir != old_dir &&
-                               new_dir->i_nlink >= EXT4_LINK_MAX)
+                   EXT4_DIR_LINK_MAX(new_dir))
                        goto end_rename;
        }
        if (!new_bh) {
@@ -2464,7 +2480,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
                }
        }
        if (retval) {
-               ext4_warning(old_dir->i_sb, "ext4_rename",
+               ext4_warning(old_dir->i_sb,
                                "Deleting old file (%lu), %d, error=%d",
                                old_dir->i_ino, old_dir->i_nlink, retval);
        }
@@ -2533,7 +2549,8 @@ const struct inode_operations ext4_dir_inode_operations = {
        .listxattr      = ext4_listxattr,
        .removexattr    = generic_removexattr,
 #endif
-       .permission     = ext4_permission,
+       .check_acl      = ext4_check_acl,
+       .fiemap         = ext4_fiemap,
 };
 
 const struct inode_operations ext4_special_inode_operations = {
@@ -2544,5 +2561,5 @@ const struct inode_operations ext4_special_inode_operations = {
        .listxattr      = ext4_listxattr,
        .removexattr    = generic_removexattr,
 #endif
-       .permission     = ext4_permission,
+       .check_acl      = ext4_check_acl,
 };