]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
repair: factor out sparse inodes from finobt reconstruction
authorBrian Foster <bfoster@redhat.com>
Tue, 23 Jun 2015 05:08:47 +0000 (15:08 +1000)
committerDave Chinner <david@fromorbit.com>
Tue, 23 Jun 2015 05:08:47 +0000 (15:08 +1000)
Phase 5 of xfs_repair recreates the on-disk btrees. The free inode btree
(finobt) contains inode records that contain one or more free inodes.
Sparse inodes are marked as free and therefore sparse inode records can
be incorrectly included in the finobt even when no real free inodes are
available in the record.

Update the finobt in-core record traversal helpers to factor out sparse
inodes and only consider inode records with allocated, free inodes for
finobt insertion.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
repair/incore.h

index d4e44a7a6b10d6fd79a9069224bdc375ce35cf2f..5a63e1e16a14ae4b571639e83b45227660de8f80 100644 (file)
@@ -384,6 +384,14 @@ void                       clear_uncertain_ino_cache(xfs_agnumber_t agno);
 /*
  * finobt helpers
  */
+
+static inline bool
+inode_rec_has_free(struct ino_tree_node *ino_rec)
+{
+       /* must have real, allocated inodes for finobt */
+       return ino_rec->ir_free & ~ino_rec->ir_sparse;
+}
+
 static inline ino_tree_node_t *
 findfirst_free_inode_rec(xfs_agnumber_t agno)
 {
@@ -391,7 +399,7 @@ findfirst_free_inode_rec(xfs_agnumber_t agno)
 
        ino_rec = findfirst_inode_rec(agno);
 
-       while (ino_rec && !ino_rec->ir_free)
+       while (ino_rec && !inode_rec_has_free(ino_rec))
                ino_rec = next_ino_rec(ino_rec);
 
        return ino_rec;
@@ -402,7 +410,7 @@ next_free_ino_rec(ino_tree_node_t *ino_rec)
 {
        ino_rec = next_ino_rec(ino_rec);
 
-       while (ino_rec && !ino_rec->ir_free)
+       while (ino_rec && !inode_rec_has_free(ino_rec))
                ino_rec = next_ino_rec(ino_rec);
 
        return ino_rec;