fs/ntfs3/bitmap.c

Source file repositories/reference/linux-study-clean/fs/ntfs3/bitmap.c

File Facts

System
Linux kernel
Corpus path
fs/ntfs3/bitmap.c
Extension
.c
Size
33314 bytes
Lines
1565
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rb_node_key {
	struct rb_node node;
	size_t key;
};

struct e_node {
	struct rb_node_key start; /* Tree sorted by start. */
	struct rb_node_key count; /* Tree sorted by len. */
};

static int wnd_rescan(struct wnd_bitmap *wnd);
static struct buffer_head *wnd_map(struct wnd_bitmap *wnd, size_t iw);
static bool wnd_is_free_hlp(struct wnd_bitmap *wnd, size_t bit, size_t bits);

static struct kmem_cache *ntfs_enode_cachep;

int __init ntfs3_init_bitmap(void)
{
	ntfs_enode_cachep = kmem_cache_create("ntfs3_enode_cache",
					      sizeof(struct e_node), 0,
					      SLAB_RECLAIM_ACCOUNT, NULL);
	return ntfs_enode_cachep ? 0 : -ENOMEM;
}

void ntfs3_exit_bitmap(void)
{
	kmem_cache_destroy(ntfs_enode_cachep);
}

/*
 * wnd_scan
 *
 * b_pos + b_len - biggest fragment.
 * Scan range [wpos wbits) window @buf.
 *
 * Return: -1 if not found.
 */
static size_t wnd_scan(const void *buf, size_t wbit, u32 wpos, u32 wend,
		       size_t to_alloc, size_t *prev_tail, size_t *b_pos,
		       size_t *b_len)
{
	while (wpos < wend) {
		size_t free_len;
		u32 free_bits, end;
		u32 used = find_next_zero_bit_le(buf, wend, wpos);

		if (used >= wend) {
			if (*b_len < *prev_tail) {
				*b_pos = wbit - *prev_tail;
				*b_len = *prev_tail;
			}

			*prev_tail = 0;
			return -1;
		}

		if (used > wpos) {
			wpos = used;
			if (*b_len < *prev_tail) {
				*b_pos = wbit - *prev_tail;
				*b_len = *prev_tail;
			}

			*prev_tail = 0;
		}

		/*
		 * Now we have a fragment [wpos, wend) staring with 0.
		 */
		end = wpos + to_alloc - *prev_tail;
		free_bits = find_next_bit_le(buf, min(end, wend), wpos);

		free_len = *prev_tail + free_bits - wpos;

		if (*b_len < free_len) {
			*b_pos = wbit + wpos - *prev_tail;
			*b_len = free_len;
		}

		if (free_len >= to_alloc)
			return wbit + wpos - *prev_tail;

		if (free_bits >= wend) {
			*prev_tail += free_bits - wpos;
			return -1;
		}

		wpos = free_bits + 1;

		*prev_tail = 0;

Annotation

Implementation Notes