fs/afs/server.c

Source file repositories/reference/linux-study-clean/fs/afs/server.c

File Facts

System
Linux kernel
Corpus path
fs/afs/server.c
Extension
.c
Size
16501 bytes
Lines
632
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

if (diff < 0) {
			p = p->rb_left;
		} else if (diff > 0) {
			p = p->rb_right;
		} else {
			if (test_bit(AFS_SERVER_FL_UNCREATED, &server->flags))
				return NULL; /* Need a write lock */
			afs_use_server(server, true, afs_server_trace_use_by_uuid);
			return server;
		}
	}

	return NULL;
}

/*
 * Install a server record in the cell tree.  The caller must hold an exclusive
 * lock on cell->fs_lock.
 */
static struct afs_server *afs_install_server(struct afs_cell *cell,
					     struct afs_server **candidate)
{
	struct afs_server *server;
	struct afs_net *net = cell->net;
	struct rb_node **pp, *p;
	int diff;

	_enter("%p", candidate);

	/* Firstly install the server in the UUID lookup tree */
	pp = &cell->fs_servers.rb_node;
	p = NULL;
	while (*pp) {
		p = *pp;
		_debug("- consider %p", p);
		server = rb_entry(p, struct afs_server, uuid_rb);
		diff = memcmp(&(*candidate)->uuid, &server->uuid, sizeof(uuid_t));
		if (diff < 0)
			pp = &(*pp)->rb_left;
		else if (diff > 0)
			pp = &(*pp)->rb_right;
		else
			goto exists;
	}

	server = *candidate;
	*candidate = NULL;
	rb_link_node(&server->uuid_rb, p, pp);
	rb_insert_color(&server->uuid_rb, &cell->fs_servers);
	write_seqlock(&net->fs_lock);
	hlist_add_head_rcu(&server->proc_link, &net->fs_proc);
	write_sequnlock(&net->fs_lock);

	afs_get_cell(cell, afs_cell_trace_get_server);

exists:
	afs_use_server(server, true, afs_server_trace_use_install);
	return server;
}

/*
 * Allocate a new server record and mark it as active but uncreated.
 */
static struct afs_server *afs_alloc_server(struct afs_cell *cell, const uuid_t *uuid)
{
	struct afs_server *server;
	struct afs_net *net = cell->net;

	_enter("");

	server = kzalloc_obj(struct afs_server);
	if (!server)
		return NULL;

	refcount_set(&server->ref, 1);
	atomic_set(&server->active, 0);
	__set_bit(AFS_SERVER_FL_UNCREATED, &server->flags);
	server->debug_id = atomic_inc_return(&afs_server_debug_id);
	server->uuid = *uuid;
	rwlock_init(&server->fs_lock);
	INIT_WORK(&server->destroyer, &afs_server_destroyer);
	timer_setup(&server->timer, afs_server_timer, 0);
	INIT_LIST_HEAD(&server->volumes);
	init_waitqueue_head(&server->probe_wq);
	mutex_init(&server->cm_token_lock);
	INIT_LIST_HEAD(&server->probe_link);
	INIT_HLIST_NODE(&server->proc_link);
	spin_lock_init(&server->probe_lock);
	server->cell = cell;
	server->rtt = UINT_MAX;

Annotation

Implementation Notes