summaryrefslogtreecommitdiff
path: root/extent_io.c
diff options
context:
space:
mode:
authorNikolay Borisov <nborisov@suse.com>2018-10-01 17:46:13 +0300
committerDavid Sterba <dsterba@suse.com>2018-10-23 15:46:33 +0200
commitb1a1b8902998d3c1e082ae2fe09cdfd09d1c4583 (patch)
tree88a831af17c9b2d918df1274526b0836439c3b75 /extent_io.c
parentd8acc433533ac25a1a4b2432c73516a369acddb0 (diff)
btrfs-progs: Add extent buffer bitmap manipulation infrastructure
Those functions are in preparation for adding the freespace tree repair code since it needs to be able to deal with bitmap based FSTs. This patch adds extent_buffer_bitmap_set and extent_buffer_bitmap_clear functions. Since in userspace we don't have to deal with page mappings their implementation is vastly simplified by simply setting each bit in the passed range. Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com> Reviewed-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'extent_io.c')
-rw-r--r--extent_io.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/extent_io.c b/extent_io.c
index b8510b0a..c57f6282 100644
--- a/extent_io.c
+++ b/extent_io.c
@@ -205,6 +205,62 @@ static int clear_state_bit(struct extent_io_tree *tree,
}
/*
+ * extent_buffer_bitmap_set - set an area of a bitmap
+ * @eb: the extent buffer
+ * @start: offset of the bitmap item in the extent buffer
+ * @pos: bit number of the first bit
+ * @len: number of bits to set
+ */
+void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
+ unsigned long pos, unsigned long len)
+{
+ u8 *p = (u8 *)eb->data + start + BIT_BYTE(pos);
+ const unsigned int size = pos + len;
+ int bits_to_set = BITS_PER_BYTE - (pos % BITS_PER_BYTE);
+ u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(pos);
+
+ while (len >= bits_to_set) {
+ *p |= mask_to_set;
+ len -= bits_to_set;
+ bits_to_set = BITS_PER_BYTE;
+ mask_to_set = ~0;
+ p++;
+ }
+ if (len) {
+ mask_to_set &= BITMAP_LAST_BYTE_MASK(size);
+ *p |= mask_to_set;
+ }
+}
+
+/*
+ * extent_buffer_bitmap_clear - clear an area of a bitmap
+ * @eb: the extent buffer
+ * @start: offset of the bitmap item in the extent buffer
+ * @pos: bit number of the first bit
+ * @len: number of bits to clear
+ */
+void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
+ unsigned long pos, unsigned long len)
+{
+ u8 *p = (u8 *)eb->data + start + BIT_BYTE(pos);
+ const unsigned int size = pos + len;
+ int bits_to_clear = BITS_PER_BYTE - (pos % BITS_PER_BYTE);
+ u8 mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos);
+
+ while (len >= bits_to_clear) {
+ *p &= ~mask_to_clear;
+ len -= bits_to_clear;
+ bits_to_clear = BITS_PER_BYTE;
+ mask_to_clear = ~0;
+ p++;
+ }
+ if (len) {
+ mask_to_clear &= BITMAP_LAST_BYTE_MASK(size);
+ *p &= ~mask_to_clear;
+ }
+}
+
+/*
* clear some bits on a range in the tree.
*/
int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, int bits)