]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/ext4/migrate.c
Merge branch 'ras-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / fs / ext4 / migrate.c
index b1e4d359f73b5490be121a8bf637c0ad1e958c13..89725fa425732e4933a95b60200b33f40158537d 100644 (file)
@@ -50,29 +50,9 @@ static int finish_range(handle_t *handle, struct inode *inode,
        needed = ext4_ext_calc_credits_for_single_extent(inode,
                    lb->last_block - lb->first_block + 1, path);
 
-       /*
-        * Make sure the credit we accumalated is not really high
-        */
-       if (needed && ext4_handle_has_enough_credits(handle,
-                                               EXT4_RESERVE_TRANS_BLOCKS)) {
-               up_write((&EXT4_I(inode)->i_data_sem));
-               retval = ext4_journal_restart(handle, needed);
-               down_write((&EXT4_I(inode)->i_data_sem));
-               if (retval)
-                       goto err_out;
-       } else if (needed) {
-               retval = ext4_journal_extend(handle, needed);
-               if (retval) {
-                       /*
-                        * IF not able to extend the journal restart the journal
-                        */
-                       up_write((&EXT4_I(inode)->i_data_sem));
-                       retval = ext4_journal_restart(handle, needed);
-                       down_write((&EXT4_I(inode)->i_data_sem));
-                       if (retval)
-                               goto err_out;
-               }
-       }
+       retval = ext4_datasem_ensure_credits(handle, inode, needed, needed, 0);
+       if (retval < 0)
+               goto err_out;
        retval = ext4_ext_insert_extent(handle, inode, &path, &newext, 0);
 err_out:
        up_write((&EXT4_I(inode)->i_data_sem));
@@ -196,42 +176,30 @@ static int update_tind_extent_range(handle_t *handle, struct inode *inode,
 
 }
 
-static int extend_credit_for_blkdel(handle_t *handle, struct inode *inode)
-{
-       int retval = 0, needed;
-
-       if (ext4_handle_has_enough_credits(handle, EXT4_RESERVE_TRANS_BLOCKS+1))
-               return 0;
-       /*
-        * We are freeing a blocks. During this we touch
-        * superblock, group descriptor and block bitmap.
-        * So allocate a credit of 3. We may update
-        * quota (user and group).
-        */
-       needed = 3 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb);
-
-       if (ext4_journal_extend(handle, needed) != 0)
-               retval = ext4_journal_restart(handle, needed);
-
-       return retval;
-}
-
 static int free_dind_blocks(handle_t *handle,
                                struct inode *inode, __le32 i_data)
 {
        int i;
        __le32 *tmp_idata;
        struct buffer_head *bh;
+       struct super_block *sb = inode->i_sb;
        unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
+       int err;
 
-       bh = ext4_sb_bread(inode->i_sb, le32_to_cpu(i_data), 0);
+       bh = ext4_sb_bread(sb, le32_to_cpu(i_data), 0);
        if (IS_ERR(bh))
                return PTR_ERR(bh);
 
        tmp_idata = (__le32 *)bh->b_data;
        for (i = 0; i < max_entries; i++) {
                if (tmp_idata[i]) {
-                       extend_credit_for_blkdel(handle, inode);
+                       err = ext4_journal_ensure_credits(handle,
+                               EXT4_RESERVE_TRANS_BLOCKS,
+                               ext4_free_metadata_revoke_credits(sb, 1));
+                       if (err < 0) {
+                               put_bh(bh);
+                               return err;
+                       }
                        ext4_free_blocks(handle, inode, NULL,
                                         le32_to_cpu(tmp_idata[i]), 1,
                                         EXT4_FREE_BLOCKS_METADATA |
@@ -239,7 +207,10 @@ static int free_dind_blocks(handle_t *handle,
                }
        }
        put_bh(bh);
-       extend_credit_for_blkdel(handle, inode);
+       err = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS,
+                               ext4_free_metadata_revoke_credits(sb, 1));
+       if (err < 0)
+               return err;
        ext4_free_blocks(handle, inode, NULL, le32_to_cpu(i_data), 1,
                         EXT4_FREE_BLOCKS_METADATA |
                         EXT4_FREE_BLOCKS_FORGET);
@@ -270,7 +241,10 @@ static int free_tind_blocks(handle_t *handle,
                }
        }
        put_bh(bh);
-       extend_credit_for_blkdel(handle, inode);
+       retval = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS,
+                       ext4_free_metadata_revoke_credits(inode->i_sb, 1));
+       if (retval < 0)
+               return retval;
        ext4_free_blocks(handle, inode, NULL, le32_to_cpu(i_data), 1,
                         EXT4_FREE_BLOCKS_METADATA |
                         EXT4_FREE_BLOCKS_FORGET);
