We need to validate fragmenation_lru is consistent with sectors counts
and bucket type.

Signed-off-by: Daniel Hill <[email protected]>
---
 fs/bcachefs/alloc_background.c | 18 ++++++++++++++++++
 fs/bcachefs/sb-errors_types.h  |  3 ++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
index 4de4036ded06..3bf2a2daad93 100644
--- a/fs/bcachefs/alloc_background.c
+++ b/fs/bcachefs/alloc_background.c
@@ -292,6 +292,24 @@ int bch2_alloc_v4_invalid(struct bch_fs *c, struct 
bkey_s_c k,
        case BCH_DATA_stripe:
                break;
        }
+
+       /* this check fails to work during device removal evacuate etc,
+        * so fall back to something less robust
+        */
+       if (bch2_dev_exists2(c, a.k->p.inode)) {
+               u64 fragmentation_lru = alloc_lru_idx_fragmentation(*a.v,
+                                                           
bch_dev_bkey_exists(c, a.k->p.inode));
+
+               bkey_fsck_err_on(a.v->fragmentation_lru != fragmentation_lru, 
c, err,
+                                alloc_lru_fragmentation_wrong,
+                                "bad fragmentation_lru (got %llu should be 
%llu)",
+                                a.v->fragmentation_lru, fragmentation_lru);
+       }
+       else
+               bkey_fsck_err_on(a.v->fragmentation_lru && 
!data_type_movable(a.v->data_type),
+                                c, err, alloc_lru_fragmentation_wrong,
+                                "alloc type %s is unmovabled but 
fragmentation_lru not 0 (%llu)",
+                                bch2_data_type_str(a.v->data_type), 
a.v->fragmentation_lru);
 fsck_err:
        return ret;
 }
diff --git a/fs/bcachefs/sb-errors_types.h b/fs/bcachefs/sb-errors_types.h
index 0df4b0e7071a..cc70a93dfd0d 100644
--- a/fs/bcachefs/sb-errors_types.h
+++ b/fs/bcachefs/sb-errors_types.h
@@ -264,7 +264,8 @@
        x(subvol_children_not_set,                              256)    \
        x(subvol_children_bad,                                  257)    \
        x(subvol_loop,                                          258)    \
-       x(subvol_unreachable,                                   259)
+       x(subvol_unreachable,                                   259)    \
+       x(alloc_lru_fragmentation_wrong,                        260)
 
 enum bch_sb_error_id {
 #define x(t, n) BCH_FSCK_ERR_##t = n,
-- 
2.43.0


Reply via email to