Skip to content
5 changes: 5 additions & 0 deletions utils/src/bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
* Just a quick simple native bitmap.
*/

int test_bit(unsigned long *bits, u64 nr)
{
return !!(bits[nr / BITS_PER_LONG] & (1UL << (nr & (BITS_PER_LONG - 1))));
}

void set_bit(unsigned long *bits, u64 nr)
{
bits[nr / BITS_PER_LONG] |= 1UL << (nr & (BITS_PER_LONG - 1));
Expand Down
1 change: 1 addition & 0 deletions utils/src/bitmap.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _BITMAP_H_
#define _BITMAP_H_

int test_bit(unsigned long *bits, u64 nr);
void set_bit(unsigned long *bits, u64 nr);
void clear_bit(unsigned long *bits, u64 nr);
u64 find_next_set_bit(unsigned long *start, u64 from, u64 total);
Expand Down
20 changes: 20 additions & 0 deletions utils/src/bloom.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <errno.h>

#include "sparse.h"
#include "util.h"
#include "format.h"
#include "hash.h"
#include "bloom.h"

void calc_bloom_nrs(struct scoutfs_key *key, unsigned int *nrs)
{
u64 hash;
int i;

hash = scoutfs_hash64(key, sizeof(struct scoutfs_key));

for (i = 0; i < SCOUTFS_FOREST_BLOOM_NRS; i++) {
nrs[i] = (u32)hash % SCOUTFS_FOREST_BLOOM_BITS;
hash >>= SCOUTFS_FOREST_BLOOM_FUNC_BITS;
}
}
6 changes: 6 additions & 0 deletions utils/src/bloom.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _BLOOM_H_
#define _BLOOM_H_

void calc_bloom_nrs(struct scoutfs_key *key, unsigned int *nrs);

#endif
4 changes: 2 additions & 2 deletions utils/src/btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "leaf_item_hash.h"
#include "btree.h"

static void init_block(struct scoutfs_btree_block *bt, int level)
void btree_init_block(struct scoutfs_btree_block *bt, int level)
{
int free;

Expand All @@ -33,7 +33,7 @@ void btree_init_root_single(struct scoutfs_btree_root *root,

memset(bt, 0, SCOUTFS_BLOCK_LG_SIZE);

init_block(bt, 0);
btree_init_block(bt, 0);
}

static void *alloc_val(struct scoutfs_btree_block *bt, int len)
Expand Down
1 change: 1 addition & 0 deletions utils/src/btree.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _BTREE_H_
#define _BTREE_H_

void btree_init_block(struct scoutfs_btree_block *bt, int level);
void btree_init_root_single(struct scoutfs_btree_root *root,
struct scoutfs_btree_block *bt,
u64 seq, u64 blkno);
Expand Down
43 changes: 43 additions & 0 deletions utils/src/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@ static inline void list_move_tail(struct list_head *list,
list_add_tail(list, head);
}

/**
* list_is_head - tests whether @list is the list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_head(const struct list_head *list, const struct list_head *head)
{
return list == head;
}

/**
* list_empty - tests whether a list is empty
* @head: the list to test.
Expand Down Expand Up @@ -242,6 +252,15 @@ static inline void list_splice_init(struct list_head *list,
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)

/**
* list_entry_is_head - test if the entry points to the head of the list
* @pos: the type * to cursor
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_entry_is_head(pos, head, member) \
(&pos->member == (head))

/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
Expand Down Expand Up @@ -307,4 +326,28 @@ static inline void list_splice_init(struct list_head *list,
#define list_next_entry(pos, member) \
list_entry((pos)->member.next, typeof(*(pos)), member)

/**
* list_prev_entry - get the prev element in list
* @pos: the type * to cursor
* @member: the name of the list_head within the struct.
*/
#define list_prev_entry(pos, member) \
list_entry((pos)->member.prev, typeof(*(pos)), member)

/**
* list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*
* Iterate backwards over list of given type, safe against removal
* of list entry.
*/
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_last_entry(head, typeof(*pos), member), \
n = list_prev_entry(pos, member); \
!list_entry_is_head(pos, head, member); \
pos = n, n = list_prev_entry(n, member))

#endif
24 changes: 24 additions & 0 deletions utils/src/lk_rbtree_wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef _LK_RBTREE_WRAPPER_H_
#define _LK_RBTREE_WRAPPER_H_

/*
* We're using this lame hack to build and use the kernel's rbtree in
* userspace. We drop the kernel's rbtree*[ch] implementation in and
* use them with this wrapper. We only have to remove the kernel
* includes from the imported files.
*/

#include <stdbool.h>
#include "util.h"

#define rcu_assign_pointer(a, b) do { a = b; } while (0)
#define READ_ONCE(a) ({ a; })
#define WRITE_ONCE(a, b) do { a = b; } while (0)
#define unlikely(a) ({ a; })
#define EXPORT_SYMBOL(a) /* nop */

#include "rbtree_types.h"
#include "rbtree.h"
#include "rbtree_augmented.h"

#endif
24 changes: 24 additions & 0 deletions utils/src/mode_types.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <unistd.h>
#include <sys/stat.h>

#include "sparse.h"
#include "util.h"
#include "format.h"
#include "mode_types.h"

unsigned int mode_to_type(mode_t mode)
{
#define S_SHIFT 12
static unsigned char mode_types[S_IFMT >> S_SHIFT] = {
[S_IFIFO >> S_SHIFT] = SCOUTFS_DT_FIFO,
[S_IFCHR >> S_SHIFT] = SCOUTFS_DT_CHR,
[S_IFDIR >> S_SHIFT] = SCOUTFS_DT_DIR,
[S_IFBLK >> S_SHIFT] = SCOUTFS_DT_BLK,
[S_IFREG >> S_SHIFT] = SCOUTFS_DT_REG,
[S_IFLNK >> S_SHIFT] = SCOUTFS_DT_LNK,
[S_IFSOCK >> S_SHIFT] = SCOUTFS_DT_SOCK,
};

return mode_types[(mode & S_IFMT) >> S_SHIFT];
#undef S_SHIFT
}
6 changes: 6 additions & 0 deletions utils/src/mode_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _MODE_TYPES_H_
#define _MODE_TYPES_H_

unsigned int mode_to_type(mode_t mode);

#endif
46 changes: 46 additions & 0 deletions utils/src/name_hash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef _SCOUTFS_NAME_HASH_H_
#define _SCOUTFS_NAME_HASH_H_

#include "hash.h"

/*
* Test a bit number as though an array of bytes is a large len-bit
* big-endian value. nr 0 is the LSB of the final byte, nr (len - 1) is
* the MSB of the first byte.
*/
static int test_be_bytes_bit(int nr, const char *bytes, int len)
{
return bytes[(len - 1 - nr) >> 3] & (1 << (nr & 7));
}

/*
* Generate a 32bit "fingerprint" of the name by extracting 32 evenly
* distributed bits from the name. The intent is to have the sort order
* of the fingerprints reflect the memcmp() sort order of the names
* while mapping large names down to small fs keys.
*
* Names that are smaller than 32bits are biased towards the high bits
* of the fingerprint so that most significant bits of the fingerprints
* consistently reflect the initial characters of the names.
*/
static inline u32 dirent_name_fingerprint(const char *name, unsigned int name_len)
{
int name_bits = name_len * 8;
int skip = max(name_bits / 32, 1);
u32 fp = 0;
int f;
int n;

for (f = 31, n = name_bits - 1; f >= 0 && n >= 0; f--, n -= skip)
fp |= !!test_be_bytes_bit(n, name, name_bits) << f;

return fp;
}

static inline u64 dirent_name_hash(const char *name, unsigned int name_len)
{
return scoutfs_hash32(name, name_len) |
((u64)dirent_name_fingerprint(name, name_len) << 32);
}

#endif
48 changes: 30 additions & 18 deletions utils/src/print.c
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,8 @@ static int print_alloc_list_block(int fd, char *str, struct scoutfs_block_ref *r
u64 blkno;
u64 start;
u64 len;
u64 st;
u64 nr;
int wid;
int ret;
int i;
Expand All @@ -663,27 +665,37 @@ static int print_alloc_list_block(int fd, char *str, struct scoutfs_block_ref *r
AL_REF_A(&lblk->next), le32_to_cpu(lblk->start),
le32_to_cpu(lblk->nr));

if (lblk->nr) {
wid = printf(" exts: ");
start = 0;
len = 0;
for (i = 0; i < le32_to_cpu(lblk->nr); i++) {
if (len == 0)
start = le64_to_cpu(lblk->blknos[i]);
len++;

if (i == (le32_to_cpu(lblk->nr) - 1) ||
start + len != le64_to_cpu(lblk->blknos[i + 1])) {
if (wid >= 72)
wid = printf("\n ");

wid += printf("%llu,%llu ", start, len);
len = 0;
}
st = le32_to_cpu(lblk->start);
nr = le32_to_cpu(lblk->nr);
if (st >= SCOUTFS_ALLOC_LIST_MAX_BLOCKS ||
nr > SCOUTFS_ALLOC_LIST_MAX_BLOCKS ||
(st + nr) > SCOUTFS_ALLOC_LIST_MAX_BLOCKS) {
printf(" (invalid start and nr fields)\n");
goto out;
}

if (lblk->nr == 0)
goto out;

wid = printf(" exts: ");
start = 0;
len = 0;
for (i = 0; i < nr; i++) {
if (len == 0)
start = le64_to_cpu(lblk->blknos[st + i]);
len++;

if (i == (nr - 1) || (start + len) != le64_to_cpu(lblk->blknos[st + i + 1])) {
if (wid >= 72)
wid = printf("\n ");

wid += printf("%llu,%llu ", start, len);
len = 0;
}
printf("\n");
}
printf("\n");

out:
next = lblk->next;
free(lblk);
return print_alloc_list_block(fd, str, &next);
Expand Down
Loading