xfs: decouple log and transaction headers
[deliverable/linux.git] / fs / xfs / xfs_btree.c
index 047573f02702c49115eb2567eda48131172197c4..08365117a933aa22cf457b663dc537d554a2c82b 100644 (file)
  */
 #include "xfs.h"
 #include "xfs_fs.h"
-#include "xfs_types.h"
+#include "xfs_shared.h"
+#include "xfs_log_format.h"
+#include "xfs_trans_resv.h"
 #include "xfs_bit.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
 #include "xfs_mount.h"
@@ -29,6 +29,7 @@
 #include "xfs_ialloc_btree.h"
 #include "xfs_dinode.h"
 #include "xfs_inode.h"
+#include "xfs_trans.h"
 #include "xfs_inode_item.h"
 #include "xfs_buf_item.h"
 #include "xfs_btree.h"
@@ -3907,13 +3908,16 @@ xfs_btree_get_rec(
  * buffer as an ordered buffer and log it appropriately. We need to ensure that
  * we mark the region we change dirty so that if the buffer is relogged in
  * a subsequent transaction the changes we make here as an ordered buffer are
- * correctly relogged in that transaction.
+ * correctly relogged in that transaction.  If we are in recovery context, then
+ * just queue the modified buffer as delayed write buffer so the transaction
+ * recovery completion writes the changes to disk.
  */
 static int
 xfs_btree_block_change_owner(
        struct xfs_btree_cur    *cur,
        int                     level,
-       __uint64_t              new_owner)
+       __uint64_t              new_owner,
+       struct list_head        *buffer_list)
 {
        struct xfs_btree_block  *block;
        struct xfs_buf          *bp;
@@ -3930,16 +3934,19 @@ xfs_btree_block_change_owner(
                block->bb_u.s.bb_owner = cpu_to_be32(new_owner);
 
        /*
-        * Log owner change as an ordered buffer. If the block is a root block
-        * hosted in an inode, we might not have a buffer pointer here and we
-        * shouldn't attempt to log the change as the information is already
-        * held in the inode and discarded when the root block is formatted into
-        * the on-disk inode fork. We still change it, though, so everything is
-        * consistent in memory.
+        * If the block is a root block hosted in an inode, we might not have a
+        * buffer pointer here and we shouldn't attempt to log the change as the
+        * information is already held in the inode and discarded when the root
+        * block is formatted into the on-disk inode fork. We still change it,
+        * though, so everything is consistent in memory.
         */
        if (bp) {
-               xfs_trans_ordered_buf(cur->bc_tp, bp);
-               xfs_btree_log_block(cur, bp, XFS_BB_OWNER);
+               if (cur->bc_tp) {
+                       xfs_trans_ordered_buf(cur->bc_tp, bp);
+                       xfs_btree_log_block(cur, bp, XFS_BB_OWNER);
+               } else {
+                       xfs_buf_delwri_queue(bp, buffer_list);
+               }
        } else {
                ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
                ASSERT(level == cur->bc_nlevels - 1);
@@ -3956,7 +3963,8 @@ xfs_btree_block_change_owner(
 int
 xfs_btree_change_owner(
        struct xfs_btree_cur    *cur,
-       __uint64_t              new_owner)
+       __uint64_t              new_owner,
+       struct list_head        *buffer_list)
 {
        union xfs_btree_ptr     lptr;
        int                     level;
@@ -3986,7 +3994,8 @@ xfs_btree_change_owner(
                /* for each buffer in the level */
                do {
                        error = xfs_btree_block_change_owner(cur, level,
-                                                            new_owner);
+                                                            new_owner,
+                                                            buffer_list);
                } while (!error);
 
                if (error != ENOENT)
This page took 0.119408 seconds and 5 git commands to generate.