fs/nfs/client.c

Source file repositories/reference/linux-study-clean/fs/nfs/client.c

File Facts

System
Linux kernel
Corpus path
fs/nfs/client.c
Extension
.c
Size
40532 bytes
Lines
1541
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 (clp->cl_cons_state > NFS_CS_READY) {
			refcount_inc(&clp->cl_count);
			spin_unlock(&nn->nfs_client_lock);
			error = nfs_wait_client_init_complete(clp);
			nfs_put_client(clp);
			spin_lock(&nn->nfs_client_lock);
			if (error < 0)
				return ERR_PTR(error);
			goto again;
		}

		/* Different NFS versions cannot share the same nfs_client */
		if (clp->rpc_ops != data->nfs_mod->rpc_ops)
			continue;

		if (clp->cl_proto != data->proto)
			continue;
		/* Match nfsv4 minorversion */
		if (clp->cl_minorversion != data->minorversion)
			continue;

		/* Match request for a dedicated DS */
		if (test_bit(NFS_CS_DS, &data->init_flags) !=
		    test_bit(NFS_CS_DS, &clp->cl_flags))
			continue;

		/* Match the full socket address */
		if (!rpc_cmp_addr_port(sap, clap))
			/* Match all xprt_switch full socket addresses */
			if (IS_ERR(clp->cl_rpcclient) ||
                            !rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient,
							   sap))
				continue;

		/* Match the xprt security policy */
		if (clp->cl_xprtsec.policy != data->xprtsec.policy)
			continue;
		if (clp->cl_xprtsec.policy == RPC_XPRTSEC_TLS_X509) {
			if (clp->cl_xprtsec.cert_serial !=
			    data->xprtsec.cert_serial)
				continue;
			if (clp->cl_xprtsec.privkey_serial !=
			    data->xprtsec.privkey_serial)
				continue;
		}

		refcount_inc(&clp->cl_count);
		return clp;
	}
	return NULL;
}

/*
 * Return true if @clp is done initializing, false if still working on it.
 *
 * Use nfs_client_init_status to check if it was successful.
 */
bool nfs_client_init_is_complete(const struct nfs_client *clp)
{
	return clp->cl_cons_state <= NFS_CS_READY;
}
EXPORT_SYMBOL_GPL(nfs_client_init_is_complete);

/*
 * Return 0 if @clp was successfully initialized, -errno otherwise.
 *
 * This must be called *after* nfs_client_init_is_complete() returns true,
 * otherwise it will pop WARN_ON_ONCE and return -EINVAL
 */
int nfs_client_init_status(const struct nfs_client *clp)
{
	/* called without checking nfs_client_init_is_complete */
	if (clp->cl_cons_state > NFS_CS_READY) {
		WARN_ON_ONCE(1);
		return -EINVAL;
	}
	return clp->cl_cons_state;
}
EXPORT_SYMBOL_GPL(nfs_client_init_status);

int nfs_wait_client_init_complete(const struct nfs_client *clp)
{
	return wait_event_killable(nfs_client_active_wq,
			nfs_client_init_is_complete(clp));
}
EXPORT_SYMBOL_GPL(nfs_wait_client_init_complete);

/*
 * Found an existing client.  Make sure it's ready before returning.
 */

Annotation

Implementation Notes