summaryrefslogtreecommitdiff
path: root/fs/xfs/scrub/bmap_repair.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/scrub/bmap_repair.c')
-rw-r--r--fs/xfs/scrub/bmap_repair.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/fs/xfs/scrub/bmap_repair.c b/fs/xfs/scrub/bmap_repair.c
index a8d6415b1c38..a4bb89fdd510 100644
--- a/fs/xfs/scrub/bmap_repair.c
+++ b/fs/xfs/scrub/bmap_repair.c
@@ -86,6 +86,9 @@ struct xrep_bmap {
/* What d the REFLINK flag be set when the repair is over? */
enum reflink_scan_state reflink_scan;
+
+ /* Do we allow unwritten extents? */
+ bool allow_unwritten;
};
/* Is this space extent shared? Flag the inode if it is. */
@@ -262,6 +265,10 @@ xrep_bmap_walk_rmap(
!(rec->rm_flags & XFS_RMAP_ATTR_FORK))
return 0;
+ /* Reject unwritten extents if we don't allow those. */
+ if ((rec->rm_flags & XFS_RMAP_UNWRITTEN) && !rb->allow_unwritten)
+ return -EFSCORRUPTED;
+
fsbno = XFS_AGB_TO_FSB(mp, cur->bc_ag.pag->pag_agno,
rec->rm_startblock);
@@ -780,10 +787,11 @@ xrep_bmap_init_reflink_scan(
}
/* Repair an inode fork. */
-STATIC int
+int
xrep_bmap(
struct xfs_scrub *sc,
- int whichfork)
+ int whichfork,
+ bool allow_unwritten)
{
struct xrep_bmap *rb;
char *descr;
@@ -803,6 +811,7 @@ xrep_bmap(
rb->sc = sc;
rb->whichfork = whichfork;
rb->reflink_scan = xrep_bmap_init_reflink_scan(sc, whichfork);
+ rb->allow_unwritten = allow_unwritten;
/* Set up enough storage to handle the max records for this fork. */
large_extcount = xfs_has_large_extent_counts(sc->mp);
@@ -846,7 +855,7 @@ int
xrep_bmap_data(
struct xfs_scrub *sc)
{
- return xrep_bmap(sc, XFS_DATA_FORK);
+ return xrep_bmap(sc, XFS_DATA_FORK, true);
}
/* Repair an inode's attr fork. */
@@ -854,5 +863,5 @@ int
xrep_bmap_attr(
struct xfs_scrub *sc)
{
- return xrep_bmap(sc, XFS_ATTR_FORK);
+ return xrep_bmap(sc, XFS_ATTR_FORK, false);
}