ext4: prepare to drop EXT4_STATE_DELALLOC_RESERVED
authorTheodore Ts'o <tytso@mit.edu>
Thu, 4 Sep 2014 22:07:25 +0000 (18:07 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 4 Sep 2014 22:07:25 +0000 (18:07 -0400)
The EXT4_STATE_DELALLOC_RESERVED flag was originally implemented
because it was too hard to make sure the mballoc and get_block flags
could be reliably passed down through all of the codepaths that end up
calling ext4_mb_new_blocks().

Since then, we have mb_flags passed down through most of the code
paths, so getting rid of EXT4_STATE_DELALLOC_RESERVED isn't as tricky
as it used to.

This commit plumbs in the last of what is required, and then adds a
WARN_ON check to make sure we haven't missed anything.  If this passes
a full regression test run, we can then drop
EXT4_STATE_DELALLOC_RESERVED.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
fs/ext4/balloc.c
fs/ext4/extents.c
fs/ext4/indirect.c
fs/ext4/mballoc.c
fs/ext4/xattr.c

index 581ef40fbe90b8b45f3d3474d48b8c80f6639ba8..d70f154f6da354f718e8f0f2e9b300947fe05773 100644 (file)
@@ -636,8 +636,7 @@ ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
         * Account for the allocated meta blocks.  We will never
         * fail EDQUOT for metdata, but we do account for it.
         */
-       if (!(*errp) &&
-           ext4_test_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED)) {
+       if (!(*errp) && (flags & EXT4_MB_DELALLOC_RESERVED)) {
                spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
                spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
                dquot_alloc_block_nofail(inode,
index 3ac1686efff81a84ad2807c389f0f5b713eef3fd..8170b3254767e3b0f570bd076f4a79676a142347 100644 (file)
@@ -1933,6 +1933,8 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
        ext4_lblk_t next;
        int mb_flags = 0, unwritten;
 
+       if (gb_flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
+               mb_flags |= EXT4_MB_DELALLOC_RESERVED;
        if (unlikely(ext4_ext_get_actual_len(newext) == 0)) {
                EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0");
                return -EIO;
@@ -2054,7 +2056,7 @@ prepend:
         * We're gonna add a new leaf in the tree.
         */
        if (gb_flags & EXT4_GET_BLOCKS_METADATA_NOFAIL)
-               mb_flags = EXT4_MB_USE_RESERVED;
+               mb_flags |= EXT4_MB_USE_RESERVED;
        err = ext4_ext_create_new_leaf(handle, inode, mb_flags, gb_flags,
                                       ppath, newext);
        if (err)
@@ -4438,6 +4440,8 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
                ar.flags = 0;
        if (flags & EXT4_GET_BLOCKS_NO_NORMALIZE)
                ar.flags |= EXT4_MB_HINT_NOPREALLOC;
+       if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
+               ar.flags |= EXT4_MB_DELALLOC_RESERVED;
        newblock = ext4_mb_new_blocks(handle, &ar, &err);
        if (!newblock)
                goto out2;
index 69af0cd6472402d304f123e629f37af3aeec7bc6..36b369697a131523f26f6a6336eec17b4da3ae4f 100644 (file)
@@ -333,7 +333,9 @@ static int ext4_alloc_branch(handle_t *handle,
                        new_blocks[i] = ext4_mb_new_blocks(handle, ar, &err);
                } else
                        ar->goal = new_blocks[i] = ext4_new_meta_blocks(handle,
-                                   ar->inode, ar->goal, 0, NULL, &err);
+                                       ar->inode, ar->goal,
+                                       ar->flags & EXT4_MB_DELALLOC_RESERVED,
+                                       NULL, &err);
                if (err) {
                        i--;
                        goto failed;
@@ -572,6 +574,8 @@ int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
        ar.logical = map->m_lblk;
        if (S_ISREG(inode->i_mode))
                ar.flags = EXT4_MB_HINT_DATA;
+       if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
+               ar.flags |= EXT4_MB_DELALLOC_RESERVED;
 
        ar.goal = ext4_find_goal(inode, map->m_lblk, partial);
 
index 8b0f9ef517d690ea0ede0958c8aa726aebb86b35..15dffdac59072c3981d0bfa97b8916de748fcb71 100644 (file)
@@ -4415,9 +4415,12 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
         * EDQUOT check, as blocks and quotas have been already
         * reserved when data being copied into pagecache.
         */
-       if (ext4_test_inode_state(ar->inode, EXT4_STATE_DELALLOC_RESERVED))
+       if (ext4_test_inode_state(ar->inode, EXT4_STATE_DELALLOC_RESERVED)) {
+               WARN_ON((ar->flags & EXT4_MB_DELALLOC_RESERVED) == 0);
                ar->flags |= EXT4_MB_DELALLOC_RESERVED;
-       else {
+       }
+
+       if ((ar->flags & EXT4_MB_DELALLOC_RESERVED) == 0) {
                /* Without delayed allocation we need to verify
                 * there is enough free blocks to do block allocation
                 * and verify allocation doesn't exceed the quota limits.
@@ -4528,8 +4531,7 @@ out:
        if (inquota && ar->len < inquota)
                dquot_free_block(ar->inode, EXT4_C2B(sbi, inquota - ar->len));
        if (!ar->len) {
-               if (!ext4_test_inode_state(ar->inode,
-                                          EXT4_STATE_DELALLOC_RESERVED))
+               if ((ar->flags & EXT4_MB_DELALLOC_RESERVED) == 0)
                        /* release all the reserved blocks if non delalloc */
                        percpu_counter_sub(&sbi->s_dirtyclusters_counter,
                                                reserv_clstrs);
index e7387337060c96f06fe9360966992bb286c20496..da4df703c211bd95bfb677ba005c3801e408b645 100644 (file)
@@ -899,14 +899,8 @@ inserted:
                        if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
                                goal = goal & EXT4_MAX_BLOCK_FILE_PHYS;
 
-                       /*
-                        * take i_data_sem because we will test
-                        * i_delalloc_reserved_flag in ext4_mb_new_blocks
-                        */
-                       down_read(&EXT4_I(inode)->i_data_sem);
                        block = ext4_new_meta_blocks(handle, inode, goal, 0,
                                                     NULL, &error);
-                       up_read((&EXT4_I(inode)->i_data_sem));
                        if (error)
                                goto cleanup;