Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
[linux-2.6-microblaze.git] / fs / xfs / xfs_itable.c
index f331975..c08c79d 100644 (file)
@@ -19,6 +19,7 @@
 #include "xfs_error.h"
 #include "xfs_icache.h"
 #include "xfs_health.h"
+#include "xfs_trans.h"
 
 /*
  * Bulk Stat
@@ -107,7 +108,7 @@ xfs_bulkstat_one_int(
        buf->bs_forkoff = XFS_IFORK_BOFF(ip);
        buf->bs_version = XFS_BULKSTAT_VERSION_V5;
 
-       if (xfs_sb_version_has_v3inode(&mp->m_sb)) {
+       if (xfs_has_v3inodes(mp)) {
                buf->bs_btime = ip->i_crtime.tv_sec;
                buf->bs_btime_nsec = ip->i_crtime.tv_nsec;
                if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
@@ -163,6 +164,7 @@ xfs_bulkstat_one(
                .formatter      = formatter,
                .breq           = breq,
        };
+       struct xfs_trans        *tp;
        int                     error;
 
        if (breq->mnt_userns != &init_user_ns) {
@@ -178,9 +180,18 @@ xfs_bulkstat_one(
        if (!bc.buf)
                return -ENOMEM;
 
-       error = xfs_bulkstat_one_int(breq->mp, breq->mnt_userns, NULL,
-                                    breq->startino, &bc);
+       /*
+        * Grab an empty transaction so that we can use its recursive buffer
+        * locking abilities to detect cycles in the inobt without deadlocking.
+        */
+       error = xfs_trans_alloc_empty(breq->mp, &tp);
+       if (error)
+               goto out;
 
+       error = xfs_bulkstat_one_int(breq->mp, breq->mnt_userns, tp,
+                       breq->startino, &bc);
+       xfs_trans_cancel(tp);
+out:
        kmem_free(bc.buf);
 
        /*
@@ -244,6 +255,7 @@ xfs_bulkstat(
                .formatter      = formatter,
                .breq           = breq,
        };
+       struct xfs_trans        *tp;
        int                     error;
 
        if (breq->mnt_userns != &init_user_ns) {
@@ -259,9 +271,18 @@ xfs_bulkstat(
        if (!bc.buf)
                return -ENOMEM;
 
-       error = xfs_iwalk(breq->mp, NULL, breq->startino, breq->flags,
-                       xfs_bulkstat_iwalk, breq->icount, &bc);
+       /*
+        * Grab an empty transaction so that we can use its recursive buffer
+        * locking abilities to detect cycles in the inobt without deadlocking.
+        */
+       error = xfs_trans_alloc_empty(breq->mp, &tp);
+       if (error)
+               goto out;
 
+       error = xfs_iwalk(breq->mp, tp, breq->startino, breq->flags,
+                       xfs_bulkstat_iwalk, breq->icount, &bc);
+       xfs_trans_cancel(tp);
+out:
        kmem_free(bc.buf);
 
        /*
@@ -374,13 +395,24 @@ xfs_inumbers(
                .formatter      = formatter,
                .breq           = breq,
        };
+       struct xfs_trans        *tp;
        int                     error = 0;
 
        if (xfs_bulkstat_already_done(breq->mp, breq->startino))
                return 0;
 
-       error = xfs_inobt_walk(breq->mp, NULL, breq->startino, breq->flags,
+       /*
+        * Grab an empty transaction so that we can use its recursive buffer
+        * locking abilities to detect cycles in the inobt without deadlocking.
+        */
+       error = xfs_trans_alloc_empty(breq->mp, &tp);
+       if (error)
+               goto out;
+
+       error = xfs_inobt_walk(breq->mp, tp, breq->startino, breq->flags,
                        xfs_inumbers_walk, breq->icount, &ic);
+       xfs_trans_cancel(tp);
+out:
 
        /*
         * We found some inode groups, so clear the error status and return