summaryrefslogtreecommitdiff
path: root/fs/xfs/scrub/repair.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/scrub/repair.c')
-rw-r--r--fs/xfs/scrub/repair.c73
1 files changed, 22 insertions, 51 deletions
diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c
index 3b5288d3ef4e..d00c18954a26 100644
--- a/fs/xfs/scrub/repair.c
+++ b/fs/xfs/scrub/repair.c
@@ -43,6 +43,7 @@
#include "xfs_rtalloc.h"
#include "xfs_metafile.h"
#include "xfs_rtrefcount_btree.h"
+#include "xfs_zone_alloc.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
@@ -1050,7 +1051,13 @@ xrep_require_rtext_inuse(
xfs_rtxnum_t startrtx;
xfs_rtxnum_t endrtx;
bool is_free = false;
- int error;
+ int error = 0;
+
+ if (xfs_has_zoned(mp)) {
+ if (!xfs_zone_rgbno_is_valid(sc->sr.rtg, rgbno + len - 1))
+ return -EFSCORRUPTED;
+ return 0;
+ }
startrtx = xfs_rgbno_to_rtx(mp, rgbno);
endrtx = xfs_rgbno_to_rtx(mp, rgbno + len - 1);
@@ -1262,42 +1269,6 @@ xrep_setup_xfbtree(
}
/*
- * Create a dummy transaction for use in a live update hook function. This
- * function MUST NOT be called from regular repair code because the current
- * process' transaction is saved via the cookie.
- */
-int
-xrep_trans_alloc_hook_dummy(
- struct xfs_mount *mp,
- void **cookiep,
- struct xfs_trans **tpp)
-{
- int error;
-
- *cookiep = current->journal_info;
- current->journal_info = NULL;
-
- error = xfs_trans_alloc_empty(mp, tpp);
- if (!error)
- return 0;
-
- current->journal_info = *cookiep;
- *cookiep = NULL;
- return error;
-}
-
-/* Cancel a dummy transaction used by a live update hook function. */
-void
-xrep_trans_cancel_hook_dummy(
- void **cookiep,
- struct xfs_trans *tp)
-{
- xfs_trans_cancel(tp);
- current->journal_info = *cookiep;
- *cookiep = NULL;
-}
-
-/*
* See if this buffer can pass the given ->verify_struct() function.
*
* If the buffer already has ops attached and they're not the ones that were
@@ -1386,11 +1357,12 @@ int
xrep_reset_metafile_resv(
struct xfs_scrub *sc)
{
- struct xfs_inode *ip = sc->ip;
+ struct xfs_mount *mp = sc->mp;
int64_t delta;
int error;
- delta = ip->i_nblocks + ip->i_delayed_blks - ip->i_meta_resv_asked;
+ delta = mp->m_metafile_resv_used + mp->m_metafile_resv_avail -
+ mp->m_metafile_resv_target;
if (delta == 0)
return 0;
@@ -1401,11 +1373,11 @@ xrep_reset_metafile_resv(
if (delta > 0) {
int64_t give_back;
- give_back = min_t(uint64_t, delta, ip->i_delayed_blks);
+ give_back = min_t(uint64_t, delta, mp->m_metafile_resv_avail);
if (give_back > 0) {
- xfs_mod_delalloc(ip, 0, -give_back);
- xfs_add_fdblocks(ip->i_mount, give_back);
- ip->i_delayed_blks -= give_back;
+ xfs_mod_sb_delalloc(mp, -give_back);
+ xfs_add_fdblocks(mp, give_back);
+ mp->m_metafile_resv_avail -= give_back;
}
return 0;
@@ -1413,24 +1385,23 @@ xrep_reset_metafile_resv(
/*
* Not enough reservation; try to take some blocks from the filesystem
- * to the metadata inode. @delta is negative here, so invert the sign.
+ * to the metabtree reservation.
*/
- delta = -delta;
- error = xfs_dec_fdblocks(sc->mp, delta, true);
+ delta = -delta; /* delta is negative here, so invert the sign. */
+ error = xfs_dec_fdblocks(mp, delta, true);
while (error == -ENOSPC) {
delta--;
if (delta == 0) {
xfs_warn(sc->mp,
-"Insufficient free space to reset space reservation for inode 0x%llx after repair.",
- ip->i_ino);
+"Insufficient free space to reset metabtree reservation after repair.");
return 0;
}
- error = xfs_dec_fdblocks(sc->mp, delta, true);
+ error = xfs_dec_fdblocks(mp, delta, true);
}
if (error)
return error;
- xfs_mod_delalloc(ip, 0, delta);
- ip->i_delayed_blks += delta;
+ xfs_mod_sb_delalloc(mp, delta);
+ mp->m_metafile_resv_avail += delta;
return 0;
}