ext4: Provide function to handle transaction restarts
[linux-2.6-microblaze.git] / fs / ext4 / xattr.c
index 491f9ee..b79d8ff 100644 (file)
@@ -967,55 +967,6 @@ int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,
        return credits;
 }
 
-static int ext4_xattr_ensure_credits(handle_t *handle, struct inode *inode,
-                                    int credits, struct buffer_head *bh,
-                                    bool dirty, bool block_csum)
-{
-       int error;
-
-       if (!ext4_handle_valid(handle))
-               return 0;
-
-       if (handle->h_buffer_credits >= credits)
-               return 0;
-
-       error = ext4_journal_extend(handle, credits - handle->h_buffer_credits);
-       if (!error)
-               return 0;
-       if (error < 0) {
-               ext4_warning(inode->i_sb, "Extend journal (error %d)", error);
-               return error;
-       }
-
-       if (bh && dirty) {
-               if (block_csum)
-                       ext4_xattr_block_csum_set(inode, bh);
-               error = ext4_handle_dirty_metadata(handle, NULL, bh);
-               if (error) {
-                       ext4_warning(inode->i_sb, "Handle metadata (error %d)",
-                                    error);
-                       return error;
-               }
-       }
-
-       error = ext4_journal_restart(handle, credits);
-       if (error) {
-               ext4_warning(inode->i_sb, "Restart journal (error %d)", error);
-               return error;
-       }
-
-       if (bh) {
-               error = ext4_journal_get_write_access(handle, bh);
-               if (error) {
-                       ext4_warning(inode->i_sb,
-                                    "Get write access failed (error %d)",
-                                    error);
-                       return error;
-               }
-       }
-       return 0;
-}
-
 static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
                                       int ref_change)
 {
@@ -1149,6 +1100,24 @@ cleanup:
        return saved_err;
 }
 
+static int ext4_xattr_restart_fn(handle_t *handle, struct inode *inode,
+                       struct buffer_head *bh, bool block_csum, bool dirty)
+{
+       int error;
+
+       if (bh && dirty) {
+               if (block_csum)
+                       ext4_xattr_block_csum_set(inode, bh);
+               error = ext4_handle_dirty_metadata(handle, NULL, bh);
+               if (error) {
+                       ext4_warning(inode->i_sb, "Handle metadata (error %d)",
+                                    error);
+                       return error;
+               }
+       }
+       return 0;
+}
+
 static void
 ext4_xattr_inode_dec_ref_all(handle_t *handle, struct inode *parent,
                             struct buffer_head *bh,
@@ -1185,13 +1154,23 @@ ext4_xattr_inode_dec_ref_all(handle_t *handle, struct inode *parent,
                        continue;
                }
 
-               err = ext4_xattr_ensure_credits(handle, parent, credits, bh,
-                                               dirty, block_csum);
-               if (err) {
+               err = ext4_journal_ensure_credits_fn(handle, credits, credits,
+                       ext4_xattr_restart_fn(handle, parent, bh, block_csum,
+                                             dirty));
+               if (err < 0) {
                        ext4_warning_inode(ea_inode, "Ensure credits err=%d",
                                           err);
                        continue;
                }
+               if (err > 0) {
+                       err = ext4_journal_get_write_access(handle, bh);
+                       if (err) {
+                               ext4_warning_inode(ea_inode,
+                                               "Re-get write access err=%d",
+                                               err);
+                               continue;
+                       }
+               }
 
                err = ext4_xattr_inode_dec_ref(handle, ea_inode);
                if (err) {
@@ -2862,11 +2841,8 @@ int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
        struct inode *ea_inode;
        int error;
 
-       error = ext4_xattr_ensure_credits(handle, inode, extra_credits,
-                                         NULL /* bh */,
-                                         false /* dirty */,
-                                         false /* block_csum */);
-       if (error) {
+       error = ext4_journal_ensure_credits(handle, extra_credits);
+       if (error < 0) {
                EXT4_ERROR_INODE(inode, "ensure credits (error %d)", error);
                goto cleanup;
        }