@@ -283,7 +257,11 @@ static int free_ind_block(handle_t *handle, struct inode *inode, __le32 *i_data)
 
        /* ei->i_data[EXT4_IND_BLOCK] */
        if (i_data[0]) {
-               extend_credit_for_blkdel(handle, inode);
+               retval = ext4_journal_ensure_credits(handle,
+                       EXT4_RESERVE_TRANS_BLOCKS,
+                       ext4_free_metadata_revoke_credits(inode->i_sb, 1));
+               if (retval < 0)
+                       return retval;
                ext4_free_blocks(handle, inode, NULL,
                                le32_to_cpu(i_data[0]), 1,
                                 EXT4_FREE_BLOCKS_METADATA |
@@ -318,12 +296,9 @@ static int ext4_ext_swap_inode_data(handle_t *handle, struct inode *inode,
         * One credit accounted for writing the
         * i_data field of the original inode
         */
-       retval = ext4_journal_extend(handle, 1);
-       if (retval) {
-               retval = ext4_journal_restart(handle, 1);
-               if (retval)
-                       goto err_out;
-       }
+       retval = ext4_journal_ensure_credits(handle, 1, 0);
+       if (retval < 0)
+               goto err_out;
 
        i_data[0] = ei->i_data[EXT4_IND_BLOCK];
        i_data[1] = ei->i_data[EXT4_DIND_BLOCK];
@@ -391,15 +366,20 @@ static int free_ext_idx(handle_t *handle, struct inode *inode,
                ix = EXT_FIRST_INDEX(eh);
                for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ix++) {
                        retval = free_ext_idx(handle, inode, ix);
-                       if (retval)
-                               break;
+                       if (retval) {
+                               put_bh(bh);
+                               return retval;
+                       }
                }
        }
        put_bh(bh);
-       extend_credit_for_blkdel(handle, inode);
+       retval = ext4_journal_ensure_credits(handle, EXT4_RESERVE_TRANS_BLOCKS,
+                       ext4_free_metadata_revoke_credits(inode->i_sb, 1));
+       if (retval < 0)
+               return retval;
        ext4_free_blocks(handle, inode, NULL, block, 1,
                         EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET);
-       return retval;
+       return 0;
 }
 
 /*
@@ -574,9 +554,9 @@ int ext4_ext_migrate(struct inode *inode)
        }
 
        /* We mark the tmp_inode dirty via ext4_ext_tree_init. */
-       if (ext4_journal_extend(handle, 1) != 0)
-               ext4_journal_restart(handle, 1);
-
+       retval = ext4_journal_ensure_credits(handle, 1, 0);
+       if (retval < 0)
+               goto out_stop;
        /*
         * Mark the tmp_inode as of size zero
         */
@@ -594,6 +574,7 @@ int ext4_ext_migrate(struct inode *inode)
 
        /* Reset the extent details */
        ext4_ext_tree_init(handle, tmp_inode);
+out_stop:
        ext4_journal_stop(handle);
 out:
        unlock_new_inode(tmp_inode);