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>
This commit is contained in:
parent
d8acc43353
commit
b1a1b89029
56
extent_io.c
56
extent_io.c
|
@ -204,6 +204,62 @@ static int clear_state_bit(struct extent_io_tree *tree,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue