xfs: use current->journal_info for detecting transaction recursion
[linux-2.6-microblaze.git] / fs / xfs / libxfs / xfs_btree.c
index c4d7a92..5b6fcb9 100644 (file)
@@ -353,20 +353,17 @@ xfs_btree_free_block(
  */
 void
 xfs_btree_del_cursor(
-       xfs_btree_cur_t *cur,           /* btree cursor */
-       int             error)          /* del because of error */
+       struct xfs_btree_cur    *cur,           /* btree cursor */
+       int                     error)          /* del because of error */
 {
-       int             i;              /* btree level */
+       int                     i;              /* btree level */
 
        /*
-        * Clear the buffer pointers, and release the buffers.
-        * If we're doing this in the face of an error, we
-        * need to make sure to inspect all of the entries
-        * in the bc_bufs array for buffers to be unlocked.
-        * This is because some of the btree code works from
-        * level n down to 0, and if we get an error along
-        * the way we won't have initialized all the entries
-        * down to 0.
+        * Clear the buffer pointers and release the buffers. If we're doing
+        * this because of an error, inspect all of the entries in the bc_bufs
+        * array for buffers to be unlocked. This is because some of the btree
+        * code works from level n down to 0, and if we get an error along the
+        * way we won't have initialized all the entries down to 0.
         */
        for (i = 0; i < cur->bc_nlevels; i++) {
                if (cur->bc_bufs[i])
@@ -374,17 +371,11 @@ xfs_btree_del_cursor(
                else if (!error)
                        break;
        }
-       /*
-        * Can't free a bmap cursor without having dealt with the
-        * allocated indirect blocks' accounting.
-        */
-       ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP ||
-              cur->bc_ino.allocated == 0);
-       /*
-        * Free the cursor.
-        */
+
+       ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || cur->bc_ino.allocated == 0 ||
+              XFS_FORCED_SHUTDOWN(cur->bc_mp));
        if (unlikely(cur->bc_flags & XFS_BTREE_STAGING))
-               kmem_free((void *)cur->bc_ops);
+               kmem_free(cur->bc_ops);
        kmem_cache_free(xfs_btree_cur_zone, cur);
 }
 
@@ -2814,7 +2805,7 @@ xfs_btree_split_worker(
        struct xfs_btree_split_args     *args = container_of(work,
                                                struct xfs_btree_split_args, work);
        unsigned long           pflags;
-       unsigned long           new_pflags = PF_MEMALLOC_NOFS;
+       unsigned long           new_pflags = 0;
 
        /*
         * we are in a transaction context here, but may also be doing work
@@ -2826,12 +2817,20 @@ xfs_btree_split_worker(
                new_pflags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD;
 
        current_set_flags_nested(&pflags, new_pflags);
+       xfs_trans_set_context(args->cur->bc_tp);
 
        args->result = __xfs_btree_split(args->cur, args->level, args->ptrp,
                                         args->key, args->curp, args->stat);
-       complete(args->done);
 
+       xfs_trans_clear_context(args->cur->bc_tp);
        current_restore_flags_nested(&pflags, new_pflags);
+
+       /*
+        * Do not access args after complete() has run here. We don't own args
+        * and the owner may run and free args before we return here.
+        */
+       complete(args->done);
+
 }
 
 /*