]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - libxfs/trans.c
xfs_repair: rebuild block mappings from rmapbt data
[thirdparty/xfsprogs-dev.git] / libxfs / trans.c
index bd1186b24e628074efd6ddc2605f9c4e906849cb..8143a6a99f620b528bfc9017fc8a318f8bad83e7 100644 (file)
@@ -1143,3 +1143,51 @@ libxfs_trans_alloc_inode(
        *tpp = tp;
        return 0;
 }
+
+/*
+ * Try to reserve more blocks for a transaction.  The single use case we
+ * support is for offline repair -- use a transaction to gather data without
+ * fear of btree cycle deadlocks; calculate how many blocks we really need
+ * from that data; and only then start modifying data.  This can fail due to
+ * ENOSPC, so we have to be able to cancel the transaction.
+ */
+int
+libxfs_trans_reserve_more(
+       struct xfs_trans        *tp,
+       uint                    blocks,
+       uint                    rtextents)
+{
+       int                     error = 0;
+
+       ASSERT(!(tp->t_flags & XFS_TRANS_DIRTY));
+
+       /*
+        * Attempt to reserve the needed disk blocks by decrementing
+        * the number needed from the number available.  This will
+        * fail if the count would go below zero.
+        */
+       if (blocks > 0) {
+               if (tp->t_mountp->m_sb.sb_fdblocks < blocks)
+                       return -ENOSPC;
+               tp->t_blk_res += blocks;
+       }
+
+       /*
+        * Attempt to reserve the needed realtime extents by decrementing
+        * the number needed from the number available.  This will
+        * fail if the count would go below zero.
+        */
+       if (rtextents > 0) {
+               if (tp->t_mountp->m_sb.sb_rextents < rtextents) {
+                       error = -ENOSPC;
+                       goto out_blocks;
+               }
+       }
+
+       return 0;
+out_blocks:
+       if (blocks > 0)
+               tp->t_blk_res -= blocks;
+
+       return error;
+}