fs/orangefs/orangefs-bufmap.c

Source file repositories/reference/linux-study-clean/fs/orangefs/orangefs-bufmap.c

File Facts

System
Linux kernel
Corpus path
fs/orangefs/orangefs-bufmap.c
Extension
.c
Size
20022 bytes
Lines
837
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 slot_map {
	int c;
	wait_queue_head_t q;
	int count;
	unsigned long *map;
};

static struct slot_map rw_map = {
	.c = -1,
	.q = __WAIT_QUEUE_HEAD_INITIALIZER(rw_map.q)
};
static struct slot_map readdir_map = {
	.c = -1,
	.q = __WAIT_QUEUE_HEAD_INITIALIZER(readdir_map.q)
};


static void install(struct slot_map *m, int count, unsigned long *map)
{
	spin_lock(&m->q.lock);
	m->c = m->count = count;
	m->map = map;
	wake_up_all_locked(&m->q);
	spin_unlock(&m->q.lock);
}

static void mark_killed(struct slot_map *m)
{
	spin_lock(&m->q.lock);
	m->c -= m->count + 1;
	spin_unlock(&m->q.lock);
}

static void run_down(struct slot_map *m)
{
	DEFINE_WAIT(wait);
	spin_lock(&m->q.lock);
	if (m->c != -1) {
		for (;;) {
			if (likely(list_empty(&wait.entry)))
				__add_wait_queue_entry_tail(&m->q, &wait);
			set_current_state(TASK_UNINTERRUPTIBLE);

			if (m->c == -1)
				break;

			spin_unlock(&m->q.lock);
			schedule();
			spin_lock(&m->q.lock);
		}
		__remove_wait_queue(&m->q, &wait);
		__set_current_state(TASK_RUNNING);
	}
	m->map = NULL;
	spin_unlock(&m->q.lock);
}

static void put(struct slot_map *m, int slot)
{
	int v;
	spin_lock(&m->q.lock);
	__clear_bit(slot, m->map);
	v = ++m->c;
	if (v > 0)
		wake_up_locked(&m->q);
	if (unlikely(v == -1))     /* finished dying */
		wake_up_all_locked(&m->q);
	spin_unlock(&m->q.lock);
}

static int wait_for_free(struct slot_map *m)
{
	long left = slot_timeout_secs * HZ;
	DEFINE_WAIT(wait);

	do {
		long n = left, t;
		if (likely(list_empty(&wait.entry)))
			__add_wait_queue_entry_tail_exclusive(&m->q, &wait);
		set_current_state(TASK_INTERRUPTIBLE);

		if (m->c > 0)
			break;

		if (m->c < 0) {
			/* we are waiting for map to be installed */
			/* it would better be there soon, or we go away */
			if (n > ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS * HZ)
				n = ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS * HZ;
		}

Annotation

Implementation Notes