summaryrefslogtreecommitdiff
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
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>
-rw-r--r--extent_io.c56
-rw-r--r--extent_io.h5
2 files changed, 61 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)
diff --git a/extent_io.h b/extent_io.h
index d407d93d..9587528b 100644
--- a/extent_io.h
+++ b/extent_io.h
@@ -175,4 +175,9 @@ int read_data_from_disk(struct btrfs_fs_info *info, void *buf, u64 offset,
u64 bytes, int mirror);
int write_data_to_disk(struct btrfs_fs_info *info, void *buf, u64 offset,
u64 bytes, int mirror);
+void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
+ unsigned long pos, unsigned long len);
+void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
+ unsigned long pos, unsigned long len);
+
#endif