Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ef97622 authored by Chris Mason's avatar Chris Mason Committed by David Woodhouse
Browse files

Btrfs: add a radix back bit tree

parent f7922033
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3,7 +3,8 @@ ifneq ($(KERNELRELEASE),)

obj-m  := btrfs.o
btrfs-y := super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
	   hash.o file-item.o inode-item.o inode-map.o disk-io.o transaction.o
	   hash.o file-item.o inode-item.o inode-map.o disk-io.o \
	   transaction.o bit-radix.o

#btrfs-y := ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
#	  root-tree.o dir-item.o hash.o file-item.o inode-item.o \

fs/btrfs/bit-radix.c

0 → 100644
+107 −0
Original line number Diff line number Diff line
#include <linux/module.h>
#include "bit-radix.h"

#define BIT_ARRAY_BYTES 256
#define BIT_RADIX_BITS_PER_ARRAY ((BIT_ARRAY_BYTES - sizeof(unsigned long)) * 8)

int set_radix_bit(struct radix_tree_root *radix, unsigned long bit)
{
	unsigned long *bits;
	unsigned long slot;
	int bit_slot;
	int ret;

	slot = bit / BIT_RADIX_BITS_PER_ARRAY;
	bit_slot = bit % BIT_RADIX_BITS_PER_ARRAY;

	bits = radix_tree_lookup(radix, slot);
	if (!bits) {
		bits = kmalloc(BIT_ARRAY_BYTES, GFP_NOIO);
		if (!bits)
			return -ENOMEM;
		memset(bits + 1, 0, BIT_ARRAY_BYTES - sizeof(unsigned long));
		bits[0] = slot;
		ret = radix_tree_insert(radix, slot, bits);
		if (ret)
			return ret;
	}
	set_bit(bit_slot, bits + 1);
	return 0;
}

int test_radix_bit(struct radix_tree_root *radix, unsigned long bit)
{
	unsigned long *bits;
	unsigned long slot;
	int bit_slot;

	slot = bit / BIT_RADIX_BITS_PER_ARRAY;
	bit_slot = bit % BIT_RADIX_BITS_PER_ARRAY;

	bits = radix_tree_lookup(radix, slot);
	if (!bits)
		return 0;
	return test_bit(bit_slot, bits + 1);
}

int clear_radix_bit(struct radix_tree_root *radix, unsigned long bit)
{
	unsigned long *bits;
	unsigned long slot;
	int bit_slot;
	int i;
	int empty = 1;

	slot = bit / BIT_RADIX_BITS_PER_ARRAY;
	bit_slot = bit % BIT_RADIX_BITS_PER_ARRAY;

	bits = radix_tree_lookup(radix, slot);
	if (!bits)
		return 0;
	clear_bit(bit_slot, bits + 1);

	for (i = 1; i < BIT_ARRAY_BYTES / sizeof(unsigned long); i++) {
		if (bits[i]) {
			empty = 0;
			break;
		}
	}

	if (empty) {
		bits = radix_tree_delete(radix, slot);
		BUG_ON(!bits);
	}
	return 0;
}

int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits,
			 int nr)
{
	unsigned long *bits;
	unsigned long *gang[4];
	int found;
	int ret;
	int i;
	int total_found = 0;

	ret = radix_tree_gang_lookup(radix, (void *)&gang, 0, ARRAY_SIZE(gang));
	for (i = 0; i < ret && nr > 0; i++) {
		found = 0;
		bits = gang[i];
		while(nr > 0) {
			found = find_next_bit(bits + 1,
					      BIT_RADIX_BITS_PER_ARRAY,
					      found);
			if (found < BIT_RADIX_BITS_PER_ARRAY) {
				*retbits = bits[0] *
					BIT_RADIX_BITS_PER_ARRAY + found;
				retbits++;
				nr--;
				total_found++;
				found++;
			} else
				break;
		}
	}
	return total_found;
}

fs/btrfs/bit-radix.h

0 → 100644
+15 −0
Original line number Diff line number Diff line
#ifndef __BIT_RADIX__
#define __BIT_RADIX__
#include <linux/radix-tree.h>

int set_radix_bit(struct radix_tree_root *radix, unsigned long bit);
int test_radix_bit(struct radix_tree_root *radix, unsigned long bit);
int clear_radix_bit(struct radix_tree_root *radix, unsigned long bit);
int find_first_radix_bit(struct radix_tree_root *radix, unsigned long *retbits,
			 int nr);

static inline void init_bit_radix(struct radix_tree_root *radix)
{
	INIT_RADIX_TREE(radix, GFP_NOFS);
}
#endif
+2 −1
Original line number Diff line number Diff line
#ifndef __BTRFS__
#define __BTRFS__

#include <linux/radix-tree.h>
#include <linux/fs.h>
#include "bit-radix.h"

struct btrfs_trans_handle;
struct btrfs_transaction;
@@ -222,6 +222,7 @@ struct btrfs_fs_info {
	struct btrfs_root *inode_root;
	struct btrfs_key current_insert;
	struct btrfs_key last_insert;
	struct radix_tree_root pending_del_radix;
	struct radix_tree_root pinned_radix;
	u64 last_inode_alloc;
	u64 last_inode_alloc_dirid;
+2 −1
Original line number Diff line number Diff line
@@ -104,7 +104,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
	/* FIXME: don't be stupid */
	if (!btrfs_super_root(disk_super))
		return NULL;
	INIT_RADIX_TREE(&fs_info->pinned_radix, GFP_KERNEL);
	init_bit_radix(&fs_info->pinned_radix);
	init_bit_radix(&fs_info->pending_del_radix);
	fs_info->running_transaction = NULL;
	fs_info->fs_root = root;
	fs_info->tree_root = tree_root;
Loading