Release 4.11 fs/nfs/client.c
/* client.c: NFS client sharing and management code
*
* Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/sunrpc/addr.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/metrics.h>
#include <linux/sunrpc/xprtsock.h>
#include <linux/sunrpc/xprtrdma.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include <linux/nfs4_mount.h>
#include <linux/lockd/bind.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/vfs.h>
#include <linux/inet.h>
#include <linux/in6.h>
#include <linux/slab.h>
#include <linux/idr.h>
#include <net/ipv6.h>
#include <linux/nfs_xdr.h>
#include <linux/sunrpc/bc_xprt.h>
#include <linux/nsproxy.h>
#include <linux/pid_namespace.h>
#include "nfs4_fs.h"
#include "callback.h"
#include "delegation.h"
#include "iostat.h"
#include "internal.h"
#include "fscache.h"
#include "pnfs.h"
#include "nfs.h"
#include "netns.h"
#define NFSDBG_FACILITY NFSDBG_CLIENT
static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
static DEFINE_SPINLOCK(nfs_version_lock);
static DEFINE_MUTEX(nfs_version_mutex);
static LIST_HEAD(nfs_versions);
/*
* RPC cruft for NFS
*/
static const struct rpc_version *nfs_version[5] = {
[2] = NULL,
[3] = NULL,
[4] = NULL,
};
const struct rpc_program nfs_program = {
.name = "nfs",
.number = NFS_PROGRAM,
.nrvers = ARRAY_SIZE(nfs_version),
.version = nfs_version,
.stats = &nfs_rpcstat,
.pipe_dir_name = NFS_PIPE_DIRNAME,
};
struct rpc_stat nfs_rpcstat = {
.program = &nfs_program
};
static struct nfs_subversion *find_nfs_version(unsigned int version)
{
struct nfs_subversion *nfs;
spin_lock(&nfs_version_lock);
list_for_each_entry(nfs, &nfs_versions, list) {
if (nfs->rpc_ops->version == version) {
spin_unlock(&nfs_version_lock);
return nfs;
}
}
spin_unlock(&nfs_version_lock);
return ERR_PTR(-EPROTONOSUPPORT);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Bryan Schumaker | 67 | 100.00% | 1 | 100.00% |
Total | 67 | 100.00% | 1 | 100.00% |
struct nfs_subversion *get_nfs_version(unsigned int version)
{
struct nfs_subversion *nfs = find_nfs_version(version);
if (IS_ERR(nfs)) {
mutex_lock(&nfs_version_mutex);
request_module("nfsv%d", version);
nfs = find_nfs_version(version);
mutex_unlock(&nfs_version_mutex);
}
if (!IS_ERR(nfs) && !try_module_get(nfs->owner))
return ERR_PTR(-EAGAIN);
return nfs;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Bryan Schumaker | 72 | 87.80% | 2 | 66.67% |
Alexey Khoroshilov | 10 | 12.20% | 1 | 33.33% |
Total | 82 | 100.00% | 3 | 100.00% |
void put_nfs_version(struct nfs_subversion *nfs)
{
module_put(nfs->owner);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Bryan Schumaker | 17 | 100.00% | 1 | 100.00% |
Total | 17 | 100.00% | 1 | 100.00% |
void register_nfs_version(struct nfs_subversion *nfs)
{
spin_lock(&nfs_version_lock);
list_add(&nfs->list, &nfs_versions);
nfs_version[nfs->rpc_ops->version] = nfs->rpc_vers;
spin_unlock(&nfs_version_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Bryan Schumaker | 46 | 100.00% | 1 | 100.00% |
Total | 46 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(register_nfs_version);
void unregister_nfs_version(struct nfs_subversion *nfs)
{
spin_lock(&nfs_version_lock);
nfs_version[nfs->rpc_ops->version] = NULL;
list_del(&nfs->list);
spin_unlock(&nfs_version_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Bryan Schumaker | 41 | 100.00% | 1 | 100.00% |
Total | 41 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(unregister_nfs_version);
/*
* Allocate a shared client record
*
* Since these are allocated/deallocated very rarely, we don't
* bother putting them in a slab cache...
*/
struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
{
struct nfs_client *clp;
struct rpc_cred *cred;
int err = -ENOMEM;
if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
goto error_0;
clp->cl_nfs_mod = cl_init->nfs_mod;
if (!try_module_get(clp->cl_nfs_mod->owner))
goto error_dealloc;
clp->rpc_ops = clp->cl_nfs_mod->rpc_ops;
atomic_set(&clp->cl_count, 1);
clp->cl_cons_state = NFS_CS_INITING;
memcpy(&clp->cl_addr, cl_init->addr, cl_init->addrlen);
clp->cl_addrlen = cl_init->addrlen;
if (cl_init->hostname) {
err = -ENOMEM;
clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL);
if (!clp->cl_hostname)
goto error_cleanup;
}
INIT_LIST_HEAD(&clp->cl_superblocks);
clp->cl_rpcclient = ERR_PTR(-EINVAL);
clp->cl_proto = cl_init->proto;
clp->cl_net = get_net(cl_init->net);
cred = rpc_lookup_machine_cred("*");
if (!IS_ERR(cred))
clp->cl_machine_cred = cred;
nfs_fscache_get_client_cookie(clp);
return clp;
error_cleanup:
put_nfs_version(clp->cl_nfs_mod);
error_dealloc:
kfree(clp);
error_0:
return ERR_PTR(err);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 128 | 51.20% | 2 | 13.33% |
Trond Myklebust | 52 | 20.80% | 6 | 40.00% |
Chuck Lever | 26 | 10.40% | 3 | 20.00% |
Bryan Schumaker | 26 | 10.40% | 1 | 6.67% |
Alexey Khoroshilov | 9 | 3.60% | 1 | 6.67% |
Stanislav Kinsbursky | 7 | 2.80% | 1 | 6.67% |
Benny Halevy | 2 | 0.80% | 1 | 6.67% |
Total | 250 | 100.00% | 15 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_alloc_client);
#if IS_ENABLED(CONFIG_NFS_V4)
void nfs_cleanup_cb_ident_idr(struct net *net)
{
struct nfs_net *nn = net_generic(net, nfs_net_id);
idr_destroy(&nn->cb_ident_idr);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Stanislav Kinsbursky | 18 | 60.00% | 1 | 50.00% |
Andy Adamson | 12 | 40.00% | 1 | 50.00% |
Total | 30 | 100.00% | 2 | 100.00% |
/* nfs_client_lock held */
static void nfs_cb_idr_remove_locked(struct nfs_client *clp)
{
struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
if (clp->cl_cb_ident)
idr_remove(&nn->cb_ident_idr, clp->cl_cb_ident);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andy Adamson | 27 | 62.79% | 1 | 33.33% |
Stanislav Kinsbursky | 15 | 34.88% | 1 | 33.33% |
Chuck Lever | 1 | 2.33% | 1 | 33.33% |
Total | 43 | 100.00% | 3 | 100.00% |
static void pnfs_init_server(struct nfs_server *server)
{
rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Fred Isaman | 21 | 100.00% | 1 | 100.00% |
Total | 21 | 100.00% | 1 | 100.00% |
#else
void nfs_cleanup_cb_ident_idr(struct net *net)
{
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andy Adamson | 5 | 55.56% | 1 | 50.00% |
Stanislav Kinsbursky | 4 | 44.44% | 1 | 50.00% |
Total | 9 | 100.00% | 2 | 100.00% |
static void nfs_cb_idr_remove_locked(struct nfs_client *clp)
{
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andy Adamson | 10 | 100.00% | 1 | 100.00% |
Total | 10 | 100.00% | 1 | 100.00% |
static void pnfs_init_server(struct nfs_server *server)
{
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Fred Isaman | 10 | 100.00% | 1 | 100.00% |
Total | 10 | 100.00% | 1 | 100.00% |
#endif /* CONFIG_NFS_V4 */
/*
* Destroy a shared client record
*/
void nfs_free_client(struct nfs_client *clp)
{
dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version);
nfs_fscache_release_client_cookie(clp);
/* -EIO all pending I/O */
if (!IS_ERR(clp->cl_rpcclient))
rpc_shutdown_client(clp->cl_rpcclient);
if (clp->cl_machine_cred != NULL)
put_rpccred(clp->cl_machine_cred);
put_net(clp->cl_net);
put_nfs_version(clp->cl_nfs_mod);
kfree(clp->cl_hostname);
kfree(clp->cl_acceptor);
kfree(clp);
dprintk("<-- nfs_free_client()\n");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 39 | 40.21% | 2 | 18.18% |
Trond Myklebust | 37 | 38.14% | 4 | 36.36% |
Jeff Layton | 7 | 7.22% | 1 | 9.09% |
Bryan Schumaker | 7 | 7.22% | 1 | 9.09% |
Benny Halevy | 4 | 4.12% | 1 | 9.09% |
Weston Andros Adamson | 2 | 2.06% | 1 | 9.09% |
Chuck Lever | 1 | 1.03% | 1 | 9.09% |
Total | 97 | 100.00% | 11 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_free_client);
/*
* Release a reference to a shared client record
*/
void nfs_put_client(struct nfs_client *clp)
{
struct nfs_net *nn;
if (!clp)
return;
dprintk("--> nfs_put_client({%d})\n", atomic_read(&clp->cl_count));
nn = net_generic(clp->cl_net, nfs_net_id);
if (atomic_dec_and_lock(&clp->cl_count, &nn->nfs_client_lock)) {
list_del(&clp->cl_share_link);
nfs_cb_idr_remove_locked(clp);
spin_unlock(&nn->nfs_client_lock);
WARN_ON_ONCE(!list_empty(&clp->cl_superblocks));
clp->rpc_ops->free_client(clp);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 73 | 70.19% | 2 | 28.57% |
Stanislav Kinsbursky | 19 | 18.27% | 1 | 14.29% |
Andy Adamson | 5 | 4.81% | 1 | 14.29% |
Bryan Schumaker | 5 | 4.81% | 1 | 14.29% |
Chuck Lever | 1 | 0.96% | 1 | 14.29% |
Trond Myklebust | 1 | 0.96% | 1 | 14.29% |
Total | 104 | 100.00% | 7 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_put_client);
/*
* Find an nfs_client on the list that matches the initialisation data
* that is supplied.
*/
static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data)
{
struct nfs_client *clp;
const struct sockaddr *sap = data->addr;
struct nfs_net *nn = net_generic(data->net, nfs_net_id);
list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
/* Don't match clients that failed to initialise properly */
if (clp->cl_cons_state < 0)
continue;
/* 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 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;
atomic_inc(&clp->cl_count);
return clp;
}
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Trond Myklebust | 60 | 37.04% | 4 | 33.33% |
Ian Dall | 29 | 17.90% | 1 | 8.33% |
David Howells | 23 | 14.20% | 1 | 8.33% |
Stanislav Kinsbursky | 15 | 9.26% | 1 | 8.33% |
Andy Adamson | 13 | 8.02% | 1 | 8.33% |
Benny Halevy | 12 | 7.41% | 1 | 8.33% |
Petr Vandrovec | 7 | 4.32% | 1 | 8.33% |
Bryan Schumaker | 2 | 1.23% | 1 | 8.33% |
Anna Schumaker | 1 | 0.62% | 1 | 8.33% |
Total | 162 | 100.00% | 12 | 100.00% |
/*
* 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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Trond Myklebust | 18 | 100.00% | 2 | 100.00% |
Total | 18 | 100.00% | 2 | 100.00% |
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;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Weston Andros Adamson | 36 | 100.00% | 1 | 100.00% |
Total | 36 | 100.00% | 1 | 100.00% |
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));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Trond Myklebust | 22 | 100.00% | 1 | 100.00% |
Total | 22 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_wait_client_init_complete);
/*
* Found an existing client. Make sure it's ready before returning.
*/
static struct nfs_client *
nfs_found_client(const struct nfs_client_initdata *cl_init,
struct nfs_client *clp)
{
int error;
error = nfs_wait_client_init_complete(clp);
if (error < 0) {
nfs_put_client(clp);
return ERR_PTR(-ERESTARTSYS);
}
if (clp->cl_cons_state < NFS_CS_READY) {
error = clp->cl_cons_state;
nfs_put_client(clp);
return ERR_PTR(error);
}
smp_rmb();
dprintk("<-- %s found nfs_client %p for %s\n",
__func__, clp, cl_init->hostname ?: "");
return clp;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Chuck Lever | 94 | 95.92% | 1 | 33.33% |
Trond Myklebust | 4 | 4.08% | 2 | 66.67% |
Total | 98 | 100.00% | 3 | 100.00% |
/*
* Look up a client by IP address and protocol version
* - creates a new record if one doesn't yet exist
*/
struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
{
struct nfs_client *clp, *new = NULL;
struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id);
const struct nfs_rpc_ops *rpc_ops = cl_init->nfs_mod->rpc_ops;
if (cl_init->hostname == NULL) {
WARN_ON(1);
return NULL;
}
dprintk("--> nfs_get_client(%s,v%u)\n",
cl_init->hostname, rpc_ops->version);
/* see if the client already exists */
do {
spin_lock(&nn->nfs_client_lock);
clp = nfs_match_client(cl_init);
if (clp) {
spin_unlock(&nn->nfs_client_lock);
if (new)
new->rpc_ops->free_client(new);
return nfs_found_client(cl_init, clp);
}
if (new) {
list_add_tail(&new->cl_share_link,
&nn->nfs_client_list);
spin_unlock(&nn->nfs_client_lock);
new->cl_flags = cl_init->init_flags;
return rpc_ops->init_client(new, cl_init);
}
spin_unlock(&nn->nfs_client_lock);
new = rpc_ops->alloc_client(cl_init);
} while (!IS_ERR(new));
dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n",
cl_init->hostname, PTR_ERR(new));
return new;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 72 | 32.43% | 1 | 5.88% |
Chuck Lever | 70 | 31.53% | 5 | 29.41% |
Bryan Schumaker | 20 | 9.01% | 3 | 17.65% |
Stanislav Kinsbursky | 20 | 9.01% | 2 | 11.76% |
Peng Tao | 18 | 8.11% | 1 | 5.88% |
Andy Adamson | 12 | 5.41% | 1 | 5.88% |
Trond Myklebust | 10 | 4.50% | 4 | 23.53% |
Total | 222 | 100.00% | 17 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_get_client);
/*
* Mark a server as ready or failed
*/
void nfs_mark_client_ready(struct nfs_client *clp, int state)
{
smp_wmb();
clp->cl_cons_state = state;
wake_up_all(&nfs_client_active_wq);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 25 | 89.29% | 1 | 50.00% |
Trond Myklebust | 3 | 10.71% | 1 | 50.00% |
Total | 28 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_mark_client_ready);
/*
* Initialise the timeout values for a connection
*/
void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
int timeo, int retrans)
{
to->to_initval = timeo * HZ / 10;
to->to_retries = retrans;
switch (proto) {
case XPRT_TRANSPORT_TCP:
case XPRT_TRANSPORT_RDMA:
if (retrans == NFS_UNSPEC_RETRANS)
to->to_retries = NFS_DEF_TCP_RETRANS;
if (timeo == NFS_UNSPEC_TIMEO || to->to_retries == 0)
to->to_initval = NFS_DEF_TCP_TIMEO * HZ / 10;
if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
to->to_initval = NFS_MAX_TCP_TIMEOUT;
to->to_increment = to->to_initval;
to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
if (to->to_maxval > NFS_MAX_TCP_TIMEOUT)
to->to_maxval = NFS_MAX_TCP_TIMEOUT;
if (to->to_maxval < to->to_initval)
to->to_maxval = to->to_initval;
to->to_exponential = 0;
break;
case XPRT_TRANSPORT_UDP:
if (retrans == NFS_UNSPEC_RETRANS)
to->to_retries = NFS_DEF_UDP_RETRANS;
if (timeo == NFS_UNSPEC_TIMEO || to->to_initval == 0)
to->to_initval = NFS_DEF_UDP_TIMEO * HZ / 10;
if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
to->to_initval = NFS_MAX_UDP_TIMEOUT;
to->to_maxval = NFS_MAX_UDP_TIMEOUT;
to->to_exponential = 1;
break;
default:
BUG();
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 144 | 63.16% | 1 | 16.67% |
Trond Myklebust | 79 | 34.65% | 3 | 50.00% |
Talpey, Thomas | 5 | 2.19% | 2 | 33.33% |
Total | 228 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_init_timeout_values);
/*
* Create an RPC client handle
*/
int nfs_create_rpc_client(struct nfs_client *clp,
const struct nfs_client_initdata *cl_init,
rpc_authflavor_t flavor)
{
struct rpc_clnt *clnt = NULL;
struct rpc_create_args args = {
.net = clp->cl_net,
.protocol = clp->cl_proto,
.address = (struct sockaddr *)&clp->cl_addr,
.addrsize = clp->cl_addrlen,
.timeout = cl_init->timeparms,
.servername = clp->cl_hostname,
.nodename = cl_init->nodename,
.program = &nfs_program,
.version = clp->rpc_ops->version,
.authflavor = flavor,
};
if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
args.flags |= RPC_CLNT_CREATE_DISCRTRY;
if (test_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags))
args.flags |= RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT;
if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags))
args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags))
args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS;
if (!IS_ERR(clp->cl_rpcclient))
return 0;
clnt = rpc_create(&args);
if (IS_ERR(clnt)) {
dprintk("%s: cannot create RPC client. Error = %ld\n",
__func__, PTR_ERR(clnt));
return PTR_ERR(clnt);
}
clp->cl_rpcclient = clnt;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Chuck Lever | 101 | 42.80% | 6 | 40.00% |
David Howells | 75 | 31.78% | 1 | 6.67% |
Trond Myklebust | 53 | 22.46% | 5 | 33.33% |
Pavel Emelyanov | 4 | 1.69% | 1 | 6.67% |
Stanislav Kinsbursky | 2 | 0.85% | 1 | 6.67% |
Harvey Harrison | 1 | 0.42% | 1 | 6.67% |
Total | 236 | 100.00% | 15 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_create_rpc_client);
/*
* Version 2 or 3 client destruction
*/
static void nfs_destroy_server(struct nfs_server *server)
{
if (server->nlm_host)
nlmclnt_done(server->nlm_host);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 15 | 62.50% | 1 | 25.00% |
Chuck Lever | 6 | 25.00% | 1 | 25.00% |
Suresh Jayaraman | 2 | 8.33% | 1 | 25.00% |
Neil Brown | 1 | 4.17% | 1 | 25.00% |
Total | 24 | 100.00% | 4 | 100.00% |
/*
* Version 2 or 3 lockd setup
*/
static int nfs_start_lockd(struct nfs_server *server)
{
struct nlm_host *host;
struct nfs_client *clp = server->nfs_client;
struct nlmclnt_initdata nlm_init = {
.hostname = clp->cl_hostname,
.address = (struct sockaddr *)&clp->cl_addr,
.addrlen = clp->cl_addrlen,
.nfs_version = clp->rpc_ops->version,
.noresvport = server->flags & NFS_MOUNT_NORESVPORT ?
1 : 0,
.net = clp->cl_net,
};
if (nlm_init.nfs_version > 3)
return 0;
if ((server->flags & NFS_MOUNT_LOCAL_FLOCK) &&
(server->flags & NFS_MOUNT_LOCAL_FCNTL))
return 0;
switch (clp->cl_proto) {
default:
nlm_init.protocol = IPPROTO_TCP;
break;
case XPRT_TRANSPORT_UDP:
nlm_init.protocol = IPPROTO_UDP;
}
host = nlmclnt_init(&nlm_init);
if (IS_ERR(host))
return PTR_ERR(host);
server->nlm_host = host;
server->destroy = nfs_destroy_server;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Chuck Lever | 93 | 51.67% | 4 | 40.00% |
David Howells | 42 | 23.33% | 1 | 10.00% |
Trond Myklebust | 26 | 14.44% | 2 | 20.00% |
Suresh Jayaraman | 11 | 6.11% | 1 | 10.00% |
Stanislav Kinsbursky | 6 | 3.33% | 1 | 10.00% |
Neil Brown | 2 | 1.11% | 1 | 10.00% |
Total | 180 | 100.00% | 10 | 100.00% |
/*
* Create a general RPC client
*/
int nfs_init_server_rpcclient(struct nfs_server *server,
const struct rpc_timeout *timeo,
rpc_authflavor_t pseudoflavour)
{
struct nfs_client *clp = server->nfs_client;
server->client = rpc_clone_client_set_auth(clp->cl_rpcclient,
pseudoflavour);
if (IS_ERR(server->client)) {
dprintk("%s: couldn't create rpc_client!\n", __func__);
return PTR_ERR(server->client);
}
memcpy(&server->client->cl_timeout_default,
timeo,
sizeof(server->client->cl_timeout_default));
server->client->cl_timeout = &server->client->cl_timeout_default;
server->client->cl_softrtry = 0;
if (server->flags & NFS_MOUNT_SOFT)
server->client->cl_softrtry = 1;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 84 | 65.62% | 1 | 25.00% |
Trond Myklebust | 40 | 31.25% | 1 | 25.00% |
Chuck Lever | 3 | 2.34% | 1 | 25.00% |
Harvey Harrison | 1 | 0.78% | 1 | 25.00% |
Total | 128 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
/**
* nfs_init_client - Initialise an NFS2 or NFS3 client
*
* @clp: nfs_client to initialise
* @cl_init: Initialisation parameters
*
* Returns pointer to an NFS client, or an ERR_PTR value.
*/
struct nfs_client *nfs_init_client(struct nfs_client *clp,
const struct nfs_client_initdata *cl_init)
{
int error;
if (clp->cl_cons_state == NFS_CS_READY) {
/* the client is already initialised */
dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp);
return clp;
}
/*
* Create a client RPC handle for doing FSSTAT with UNIX auth only
* - RFC 2623, sec 2.3.2
*/
error = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_UNIX);
if (error < 0)
goto error;
nfs_mark_client_ready(clp, NFS_CS_READY);
return clp;
error:
nfs_mark_client_ready(clp, error);
nfs_put_client(clp);
dprintk("<-- nfs_init_client() = xerror %d\n", error);
return ERR_PTR(error);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 84 | 84.00% | 1 | 33.33% |
Chuck Lever | 13 | 13.00% | 1 | 33.33% |
Trond Myklebust | 3 | 3.00% | 1 | 33.33% |
Total | 100 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_init_client);
/*
* Create a version 2 or 3 client
*/
static int nfs_init_server(struct nfs_server *server,
const struct nfs_parsed_mount_data *data,
struct nfs_subversion *nfs_mod)
{
struct rpc_timeout timeparms;
struct nfs_client_initdata cl_init = {
.hostname = data->nfs_server.hostname,
.addr = (const struct sockaddr *)&data->nfs_server.address,
.addrlen = data->nfs_server.addrlen,
.nfs_mod = nfs_mod,
.proto = data->nfs_server.protocol,
.net = data->net,
.timeparms = &timeparms,
};
struct nfs_client *clp;
int error;
dprintk("--> nfs_init_server()\n");
nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
data->timeo, data->retrans);
if (data->flags & NFS_MOUNT_NORESVPORT)
set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
/* Allocate or find a client reference we can use */
clp = nfs_get_client(&cl_init);
if (IS_ERR(clp)) {
dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
return PTR_ERR(clp);
}
server->nfs_client = clp;
/* Initialise the client representation from the mount data */
server->flags = data->flags;
server->options = data->options;
server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP|
NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME;
if (data->rsize)
server->rsize = nfs_block_size(data->rsize, NULL);
if (data->wsize)
server->wsize = nfs_block_size(data->wsize, NULL);
server->acregmin = data->acregmin * HZ;
server->acregmax = data->acregmax * HZ;
server->acdirmin = data->acdirmin * HZ;
server->acdirmax = data->acdirmax * HZ;
/* Start lockd here, before we might error out */
error = nfs_start_lockd(server);
if (error < 0)
goto error;
server->port = data->nfs_server.port;
server->auth_info = data->auth_info;
error = nfs_init_server_rpcclient(server, &timeparms,
data->selected_flavor);
if (error < 0)
goto error;
/* Preserve the values of mount_server-related mount options */
if (data->mount_server.addrlen) {
memcpy(&server->mountd_address, &data->mount_server.address,
data->mount_server.addrlen);
server->mountd_addrlen = data->mount_server.addrlen;
}
server->mountd_version = data->mount_server.version;
server->mountd_port = data->mount_server.port;
server->mountd_protocol = data->mount_server.protocol;
server->namelen = data->namlen;
dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
return 0;
error:
server->nfs_client = NULL;
nfs_put_client(clp);
dprintk("<-- nfs_init_server() = xerror %d\n", error);
return error;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 240 | 50.63% | 2 | 10.53% |
Chuck Lever | 115 | 24.26% | 6 | 31.58% |
Trond Myklebust | 75 | 15.82% | 5 | 26.32% |
Andy Adamson | 20 | 4.22% | 1 | 5.26% |
Weston Andros Adamson | 9 | 1.90% | 2 | 10.53% |
Stanislav Kinsbursky | 7 | 1.48% | 1 | 5.26% |
Bryan Schumaker | 7 | 1.48% | 1 | 5.26% |
Talpey, Thomas | 1 | 0.21% | 1 | 5.26% |
Total | 474 | 100.00% | 19 | 100.00% |
/*
* Load up the server record from information gained in an fsinfo record
*/
static void nfs_server_set_fsinfo(struct nfs_server *server,
struct nfs_fsinfo *fsinfo)
{
unsigned long max_rpc_payload;
/* Work out a lot of parameters */
if (server->rsize == 0)
server->rsize = nfs_block_size(fsinfo->rtpref, NULL);
if (server->wsize == 0)
server->wsize = nfs_block_size(fsinfo->wtpref, NULL);
if (fsinfo->rtmax >= 512 && server->rsize > fsinfo->rtmax)
server->rsize = nfs_block_size(fsinfo->rtmax, NULL);
if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)
server->wsize = nfs_block_size(fsinfo->wtmax, NULL);
max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
if (server->rsize > max_rpc_payload)
server->rsize = max_rpc_payload;
if (server->rsize > NFS_MAX_FILE_IO_SIZE)
server->rsize = NFS_MAX_FILE_IO_SIZE;
server->rpages = (server->rsize + PAGE_SIZE - 1) >> PAGE_SHIFT;
server->backing_dev_info.name = "nfs";
server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
if (server->wsize > max_rpc_payload)
server->wsize = max_rpc_payload;
if (server->wsize > NFS_MAX_FILE_IO_SIZE)
server->wsize = NFS_MAX_FILE_IO_SIZE;
server->wpages = (server->wsize + PAGE_SIZE - 1) >> PAGE_SHIFT;
server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);
server->dtsize = nfs_block_size(fsinfo->dtpref, NULL);
if (server->dtsize > PAGE_SIZE * NFS_MAX_READDIR_PAGES)
server->dtsize = PAGE_SIZE * NFS_MAX_READDIR_PAGES;
if (server->dtsize > server->rsize)
server->dtsize = server->rsize;
if (server->flags & NFS_MOUNT_NOAC) {
server->acregmin = server->acregmax = 0;
server->acdirmin = server->acdirmax = 0;
}
server->maxfilesize = fsinfo->maxfilesize;
server->time_delta = fsinfo->time_delta;
server->clone_blksize = fsinfo->clone_blksize;
/* We're airborne Set socket buffersize */
rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 343 | 90.50% | 1 | 14.29% |
Peng Tao | 8 | 2.11% | 1 | 14.29% |
Jens Axboe | 8 | 2.11% | 1 | 14.29% |
Ricardo Labiaga | 8 | 2.11% | 1 | 14.29% |
Kirill A. Shutemov | 6 | 1.58% | 1 | 14.29% |
Bryan Schumaker | 4 | 1.06% | 1 | 14.29% |
Fred Isaman | 2 | 0.53% | 1 | 14.29% |
Total | 379 | 100.00% | 7 | 100.00% |
/*
* Probe filesystem information, including the FSID on v2/v3
*/
int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
{
struct nfs_fsinfo fsinfo;
struct nfs_client *clp = server->nfs_client;
int error;
dprintk("--> nfs_probe_fsinfo()\n");
if (clp->rpc_ops->set_capabilities != NULL) {
error = clp->rpc_ops->set_capabilities(server, mntfh);
if (error < 0)
goto out_error;
}
fsinfo.fattr = fattr;
fsinfo.nlayouttypes = 0;
memset(fsinfo.layouttype, 0, sizeof(fsinfo.layouttype));
error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
if (error < 0)
goto out_error;
nfs_server_set_fsinfo(server, &fsinfo);
/* Get some general file system info */
if (server->namelen == 0) {
struct nfs_pathconf pathinfo;
pathinfo.fattr = fattr;
nfs_fattr_init(fattr);
if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0)
server->namelen = pathinfo.max_namelen;
}
dprintk("<-- nfs_probe_fsinfo() = 0\n");
return 0;
out_error:
dprintk("nfs_probe_fsinfo: error = %d\n", -error);
return error;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 187 | 89.47% | 1 | 25.00% |
Jeff Layton | 17 | 8.13% | 2 | 50.00% |
Ricardo Labiaga | 5 | 2.39% | 1 | 25.00% |
Total | 209 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_probe_fsinfo);
/*
* Copy useful information when duplicating a server record
*/
void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
{
target->flags = source->flags;
target->rsize = source->rsize;
target->wsize = source->wsize;
target->acregmin = source->acregmin;
target->acregmax = source->acregmax;
target->acdirmin = source->acdirmin;
target->acdirmax = source->acdirmax;
target->caps = source->caps;
target->options = source->options;
target->auth_info = source->auth_info;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 71 | 74.74% | 2 | 50.00% |
Chuck Lever | 16 | 16.84% | 1 | 25.00% |
Weston Andros Adamson | 8 | 8.42% | 1 | 25.00% |
Total | 95 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_server_copy_userdata);
void nfs_server_insert_lists(struct nfs_server *server)
{
struct nfs_client *clp = server->nfs_client;
struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
spin_lock(&nn->nfs_client_lock);
list_add_tail_rcu(&server->client_link, &clp->cl_superblocks);
list_add_tail(&server->master_link, &nn->nfs_volume_list);
clear_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
spin_unlock(&nn->nfs_client_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Chuck Lever | 56 | 65.88% | 2 | 40.00% |
Stanislav Kinsbursky | 19 | 22.35% | 2 | 40.00% |
Andy Adamson | 10 | 11.76% | 1 | 20.00% |
Total | 85 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_server_insert_lists);
void nfs_server_remove_lists(struct nfs_server *server)
{
struct nfs_client *clp = server->nfs_client;
struct nfs_net *nn;
if (clp == NULL)
return;
nn = net_generic(clp->cl_net, nfs_net_id);
spin_lock(&nn->nfs_client_lock);
list_del_rcu(&server->client_link);
if (list_empty(&clp->cl_superblocks))
set_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
list_del(&server->master_link);
spin_unlock(&nn->nfs_client_lock);
synchronize_rcu();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Chuck Lever | 42 | 43.30% | 2 | 40.00% |
Andy Adamson | 29 | 29.90% | 1 | 20.00% |
Stanislav Kinsbursky | 15 | 15.46% | 1 | 20.00% |
Trond Myklebust | 11 | 11.34% | 1 | 20.00% |
Total | 97 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_server_remove_lists);
/*
* Allocate and initialise a server record
*/
struct nfs_server *nfs_alloc_server(void)
{
struct nfs_server *server;
server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
if (!server)
return NULL;
server->client = server->client_acl = ERR_PTR(-EINVAL);
/* Zero out the NFS state stuff */
INIT_LIST_HEAD(&server->client_link);
INIT_LIST_HEAD(&server->master_link);
INIT_LIST_HEAD(&server->delegations);
INIT_LIST_HEAD(&server->layouts);
INIT_LIST_HEAD(&server->state_owners_lru);
atomic_set(&server->active, 0);
server->io_stats = nfs_alloc_iostats();
if (!server->io_stats) {
kfree(server);
return NULL;
}
if (bdi_init(&server->backing_dev_info)) {
nfs_free_iostats(server->io_stats);
kfree(server);
return NULL;
}
ida_init(&server->openowner_id);
ida_init(&server->lockowner_id);
pnfs_init_server(server);
return server;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 94 | 53.71% | 1 | 11.11% |
Jens Axboe | 27 | 15.43% | 1 | 11.11% |
Chuck Lever | 16 | 9.14% | 2 | 22.22% |
Trond Myklebust | 11 | 6.29% | 2 | 22.22% |
Steve Dickson | 10 | 5.71% | 1 | 11.11% |
Fred Isaman | 9 | 5.14% | 1 | 11.11% |
Weston Andros Adamson | 8 | 4.57% | 1 | 11.11% |
Total | 175 | 100.00% | 9 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_alloc_server);
/*
* Free up a server record
*/
void nfs_free_server(struct nfs_server *server)
{
dprintk("--> nfs_free_server()\n");
nfs_server_remove_lists(server);
if (server->destroy != NULL)
server->destroy(server);
if (!IS_ERR(server->client_acl))
rpc_shutdown_client(server->client_acl);
if (!IS_ERR(server->client))
rpc_shutdown_client(server->client);
nfs_put_client(server->nfs_client);
ida_destroy(&server->lockowner_id);
ida_destroy(&server->openowner_id);
nfs_free_iostats(server->io_stats);
bdi_destroy(&server->backing_dev_info);
kfree(server);
nfs_release_automount_timer();
dprintk("<-- nfs_free_server()\n");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 78 | 65.00% | 1 | 16.67% |
Trond Myklebust | 33 | 27.50% | 3 | 50.00% |
Peter Zijlstra | 8 | 6.67% | 1 | 16.67% |
Chuck Lever | 1 | 0.83% | 1 | 16.67% |
Total | 120 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_free_server);
/*
* Create a version 2 or 3 volume record
* - keyed on server and FSID
*/
struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
struct nfs_subversion *nfs_mod)
{
struct nfs_server *server;
struct nfs_fattr *fattr;
int error;
server = nfs_alloc_server();
if (!server)
return ERR_PTR(-ENOMEM);
error = -ENOMEM;
fattr = nfs_alloc_fattr();
if (fattr == NULL)
goto error;
/* Get a client representation */
error = nfs_init_server(server, mount_info->parsed, nfs_mod);
if (error < 0)
goto error;
/* Probe the root fh to retrieve its FSID */
error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr);
if (error < 0)
goto error;
if (server->nfs_client->rpc_ops->version == 3) {
if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
server->namelen = NFS3_MAXNAMLEN;
if (!(mount_info->parsed->flags & NFS_MOUNT_NORDIRPLUS))
server->caps |= NFS_CAP_READDIRPLUS;
} else {
if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
server->namelen = NFS2_MAXNAMLEN;
}
if (!(fattr->valid & NFS_ATTR_FATTR)) {
error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh, fattr, NULL);
if (error < 0) {
dprintk("nfs_create_server: getattr error = %d\n", -error);
goto error;
}
}
memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
dprintk("Server FSID: %llx:%llx\n",
(unsigned long long) server->fsid.major,
(unsigned long long) server->fsid.minor);
nfs_server_insert_lists(server);
server->mount_time = jiffies;
nfs_free_fattr(fattr);
return server;
error:
nfs_free_fattr(fattr);
nfs_free_server(server);
return ERR_PTR(error);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 195 | 60.37% | 2 | 25.00% |
Trond Myklebust | 105 | 32.51% | 2 | 25.00% |
Bryan Schumaker | 20 | 6.19% | 2 | 25.00% |
David Quigley | 2 | 0.62% | 1 | 12.50% |
Chuck Lever | 1 | 0.31% | 1 | 12.50% |
Total | 323 | 100.00% | 8 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_create_server);
/*
* Clone an NFS2, NFS3 or NFS4 server record
*/
struct nfs_server *nfs_clone_server(struct nfs_server *source,
struct nfs_fh *fh,
struct nfs_fattr *fattr,
rpc_authflavor_t flavor)
{
struct nfs_server *server;
struct nfs_fattr *fattr_fsinfo;
int error;
dprintk("--> nfs_clone_server(,%llx:%llx,)\n",
(unsigned long long) fattr->fsid.major,
(unsigned long long) fattr->fsid.minor);
server = nfs_alloc_server();
if (!server)
return ERR_PTR(-ENOMEM);
error = -ENOMEM;
fattr_fsinfo = nfs_alloc_fattr();
if (fattr_fsinfo == NULL)
goto out_free_server;
/* Copy data from the source */
server->nfs_client = source->nfs_client;
server->destroy = source->destroy;
atomic_inc(&server->nfs_client->cl_count);
nfs_server_copy_userdata(server, source);
server->fsid = fattr->fsid;
error = nfs_init_server_rpcclient(server,
source->client->cl_timeout,
flavor);
if (error < 0)
goto out_free_server;
/* probe the filesystem info for this server filesystem */
error = nfs_probe_fsinfo(server, fh, fattr_fsinfo);
if (error < 0)
goto out_free_server;
if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
server->namelen = NFS4_MAXNAMLEN;
dprintk("Cloned FSID: %llx:%llx\n",
(unsigned long long) server->fsid.major,
(unsigned long long) server->fsid.minor);
error = nfs_start_lockd(server);
if (error < 0)
goto out_free_server;
nfs_server_insert_lists(server);
server->mount_time = jiffies;
nfs_free_fattr(fattr_fsinfo);
dprintk("<-- nfs_clone_server() = %p\n", server);
return server;
out_free_server:
nfs_free_fattr(fattr_fsinfo);
nfs_free_server(server);
dprintk("<-- nfs_clone_server() = error %d\n", error);
return ERR_PTR(error);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 176 | 58.28% | 2 | 16.67% |
Trond Myklebust | 51 | 16.89% | 3 | 25.00% |
Bryan Schumaker | 48 | 15.89% | 2 | 16.67% |
Andy Adamson | 14 | 4.64% | 1 | 8.33% |
Chuck Lever | 9 | 2.98% | 2 | 16.67% |
Stanislav Kinsbursky | 4 | 1.32% | 2 | 16.67% |
Total | 302 | 100.00% | 12 | 100.00% |
EXPORT_SYMBOL_GPL(nfs_clone_server);
void nfs_clients_init(struct net *net)
{
struct nfs_net *nn = net_generic(net, nfs_net_id);
INIT_LIST_HEAD(&nn->nfs_client_list);
INIT_LIST_HEAD(&nn->nfs_volume_list);
#if IS_ENABLED(CONFIG_NFS_V4)
idr_init(&nn->cb_ident_idr);
#endif
spin_lock_init(&nn->nfs_client_lock);
nn->boot_time = ktime_get_real();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Stanislav Kinsbursky | 49 | 71.01% | 3 | 42.86% |
Trond Myklebust | 8 | 11.59% | 1 | 14.29% |
Chuck Lever | 5 | 7.25% | 1 | 14.29% |
Bryan Schumaker | 5 | 7.25% | 1 | 14.29% |
Deepa Dinamani | 2 | 2.90% | 1 | 14.29% |
Total | 69 | 100.00% | 7 | 100.00% |
#ifdef CONFIG_PROC_FS
static int nfs_server_list_open(struct inode *inode, struct file *file);
static void *nfs_server_list_start(struct seq_file *p, loff_t *pos);
static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos);
static void nfs_server_list_stop(struct seq_file *p, void *v);
static int nfs_server_list_show(struct seq_file *m, void *v);
static const struct seq_operations nfs_server_list_ops = {
.start = nfs_server_list_start,
.next = nfs_server_list_next,
.stop = nfs_server_list_stop,
.show = nfs_server_list_show,
};
static const struct file_operations nfs_server_list_fops = {
.open = nfs_server_list_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
static int nfs_volume_list_open(struct inode *inode, struct file *file);
static void *nfs_volume_list_start(struct seq_file *p, loff_t *pos);
static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos);
static void nfs_volume_list_stop(struct seq_file *p, void *v);
static int nfs_volume_list_show(struct seq_file *m, void *v);
static const struct seq_operations nfs_volume_list_ops = {
.start = nfs_volume_list_start,
.next = nfs_volume_list_next,
.stop = nfs_volume_list_stop,
.show = nfs_volume_list_show,
};
static const struct file_operations nfs_volume_list_fops = {
.open = nfs_volume_list_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
/*
* open "/proc/fs/nfsfs/servers" which provides a summary of servers with which
* we're dealing
*/
static int nfs_server_list_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &nfs_server_list_ops,
sizeof(struct seq_net_private));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 23 | 69.70% | 1 | 50.00% |
Eric W. Biedermann | 10 | 30.30% | 1 | 50.00% |
Total | 33 | 100.00% | 2 | 100.00% |
/*
* set up the iterator to start reading from the server list and return the first item
*/
static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos)
__acquires(&nn->nfs_client_lockContributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 14 | 82.35% | 1 | 50.00% |
Jeff Layton | 3 | 17.65% | 1 | 50.00% |
Total | 17 | 100.00% | 2 | 100.00% |
)
{
struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
/* lock the list against modification */
spin_lock(&nn->nfs_client_lock);
return seq_list_start_head(&nn->nfs_client_list, *_pos);
}
/*
* move to next server
*/
static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos)
{
struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
return seq_list_next(v, &nn->nfs_client_list, pos);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 24 | 50.00% | 1 | 25.00% |
Stanislav Kinsbursky | 14 | 29.17% | 1 | 25.00% |
Pavel Emelyanov | 7 | 14.58% | 1 | 25.00% |
Eric W. Biedermann | 3 | 6.25% | 1 | 25.00% |
Total | 48 | 100.00% | 4 | 100.00% |
/*
* clean up after reading from the transports list
*/
static void nfs_server_list_stop(struct seq_file *p, void *v)
__releases(&nn->nfs_client_lockContributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 13 | 81.25% | 1 | 50.00% |
Jeff Layton | 3 | 18.75% | 1 | 50.00% |
Total | 16 | 100.00% | 2 | 100.00% |
)
{
struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
spin_unlock(&nn->nfs_client_lock);
}
/*
* display a header line followed by a load of call lines
*/
static int nfs_server_list_show(struct seq_file *m, void *v)
{
struct nfs_client *clp;
struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
/* display header on line 1 */
if (v == &nn->nfs_client_list) {
seq_puts(m, "NV SERVER PORT USE HOSTNAME\n");
return 0;
}
/* display one transport per line on subsequent lines */
clp = list_entry(v, struct nfs_client, cl_share_link);
/* Check if the client is initialized */
if (clp->cl_cons_state != NFS_CS_READY)
return 0;
rcu_read_lock();
seq_printf(m, "v%u %s %s %3d %s\n",
clp->rpc_ops->version,
rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
atomic_read(&clp->cl_count),
clp->cl_hostname);
rcu_read_unlock();
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 85 | 63.43% | 1 | 12.50% |
Stanislav Kinsbursky | 14 | 10.45% | 1 | 12.50% |
Malahal Naineni | 12 | 8.96% | 1 | 12.50% |
Trond Myklebust | 9 | 6.72% | 2 | 25.00% |
Chuck Lever | 9 | 6.72% | 1 | 12.50% |
Eric W. Biedermann | 3 | 2.24% | 1 | 12.50% |
Pavel Emelyanov | 2 | 1.49% | 1 | 12.50% |
Total | 134 | 100.00% | 8 | 100.00% |
/*
* open "/proc/fs/nfsfs/volumes" which provides a summary of extant volumes
*/
static int nfs_volume_list_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &nfs_volume_list_ops,
sizeof(struct seq_net_private));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 22 | 66.67% | 1 | 33.33% |
Eric W. Biedermann | 10 | 30.30% | 1 | 33.33% |
Fabian Frederick | 1 | 3.03% | 1 | 33.33% |
Total | 33 | 100.00% | 3 | 100.00% |
/*
* set up the iterator to start reading from the volume list and return the first item
*/
static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
__acquires(&nn->nfs_client_lockContributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 14 | 82.35% | 1 | 50.00% |
Jeff Layton | 3 | 17.65% | 1 | 50.00% |
Total | 17 | 100.00% | 2 | 100.00% |
)
{
struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
/* lock the list against modification */
spin_lock(&nn->nfs_client_lock);
return seq_list_start_head(&nn->nfs_volume_list, *_pos);
}
/*
* move to next volume
*/
static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos)
{
struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
return seq_list_next(v, &nn->nfs_volume_list, pos);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 24 | 50.00% | 1 | 25.00% |
Stanislav Kinsbursky | 14 | 29.17% | 1 | 25.00% |
Pavel Emelyanov | 7 | 14.58% | 1 | 25.00% |
Eric W. Biedermann | 3 | 6.25% | 1 | 25.00% |
Total | 48 | 100.00% | 4 | 100.00% |
/*
* clean up after reading from the transports list
*/
static void nfs_volume_list_stop(struct seq_file *p, void *v)
__releases(&nn->nfs_client_lockContributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 13 | 81.25% | 1 | 50.00% |
Jeff Layton | 3 | 18.75% | 1 | 50.00% |
Total | 16 | 100.00% | 2 | 100.00% |
)
{
struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
spin_unlock(&nn->nfs_client_lock);
}
/*
* display a header line followed by a load of call lines
*/
static int nfs_volume_list_show(struct seq_file *m, void *v)
{
struct nfs_server *server;
struct nfs_client *clp;
char dev[13]; // 8 for 2^24, 1 for ':', 3 for 2^8, 1 for '\0'
char fsid[34]; // 2 * 16 for %llx, 1 for ':', 1 for '\0'
struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
/* display header on line 1 */
if (v == &nn->nfs_volume_list) {
seq_puts(m, "NV SERVER PORT DEV FSID"
" FSC\n");
return 0;
}
/* display one transport per line on subsequent lines */
server = list_entry(v, struct nfs_server, master_link);
clp = server->nfs_client;
snprintf(dev, sizeof(dev), "%u:%u",
MAJOR(server->s_dev), MINOR(server->s_dev));
snprintf(fsid, sizeof(fsid), "%llx:%llx",
(unsigned long long) server->fsid.major,
(unsigned long long) server->fsid.minor);
rcu_read_lock();
seq_printf(m, "v%u %s %s %-12s %-33s %s\n",
clp->rpc_ops->version,
rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
dev,
fsid,
nfs_server_fscache_state(server));
rcu_read_unlock();
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 152 | 74.15% | 3 | 30.00% |
Kinglong Mee | 17 | 8.29% | 1 | 10.00% |
Stanislav Kinsbursky | 14 | 6.83% | 1 | 10.00% |
Trond Myklebust | 9 | 4.39% | 2 | 20.00% |
Chuck Lever | 8 | 3.90% | 1 | 10.00% |
Eric W. Biedermann | 3 | 1.46% | 1 | 10.00% |
Pavel Emelyanov | 2 | 0.98% | 1 | 10.00% |
Total | 205 | 100.00% | 10 | 100.00% |
int nfs_fs_proc_net_init(struct net *net)
{
struct nfs_net *nn = net_generic(net, nfs_net_id);
struct proc_dir_entry *p;
nn->proc_nfsfs = proc_net_mkdir(net, "nfsfs", net->proc_net);
if (!nn->proc_nfsfs)
goto error_0;
/* a file of servers with which we're dealing */
p = proc_create("servers", S_IFREG|S_IRUGO,
nn->proc_nfsfs, &nfs_server_list_fops);
if (!p)
goto error_1;
/* a file of volumes that we have mounted */
p = proc_create("volumes", S_IFREG|S_IRUGO,
nn->proc_nfsfs, &nfs_volume_list_fops);
if (!p)
goto error_1;
return 0;
error_1:
remove_proc_subtree("nfsfs", net->proc_net);
error_0:
return -ENOMEM;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 63 | 50.00% | 1 | 25.00% |
Eric W. Biedermann | 49 | 38.89% | 1 | 25.00% |
Denis V. Lunev | 8 | 6.35% | 1 | 25.00% |
Américo Wang | 6 | 4.76% | 1 | 25.00% |
Total | 126 | 100.00% | 4 | 100.00% |
void nfs_fs_proc_net_exit(struct net *net)
{
remove_proc_subtree("nfsfs", net->proc_net);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Eric W. Biedermann | 15 | 78.95% | 1 | 50.00% |
Américo Wang | 4 | 21.05% | 1 | 50.00% |
Total | 19 | 100.00% | 2 | 100.00% |
/*
* initialise the /proc/fs/nfsfs/ directory
*/
int __init nfs_fs_proc_init(void)
{
if (!proc_mkdir("fs/nfsfs", NULL))
goto error_0;
/* a file of servers with which we're dealing */
if (!proc_symlink("fs/nfsfs/servers", NULL, "../../net/nfsfs/servers"))
goto error_1;
/* a file of volumes that we have mounted */
if (!proc_symlink("fs/nfsfs/volumes", NULL, "../../net/nfsfs/volumes"))
goto error_1;
return 0;
error_1:
remove_proc_subtree("fs/nfsfs", NULL);
error_0:
return -ENOMEM;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Eric W. Biedermann | 41 | 57.75% | 1 | 25.00% |
Kinglong Mee | 15 | 21.13% | 1 | 25.00% |
David Howells | 13 | 18.31% | 1 | 25.00% |
Alexey Dobriyan | 2 | 2.82% | 1 | 25.00% |
Total | 71 | 100.00% | 4 | 100.00% |
/*
* clean up the /proc/fs/nfsfs/ directory
*/
void nfs_fs_proc_exit(void)
{
remove_proc_subtree("fs/nfsfs", NULL);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 11 | 78.57% | 1 | 33.33% |
Alexey Dobriyan | 2 | 14.29% | 1 | 33.33% |
Kinglong Mee | 1 | 7.14% | 1 | 33.33% |
Total | 14 | 100.00% | 3 | 100.00% |
#endif /* CONFIG_PROC_FS */
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Howells | 3165 | 50.81% | 10 | 6.99% |
Trond Myklebust | 731 | 11.74% | 31 | 21.68% |
Chuck Lever | 693 | 11.13% | 25 | 17.48% |
Bryan Schumaker | 508 | 8.16% | 10 | 6.99% |
Stanislav Kinsbursky | 325 | 5.22% | 7 | 4.90% |
Andy Adamson | 166 | 2.66% | 7 | 4.90% |
Eric W. Biedermann | 152 | 2.44% | 1 | 0.70% |
Weston Andros Adamson | 75 | 1.20% | 5 | 3.50% |
Fred Isaman | 42 | 0.67% | 2 | 1.40% |
Jeff Layton | 40 | 0.64% | 4 | 2.80% |
Jens Axboe | 35 | 0.56% | 2 | 1.40% |
Kinglong Mee | 33 | 0.53% | 2 | 1.40% |
Pavel Emelyanov | 32 | 0.51% | 2 | 1.40% |
Ian Dall | 29 | 0.47% | 1 | 0.70% |
Peng Tao | 26 | 0.42% | 2 | 1.40% |
Alexey Khoroshilov | 19 | 0.31% | 1 | 0.70% |
Benny Halevy | 18 | 0.29% | 3 | 2.10% |
Ricardo Labiaga | 16 | 0.26% | 2 | 1.40% |
Suresh Jayaraman | 13 | 0.21% | 1 | 0.70% |
Malahal Naineni | 12 | 0.19% | 1 | 0.70% |
Talpey, Thomas | 12 | 0.19% | 3 | 2.10% |
Américo Wang | 10 | 0.16% | 1 | 0.70% |
Steve Dickson | 10 | 0.16% | 1 | 0.70% |
Peter Zijlstra | 8 | 0.13% | 1 | 0.70% |
Denis V. Lunev | 8 | 0.13% | 1 | 0.70% |
Petr Vandrovec | 7 | 0.11% | 1 | 0.70% |
Alexey Dobriyan | 7 | 0.11% | 2 | 1.40% |
Alexandros Batsakis | 6 | 0.10% | 1 | 0.70% |
Kirill A. Shutemov | 6 | 0.10% | 1 | 0.70% |
Anna Schumaker | 4 | 0.06% | 1 | 0.70% |
Al Viro | 3 | 0.05% | 1 | 0.70% |
Neil Brown | 3 | 0.05% | 2 | 1.40% |
Tejun Heo | 3 | 0.05% | 1 | 0.70% |
David Quigley | 2 | 0.03% | 1 | 0.70% |
Deepa Dinamani | 2 | 0.03% | 1 | 0.70% |
James Morris | 2 | 0.03% | 1 | 0.70% |
Arjan van de Ven | 2 | 0.03% | 1 | 0.70% |
Harvey Harrison | 2 | 0.03% | 1 | 0.70% |
Jim Rees | 1 | 0.02% | 1 | 0.70% |
Fabian Frederick | 1 | 0.02% | 1 | 0.70% |
Total | 6229 | 100.00% | 143 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.