Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Darrick J. Wong | 2149 | 96.28% | 19 | 67.86% |
David Chinner | 68 | 3.05% | 5 | 17.86% |
Michal Marek | 6 | 0.27% | 1 | 3.57% |
Christoph Hellwig | 4 | 0.18% | 1 | 3.57% |
Russell Cattelan | 4 | 0.18% | 1 | 3.57% |
Nathan Scott | 1 | 0.04% | 1 | 3.57% |
Total | 2232 | 28 |
// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2018-2023 Oracle. All Rights Reserved. * Author: Darrick J. Wong <djwong@kernel.org> */ #include "xfs.h" #include "xfs_fs.h" #include "xfs_shared.h" #include "xfs_bit.h" #include "xfs_format.h" #include "xfs_trans_resv.h" #include "xfs_mount.h" #include "xfs_btree.h" #include "scrub/scrub.h" #include "scrub/bitmap.h" #include <linux/interval_tree_generic.h> /* u64 bitmap */ struct xbitmap64_node { struct rb_node bn_rbnode; /* First set bit of this interval and subtree. */ uint64_t bn_start; /* Last set bit of this interval. */ uint64_t bn_last; /* Last set bit of this subtree. Do not touch this. */ uint64_t __bn_subtree_last; }; /* Define our own interval tree type with uint64_t parameters. */ #define START(node) ((node)->bn_start) #define LAST(node) ((node)->bn_last) /* * These functions are defined by the INTERVAL_TREE_DEFINE macro, but we'll * forward-declare them anyway for clarity. */ static inline __maybe_unused void xbitmap64_tree_insert(struct xbitmap64_node *node, struct rb_root_cached *root); static inline __maybe_unused void xbitmap64_tree_remove(struct xbitmap64_node *node, struct rb_root_cached *root); static inline __maybe_unused struct xbitmap64_node * xbitmap64_tree_iter_first(struct rb_root_cached *root, uint64_t start, uint64_t last); static inline __maybe_unused struct xbitmap64_node * xbitmap64_tree_iter_next(struct xbitmap64_node *node, uint64_t start, uint64_t last); INTERVAL_TREE_DEFINE(struct xbitmap64_node, bn_rbnode, uint64_t, __bn_subtree_last, START, LAST, static inline __maybe_unused, xbitmap64_tree) /* Iterate each interval of a bitmap. Do not change the bitmap. */ #define for_each_xbitmap64_extent(bn, bitmap) \ for ((bn) = rb_entry_safe(rb_first(&(bitmap)->xb_root.rb_root), \ struct xbitmap64_node, bn_rbnode); \ (bn) != NULL; \ (bn) = rb_entry_safe(rb_next(&(bn)->bn_rbnode), \ struct xbitmap64_node, bn_rbnode)) /* Clear a range of this bitmap. */ int xbitmap64_clear( struct xbitmap64 *bitmap, uint64_t start, uint64_t len) { struct xbitmap64_node *bn; struct xbitmap64_node *new_bn; uint64_t last = start + len - 1; while ((bn = xbitmap64_tree_iter_first(&bitmap->xb_root, start, last))) { if (bn->bn_start < start && bn->bn_last > last) { uint64_t old_last = bn->bn_last; /* overlaps with the entire clearing range */ xbitmap64_tree_remove(bn, &bitmap->xb_root); bn->bn_last = start - 1; xbitmap64_tree_insert(bn, &bitmap->xb_root); /* add an extent */ new_bn = kmalloc(sizeof(struct xbitmap64_node), XCHK_GFP_FLAGS); if (!new_bn) return -ENOMEM; new_bn->bn_start = last + 1; new_bn->bn_last = old_last; xbitmap64_tree_insert(new_bn, &bitmap->xb_root); } else if (bn->bn_start < start) { /* overlaps with the left side of the clearing range */ xbitmap64_tree_remove(bn, &bitmap->xb_root); bn->bn_last = start - 1; xbitmap64_tree_insert(bn, &bitmap->xb_root); } else if (bn->bn_last > last) { /* overlaps with the right side of the clearing range */ xbitmap64_tree_remove(bn, &bitmap->xb_root); bn->bn_start = last + 1; xbitmap64_tree_insert(bn, &bitmap->xb_root); break; } else { /* in the middle of the clearing range */ xbitmap64_tree_remove(bn, &bitmap->xb_root); kfree(bn); } } return 0; } /* Set a range of this bitmap. */ int xbitmap64_set( struct xbitmap64 *bitmap, uint64_t start, uint64_t len) { struct xbitmap64_node *left; struct xbitmap64_node *right; uint64_t last = start + len - 1; int error; /* Is this whole range already set? */ left = xbitmap64_tree_iter_first(&bitmap->xb_root, start, last); if (left && left->bn_start <= start && left->bn_last >= last) return 0; /* Clear out everything in the range we want to set. */ error = xbitmap64_clear(bitmap, start, len); if (error) return error; /* Do we have a left-adjacent extent? */ left = xbitmap64_tree_iter_first(&bitmap->xb_root, start - 1, start - 1); ASSERT(!left || left->bn_last + 1 == start); /* Do we have a right-adjacent extent? */ right = xbitmap64_tree_iter_first(&bitmap->xb_root, last + 1, last + 1); ASSERT(!right || right->bn_start == last + 1); if (left && right) { /* combine left and right adjacent extent */ xbitmap64_tree_remove(left, &bitmap->xb_root); xbitmap64_tree_remove(right, &bitmap->xb_root); left->bn_last = right->bn_last; xbitmap64_tree_insert(left, &bitmap->xb_root); kfree(right); } else if (left) { /* combine with left extent */ xbitmap64_tree_remove(left, &bitmap->xb_root); left->bn_last = last; xbitmap64_tree_insert(left, &bitmap->xb_root); } else if (right) { /* combine with right extent */ xbitmap64_tree_remove(right, &bitmap->xb_root); right->bn_start = start; xbitmap64_tree_insert(right, &bitmap->xb_root); } else { /* add an extent */ left = kmalloc(sizeof(struct xbitmap64_node), XCHK_GFP_FLAGS); if (!left) return -ENOMEM; left->bn_start = start; left->bn_last = last; xbitmap64_tree_insert(left, &bitmap->xb_root); } return 0; } /* Free everything related to this bitmap. */ void xbitmap64_destroy( struct xbitmap64 *bitmap) { struct xbitmap64_node *bn; while ((bn = xbitmap64_tree_iter_first(&bitmap->xb_root, 0, -1ULL))) { xbitmap64_tree_remove(bn, &bitmap->xb_root); kfree(bn); } } /* Set up a per-AG block bitmap. */ void xbitmap64_init( struct xbitmap64 *bitmap) { bitmap->xb_root = RB_ROOT_CACHED; } /* * Remove all the blocks mentioned in @sub from the extents in @bitmap. * * The intent is that callers will iterate the rmapbt for all of its records * for a given owner to generate @bitmap; and iterate all the blocks of the * metadata structures that are not being rebuilt and have the same rmapbt * owner to generate @sub. This routine subtracts all the extents * mentioned in sub from all the extents linked in @bitmap, which leaves * @bitmap as the list of blocks that are not accounted for, which we assume * are the dead blocks of the old metadata structure. The blocks mentioned in * @bitmap can be reaped. * * This is the logical equivalent of bitmap &= ~sub. */ int xbitmap64_disunion( struct xbitmap64 *bitmap, struct xbitmap64 *sub) { struct xbitmap64_node *bn; int error; if (xbitmap64_empty(bitmap) || xbitmap64_empty(sub)) return 0; for_each_xbitmap64_extent(bn, sub) { error = xbitmap64_clear(bitmap, bn->bn_start, bn->bn_last - bn->bn_start + 1); if (error) return error; } return 0; } /* How many bits are set in this bitmap? */ uint64_t xbitmap64_hweight( struct xbitmap64 *bitmap) { struct xbitmap64_node *bn; uint64_t ret = 0; for_each_xbitmap64_extent(bn, bitmap) ret += bn->bn_last - bn->bn_start + 1; return ret; } /* Call a function for every run of set bits in this bitmap. */ int xbitmap64_walk( struct xbitmap64 *bitmap, xbitmap64_walk_fn fn, void *priv) { struct xbitmap64_node *bn; int error = 0; for_each_xbitmap64_extent(bn, bitmap) { error = fn(bn->bn_start, bn->bn_last - bn->bn_start + 1, priv); if (error) break; } return error; } /* Does this bitmap have no bits set at all? */ bool xbitmap64_empty( struct xbitmap64 *bitmap) { return bitmap->xb_root.rb_root.rb_node == NULL; } /* Is the start of the range set or clear? And for how long? */ bool xbitmap64_test( struct xbitmap64 *bitmap, uint64_t start, uint64_t *len) { struct xbitmap64_node *bn; uint64_t last = start + *len - 1; bn = xbitmap64_tree_iter_first(&bitmap->xb_root, start, last); if (!bn) return false; if (bn->bn_start <= start) { if (bn->bn_last < last) *len = bn->bn_last - start + 1; return true; } *len = bn->bn_start - start; return false; } /* u32 bitmap */ struct xbitmap32_node { struct rb_node bn_rbnode; /* First set bit of this interval and subtree. */ uint32_t bn_start; /* Last set bit of this interval. */ uint32_t bn_last; /* Last set bit of this subtree. Do not touch this. */ uint32_t __bn_subtree_last; }; /* Define our own interval tree type with uint32_t parameters. */ /* * These functions are defined by the INTERVAL_TREE_DEFINE macro, but we'll * forward-declare them anyway for clarity. */ static inline __maybe_unused void xbitmap32_tree_insert(struct xbitmap32_node *node, struct rb_root_cached *root); static inline __maybe_unused void xbitmap32_tree_remove(struct xbitmap32_node *node, struct rb_root_cached *root); static inline __maybe_unused struct xbitmap32_node * xbitmap32_tree_iter_first(struct rb_root_cached *root, uint32_t start, uint32_t last); static inline __maybe_unused struct xbitmap32_node * xbitmap32_tree_iter_next(struct xbitmap32_node *node, uint32_t start, uint32_t last); INTERVAL_TREE_DEFINE(struct xbitmap32_node, bn_rbnode, uint32_t, __bn_subtree_last, START, LAST, static inline __maybe_unused, xbitmap32_tree) /* Iterate each interval of a bitmap. Do not change the bitmap. */ #define for_each_xbitmap32_extent(bn, bitmap) \ for ((bn) = rb_entry_safe(rb_first(&(bitmap)->xb_root.rb_root), \ struct xbitmap32_node, bn_rbnode); \ (bn) != NULL; \ (bn) = rb_entry_safe(rb_next(&(bn)->bn_rbnode), \ struct xbitmap32_node, bn_rbnode)) /* Clear a range of this bitmap. */ int xbitmap32_clear( struct xbitmap32 *bitmap, uint32_t start, uint32_t len) { struct xbitmap32_node *bn; struct xbitmap32_node *new_bn; uint32_t last = start + len - 1; while ((bn = xbitmap32_tree_iter_first(&bitmap->xb_root, start, last))) { if (bn->bn_start < start && bn->bn_last > last) { uint32_t old_last = bn->bn_last; /* overlaps with the entire clearing range */ xbitmap32_tree_remove(bn, &bitmap->xb_root); bn->bn_last = start - 1; xbitmap32_tree_insert(bn, &bitmap->xb_root); /* add an extent */ new_bn = kmalloc(sizeof(struct xbitmap32_node), XCHK_GFP_FLAGS); if (!new_bn) return -ENOMEM; new_bn->bn_start = last + 1; new_bn->bn_last = old_last; xbitmap32_tree_insert(new_bn, &bitmap->xb_root); } else if (bn->bn_start < start) { /* overlaps with the left side of the clearing range */ xbitmap32_tree_remove(bn, &bitmap->xb_root); bn->bn_last = start - 1; xbitmap32_tree_insert(bn, &bitmap->xb_root); } else if (bn->bn_last > last) { /* overlaps with the right side of the clearing range */ xbitmap32_tree_remove(bn, &bitmap->xb_root); bn->bn_start = last + 1; xbitmap32_tree_insert(bn, &bitmap->xb_root); break; } else { /* in the middle of the clearing range */ xbitmap32_tree_remove(bn, &bitmap->xb_root); kfree(bn); } } return 0; } /* Set a range of this bitmap. */ int xbitmap32_set( struct xbitmap32 *bitmap, uint32_t start, uint32_t len) { struct xbitmap32_node *left; struct xbitmap32_node *right; uint32_t last = start + len - 1; int error; /* Is this whole range already set? */ left = xbitmap32_tree_iter_first(&bitmap->xb_root, start, last); if (left && left->bn_start <= start && left->bn_last >= last) return 0; /* Clear out everything in the range we want to set. */ error = xbitmap32_clear(bitmap, start, len); if (error) return error; /* Do we have a left-adjacent extent? */ left = xbitmap32_tree_iter_first(&bitmap->xb_root, start - 1, start - 1); ASSERT(!left || left->bn_last + 1 == start); /* Do we have a right-adjacent extent? */ right = xbitmap32_tree_iter_first(&bitmap->xb_root, last + 1, last + 1); ASSERT(!right || right->bn_start == last + 1); if (left && right) { /* combine left and right adjacent extent */ xbitmap32_tree_remove(left, &bitmap->xb_root); xbitmap32_tree_remove(right, &bitmap->xb_root); left->bn_last = right->bn_last; xbitmap32_tree_insert(left, &bitmap->xb_root); kfree(right); } else if (left) { /* combine with left extent */ xbitmap32_tree_remove(left, &bitmap->xb_root); left->bn_last = last; xbitmap32_tree_insert(left, &bitmap->xb_root); } else if (right) { /* combine with right extent */ xbitmap32_tree_remove(right, &bitmap->xb_root); right->bn_start = start; xbitmap32_tree_insert(right, &bitmap->xb_root); } else { /* add an extent */ left = kmalloc(sizeof(struct xbitmap32_node), XCHK_GFP_FLAGS); if (!left) return -ENOMEM; left->bn_start = start; left->bn_last = last; xbitmap32_tree_insert(left, &bitmap->xb_root); } return 0; } /* Free everything related to this bitmap. */ void xbitmap32_destroy( struct xbitmap32 *bitmap) { struct xbitmap32_node *bn; while ((bn = xbitmap32_tree_iter_first(&bitmap->xb_root, 0, -1U))) { xbitmap32_tree_remove(bn, &bitmap->xb_root); kfree(bn); } } /* Set up a per-AG block bitmap. */ void xbitmap32_init( struct xbitmap32 *bitmap) { bitmap->xb_root = RB_ROOT_CACHED; } /* * Remove all the blocks mentioned in @sub from the extents in @bitmap. * * The intent is that callers will iterate the rmapbt for all of its records * for a given owner to generate @bitmap; and iterate all the blocks of the * metadata structures that are not being rebuilt and have the same rmapbt * owner to generate @sub. This routine subtracts all the extents * mentioned in sub from all the extents linked in @bitmap, which leaves * @bitmap as the list of blocks that are not accounted for, which we assume * are the dead blocks of the old metadata structure. The blocks mentioned in * @bitmap can be reaped. * * This is the logical equivalent of bitmap &= ~sub. */ int xbitmap32_disunion( struct xbitmap32 *bitmap, struct xbitmap32 *sub) { struct xbitmap32_node *bn; int error; if (xbitmap32_empty(bitmap) || xbitmap32_empty(sub)) return 0; for_each_xbitmap32_extent(bn, sub) { error = xbitmap32_clear(bitmap, bn->bn_start, bn->bn_last - bn->bn_start + 1); if (error) return error; } return 0; } /* How many bits are set in this bitmap? */ uint32_t xbitmap32_hweight( struct xbitmap32 *bitmap) { struct xbitmap32_node *bn; uint32_t ret = 0; for_each_xbitmap32_extent(bn, bitmap) ret += bn->bn_last - bn->bn_start + 1; return ret; } /* Call a function for every run of set bits in this bitmap. */ int xbitmap32_walk( struct xbitmap32 *bitmap, xbitmap32_walk_fn fn, void *priv) { struct xbitmap32_node *bn; int error = 0; for_each_xbitmap32_extent(bn, bitmap) { error = fn(bn->bn_start, bn->bn_last - bn->bn_start + 1, priv); if (error) break; } return error; } /* Does this bitmap have no bits set at all? */ bool xbitmap32_empty( struct xbitmap32 *bitmap) { return bitmap->xb_root.rb_root.rb_node == NULL; } /* Is the start of the range set or clear? And for how long? */ bool xbitmap32_test( struct xbitmap32 *bitmap, uint32_t start, uint32_t *len) { struct xbitmap32_node *bn; uint32_t last = start + *len - 1; bn = xbitmap32_tree_iter_first(&bitmap->xb_root, start, last); if (!bn) return false; if (bn->bn_start <= start) { if (bn->bn_last < last) *len = bn->bn_last - start + 1; return true; } *len = bn->bn_start - start; return false; } /* Count the number of set regions in this bitmap. */ uint32_t xbitmap32_count_set_regions( struct xbitmap32 *bitmap) { struct xbitmap32_node *bn; uint32_t nr = 0; for_each_xbitmap32_extent(bn, bitmap) nr++; return nr; }
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1