fs/nfs_common/nfslocalio.c

Source file repositories/reference/linux-study-clean/fs/nfs_common/nfslocalio.c

File Facts

System
Linux kernel
Corpus path
fs/nfs_common/nfslocalio.c
Extension
.c
Size
10382 bytes
Lines
374
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration 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 (!rcu_access_pointer(nfs_uuid->net)) {
			/* Not local, remove from nfs_uuids */
			spin_lock(&nfs_uuids_lock);
			list_del_init(&nfs_uuid->list);
			spin_unlock(&nfs_uuids_lock);
		}
		spin_unlock(&nfs_uuid->lock);
        }
}
EXPORT_SYMBOL_GPL(nfs_uuid_end);

static nfs_uuid_t * nfs_uuid_lookup_locked(const uuid_t *uuid)
{
	nfs_uuid_t *nfs_uuid;

	list_for_each_entry(nfs_uuid, &nfs_uuids, list)
		if (uuid_equal(&nfs_uuid->uuid, uuid))
			return nfs_uuid;

	return NULL;
}

static struct module *nfsd_mod;

void nfs_uuid_is_local(const uuid_t *uuid, struct list_head *list,
		       spinlock_t *list_lock, struct net *net,
		       struct auth_domain *dom, struct module *mod)
{
	nfs_uuid_t *nfs_uuid;

	spin_lock(&nfs_uuids_lock);
	nfs_uuid = nfs_uuid_lookup_locked(uuid);
	if (!nfs_uuid) {
		spin_unlock(&nfs_uuids_lock);
		return;
	}

	/*
	 * We don't hold a ref on the net, but instead put
	 * ourselves on @list (nn->local_clients) so the net
	 * pointer can be invalidated.
	 */
	spin_lock(list_lock); /* list_lock is nn->local_clients_lock */
	list_move(&nfs_uuid->list, list);
	spin_unlock(list_lock);

	spin_unlock(&nfs_uuids_lock);
	/* Once nfs_uuid is parented to @list, avoid global nfs_uuids_lock */
	spin_lock(&nfs_uuid->lock);

	__module_get(mod);
	nfsd_mod = mod;

	nfs_uuid->list_lock = list_lock;
	kref_get(&dom->ref);
	nfs_uuid->dom = dom;
	rcu_assign_pointer(nfs_uuid->net, net);
	spin_unlock(&nfs_uuid->lock);
}
EXPORT_SYMBOL_GPL(nfs_uuid_is_local);

void nfs_localio_enable_client(struct nfs_client *clp)
{
	/* nfs_uuid_is_local() does the actual enablement */
	trace_nfs_localio_enable_client(clp);
}
EXPORT_SYMBOL_GPL(nfs_localio_enable_client);

/*
 * Cleanup the nfs_uuid_t embedded in an nfs_client.
 * This is the long-form of nfs_uuid_init().
 */
static bool nfs_uuid_put(nfs_uuid_t *nfs_uuid)
{
	struct nfs_file_localio *nfl;

	spin_lock(&nfs_uuid->lock);
	if (unlikely(!rcu_access_pointer(nfs_uuid->net))) {
		spin_unlock(&nfs_uuid->lock);
		return false;
	}
	RCU_INIT_POINTER(nfs_uuid->net, NULL);

	if (nfs_uuid->dom) {
		auth_domain_put(nfs_uuid->dom);
		nfs_uuid->dom = NULL;
	}

	/* Walk list of files and ensure their last references dropped */

Annotation

Implementation Notes