NFS client updates for Linux 3.6
Features include: - Patches from Bryan to allow splitting of the NFSv2/v3/v4 code into separate modules. - Fix Oopses in the NFSv4 idmapper - Fix a deadlock whereby rpciod tries to allocate a new socket and ends up recursing into the NFS code due to memory reclaim. - Increase the number of permitted callback connections. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJQGF+vAAoJEGcL54qWCgDy6ncP/jKVl/Yjz6i1b/8QtC0EmYFb XNwbjZicNupVM98XPLm+sfdWxvoGiHSMbwG8t/hx5Z6CteM18adeGNO1KqP9xQyg scPvFmqj5VJNHsHztcHIFHFYdpsuJqRKcW3TA2l8AkNOm6uBcnXArRosYN6LrXik hI/jWcyv8wZuooSQrLf463JK37t/s6LuUQo6jKP4582sbANHvPdLkHFCYg3yt1Sk 2IIo2CLLs2cJUswGJnsHT76Jxfvh21NdGtvydjVjpr4H0/LY5GykBc23AAL9TWj6 KlegDO902hLzEE93xazF59hQZrPuwBi3quEMJ3X0mjdNQWb4G96s/t2hmwpTjWyc mjpRsuaGlCXDxcrI5dnU52hqKa0Ju1ipbLpghxSVfilRy998xvGp5Yc6ADU+pYnt uP09lamCyjFEa+gDSqGt7lv4dFmdPJjWZdkXLPv0ah5sXVMYAT8NRLUfiE1+hLLu zKaM84PHSEvykFeJ2WvjDTgF3L55y3x6L3LN4UkKmfO5nqQf7csPcquU1NfHh25S jjKGq2SKGoYG1l6FwK3hemup5cnFUEX78E2QeLrmaHg92fJDGrz587i6MPc5jrSe sOSX/CpuCJd4VhodIo8T00me0GZSHEU7RP2KEc518ZvrPmz13avXeLeG9nYhjuxM cV9Ex8zh2Y4aiUXCy3uA =KSix -----END PGP SIGNATURE----- Merge tag 'nfs-for-3.6-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs Pull second wave of NFS client updates from Trond Myklebust: - Patches from Bryan to allow splitting of the NFSv2/v3/v4 code into separate modules. - Fix Oopses in the NFSv4 idmapper - Fix a deadlock whereby rpciod tries to allocate a new socket and ends up recursing into the NFS code due to memory reclaim. - Increase the number of permitted callback connections. * tag 'nfs-for-3.6-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: nfs: explicitly reject LOCK_MAND flock() requests nfs: increase number of permitted callback connections. SUNRPC: return negative value in case rpcbind client creation error NFS: Convert v4 into a module NFS: Convert v3 into a module NFS: Convert v2 into a module NFS: Keep module parameters in the generic NFS client NFS: Split out remaining NFS v4 inode functions NFS: Pass super operations and xattr handlers in the nfs_subversion NFS: Only initialize the ACL client in the v3 case NFS: Create a try_mount rpc op NFS: Remove the NFS v4 xdev mount function NFS: Add version registering framework NFS: Fix a number of bugs in the idmapper nfs: skip commit in releasepage if we're freeing memory for fs-related reasons sunrpc: clarify comments on rpc_make_runnable pnfsblock: bail out partial page IO
This commit is contained in:
commit
6dbb35b0a7
40 changed files with 728 additions and 406 deletions
|
@ -30,7 +30,7 @@ config NFS_FS
|
|||
If unsure, say N.
|
||||
|
||||
config NFS_V2
|
||||
bool "NFS client support for NFS version 2"
|
||||
tristate "NFS client support for NFS version 2"
|
||||
depends on NFS_FS
|
||||
default y
|
||||
help
|
||||
|
@ -40,7 +40,7 @@ config NFS_V2
|
|||
If unsure, say Y.
|
||||
|
||||
config NFS_V3
|
||||
bool "NFS client support for NFS version 3"
|
||||
tristate "NFS client support for NFS version 3"
|
||||
depends on NFS_FS
|
||||
default y
|
||||
help
|
||||
|
@ -72,7 +72,7 @@ config NFS_V3_ACL
|
|||
If unsure, say N.
|
||||
|
||||
config NFS_V4
|
||||
bool "NFS client support for NFS version 4"
|
||||
tristate "NFS client support for NFS version 4"
|
||||
depends on NFS_FS
|
||||
select SUNRPC_GSS
|
||||
select KEYS
|
||||
|
|
|
@ -9,22 +9,23 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
|
|||
write.o namespace.o mount_clnt.o \
|
||||
dns_resolve.o cache_lib.o
|
||||
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
|
||||
nfs-$(CONFIG_NFS_V2) += proc.o nfs2xdr.o
|
||||
nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
|
||||
nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
|
||||
nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
|
||||
nfs4super.o nfs4file.o delegation.o idmap.o \
|
||||
callback.o callback_xdr.o callback_proc.o \
|
||||
nfs4namespace.o nfs4getroot.o nfs4client.o
|
||||
nfs-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
|
||||
|
||||
ifeq ($(CONFIG_SYSCTL), y)
|
||||
nfs-y += sysctl.o
|
||||
nfs-$(CONFIG_NFS_V4) += nfs4sysctl.o
|
||||
endif
|
||||
|
||||
nfs-$(CONFIG_SYSCTL) += sysctl.o
|
||||
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
|
||||
|
||||
obj-$(CONFIG_NFS_V2) += nfs2.o
|
||||
nfs2-y := nfs2super.o proc.o nfs2xdr.o
|
||||
|
||||
obj-$(CONFIG_NFS_V3) += nfs3.o
|
||||
nfs3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
|
||||
nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
|
||||
|
||||
obj-$(CONFIG_NFS_V4) += nfs4.o
|
||||
nfs4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
|
||||
delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
|
||||
nfs4namespace.o nfs4getroot.o nfs4client.o
|
||||
nfs4-$(CONFIG_SYSCTL) += nfs4sysctl.o
|
||||
nfs4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
|
||||
|
||||
obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
|
||||
nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
|
||||
|
||||
|
|
|
@ -228,6 +228,14 @@ bl_end_par_io_read(void *data, int unused)
|
|||
schedule_work(&rdata->task.u.tk_work);
|
||||
}
|
||||
|
||||
static bool
|
||||
bl_check_alignment(u64 offset, u32 len, unsigned long blkmask)
|
||||
{
|
||||
if ((offset & blkmask) || (len & blkmask))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static enum pnfs_try_status
|
||||
bl_read_pagelist(struct nfs_read_data *rdata)
|
||||
{
|
||||
|
@ -244,6 +252,9 @@ bl_read_pagelist(struct nfs_read_data *rdata)
|
|||
dprintk("%s enter nr_pages %u offset %lld count %u\n", __func__,
|
||||
rdata->pages.npages, f_offset, (unsigned int)rdata->args.count);
|
||||
|
||||
if (!bl_check_alignment(f_offset, rdata->args.count, PAGE_CACHE_MASK))
|
||||
goto use_mds;
|
||||
|
||||
par = alloc_parallel(rdata);
|
||||
if (!par)
|
||||
goto use_mds;
|
||||
|
@ -552,7 +563,7 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
|
|||
struct bio *bio = NULL;
|
||||
struct pnfs_block_extent *be = NULL, *cow_read = NULL;
|
||||
sector_t isect, last_isect = 0, extent_length = 0;
|
||||
struct parallel_io *par;
|
||||
struct parallel_io *par = NULL;
|
||||
loff_t offset = wdata->args.offset;
|
||||
size_t count = wdata->args.count;
|
||||
struct page **pages = wdata->args.pages;
|
||||
|
@ -563,6 +574,10 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
|
|||
NFS_SERVER(header->inode)->pnfs_blksize >> PAGE_CACHE_SHIFT;
|
||||
|
||||
dprintk("%s enter, %Zu@%lld\n", __func__, count, offset);
|
||||
/* Check for alignment first */
|
||||
if (!bl_check_alignment(offset, count, PAGE_CACHE_MASK))
|
||||
goto out_mds;
|
||||
|
||||
/* At this point, wdata->pages is a (sequential) list of nfs_pages.
|
||||
* We want to write each, and if there is an error set pnfs_error
|
||||
* to have it redone using nfs.
|
||||
|
@ -996,14 +1011,32 @@ bl_clear_layoutdriver(struct nfs_server *server)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
bl_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
|
||||
{
|
||||
if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK))
|
||||
nfs_pageio_reset_read_mds(pgio);
|
||||
else
|
||||
pnfs_generic_pg_init_read(pgio, req);
|
||||
}
|
||||
|
||||
static void
|
||||
bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
|
||||
{
|
||||
if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK))
|
||||
nfs_pageio_reset_write_mds(pgio);
|
||||
else
|
||||
pnfs_generic_pg_init_write(pgio, req);
|
||||
}
|
||||
|
||||
static const struct nfs_pageio_ops bl_pg_read_ops = {
|
||||
.pg_init = pnfs_generic_pg_init_read,
|
||||
.pg_init = bl_pg_init_read,
|
||||
.pg_test = pnfs_generic_pg_test,
|
||||
.pg_doio = pnfs_generic_pg_readpages,
|
||||
};
|
||||
|
||||
static const struct nfs_pageio_ops bl_pg_write_ops = {
|
||||
.pg_init = pnfs_generic_pg_init_write,
|
||||
.pg_init = bl_pg_init_write,
|
||||
.pg_test = pnfs_generic_pg_test,
|
||||
.pg_doio = pnfs_generic_pg_writepages,
|
||||
};
|
||||
|
|
|
@ -37,31 +37,7 @@ static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1];
|
|||
static DEFINE_MUTEX(nfs_callback_mutex);
|
||||
static struct svc_program nfs4_callback_program;
|
||||
|
||||
unsigned int nfs_callback_set_tcpport;
|
||||
unsigned short nfs_callback_tcpport;
|
||||
unsigned short nfs_callback_tcpport6;
|
||||
#define NFS_CALLBACK_MAXPORTNR (65535U)
|
||||
|
||||
static int param_set_portnr(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
unsigned long num;
|
||||
int ret;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
ret = strict_strtoul(val, 0, &num);
|
||||
if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR)
|
||||
return -EINVAL;
|
||||
*((unsigned int *)kp->arg) = num;
|
||||
return 0;
|
||||
}
|
||||
static struct kernel_param_ops param_ops_portnr = {
|
||||
.set = param_set_portnr,
|
||||
.get = param_get_uint,
|
||||
};
|
||||
#define param_check_portnr(name, p) __param_check(name, p, unsigned int);
|
||||
|
||||
module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
|
||||
|
||||
/*
|
||||
* This is the NFSv4 callback kernel thread.
|
||||
|
@ -265,6 +241,10 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
|
|||
ret = -ENOMEM;
|
||||
goto out_err;
|
||||
}
|
||||
/* As there is only one thread we need to over-ride the
|
||||
* default maximum of 80 connections
|
||||
*/
|
||||
serv->sv_maxconn = 1024;
|
||||
|
||||
ret = svc_bind(serv, net);
|
||||
if (ret < 0) {
|
||||
|
|
|
@ -192,7 +192,7 @@ extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args,
|
|||
struct cb_process_state *cps);
|
||||
extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy,
|
||||
struct cb_process_state *cps);
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
|
||||
extern void nfs_callback_down(int minorversion);
|
||||
extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation,
|
||||
|
|
191
fs/nfs/client.c
191
fs/nfs/client.c
|
@ -51,25 +51,23 @@
|
|||
#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] = {
|
||||
#ifdef CONFIG_NFS_V2
|
||||
[2] = &nfs_version2,
|
||||
#endif
|
||||
#ifdef CONFIG_NFS_V3
|
||||
[3] = &nfs_version3,
|
||||
#endif
|
||||
#ifdef CONFIG_NFS_V4
|
||||
[4] = &nfs_version4,
|
||||
#endif
|
||||
[2] = NULL,
|
||||
[3] = NULL,
|
||||
[4] = NULL,
|
||||
};
|
||||
|
||||
const struct rpc_program nfs_program = {
|
||||
|
@ -85,21 +83,64 @@ 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);
|
||||
|
||||
#ifdef CONFIG_NFS_V3_ACL
|
||||
static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
|
||||
static const struct rpc_version *nfsacl_version[] = {
|
||||
[3] = &nfsacl_version3,
|
||||
};
|
||||
list_for_each_entry(nfs, &nfs_versions, list) {
|
||||
if (nfs->rpc_ops->version == version) {
|
||||
spin_unlock(&nfs_version_lock);
|
||||
return nfs;
|
||||
}
|
||||
};
|
||||
|
||||
const struct rpc_program nfsacl_program = {
|
||||
.name = "nfsacl",
|
||||
.number = NFS_ACL_PROGRAM,
|
||||
.nrvers = ARRAY_SIZE(nfsacl_version),
|
||||
.version = nfsacl_version,
|
||||
.stats = &nfsacl_rpcstat,
|
||||
};
|
||||
#endif /* CONFIG_NFS_V3_ACL */
|
||||
spin_unlock(&nfs_version_lock);
|
||||
return ERR_PTR(-EPROTONOSUPPORT);;
|
||||
}
|
||||
|
||||
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("nfs%d", version);
|
||||
nfs = find_nfs_version(version);
|
||||
mutex_unlock(&nfs_version_mutex);
|
||||
}
|
||||
|
||||
if (!IS_ERR(nfs))
|
||||
try_module_get(nfs->owner);
|
||||
return nfs;
|
||||
}
|
||||
|
||||
void put_nfs_version(struct nfs_subversion *nfs)
|
||||
{
|
||||
module_put(nfs->owner);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_nfs_version);
|
||||
|
||||
/*
|
||||
* Allocate a shared client record
|
||||
|
@ -116,7 +157,10 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
|
|||
if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
|
||||
goto error_0;
|
||||
|
||||
clp->rpc_ops = cl_init->rpc_ops;
|
||||
clp->cl_nfs_mod = cl_init->nfs_mod;
|
||||
try_module_get(clp->cl_nfs_mod->owner);
|
||||
|
||||
clp->rpc_ops = clp->cl_nfs_mod->rpc_ops;
|
||||
|
||||
atomic_set(&clp->cl_count, 1);
|
||||
clp->cl_cons_state = NFS_CS_INITING;
|
||||
|
@ -145,12 +189,14 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
|
|||
return clp;
|
||||
|
||||
error_cleanup:
|
||||
put_nfs_version(clp->cl_nfs_mod);
|
||||
kfree(clp);
|
||||
error_0:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_alloc_client);
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
/* idr_remove_all is not needed as all id's are removed by nfs_put_client */
|
||||
void nfs_cleanup_cb_ident_idr(struct net *net)
|
||||
{
|
||||
|
@ -205,11 +251,13 @@ void nfs_free_client(struct nfs_client *clp)
|
|||
put_rpccred(clp->cl_machine_cred);
|
||||
|
||||
put_net(clp->cl_net);
|
||||
put_nfs_version(clp->cl_nfs_mod);
|
||||
kfree(clp->cl_hostname);
|
||||
kfree(clp);
|
||||
|
||||
dprintk("<-- nfs_free_client()\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_free_client);
|
||||
|
||||
/*
|
||||
* Release a reference to a shared client record
|
||||
|
@ -324,6 +372,7 @@ int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_sockaddr_match_ipaddr);
|
||||
#endif /* CONFIG_NFS_V4_1 */
|
||||
|
||||
/*
|
||||
|
@ -362,7 +411,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
|
|||
continue;
|
||||
|
||||
/* Different NFS versions cannot share the same nfs_client */
|
||||
if (clp->rpc_ops != data->rpc_ops)
|
||||
if (clp->rpc_ops != data->nfs_mod->rpc_ops)
|
||||
continue;
|
||||
|
||||
if (clp->cl_proto != data->proto)
|
||||
|
@ -390,6 +439,7 @@ 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.
|
||||
|
@ -431,9 +481,10 @@ 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;
|
||||
|
||||
dprintk("--> nfs_get_client(%s,v%u)\n",
|
||||
cl_init->hostname ?: "", cl_init->rpc_ops->version);
|
||||
cl_init->hostname ?: "", rpc_ops->version);
|
||||
|
||||
/* see if the client already exists */
|
||||
do {
|
||||
|
@ -450,20 +501,20 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
|
|||
list_add(&new->cl_share_link, &nn->nfs_client_list);
|
||||
spin_unlock(&nn->nfs_client_lock);
|
||||
new->cl_flags = cl_init->init_flags;
|
||||
return cl_init->rpc_ops->init_client(new,
|
||||
timeparms, ip_addr,
|
||||
authflavour);
|
||||
return rpc_ops->init_client(new, timeparms, ip_addr,
|
||||
authflavour);
|
||||
}
|
||||
|
||||
spin_unlock(&nn->nfs_client_lock);
|
||||
|
||||
new = cl_init->rpc_ops->alloc_client(cl_init);
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_get_client);
|
||||
|
||||
/*
|
||||
* Mark a server as ready or failed
|
||||
|
@ -474,6 +525,7 @@ void nfs_mark_client_ready(struct nfs_client *clp, int state)
|
|||
clp->cl_cons_state = state;
|
||||
wake_up_all(&nfs_client_active_wq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_mark_client_ready);
|
||||
|
||||
/*
|
||||
* Initialise the timeout values for a connection
|
||||
|
@ -515,6 +567,7 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
|
|||
BUG();
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_init_timeout_values);
|
||||
|
||||
/*
|
||||
* Create an RPC client handle
|
||||
|
@ -554,6 +607,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
|
|||
clp->cl_rpcclient = clnt;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_create_rpc_client);
|
||||
|
||||
/*
|
||||
* Version 2 or 3 client destruction
|
||||
|
@ -605,36 +659,6 @@ static int nfs_start_lockd(struct nfs_server *server)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise an NFSv3 ACL client connection
|
||||
*/
|
||||
#ifdef CONFIG_NFS_V3_ACL
|
||||
static void nfs_init_server_aclclient(struct nfs_server *server)
|
||||
{
|
||||
if (server->nfs_client->rpc_ops->version != 3)
|
||||
goto out_noacl;
|
||||
if (server->flags & NFS_MOUNT_NOACL)
|
||||
goto out_noacl;
|
||||
|
||||
server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
|
||||
if (IS_ERR(server->client_acl))
|
||||
goto out_noacl;
|
||||
|
||||
/* No errors! Assume that Sun nfsacls are supported */
|
||||
server->caps |= NFS_CAP_ACLS;
|
||||
return;
|
||||
|
||||
out_noacl:
|
||||
server->caps &= ~NFS_CAP_ACLS;
|
||||
}
|
||||
#else
|
||||
static inline void nfs_init_server_aclclient(struct nfs_server *server)
|
||||
{
|
||||
server->flags &= ~NFS_MOUNT_NOACL;
|
||||
server->caps &= ~NFS_CAP_ACLS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create a general RPC client
|
||||
*/
|
||||
|
@ -670,6 +694,7 @@ int nfs_init_server_rpcclient(struct nfs_server *server,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
|
||||
|
||||
/**
|
||||
* nfs_init_client - Initialise an NFS2 or NFS3 client
|
||||
|
@ -709,18 +734,20 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp,
|
|||
dprintk("<-- nfs_init_client() = xerror %d\n", error);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
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)
|
||||
const struct nfs_parsed_mount_data *data,
|
||||
struct nfs_subversion *nfs_mod)
|
||||
{
|
||||
struct nfs_client_initdata cl_init = {
|
||||
.hostname = data->nfs_server.hostname,
|
||||
.addr = (const struct sockaddr *)&data->nfs_server.address,
|
||||
.addrlen = data->nfs_server.addrlen,
|
||||
.rpc_ops = NULL,
|
||||
.nfs_mod = nfs_mod,
|
||||
.proto = data->nfs_server.protocol,
|
||||
.net = data->net,
|
||||
};
|
||||
|
@ -730,21 +757,6 @@ static int nfs_init_server(struct nfs_server *server,
|
|||
|
||||
dprintk("--> nfs_init_server()\n");
|
||||
|
||||
switch (data->version) {
|
||||
#ifdef CONFIG_NFS_V2
|
||||
case 2:
|
||||
cl_init.rpc_ops = &nfs_v2_clientops;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_NFS_V3
|
||||
case 3:
|
||||
cl_init.rpc_ops = &nfs_v3_clientops;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
|
||||
data->timeo, data->retrans);
|
||||
if (data->flags & NFS_MOUNT_NORESVPORT)
|
||||
|
@ -798,8 +810,6 @@ static int nfs_init_server(struct nfs_server *server,
|
|||
server->mountd_protocol = data->mount_server.protocol;
|
||||
|
||||
server->namelen = data->namlen;
|
||||
/* Create a client RPC handle for the NFSv3 ACL management interface */
|
||||
nfs_init_server_aclclient(server);
|
||||
dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
|
||||
return 0;
|
||||
|
||||
|
@ -911,6 +921,7 @@ int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs
|
|||
dprintk("nfs_probe_fsinfo: error = %d\n", -error);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_probe_fsinfo);
|
||||
|
||||
/*
|
||||
* Copy useful information when duplicating a server record
|
||||
|
@ -927,6 +938,7 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour
|
|||
target->caps = source->caps;
|
||||
target->options = source->options;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_server_copy_userdata);
|
||||
|
||||
void nfs_server_insert_lists(struct nfs_server *server)
|
||||
{
|
||||
|
@ -940,6 +952,7 @@ void nfs_server_insert_lists(struct nfs_server *server)
|
|||
spin_unlock(&nn->nfs_client_lock);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_server_insert_lists);
|
||||
|
||||
static void nfs_server_remove_lists(struct nfs_server *server)
|
||||
{
|
||||
|
@ -999,6 +1012,7 @@ struct nfs_server *nfs_alloc_server(void)
|
|||
|
||||
return server;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_alloc_server);
|
||||
|
||||
/*
|
||||
* Free up a server record
|
||||
|
@ -1027,13 +1041,14 @@ void nfs_free_server(struct nfs_server *server)
|
|||
nfs_release_automount_timer();
|
||||
dprintk("<-- nfs_free_server()\n");
|
||||
}
|
||||
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(const struct nfs_parsed_mount_data *data,
|
||||
struct nfs_fh *mntfh)
|
||||
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;
|
||||
|
@ -1049,7 +1064,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
|
|||
goto error;
|
||||
|
||||
/* Get a client representation */
|
||||
error = nfs_init_server(server, data);
|
||||
error = nfs_init_server(server, mount_info->parsed, nfs_mod);
|
||||
if (error < 0)
|
||||
goto error;
|
||||
|
||||
|
@ -1058,13 +1073,13 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
|
|||
BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
|
||||
|
||||
/* Probe the root fh to retrieve its FSID */
|
||||
error = nfs_probe_fsinfo(server, mntfh, fattr);
|
||||
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 (!(data->flags & NFS_MOUNT_NORDIRPLUS))
|
||||
if (!(mount_info->parsed->flags & NFS_MOUNT_NORDIRPLUS))
|
||||
server->caps |= NFS_CAP_READDIRPLUS;
|
||||
} else {
|
||||
if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
|
||||
|
@ -1072,7 +1087,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
|
|||
}
|
||||
|
||||
if (!(fattr->valid & NFS_ATTR_FATTR)) {
|
||||
error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr);
|
||||
error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh, fattr);
|
||||
if (error < 0) {
|
||||
dprintk("nfs_create_server: getattr error = %d\n", -error);
|
||||
goto error;
|
||||
|
@ -1094,6 +1109,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
|
|||
nfs_free_server(server);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_create_server);
|
||||
|
||||
/*
|
||||
* Clone an NFS2, NFS3 or NFS4 server record
|
||||
|
@ -1133,8 +1149,6 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
|
|||
flavor);
|
||||
if (error < 0)
|
||||
goto out_free_server;
|
||||
if (!IS_ERR(source->client_acl))
|
||||
nfs_init_server_aclclient(server);
|
||||
|
||||
/* probe the filesystem info for this server filesystem */
|
||||
error = nfs_probe_fsinfo(server, fh, fattr_fsinfo);
|
||||
|
@ -1165,6 +1179,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
|
|||
dprintk("<-- nfs_clone_server() = error %d\n", error);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_clone_server);
|
||||
|
||||
void nfs_clients_init(struct net *net)
|
||||
{
|
||||
|
@ -1172,7 +1187,7 @@ void nfs_clients_init(struct net *net)
|
|||
|
||||
INIT_LIST_HEAD(&nn->nfs_client_list);
|
||||
INIT_LIST_HEAD(&nn->nfs_volume_list);
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
idr_init(&nn->cb_ident_idr);
|
||||
#endif
|
||||
spin_lock_init(&nn->nfs_client_lock);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#ifndef FS_NFS_DELEGATION_H
|
||||
#define FS_NFS_DELEGATION_H
|
||||
|
||||
#if defined(CONFIG_NFS_V4)
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
/*
|
||||
* NFSv4 delegation
|
||||
*/
|
||||
|
|
20
fs/nfs/dir.c
20
fs/nfs/dir.c
|
@ -17,6 +17,7 @@
|
|||
* 6 Jun 1999 Cache readdir lookups in the page cache. -DaveM
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/stat.h>
|
||||
|
@ -935,6 +936,7 @@ void nfs_force_lookup_revalidate(struct inode *dir)
|
|||
{
|
||||
NFS_I(dir)->cache_change_attribute++;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_force_lookup_revalidate);
|
||||
|
||||
/*
|
||||
* A check for whether or not the parent directory has changed.
|
||||
|
@ -1196,6 +1198,7 @@ const struct dentry_operations nfs_dentry_operations = {
|
|||
.d_automount = nfs_d_automount,
|
||||
.d_release = nfs_d_release,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nfs_dentry_operations);
|
||||
|
||||
struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
|
||||
{
|
||||
|
@ -1263,8 +1266,9 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
|
|||
nfs_free_fhandle(fhandle);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_lookup);
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
static int nfs4_lookup_revalidate(struct dentry *, unsigned int);
|
||||
|
||||
const struct dentry_operations nfs4_dentry_operations = {
|
||||
|
@ -1274,6 +1278,7 @@ const struct dentry_operations nfs4_dentry_operations = {
|
|||
.d_automount = nfs_d_automount,
|
||||
.d_release = nfs_d_release,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nfs4_dentry_operations);
|
||||
|
||||
static fmode_t flags_to_mode(int flags)
|
||||
{
|
||||
|
@ -1416,6 +1421,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
|||
|
||||
return finish_no_open(file, res);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_atomic_open);
|
||||
|
||||
static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
|
@ -1508,6 +1514,7 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
|
|||
dput(parent);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_instantiate);
|
||||
|
||||
/*
|
||||
* Following a failed create operation, we drop the dentry rather
|
||||
|
@ -1536,6 +1543,7 @@ int nfs_create(struct inode *dir, struct dentry *dentry,
|
|||
d_drop(dentry);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_create);
|
||||
|
||||
/*
|
||||
* See comments for nfs_proc_create regarding failed operations.
|
||||
|
@ -1563,6 +1571,7 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
|
|||
d_drop(dentry);
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_mknod);
|
||||
|
||||
/*
|
||||
* See comments for nfs_proc_create regarding failed operations.
|
||||
|
@ -1586,6 +1595,7 @@ int nfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||
d_drop(dentry);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_mkdir);
|
||||
|
||||
static void nfs_dentry_handle_enoent(struct dentry *dentry)
|
||||
{
|
||||
|
@ -1609,6 +1619,7 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry)
|
|||
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_rmdir);
|
||||
|
||||
/*
|
||||
* Remove a file after making sure there are no pending writes,
|
||||
|
@ -1680,6 +1691,7 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
|
|||
d_rehash(dentry);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_unlink);
|
||||
|
||||
/*
|
||||
* To create a symbolic link, most file systems instantiate a new inode,
|
||||
|
@ -1750,6 +1762,7 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_symlink);
|
||||
|
||||
int
|
||||
nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
||||
|
@ -1771,6 +1784,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
|||
}
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_link);
|
||||
|
||||
/*
|
||||
* RENAME
|
||||
|
@ -1869,6 +1883,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|||
dput(dentry);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_rename);
|
||||
|
||||
static DEFINE_SPINLOCK(nfs_access_lru_lock);
|
||||
static LIST_HEAD(nfs_access_lru_list);
|
||||
|
@ -1969,6 +1984,7 @@ void nfs_access_zap_cache(struct inode *inode)
|
|||
spin_unlock(&nfs_access_lru_lock);
|
||||
nfs_access_free_list(&head);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_access_zap_cache);
|
||||
|
||||
static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred)
|
||||
{
|
||||
|
@ -2129,6 +2145,7 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
|
|||
{
|
||||
return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_may_open);
|
||||
|
||||
int nfs_permission(struct inode *inode, int mask)
|
||||
{
|
||||
|
@ -2188,6 +2205,7 @@ int nfs_permission(struct inode *inode, int mask)
|
|||
res = generic_permission(inode, mask);
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_permission);
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
|
|
@ -460,7 +460,7 @@ static void nfs_inode_dio_write_done(struct inode *inode)
|
|||
inode_dio_done(inode);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
|
||||
#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
|
||||
static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
|
||||
{
|
||||
struct nfs_pageio_descriptor desc;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#ifdef CONFIG_NFS_USE_KERNEL_DNS
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/dns_resolver.h>
|
||||
#include "dns_resolve.h"
|
||||
|
@ -27,9 +28,11 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
|
|||
kfree(ip_addr);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_dns_resolve_name);
|
||||
|
||||
#else
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/hash.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kmod.h>
|
||||
|
@ -345,6 +348,7 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name,
|
|||
ret = -ESRCH;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_dns_resolve_name);
|
||||
|
||||
int nfs_dns_resolver_cache_init(struct net *net)
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* nfs regular file handling functions
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -52,6 +53,7 @@ int nfs_check_flags(int flags)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_check_flags);
|
||||
|
||||
/*
|
||||
* Open file
|
||||
|
@ -84,6 +86,7 @@ nfs_file_release(struct inode *inode, struct file *filp)
|
|||
nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
|
||||
return nfs_release(inode, filp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_file_release);
|
||||
|
||||
/**
|
||||
* nfs_revalidate_size - Revalidate the file size
|
||||
|
@ -137,6 +140,7 @@ loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
|
|||
|
||||
return generic_file_llseek(filp, offset, origin);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_file_llseek);
|
||||
|
||||
/*
|
||||
* Flush all dirty pages, and check for write errors.
|
||||
|
@ -165,6 +169,7 @@ nfs_file_flush(struct file *file, fl_owner_t id)
|
|||
/* Flush writes to the server and return any errors */
|
||||
return vfs_fsync(file, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_file_flush);
|
||||
|
||||
ssize_t
|
||||
nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
|
||||
|
@ -189,6 +194,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
|
|||
}
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_file_read);
|
||||
|
||||
ssize_t
|
||||
nfs_file_splice_read(struct file *filp, loff_t *ppos,
|
||||
|
@ -211,6 +217,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
|
|||
}
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_file_splice_read);
|
||||
|
||||
int
|
||||
nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
|
||||
|
@ -232,6 +239,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
|
|||
}
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_file_mmap);
|
||||
|
||||
/*
|
||||
* Flush any dirty pages for this process, and check for write errors.
|
||||
|
@ -270,6 +278,7 @@ nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync)
|
|||
ret = status;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_file_fsync_commit);
|
||||
|
||||
static int
|
||||
nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
|
@ -447,8 +456,11 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
|
|||
|
||||
dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
|
||||
|
||||
/* Only do I/O if gfp is a superset of GFP_KERNEL */
|
||||
if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL) {
|
||||
/* Only do I/O if gfp is a superset of GFP_KERNEL, and we're not
|
||||
* doing this memory reclaim for a fs-related allocation.
|
||||
*/
|
||||
if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL &&
|
||||
!(current->flags & PF_FSTRANS)) {
|
||||
int how = FLUSH_SYNC;
|
||||
|
||||
/* Don't let kswapd deadlock waiting for OOM RPC calls */
|
||||
|
@ -611,6 +623,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
|
|||
printk(KERN_INFO "NFS: attempt to write to active swap file!\n");
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_file_write);
|
||||
|
||||
ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
|
||||
struct file *filp, loff_t *ppos,
|
||||
|
@ -642,6 +655,7 @@ ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
|
|||
nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_file_splice_write);
|
||||
|
||||
static int
|
||||
do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
|
||||
|
@ -802,6 +816,7 @@ int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
|
|||
out_err:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_lock);
|
||||
|
||||
/*
|
||||
* Lock a (portion of) a file
|
||||
|
@ -819,6 +834,15 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
|
|||
if (!(fl->fl_flags & FL_FLOCK))
|
||||
return -ENOLCK;
|
||||
|
||||
/*
|
||||
* The NFSv4 protocol doesn't support LOCK_MAND, which is not part of
|
||||
* any standard. In principle we might be able to support LOCK_MAND
|
||||
* on NFSv2/3 since NLMv3/4 support DOS share modes, but for now the
|
||||
* NFS code is not set up for it.
|
||||
*/
|
||||
if (fl->fl_type & LOCK_MAND)
|
||||
return -EINVAL;
|
||||
|
||||
if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FLOCK)
|
||||
is_local = 1;
|
||||
|
||||
|
@ -831,6 +855,7 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
|
|||
return do_unlk(filp, cmd, fl, is_local);
|
||||
return do_setlk(filp, cmd, fl, is_local);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_flock);
|
||||
|
||||
/*
|
||||
* There is no protocol support for leases, so we have no way to implement
|
||||
|
@ -843,6 +868,7 @@ int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
|
|||
file->f_path.dentry->d_name.name, arg);
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_setlease);
|
||||
|
||||
const struct file_operations nfs_file_operations = {
|
||||
.llseek = nfs_file_llseek,
|
||||
|
@ -862,3 +888,4 @@ const struct file_operations nfs_file_operations = {
|
|||
.check_flags = nfs_check_flags,
|
||||
.setlease = nfs_setlease,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nfs_file_operations);
|
||||
|
|
|
@ -52,8 +52,6 @@
|
|||
|
||||
#define NFS_UINT_MAXLEN 11
|
||||
|
||||
/* Default cache timeout is 10 minutes */
|
||||
unsigned int nfs_idmap_cache_timeout = 600;
|
||||
static const struct cred *id_resolver_cache;
|
||||
static struct key_type key_type_id_resolver_legacy;
|
||||
|
||||
|
@ -205,12 +203,18 @@ static int nfs_idmap_init_keyring(void)
|
|||
if (ret < 0)
|
||||
goto failed_put_key;
|
||||
|
||||
ret = register_key_type(&key_type_id_resolver_legacy);
|
||||
if (ret < 0)
|
||||
goto failed_reg_legacy;
|
||||
|
||||
set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
|
||||
cred->thread_keyring = keyring;
|
||||
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
|
||||
id_resolver_cache = cred;
|
||||
return 0;
|
||||
|
||||
failed_reg_legacy:
|
||||
unregister_key_type(&key_type_id_resolver);
|
||||
failed_put_key:
|
||||
key_put(keyring);
|
||||
failed_put_cred:
|
||||
|
@ -222,6 +226,7 @@ static void nfs_idmap_quit_keyring(void)
|
|||
{
|
||||
key_revoke(id_resolver_cache->thread_keyring);
|
||||
unregister_key_type(&key_type_id_resolver);
|
||||
unregister_key_type(&key_type_id_resolver_legacy);
|
||||
put_cred(id_resolver_cache);
|
||||
}
|
||||
|
||||
|
@ -359,7 +364,6 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ
|
|||
}
|
||||
|
||||
/* idmap classic begins here */
|
||||
module_param(nfs_idmap_cache_timeout, int, 0644);
|
||||
|
||||
enum {
|
||||
Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err
|
||||
|
@ -385,7 +389,7 @@ static const struct rpc_pipe_ops idmap_upcall_ops = {
|
|||
};
|
||||
|
||||
static struct key_type key_type_id_resolver_legacy = {
|
||||
.name = "id_resolver",
|
||||
.name = "id_legacy",
|
||||
.instantiate = user_instantiate,
|
||||
.match = user_match,
|
||||
.revoke = user_revoke,
|
||||
|
@ -674,6 +678,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
|
|||
if (ret < 0)
|
||||
goto out2;
|
||||
|
||||
BUG_ON(idmap->idmap_key_cons != NULL);
|
||||
idmap->idmap_key_cons = cons;
|
||||
|
||||
ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
|
||||
|
@ -687,8 +692,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
|
|||
out1:
|
||||
kfree(msg);
|
||||
out0:
|
||||
key_revoke(cons->key);
|
||||
key_revoke(cons->authkey);
|
||||
complete_request_key(cons, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -722,11 +726,18 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
|||
{
|
||||
struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
|
||||
struct idmap *idmap = (struct idmap *)rpci->private;
|
||||
struct key_construction *cons = idmap->idmap_key_cons;
|
||||
struct key_construction *cons;
|
||||
struct idmap_msg im;
|
||||
size_t namelen_in;
|
||||
int ret;
|
||||
|
||||
/* If instantiation is successful, anyone waiting for key construction
|
||||
* will have been woken up and someone else may now have used
|
||||
* idmap_key_cons - so after this point we may no longer touch it.
|
||||
*/
|
||||
cons = ACCESS_ONCE(idmap->idmap_key_cons);
|
||||
idmap->idmap_key_cons = NULL;
|
||||
|
||||
if (mlen != sizeof(im)) {
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
|
@ -739,7 +750,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
|||
|
||||
if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
|
||||
ret = mlen;
|
||||
complete_request_key(idmap->idmap_key_cons, -ENOKEY);
|
||||
complete_request_key(cons, -ENOKEY);
|
||||
goto out_incomplete;
|
||||
}
|
||||
|
||||
|
@ -756,7 +767,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
|||
}
|
||||
|
||||
out:
|
||||
complete_request_key(idmap->idmap_key_cons, ret);
|
||||
complete_request_key(cons, ret);
|
||||
out_incomplete:
|
||||
return ret;
|
||||
}
|
||||
|
|
105
fs/nfs/inode.c
105
fs/nfs/inode.c
|
@ -50,6 +50,7 @@
|
|||
#include "fscache.h"
|
||||
#include "dns_resolve.h"
|
||||
#include "pnfs.h"
|
||||
#include "nfs.h"
|
||||
#include "netns.h"
|
||||
|
||||
#define NFSDBG_FACILITY NFSDBG_VFS
|
||||
|
@ -81,6 +82,7 @@ int nfs_wait_bit_killable(void *word)
|
|||
freezable_schedule();
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_wait_bit_killable);
|
||||
|
||||
/**
|
||||
* nfs_compat_user_ino64 - returns the user-visible inode number
|
||||
|
@ -105,7 +107,7 @@ u64 nfs_compat_user_ino64(u64 fileid)
|
|||
return ino;
|
||||
}
|
||||
|
||||
static void nfs_clear_inode(struct inode *inode)
|
||||
void nfs_clear_inode(struct inode *inode)
|
||||
{
|
||||
/*
|
||||
* The following should never happen...
|
||||
|
@ -116,6 +118,7 @@ static void nfs_clear_inode(struct inode *inode)
|
|||
nfs_access_zap_cache(inode);
|
||||
nfs_fscache_release_inode_cookie(inode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_clear_inode);
|
||||
|
||||
void nfs_evict_inode(struct inode *inode)
|
||||
{
|
||||
|
@ -185,6 +188,7 @@ void nfs_zap_acl_cache(struct inode *inode)
|
|||
NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL;
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_zap_acl_cache);
|
||||
|
||||
void nfs_invalidate_atime(struct inode *inode)
|
||||
{
|
||||
|
@ -192,6 +196,7 @@ void nfs_invalidate_atime(struct inode *inode)
|
|||
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_invalidate_atime);
|
||||
|
||||
/*
|
||||
* Invalidate, but do not unhash, the inode.
|
||||
|
@ -390,6 +395,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
|
|||
dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode));
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_fhget);
|
||||
|
||||
#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN)
|
||||
|
||||
|
@ -437,6 +443,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
out:
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_setattr);
|
||||
|
||||
/**
|
||||
* nfs_vmtruncate - unmap mappings "freed" by truncate() syscall
|
||||
|
@ -495,6 +502,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
|
|||
nfs_vmtruncate(inode, attr->ia_size);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
|
||||
|
||||
int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
|
||||
{
|
||||
|
@ -534,6 +542,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
|
|||
out:
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_getattr);
|
||||
|
||||
static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
|
||||
{
|
||||
|
@ -622,6 +631,7 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
|
|||
return;
|
||||
nfs_revalidate_inode(server, inode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_close_context);
|
||||
|
||||
struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode)
|
||||
{
|
||||
|
@ -648,6 +658,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f
|
|||
ctx->mdsthreshold = NULL;
|
||||
return ctx;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(alloc_nfs_open_context);
|
||||
|
||||
struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
|
||||
{
|
||||
|
@ -655,6 +666,7 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
|
|||
atomic_inc(&ctx->lock_context.count);
|
||||
return ctx;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_nfs_open_context);
|
||||
|
||||
static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
|
||||
{
|
||||
|
@ -682,6 +694,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
|
|||
{
|
||||
__put_nfs_open_context(ctx, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(put_nfs_open_context);
|
||||
|
||||
/*
|
||||
* Ensure that mmap has a recent RPC credential for use when writing out
|
||||
|
@ -697,6 +710,7 @@ void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
|
|||
list_add(&ctx->list, &nfsi->open_files);
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_file_set_open_context);
|
||||
|
||||
/*
|
||||
* Given an inode, search for an open context with the desired characteristics
|
||||
|
@ -841,6 +855,7 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
|
|||
return NFS_STALE(inode) ? -ESTALE : 0;
|
||||
return __nfs_revalidate_inode(server, inode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_revalidate_inode);
|
||||
|
||||
static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
|
||||
{
|
||||
|
@ -1027,6 +1042,7 @@ void nfs_fattr_init(struct nfs_fattr *fattr)
|
|||
fattr->owner_name = NULL;
|
||||
fattr->group_name = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_fattr_init);
|
||||
|
||||
struct nfs_fattr *nfs_alloc_fattr(void)
|
||||
{
|
||||
|
@ -1037,6 +1053,7 @@ struct nfs_fattr *nfs_alloc_fattr(void)
|
|||
nfs_fattr_init(fattr);
|
||||
return fattr;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_alloc_fattr);
|
||||
|
||||
struct nfs_fh *nfs_alloc_fhandle(void)
|
||||
{
|
||||
|
@ -1047,6 +1064,7 @@ struct nfs_fh *nfs_alloc_fhandle(void)
|
|||
fh->size = 0;
|
||||
return fh;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_alloc_fhandle);
|
||||
|
||||
#ifdef NFS_DEBUG
|
||||
/*
|
||||
|
@ -1167,6 +1185,7 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|||
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_refresh_inode);
|
||||
|
||||
static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
|
||||
{
|
||||
|
@ -1203,6 +1222,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|||
spin_unlock(&inode->i_lock);
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_post_op_update_inode);
|
||||
|
||||
/**
|
||||
* nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache
|
||||
|
@ -1254,6 +1274,7 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa
|
|||
spin_unlock(&inode->i_lock);
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);
|
||||
|
||||
/*
|
||||
* Many nfs protocol calls return the new file attributes after
|
||||
|
@ -1471,27 +1492,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|||
return -ESTALE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
|
||||
/*
|
||||
* Clean out any remaining NFSv4 state that might be left over due
|
||||
* to open() calls that passed nfs_atomic_lookup, but failed to call
|
||||
* nfs_open().
|
||||
*/
|
||||
void nfs4_evict_inode(struct inode *inode)
|
||||
{
|
||||
truncate_inode_pages(&inode->i_data, 0);
|
||||
clear_inode(inode);
|
||||
pnfs_return_layout(inode);
|
||||
pnfs_destroy_layout(NFS_I(inode));
|
||||
/* If we are holding a delegation, return it! */
|
||||
nfs_inode_return_delegation_noreclaim(inode);
|
||||
/* First call standard NFS clear_inode() code */
|
||||
nfs_clear_inode(inode);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct inode *nfs_alloc_inode(struct super_block *sb)
|
||||
{
|
||||
struct nfs_inode *nfsi;
|
||||
|
@ -1504,11 +1504,12 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
|
|||
nfsi->acl_access = ERR_PTR(-EAGAIN);
|
||||
nfsi->acl_default = ERR_PTR(-EAGAIN);
|
||||
#endif
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
nfsi->nfs4_acl = NULL;
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
return &nfsi->vfs_inode;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_alloc_inode);
|
||||
|
||||
static void nfs_i_callback(struct rcu_head *head)
|
||||
{
|
||||
|
@ -1520,10 +1521,11 @@ void nfs_destroy_inode(struct inode *inode)
|
|||
{
|
||||
call_rcu(&inode->i_rcu, nfs_i_callback);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_destroy_inode);
|
||||
|
||||
static inline void nfs4_init_once(struct nfs_inode *nfsi)
|
||||
{
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
INIT_LIST_HEAD(&nfsi->open_states);
|
||||
nfsi->delegation = NULL;
|
||||
nfsi->delegation_state = 0;
|
||||
|
@ -1569,6 +1571,7 @@ static void nfs_destroy_inodecache(void)
|
|||
}
|
||||
|
||||
struct workqueue_struct *nfsiod_workqueue;
|
||||
EXPORT_SYMBOL_GPL(nfsiod_workqueue);
|
||||
|
||||
/*
|
||||
* start up the nfsiod workqueue
|
||||
|
@ -1629,94 +1632,80 @@ static int __init init_nfs_fs(void)
|
|||
|
||||
err = nfs_dns_resolver_init();
|
||||
if (err < 0)
|
||||
goto out11;
|
||||
goto out10;;
|
||||
|
||||
err = register_pernet_subsys(&nfs_net_ops);
|
||||
if (err < 0)
|
||||
goto out10;
|
||||
goto out9;
|
||||
|
||||
err = nfs_fscache_register();
|
||||
if (err < 0)
|
||||
goto out9;
|
||||
goto out8;
|
||||
|
||||
err = nfsiod_start();
|
||||
if (err)
|
||||
goto out8;
|
||||
goto out7;
|
||||
|
||||
err = nfs_fs_proc_init();
|
||||
if (err)
|
||||
goto out7;
|
||||
goto out6;
|
||||
|
||||
err = nfs_init_nfspagecache();
|
||||
if (err)
|
||||
goto out6;
|
||||
goto out5;
|
||||
|
||||
err = nfs_init_inodecache();
|
||||
if (err)
|
||||
goto out5;
|
||||
goto out4;
|
||||
|
||||
err = nfs_init_readpagecache();
|
||||
if (err)
|
||||
goto out4;
|
||||
goto out3;
|
||||
|
||||
err = nfs_init_writepagecache();
|
||||
if (err)
|
||||
goto out3;
|
||||
goto out2;
|
||||
|
||||
err = nfs_init_directcache();
|
||||
if (err)
|
||||
goto out2;
|
||||
goto out1;
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
rpc_proc_register(&init_net, &nfs_rpcstat);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
err = init_nfs_v4();
|
||||
if (err)
|
||||
goto out1;
|
||||
#endif
|
||||
|
||||
if ((err = register_nfs_fs()) != 0)
|
||||
goto out0;
|
||||
|
||||
return 0;
|
||||
out0:
|
||||
#ifdef CONFIG_NFS_V4
|
||||
exit_nfs_v4();
|
||||
out1:
|
||||
#endif
|
||||
#ifdef CONFIG_PROC_FS
|
||||
rpc_proc_unregister(&init_net, "nfs");
|
||||
#endif
|
||||
nfs_destroy_directcache();
|
||||
out2:
|
||||
out1:
|
||||
nfs_destroy_writepagecache();
|
||||
out3:
|
||||
out2:
|
||||
nfs_destroy_readpagecache();
|
||||
out4:
|
||||
out3:
|
||||
nfs_destroy_inodecache();
|
||||
out5:
|
||||
out4:
|
||||
nfs_destroy_nfspagecache();
|
||||
out6:
|
||||
out5:
|
||||
nfs_fs_proc_exit();
|
||||
out7:
|
||||
out6:
|
||||
nfsiod_stop();
|
||||
out8:
|
||||
out7:
|
||||
nfs_fscache_unregister();
|
||||
out9:
|
||||
out8:
|
||||
unregister_pernet_subsys(&nfs_net_ops);
|
||||
out10:
|
||||
out9:
|
||||
nfs_dns_resolver_destroy();
|
||||
out11:
|
||||
out10:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit exit_nfs_fs(void)
|
||||
{
|
||||
#ifdef CONFIG_NFS_V4
|
||||
exit_nfs_v4();
|
||||
#endif
|
||||
nfs_destroy_directcache();
|
||||
nfs_destroy_writepagecache();
|
||||
nfs_destroy_readpagecache();
|
||||
|
|
|
@ -90,7 +90,7 @@ struct nfs_client_initdata {
|
|||
const char *hostname;
|
||||
const struct sockaddr *addr;
|
||||
size_t addrlen;
|
||||
const struct nfs_rpc_ops *rpc_ops;
|
||||
struct nfs_subversion *nfs_mod;
|
||||
int proto;
|
||||
u32 minorversion;
|
||||
struct net *net;
|
||||
|
@ -187,12 +187,11 @@ extern struct nfs_client *nfs4_find_client_ident(struct net *, int);
|
|||
extern struct nfs_client *
|
||||
nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
|
||||
struct nfs4_sessionid *);
|
||||
extern struct nfs_server *nfs_create_server(
|
||||
const struct nfs_parsed_mount_data *,
|
||||
struct nfs_fh *);
|
||||
extern struct nfs_server *nfs_create_server(struct nfs_mount_info *,
|
||||
struct nfs_subversion *);
|
||||
extern struct nfs_server *nfs4_create_server(
|
||||
const struct nfs_parsed_mount_data *,
|
||||
struct nfs_fh *);
|
||||
struct nfs_mount_info *,
|
||||
struct nfs_subversion *);
|
||||
extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
|
||||
struct nfs_fh *);
|
||||
extern void nfs_free_server(struct nfs_server *server);
|
||||
|
@ -224,6 +223,13 @@ static inline void nfs_fs_proc_exit(void)
|
|||
int nfs_sockaddr_match_ipaddr(const struct sockaddr *, const struct sockaddr *);
|
||||
#endif
|
||||
|
||||
/* nfs3client.c */
|
||||
#if IS_ENABLED(CONFIG_NFS_V3)
|
||||
struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subversion *);
|
||||
struct nfs_server *nfs3_clone_server(struct nfs_server *, struct nfs_fh *,
|
||||
struct nfs_fattr *, rpc_authflavor_t);
|
||||
#endif
|
||||
|
||||
/* callback_xdr.c */
|
||||
extern struct svc_version nfs4_callback_version1;
|
||||
extern struct svc_version nfs4_callback_version4;
|
||||
|
@ -256,7 +262,7 @@ extern int nfs3_decode_dirent(struct xdr_stream *,
|
|||
struct nfs_entry *, int);
|
||||
|
||||
/* nfs4xdr.c */
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
extern int nfs4_decode_dirent(struct xdr_stream *,
|
||||
struct nfs_entry *, int);
|
||||
#endif
|
||||
|
@ -266,7 +272,7 @@ extern const u32 nfs41_maxwrite_overhead;
|
|||
#endif
|
||||
|
||||
/* nfs4proc.c */
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
extern struct rpc_procinfo nfs4_procedures[];
|
||||
#endif
|
||||
|
||||
|
@ -313,24 +319,26 @@ extern struct workqueue_struct *nfsiod_workqueue;
|
|||
extern struct inode *nfs_alloc_inode(struct super_block *sb);
|
||||
extern void nfs_destroy_inode(struct inode *);
|
||||
extern int nfs_write_inode(struct inode *, struct writeback_control *);
|
||||
extern void nfs_clear_inode(struct inode *);
|
||||
extern void nfs_evict_inode(struct inode *);
|
||||
#ifdef CONFIG_NFS_V4
|
||||
extern void nfs4_evict_inode(struct inode *);
|
||||
#endif
|
||||
void nfs_zap_acl_cache(struct inode *inode);
|
||||
extern int nfs_wait_bit_killable(void *word);
|
||||
|
||||
/* super.c */
|
||||
extern const struct super_operations nfs_sops;
|
||||
extern struct file_system_type nfs_fs_type;
|
||||
extern struct file_system_type nfs_xdev_fs_type;
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
extern struct file_system_type nfs4_xdev_fs_type;
|
||||
extern struct file_system_type nfs4_referral_fs_type;
|
||||
#endif
|
||||
struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *,
|
||||
struct nfs_subversion *);
|
||||
void nfs_initialise_sb(struct super_block *);
|
||||
int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
|
||||
int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
|
||||
struct dentry *nfs_fs_mount_common(struct file_system_type *, struct nfs_server *,
|
||||
int, const char *, struct nfs_mount_info *);
|
||||
struct dentry *nfs_fs_mount_common(struct nfs_server *, int, const char *,
|
||||
struct nfs_mount_info *, struct nfs_subversion *);
|
||||
struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *);
|
||||
struct dentry * nfs_xdev_mount_common(struct file_system_type *, int,
|
||||
const char *, struct nfs_mount_info *);
|
||||
|
@ -356,7 +364,7 @@ struct vfsmount *nfs_do_submount(struct dentry *, struct nfs_fh *,
|
|||
/* getroot.c */
|
||||
extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,
|
||||
const char *);
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *,
|
||||
const char *);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* NFS namespace
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/mount.h>
|
||||
|
@ -112,6 +113,7 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
|
|||
Elong:
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_path);
|
||||
|
||||
/*
|
||||
* nfs_d_automount - Handle crossing a mountpoint on the server
|
||||
|
@ -195,20 +197,7 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
|
|||
const char *devname,
|
||||
struct nfs_clone_mount *mountdata)
|
||||
{
|
||||
#ifdef CONFIG_NFS_V4
|
||||
struct vfsmount *mnt = ERR_PTR(-EINVAL);
|
||||
switch (server->nfs_client->rpc_ops->version) {
|
||||
case 2:
|
||||
case 3:
|
||||
mnt = vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
|
||||
break;
|
||||
case 4:
|
||||
mnt = vfs_kern_mount(&nfs4_xdev_fs_type, 0, devname, mountdata);
|
||||
}
|
||||
return mnt;
|
||||
#else
|
||||
return vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,6 +242,7 @@ struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh,
|
|||
dprintk("<-- nfs_do_submount() = %p\n", mnt);
|
||||
return mnt;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_do_submount);
|
||||
|
||||
struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry,
|
||||
struct nfs_fh *fh, struct nfs_fattr *fattr)
|
||||
|
@ -268,3 +258,4 @@ struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry,
|
|||
|
||||
return nfs_do_submount(dentry, fh, fattr, server->client->cl_auth->au_flavor);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_submount);
|
||||
|
|
|
@ -20,7 +20,7 @@ struct nfs_net {
|
|||
wait_queue_head_t bl_wq;
|
||||
struct list_head nfs_client_list;
|
||||
struct list_head nfs_volume_list;
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
struct idr cb_ident_idr; /* Protected by nfs_client_lock */
|
||||
#endif
|
||||
spinlock_t nfs_client_lock;
|
||||
|
|
29
fs/nfs/nfs.h
Normal file
29
fs/nfs/nfs.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Netapp, Inc. All rights reserved.
|
||||
*
|
||||
* Function and structures exported by the NFS module
|
||||
* for use by NFS version-specific modules.
|
||||
*/
|
||||
#ifndef __LINUX_INTERNAL_NFS_H
|
||||
#define __LINUX_INTERNAL_NFS_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/sunrpc/sched.h>
|
||||
#include <linux/nfs_xdr.h>
|
||||
|
||||
struct nfs_subversion {
|
||||
struct module *owner; /* THIS_MODULE pointer */
|
||||
struct file_system_type *nfs_fs; /* NFS filesystem type */
|
||||
const struct rpc_version *rpc_vers; /* NFS version information */
|
||||
const struct nfs_rpc_ops *rpc_ops; /* NFS operations */
|
||||
const struct super_operations *sops; /* NFS Super operations */
|
||||
const struct xattr_handler **xattr; /* NFS xattr handlers */
|
||||
struct list_head list; /* List of NFS versions */
|
||||
};
|
||||
|
||||
struct nfs_subversion *get_nfs_version(unsigned int);
|
||||
void put_nfs_version(struct nfs_subversion *);
|
||||
void register_nfs_version(struct nfs_subversion *);
|
||||
void unregister_nfs_version(struct nfs_subversion *);
|
||||
|
||||
#endif /* __LINUX_INTERNAL_NFS_H */
|
31
fs/nfs/nfs2super.c
Normal file
31
fs/nfs/nfs2super.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Netapp, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/nfs_fs.h>
|
||||
#include "internal.h"
|
||||
#include "nfs.h"
|
||||
|
||||
static struct nfs_subversion nfs_v2 = {
|
||||
.owner = THIS_MODULE,
|
||||
.nfs_fs = &nfs_fs_type,
|
||||
.rpc_vers = &nfs_version2,
|
||||
.rpc_ops = &nfs_v2_clientops,
|
||||
.sops = &nfs_sops,
|
||||
};
|
||||
|
||||
static int __init init_nfs_v2(void)
|
||||
{
|
||||
register_nfs_version(&nfs_v2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit exit_nfs_v2(void)
|
||||
{
|
||||
unregister_nfs_version(&nfs_v2);
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(init_nfs_v2);
|
||||
module_exit(exit_nfs_v2);
|
65
fs/nfs/nfs3client.c
Normal file
65
fs/nfs/nfs3client.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
#include <linux/nfs_fs.h>
|
||||
#include <linux/nfs_mount.h>
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_NFS_V3_ACL
|
||||
static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
|
||||
static const struct rpc_version *nfsacl_version[] = {
|
||||
[3] = &nfsacl_version3,
|
||||
};
|
||||
|
||||
const struct rpc_program nfsacl_program = {
|
||||
.name = "nfsacl",
|
||||
.number = NFS_ACL_PROGRAM,
|
||||
.nrvers = ARRAY_SIZE(nfsacl_version),
|
||||
.version = nfsacl_version,
|
||||
.stats = &nfsacl_rpcstat,
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialise an NFSv3 ACL client connection
|
||||
*/
|
||||
static void nfs_init_server_aclclient(struct nfs_server *server)
|
||||
{
|
||||
if (server->flags & NFS_MOUNT_NOACL)
|
||||
goto out_noacl;
|
||||
|
||||
server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
|
||||
if (IS_ERR(server->client_acl))
|
||||
goto out_noacl;
|
||||
|
||||
/* No errors! Assume that Sun nfsacls are supported */
|
||||
server->caps |= NFS_CAP_ACLS;
|
||||
return;
|
||||
|
||||
out_noacl:
|
||||
server->caps &= ~NFS_CAP_ACLS;
|
||||
}
|
||||
#else
|
||||
static inline void nfs_init_server_aclclient(struct nfs_server *server)
|
||||
{
|
||||
server->flags &= ~NFS_MOUNT_NOACL;
|
||||
server->caps &= ~NFS_CAP_ACLS;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct nfs_server *nfs3_create_server(struct nfs_mount_info *mount_info,
|
||||
struct nfs_subversion *nfs_mod)
|
||||
{
|
||||
struct nfs_server *server = nfs_create_server(mount_info, nfs_mod);
|
||||
/* Create a client RPC handle for the NFS v3 ACL management interface */
|
||||
if (!IS_ERR(server))
|
||||
nfs_init_server_aclclient(server);
|
||||
return server;
|
||||
}
|
||||
|
||||
struct nfs_server *nfs3_clone_server(struct nfs_server *source,
|
||||
struct nfs_fh *fh,
|
||||
struct nfs_fattr *fattr,
|
||||
rpc_authflavor_t flavor)
|
||||
{
|
||||
struct nfs_server *server = nfs_clone_server(source, fh, fattr, flavor);
|
||||
if (!IS_ERR(server) && !IS_ERR(source->client_acl))
|
||||
nfs_init_server_aclclient(server);
|
||||
return server;
|
||||
}
|
|
@ -925,6 +925,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
|
|||
.file_ops = &nfs_file_operations,
|
||||
.getroot = nfs3_proc_get_root,
|
||||
.submount = nfs_submount,
|
||||
.try_mount = nfs_try_mount,
|
||||
.getattr = nfs3_proc_getattr,
|
||||
.setattr = nfs3_proc_setattr,
|
||||
.lookup = nfs3_proc_lookup,
|
||||
|
@ -968,4 +969,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
|
|||
.alloc_client = nfs_alloc_client,
|
||||
.init_client = nfs_init_client,
|
||||
.free_client = nfs_free_client,
|
||||
.create_server = nfs3_create_server,
|
||||
.clone_server = nfs3_clone_server,
|
||||
};
|
||||
|
|
31
fs/nfs/nfs3super.c
Normal file
31
fs/nfs/nfs3super.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Netapp, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/nfs_fs.h>
|
||||
#include "internal.h"
|
||||
#include "nfs.h"
|
||||
|
||||
static struct nfs_subversion nfs_v3 = {
|
||||
.owner = THIS_MODULE,
|
||||
.nfs_fs = &nfs_fs_type,
|
||||
.rpc_vers = &nfs_version3,
|
||||
.rpc_ops = &nfs_v3_clientops,
|
||||
.sops = &nfs_sops,
|
||||
};
|
||||
|
||||
static int __init init_nfs_v3(void)
|
||||
{
|
||||
register_nfs_version(&nfs_v3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit exit_nfs_v3(void)
|
||||
{
|
||||
unregister_nfs_version(&nfs_v3);
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(init_nfs_v3);
|
||||
module_exit(exit_nfs_v3);
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef __LINUX_FS_NFS_NFS4_FS_H
|
||||
#define __LINUX_FS_NFS_NFS4_FS_H
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
|
||||
struct idmap;
|
||||
|
||||
|
@ -205,9 +205,6 @@ extern const struct dentry_operations nfs4_dentry_operations;
|
|||
int nfs_atomic_open(struct inode *, struct dentry *, struct file *,
|
||||
unsigned, umode_t, int *);
|
||||
|
||||
/* write.c */
|
||||
int nfs4_write_inode(struct inode *, struct writeback_control *);
|
||||
|
||||
/* nfs4namespace.c */
|
||||
rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *);
|
||||
struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
|
||||
|
@ -366,9 +363,11 @@ extern const nfs4_stateid zero_stateid;
|
|||
|
||||
/* nfs4super.c */
|
||||
struct nfs_mount_info;
|
||||
struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *);
|
||||
int init_nfs_v4(void);
|
||||
void exit_nfs_v4(void);
|
||||
extern struct nfs_subversion nfs_v4;
|
||||
struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *);
|
||||
extern bool nfs4_disable_idmapping;
|
||||
extern unsigned short max_session_slots;
|
||||
extern unsigned short send_implementation_id;
|
||||
|
||||
/* nfs4sysctl.c */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
|
||||
#define NFSDBG_FACILITY NFSDBG_CLIENT
|
||||
|
||||
/*
|
||||
* Turn off NFSv4 uid/gid mapping when using AUTH_SYS
|
||||
*/
|
||||
static bool nfs4_disable_idmapping = true;
|
||||
|
||||
/*
|
||||
* Get a unique NFSv4.0 callback identifier which will be used
|
||||
* by the V4.0 callback service to lookup the nfs_client struct
|
||||
|
@ -357,7 +352,7 @@ static int nfs4_set_client(struct nfs_server *server,
|
|||
.hostname = hostname,
|
||||
.addr = addr,
|
||||
.addrlen = addrlen,
|
||||
.rpc_ops = &nfs_v4_clientops,
|
||||
.nfs_mod = &nfs_v4,
|
||||
.proto = proto,
|
||||
.minorversion = minorversion,
|
||||
.net = net,
|
||||
|
@ -411,7 +406,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
|
|||
struct nfs_client_initdata cl_init = {
|
||||
.addr = ds_addr,
|
||||
.addrlen = ds_addrlen,
|
||||
.rpc_ops = &nfs_v4_clientops,
|
||||
.nfs_mod = &nfs_v4,
|
||||
.proto = ds_proto,
|
||||
.minorversion = mds_clp->cl_minorversion,
|
||||
.net = mds_clp->cl_net,
|
||||
|
@ -574,8 +569,10 @@ static int nfs4_init_server(struct nfs_server *server,
|
|||
* Create a version 4 volume record
|
||||
* - keyed on server and FSID
|
||||
*/
|
||||
struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
|
||||
struct nfs_fh *mntfh)
|
||||
/*struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
|
||||
struct nfs_fh *mntfh)*/
|
||||
struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,
|
||||
struct nfs_subversion *nfs_mod)
|
||||
{
|
||||
struct nfs_server *server;
|
||||
int error;
|
||||
|
@ -587,11 +584,11 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
|
|||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/* set up the general RPC client */
|
||||
error = nfs4_init_server(server, data);
|
||||
error = nfs4_init_server(server, mount_info->parsed);
|
||||
if (error < 0)
|
||||
goto error;
|
||||
|
||||
error = nfs4_server_common_setup(server, mntfh);
|
||||
error = nfs4_server_common_setup(server, mount_info->mntfh);
|
||||
if (error < 0)
|
||||
goto error;
|
||||
|
||||
|
@ -657,7 +654,3 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
|
|||
dprintk("<-- nfs4_create_referral_server() = error %d\n", error);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
module_param(nfs4_disable_idmapping, bool, 0644);
|
||||
MODULE_PARM_DESC(nfs4_disable_idmapping,
|
||||
"Turn off NFSv4 idmapping when using 'sec=sys'");
|
||||
|
|
|
@ -72,8 +72,6 @@
|
|||
|
||||
#define NFS4_MAX_LOOP_ON_RECOVER (10)
|
||||
|
||||
static unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
|
||||
|
||||
struct nfs4_opendata;
|
||||
static int _nfs4_proc_open(struct nfs4_opendata *data);
|
||||
static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
|
||||
|
@ -6870,6 +6868,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
|
|||
.file_ops = &nfs4_file_operations,
|
||||
.getroot = nfs4_proc_get_root,
|
||||
.submount = nfs4_submount,
|
||||
.try_mount = nfs4_try_mount,
|
||||
.getattr = nfs4_proc_getattr,
|
||||
.setattr = nfs4_proc_setattr,
|
||||
.lookup = nfs4_proc_lookup,
|
||||
|
@ -6915,6 +6914,8 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
|
|||
.alloc_client = nfs4_alloc_client,
|
||||
.init_client = nfs4_init_client,
|
||||
.free_client = nfs4_free_client,
|
||||
.create_server = nfs4_create_server,
|
||||
.clone_server = nfs_clone_server,
|
||||
};
|
||||
|
||||
static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
|
||||
|
@ -6929,10 +6930,6 @@ const struct xattr_handler *nfs4_xattr_handlers[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
module_param(max_session_slots, ushort, 0644);
|
||||
MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
|
||||
"requests the client will negotiate");
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
|
|
|
@ -6,15 +6,18 @@
|
|||
#include <linux/nfs_idmap.h>
|
||||
#include <linux/nfs4_mount.h>
|
||||
#include <linux/nfs_fs.h>
|
||||
#include "delegation.h"
|
||||
#include "internal.h"
|
||||
#include "nfs4_fs.h"
|
||||
#include "pnfs.h"
|
||||
#include "nfs.h"
|
||||
|
||||
#define NFSDBG_FACILITY NFSDBG_VFS
|
||||
|
||||
static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc);
|
||||
static void nfs4_evict_inode(struct inode *inode);
|
||||
static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name, void *raw_data);
|
||||
static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name, void *raw_data);
|
||||
static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name, void *raw_data);
|
||||
static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
|
||||
|
@ -36,14 +39,6 @@ static struct file_system_type nfs4_remote_fs_type = {
|
|||
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
|
||||
};
|
||||
|
||||
struct file_system_type nfs4_xdev_fs_type = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "nfs4",
|
||||
.mount = nfs4_xdev_mount,
|
||||
.kill_sb = nfs_kill_super,
|
||||
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
|
||||
};
|
||||
|
||||
static struct file_system_type nfs4_remote_referral_fs_type = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "nfs4",
|
||||
|
@ -75,21 +70,48 @@ static const struct super_operations nfs4_sops = {
|
|||
.remount_fs = nfs_remount,
|
||||
};
|
||||
|
||||
/*
|
||||
* Set up an NFS4 superblock
|
||||
*/
|
||||
static void nfs4_fill_super(struct super_block *sb,
|
||||
struct nfs_mount_info *mount_info)
|
||||
struct nfs_subversion nfs_v4 = {
|
||||
.owner = THIS_MODULE,
|
||||
.nfs_fs = &nfs4_fs_type,
|
||||
.rpc_vers = &nfs_version4,
|
||||
.rpc_ops = &nfs_v4_clientops,
|
||||
.sops = &nfs4_sops,
|
||||
.xattr = nfs4_xattr_handlers,
|
||||
};
|
||||
|
||||
static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc)
|
||||
{
|
||||
sb->s_time_gran = 1;
|
||||
sb->s_op = &nfs4_sops;
|
||||
/*
|
||||
* The VFS shouldn't apply the umask to mode bits. We will do
|
||||
* so ourselves when necessary.
|
||||
*/
|
||||
sb->s_flags |= MS_POSIXACL;
|
||||
sb->s_xattr = nfs4_xattr_handlers;
|
||||
nfs_initialise_sb(sb);
|
||||
int ret = nfs_write_inode(inode, wbc);
|
||||
|
||||
if (ret >= 0 && test_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags)) {
|
||||
int status;
|
||||
bool sync = true;
|
||||
|
||||
if (wbc->sync_mode == WB_SYNC_NONE)
|
||||
sync = false;
|
||||
|
||||
status = pnfs_layoutcommit_inode(inode, sync);
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean out any remaining NFSv4 state that might be left over due
|
||||
* to open() calls that passed nfs_atomic_lookup, but failed to call
|
||||
* nfs_open().
|
||||
*/
|
||||
static void nfs4_evict_inode(struct inode *inode)
|
||||
{
|
||||
truncate_inode_pages(&inode->i_data, 0);
|
||||
clear_inode(inode);
|
||||
pnfs_return_layout(inode);
|
||||
pnfs_destroy_layout(NFS_I(inode));
|
||||
/* If we are holding a delegation, return it! */
|
||||
nfs_inode_return_delegation_noreclaim(inode);
|
||||
/* First call standard NFS clear_inode() code */
|
||||
nfs_clear_inode(inode);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -103,17 +125,16 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
|
|||
struct nfs_server *server;
|
||||
struct dentry *mntroot = ERR_PTR(-ENOMEM);
|
||||
|
||||
mount_info->fill_super = nfs4_fill_super;
|
||||
mount_info->set_security = nfs_set_sb_security;
|
||||
|
||||
/* Get a volume representation */
|
||||
server = nfs4_create_server(mount_info->parsed, mount_info->mntfh);
|
||||
server = nfs4_create_server(mount_info, &nfs_v4);
|
||||
if (IS_ERR(server)) {
|
||||
mntroot = ERR_CAST(server);
|
||||
goto out;
|
||||
}
|
||||
|
||||
mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info);
|
||||
mntroot = nfs_fs_mount_common(server, flags, dev_name, mount_info, &nfs_v4);
|
||||
|
||||
out:
|
||||
return mntroot;
|
||||
|
@ -228,7 +249,8 @@ static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
|
|||
}
|
||||
|
||||
struct dentry *nfs4_try_mount(int flags, const char *dev_name,
|
||||
struct nfs_mount_info *mount_info)
|
||||
struct nfs_mount_info *mount_info,
|
||||
struct nfs_subversion *nfs_mod)
|
||||
{
|
||||
char *export_path;
|
||||
struct vfsmount *root_mnt;
|
||||
|
@ -237,8 +259,6 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
|
|||
|
||||
dfprintk(MOUNT, "--> nfs4_try_mount()\n");
|
||||
|
||||
mount_info->fill_super = nfs4_fill_super;
|
||||
|
||||
export_path = data->nfs_server.export_path;
|
||||
data->nfs_server.export_path = "/";
|
||||
root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,
|
||||
|
@ -253,27 +273,12 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
|
|||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clone an NFS4 server record on xdev traversal (FSID-change)
|
||||
*/
|
||||
static struct dentry *
|
||||
nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
|
||||
const char *dev_name, void *raw_data)
|
||||
{
|
||||
struct nfs_mount_info mount_info = {
|
||||
.fill_super = nfs_clone_super,
|
||||
.set_security = nfs_clone_sb_security,
|
||||
.cloned = raw_data,
|
||||
};
|
||||
return nfs_xdev_mount_common(&nfs4_fs_type, flags, dev_name, &mount_info);
|
||||
}
|
||||
|
||||
static struct dentry *
|
||||
nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
|
||||
const char *dev_name, void *raw_data)
|
||||
{
|
||||
struct nfs_mount_info mount_info = {
|
||||
.fill_super = nfs4_fill_super,
|
||||
.fill_super = nfs_fill_super,
|
||||
.set_security = nfs_clone_sb_security,
|
||||
.cloned = raw_data,
|
||||
};
|
||||
|
@ -293,7 +298,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
|
|||
goto out;
|
||||
}
|
||||
|
||||
mntroot = nfs_fs_mount_common(&nfs4_fs_type, server, flags, dev_name, &mount_info);
|
||||
mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, &nfs_v4);
|
||||
out:
|
||||
nfs_free_fhandle(mount_info.mntfh);
|
||||
return mntroot;
|
||||
|
@ -327,7 +332,7 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
|
|||
}
|
||||
|
||||
|
||||
int __init init_nfs_v4(void)
|
||||
static int __init init_nfs_v4(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -343,6 +348,7 @@ int __init init_nfs_v4(void)
|
|||
if (err < 0)
|
||||
goto out2;
|
||||
|
||||
register_nfs_version(&nfs_v4);
|
||||
return 0;
|
||||
out2:
|
||||
nfs4_unregister_sysctl();
|
||||
|
@ -352,9 +358,15 @@ int __init init_nfs_v4(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
void exit_nfs_v4(void)
|
||||
static void __exit exit_nfs_v4(void)
|
||||
{
|
||||
unregister_nfs_version(&nfs_v4);
|
||||
unregister_filesystem(&nfs4_fs_type);
|
||||
nfs4_unregister_sysctl();
|
||||
nfs_idmap_quit();
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(init_nfs_v4);
|
||||
module_exit(exit_nfs_v4);
|
||||
|
|
|
@ -852,12 +852,6 @@ const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
|
|||
XDR_UNIT);
|
||||
#endif /* CONFIG_NFS_V4_1 */
|
||||
|
||||
static unsigned short send_implementation_id = 1;
|
||||
|
||||
module_param(send_implementation_id, ushort, 0644);
|
||||
MODULE_PARM_DESC(send_implementation_id,
|
||||
"Send implementation ID with NFSv4.1 exchange_id");
|
||||
|
||||
static const umode_t nfs_type2fmt[] = {
|
||||
[NF4BAD] = 0,
|
||||
[NF4REG] = S_IFREG,
|
||||
|
|
|
@ -54,6 +54,7 @@ void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
|
|||
if (hdr->completion_ops->init_hdr)
|
||||
hdr->completion_ops->init_hdr(hdr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_pgheader_init);
|
||||
|
||||
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos)
|
||||
{
|
||||
|
@ -268,6 +269,7 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
|
|||
desc->pg_lseg = NULL;
|
||||
desc->pg_dreq = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_pageio_init);
|
||||
|
||||
/**
|
||||
* nfs_can_coalesce_requests - test two requests for compatibility
|
||||
|
@ -409,6 +411,7 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
|
|||
} while (ret);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_pageio_add_request);
|
||||
|
||||
/**
|
||||
* nfs_pageio_complete - Complete I/O on an nfs_pageio_descriptor
|
||||
|
@ -424,6 +427,7 @@ void nfs_pageio_complete(struct nfs_pageio_descriptor *desc)
|
|||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_pageio_complete);
|
||||
|
||||
/**
|
||||
* nfs_pageio_cond_complete - Conditional I/O completion
|
||||
|
|
|
@ -1407,6 +1407,7 @@ static void pnfs_writehdr_free(struct nfs_pgio_header *hdr)
|
|||
put_lseg(hdr->lseg);
|
||||
nfs_writehdr_free(hdr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_writehdr_free);
|
||||
|
||||
int
|
||||
pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
|
||||
|
@ -1561,6 +1562,7 @@ static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
|
|||
put_lseg(hdr->lseg);
|
||||
nfs_readhdr_free(hdr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_readhdr_free);
|
||||
|
||||
int
|
||||
pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
|
||||
|
|
|
@ -774,6 +774,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
|
|||
.file_ops = &nfs_file_operations,
|
||||
.getroot = nfs_proc_get_root,
|
||||
.submount = nfs_submount,
|
||||
.try_mount = nfs_try_mount,
|
||||
.getattr = nfs_proc_getattr,
|
||||
.setattr = nfs_proc_setattr,
|
||||
.lookup = nfs_proc_lookup,
|
||||
|
@ -816,4 +817,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
|
|||
.alloc_client = nfs_alloc_client,
|
||||
.init_client = nfs_init_client,
|
||||
.free_client = nfs_free_client,
|
||||
.create_server = nfs_create_server,
|
||||
.clone_server = nfs_clone_server,
|
||||
};
|
||||
|
|
|
@ -48,6 +48,7 @@ struct nfs_read_header *nfs_readhdr_alloc(void)
|
|||
}
|
||||
return rhdr;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_readhdr_alloc);
|
||||
|
||||
static struct nfs_read_data *nfs_readdata_alloc(struct nfs_pgio_header *hdr,
|
||||
unsigned int pagecount)
|
||||
|
@ -80,6 +81,7 @@ void nfs_readhdr_free(struct nfs_pgio_header *hdr)
|
|||
|
||||
kmem_cache_free(nfs_rdata_cachep, rhdr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_readhdr_free);
|
||||
|
||||
void nfs_readdata_release(struct nfs_read_data *rdata)
|
||||
{
|
||||
|
@ -96,6 +98,7 @@ void nfs_readdata_release(struct nfs_read_data *rdata)
|
|||
if (atomic_dec_and_test(&hdr->refcnt))
|
||||
hdr->completion_ops->completion(hdr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_readdata_release);
|
||||
|
||||
static
|
||||
int nfs_return_empty_page(struct page *page)
|
||||
|
@ -113,6 +116,7 @@ void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
|
|||
nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops, compl_ops,
|
||||
NFS_SERVER(inode)->rsize, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_pageio_init_read);
|
||||
|
||||
void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio)
|
||||
{
|
||||
|
@ -397,6 +401,7 @@ int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
|
|||
return nfs_pagein_multi(desc, hdr);
|
||||
return nfs_pagein_one(desc, hdr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_generic_pagein);
|
||||
|
||||
static int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
|
||||
{
|
||||
|
|
172
fs/nfs/super.c
172
fs/nfs/super.c
|
@ -64,11 +64,12 @@
|
|||
#include "internal.h"
|
||||
#include "fscache.h"
|
||||
#include "pnfs.h"
|
||||
#include "nfs.h"
|
||||
|
||||
#define NFSDBG_FACILITY NFSDBG_VFS
|
||||
#define NFS_TEXT_DATA 1
|
||||
|
||||
#ifdef CONFIG_NFS_V3
|
||||
#if IS_ENABLED(CONFIG_NFS_V3)
|
||||
#define NFS_DEFAULT_VERSION 3
|
||||
#else
|
||||
#define NFS_DEFAULT_VERSION 2
|
||||
|
@ -281,13 +282,14 @@ static match_table_t nfs_vers_tokens = {
|
|||
static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name, void *raw_data);
|
||||
|
||||
static struct file_system_type nfs_fs_type = {
|
||||
struct file_system_type nfs_fs_type = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "nfs",
|
||||
.mount = nfs_fs_mount,
|
||||
.kill_sb = nfs_kill_super,
|
||||
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nfs_fs_type);
|
||||
|
||||
struct file_system_type nfs_xdev_fs_type = {
|
||||
.owner = THIS_MODULE,
|
||||
|
@ -297,7 +299,7 @@ struct file_system_type nfs_xdev_fs_type = {
|
|||
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
|
||||
};
|
||||
|
||||
static const struct super_operations nfs_sops = {
|
||||
const struct super_operations nfs_sops = {
|
||||
.alloc_inode = nfs_alloc_inode,
|
||||
.destroy_inode = nfs_destroy_inode,
|
||||
.write_inode = nfs_write_inode,
|
||||
|
@ -311,8 +313,9 @@ static const struct super_operations nfs_sops = {
|
|||
.show_stats = nfs_show_stats,
|
||||
.remount_fs = nfs_remount,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(nfs_sops);
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
|
||||
static int nfs4_validate_mount_data(void *options,
|
||||
struct nfs_parsed_mount_data *args, const char *dev_name);
|
||||
|
@ -363,6 +366,7 @@ void nfs_sb_active(struct super_block *sb)
|
|||
if (atomic_inc_return(&server->active) == 1)
|
||||
atomic_inc(&sb->s_active);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_sb_active);
|
||||
|
||||
void nfs_sb_deactive(struct super_block *sb)
|
||||
{
|
||||
|
@ -371,6 +375,7 @@ void nfs_sb_deactive(struct super_block *sb)
|
|||
if (atomic_dec_and_test(&server->active))
|
||||
deactivate_super(sb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_sb_deactive);
|
||||
|
||||
/*
|
||||
* Deliver file system statistics to userspace
|
||||
|
@ -436,6 +441,7 @@ int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|||
dprintk("%s: statfs error = %d\n", __func__, -error);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_statfs);
|
||||
|
||||
/*
|
||||
* Map the security flavour number to a name
|
||||
|
@ -541,7 +547,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
|
|||
nfs_show_mountd_netid(m, nfss, showdefaults);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
|
||||
int showdefaults)
|
||||
{
|
||||
|
@ -672,8 +678,9 @@ int nfs_show_options(struct seq_file *m, struct dentry *root)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_show_options);
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
#ifdef CONFIG_NFS_V4_1
|
||||
static void show_sessions(struct seq_file *m, struct nfs_server *server)
|
||||
{
|
||||
|
@ -706,7 +713,7 @@ static void show_implementation_id(struct seq_file *m, struct nfs_server *nfss)
|
|||
}
|
||||
}
|
||||
#else
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
static void show_pnfs(struct seq_file *m, struct nfs_server *server)
|
||||
{
|
||||
}
|
||||
|
@ -731,12 +738,14 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root)
|
|||
free_page((unsigned long)page);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_show_devname);
|
||||
|
||||
int nfs_show_path(struct seq_file *m, struct dentry *dentry)
|
||||
{
|
||||
seq_puts(m, "/");
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_show_path);
|
||||
|
||||
/*
|
||||
* Present statistical information for this VFS mountpoint
|
||||
|
@ -771,7 +780,7 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
|
|||
seq_printf(m, ",bsize=%u", nfss->bsize);
|
||||
seq_printf(m, ",namlen=%u", nfss->namelen);
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
if (nfss->nfs_client->rpc_ops->version == 4) {
|
||||
seq_printf(m, "\n\tnfsv4:\t");
|
||||
seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
|
||||
|
@ -829,6 +838,7 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_show_stats);
|
||||
|
||||
/*
|
||||
* Begin unmount by attempting to remove all automounted mountpoints we added
|
||||
|
@ -848,6 +858,7 @@ void nfs_umount_begin(struct super_block *sb)
|
|||
if (!IS_ERR(rpc))
|
||||
rpc_killall_tasks(rpc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_umount_begin);
|
||||
|
||||
static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
|
||||
{
|
||||
|
@ -1649,8 +1660,9 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
|
|||
return nfs_walk_authlist(args, &request);
|
||||
}
|
||||
|
||||
static struct dentry *nfs_try_mount(int flags, const char *dev_name,
|
||||
struct nfs_mount_info *mount_info)
|
||||
struct dentry *nfs_try_mount(int flags, const char *dev_name,
|
||||
struct nfs_mount_info *mount_info,
|
||||
struct nfs_subversion *nfs_mod)
|
||||
{
|
||||
int status;
|
||||
struct nfs_server *server;
|
||||
|
@ -1662,12 +1674,13 @@ static struct dentry *nfs_try_mount(int flags, const char *dev_name,
|
|||
}
|
||||
|
||||
/* Get a volume representation */
|
||||
server = nfs_create_server(mount_info->parsed, mount_info->mntfh);
|
||||
server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
|
||||
if (IS_ERR(server))
|
||||
return ERR_CAST(server);
|
||||
|
||||
return nfs_fs_mount_common(&nfs_fs_type, server, flags, dev_name, mount_info);
|
||||
return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_try_mount);
|
||||
|
||||
/*
|
||||
* Split "dev_name" into "hostname:export_path".
|
||||
|
@ -1871,7 +1884,7 @@ static int nfs23_validate_mount_data(void *options,
|
|||
return NFS_TEXT_DATA;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_NFS_V3
|
||||
#if !IS_ENABLED(CONFIG_NFS_V3)
|
||||
if (args->version == 3)
|
||||
goto out_v3_not_compiled;
|
||||
#endif /* !CONFIG_NFS_V3 */
|
||||
|
@ -1891,7 +1904,7 @@ static int nfs23_validate_mount_data(void *options,
|
|||
dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n");
|
||||
return -EINVAL;
|
||||
|
||||
#ifndef CONFIG_NFS_V3
|
||||
#if !IS_ENABLED(CONFIG_NFS_V3)
|
||||
out_v3_not_compiled:
|
||||
dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n");
|
||||
return -EPROTONOSUPPORT;
|
||||
|
@ -1910,7 +1923,7 @@ static int nfs23_validate_mount_data(void *options,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
static int nfs_validate_mount_data(struct file_system_type *fs_type,
|
||||
void *options,
|
||||
struct nfs_parsed_mount_data *args,
|
||||
|
@ -1948,7 +1961,7 @@ static int nfs_validate_text_mount_data(void *options,
|
|||
goto out_no_address;
|
||||
|
||||
if (args->version == 4) {
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
port = NFS_PORT;
|
||||
max_namelen = NFS4_MAXNAMLEN;
|
||||
max_pathlen = NFS4_MAXPATHLEN;
|
||||
|
@ -1971,7 +1984,7 @@ static int nfs_validate_text_mount_data(void *options,
|
|||
&args->nfs_server.export_path,
|
||||
max_pathlen);
|
||||
|
||||
#ifndef CONFIG_NFS_V4
|
||||
#if !IS_ENABLED(CONFIG_NFS_V4)
|
||||
out_v4_not_compiled:
|
||||
dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
|
||||
return -EPROTONOSUPPORT;
|
||||
|
@ -2070,6 +2083,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
|
|||
kfree(data);
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_remount);
|
||||
|
||||
/*
|
||||
* Initialise the common bits of the superblock
|
||||
|
@ -2103,10 +2117,12 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
|
|||
|
||||
sb->s_blocksize_bits = 0;
|
||||
sb->s_blocksize = 0;
|
||||
if (data->bsize)
|
||||
sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr;
|
||||
sb->s_op = server->nfs_client->cl_nfs_mod->sops;
|
||||
if (data && data->bsize)
|
||||
sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
|
||||
|
||||
if (server->nfs_client->rpc_ops->version == 3) {
|
||||
if (server->nfs_client->rpc_ops->version != 2) {
|
||||
/* The VFS shouldn't apply the umask to mode bits. We will do
|
||||
* so ourselves when necessary.
|
||||
*/
|
||||
|
@ -2114,9 +2130,9 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
|
|||
sb->s_time_gran = 1;
|
||||
}
|
||||
|
||||
sb->s_op = &nfs_sops;
|
||||
nfs_initialise_sb(sb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_fill_super);
|
||||
|
||||
/*
|
||||
* Finish setting up a cloned NFS2/3/4 superblock
|
||||
|
@ -2286,6 +2302,7 @@ int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
|
|||
{
|
||||
return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_set_sb_security);
|
||||
|
||||
int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
|
||||
struct nfs_mount_info *mount_info)
|
||||
|
@ -2296,11 +2313,12 @@ int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
|
|||
return -ESTALE;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
|
||||
|
||||
struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
|
||||
struct nfs_server *server,
|
||||
struct dentry *nfs_fs_mount_common(struct nfs_server *server,
|
||||
int flags, const char *dev_name,
|
||||
struct nfs_mount_info *mount_info)
|
||||
struct nfs_mount_info *mount_info,
|
||||
struct nfs_subversion *nfs_mod)
|
||||
{
|
||||
struct super_block *s;
|
||||
struct dentry *mntroot = ERR_PTR(-ENOMEM);
|
||||
|
@ -2319,7 +2337,7 @@ struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
|
|||
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
|
||||
|
||||
/* Get a superblock - note that we may end up sharing one that already exists */
|
||||
s = sget(fs_type, compare_super, nfs_set_super, flags, &sb_mntdata);
|
||||
s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata);
|
||||
if (IS_ERR(s)) {
|
||||
mntroot = ERR_CAST(s);
|
||||
goto out_err_nosb;
|
||||
|
@ -2369,6 +2387,7 @@ struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
|
|||
deactivate_locked_super(s);
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_fs_mount_common);
|
||||
|
||||
struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name, void *raw_data)
|
||||
|
@ -2378,6 +2397,7 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
|
|||
.set_security = nfs_set_sb_security,
|
||||
};
|
||||
struct dentry *mntroot = ERR_PTR(-ENOMEM);
|
||||
struct nfs_subversion *nfs_mod;
|
||||
int error;
|
||||
|
||||
mount_info.parsed = nfs_alloc_parsed_mount_data();
|
||||
|
@ -2394,18 +2414,21 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
|
|||
goto out;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
if (mount_info.parsed->version == 4)
|
||||
mntroot = nfs4_try_mount(flags, dev_name, &mount_info);
|
||||
else
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
mntroot = nfs_try_mount(flags, dev_name, &mount_info);
|
||||
nfs_mod = get_nfs_version(mount_info.parsed->version);
|
||||
if (IS_ERR(nfs_mod)) {
|
||||
mntroot = ERR_CAST(nfs_mod);
|
||||
goto out;
|
||||
}
|
||||
|
||||
mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info, nfs_mod);
|
||||
|
||||
put_nfs_version(nfs_mod);
|
||||
out:
|
||||
nfs_free_parsed_mount_data(mount_info.parsed);
|
||||
nfs_free_fhandle(mount_info.mntfh);
|
||||
return mntroot;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_fs_mount);
|
||||
|
||||
/*
|
||||
* Ensure that we unregister the bdi before kill_anon_super
|
||||
|
@ -2417,6 +2440,7 @@ void nfs_put_super(struct super_block *s)
|
|||
|
||||
bdi_unregister(&server->backing_dev_info);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_put_super);
|
||||
|
||||
/*
|
||||
* Destroy an NFS2/3 superblock
|
||||
|
@ -2429,31 +2453,38 @@ void nfs_kill_super(struct super_block *s)
|
|||
nfs_fscache_release_super_cookie(s);
|
||||
nfs_free_server(server);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_kill_super);
|
||||
|
||||
/*
|
||||
* Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
|
||||
*/
|
||||
struct dentry *
|
||||
nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
|
||||
const char *dev_name, struct nfs_mount_info *mount_info)
|
||||
nfs_xdev_mount(struct file_system_type *fs_type, int flags,
|
||||
const char *dev_name, void *raw_data)
|
||||
{
|
||||
struct nfs_clone_mount *data = mount_info->cloned;
|
||||
struct nfs_clone_mount *data = raw_data;
|
||||
struct nfs_mount_info mount_info = {
|
||||
.fill_super = nfs_clone_super,
|
||||
.set_security = nfs_clone_sb_security,
|
||||
.cloned = data,
|
||||
};
|
||||
struct nfs_server *server;
|
||||
struct dentry *mntroot = ERR_PTR(-ENOMEM);
|
||||
struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod;
|
||||
int error;
|
||||
|
||||
dprintk("--> nfs_xdev_mount_common()\n");
|
||||
|
||||
mount_info->mntfh = data->fh;
|
||||
mount_info.mntfh = mount_info.cloned->fh;
|
||||
|
||||
/* create a new volume representation */
|
||||
server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
|
||||
server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
|
||||
if (IS_ERR(server)) {
|
||||
error = PTR_ERR(server);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info);
|
||||
mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, nfs_mod);
|
||||
dprintk("<-- nfs_xdev_mount_common() = 0\n");
|
||||
out:
|
||||
return mntroot;
|
||||
|
@ -2463,22 +2494,7 @@ nfs_xdev_mount_common(struct file_system_type *fs_type, int flags,
|
|||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clone an NFS2/3 server record on xdev traversal (FSID-change)
|
||||
*/
|
||||
static struct dentry *
|
||||
nfs_xdev_mount(struct file_system_type *fs_type, int flags,
|
||||
const char *dev_name, void *raw_data)
|
||||
{
|
||||
struct nfs_mount_info mount_info = {
|
||||
.fill_super = nfs_clone_super,
|
||||
.set_security = nfs_clone_sb_security,
|
||||
.cloned = raw_data,
|
||||
};
|
||||
return nfs_xdev_mount_common(&nfs_fs_type, flags, dev_name, &mount_info);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
|
||||
static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
|
||||
{
|
||||
|
@ -2577,4 +2593,56 @@ static int nfs4_validate_mount_data(void *options,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* NFS v4 module parameters need to stay in the
|
||||
* NFS client for backwards compatibility
|
||||
*/
|
||||
unsigned int nfs_callback_set_tcpport;
|
||||
unsigned short nfs_callback_tcpport;
|
||||
/* Default cache timeout is 10 minutes */
|
||||
unsigned int nfs_idmap_cache_timeout = 600;
|
||||
/* Turn off NFSv4 uid/gid mapping when using AUTH_SYS */
|
||||
bool nfs4_disable_idmapping = true;
|
||||
unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
|
||||
unsigned short send_implementation_id = 1;
|
||||
|
||||
EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
|
||||
EXPORT_SYMBOL_GPL(nfs_callback_tcpport);
|
||||
EXPORT_SYMBOL_GPL(nfs_idmap_cache_timeout);
|
||||
EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
|
||||
EXPORT_SYMBOL_GPL(max_session_slots);
|
||||
EXPORT_SYMBOL_GPL(send_implementation_id);
|
||||
|
||||
#define NFS_CALLBACK_MAXPORTNR (65535U)
|
||||
|
||||
static int param_set_portnr(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
unsigned long num;
|
||||
int ret;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
ret = strict_strtoul(val, 0, &num);
|
||||
if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR)
|
||||
return -EINVAL;
|
||||
*((unsigned int *)kp->arg) = num;
|
||||
return 0;
|
||||
}
|
||||
static struct kernel_param_ops param_ops_portnr = {
|
||||
.set = param_set_portnr,
|
||||
.get = param_get_uint,
|
||||
};
|
||||
#define param_check_portnr(name, p) __param_check(name, p, unsigned int);
|
||||
|
||||
module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
|
||||
module_param(nfs_idmap_cache_timeout, int, 0644);
|
||||
module_param(nfs4_disable_idmapping, bool, 0644);
|
||||
MODULE_PARM_DESC(nfs4_disable_idmapping,
|
||||
"Turn off NFSv4 idmapping when using 'sec=sys'");
|
||||
module_param(max_session_slots, ushort, 0644);
|
||||
MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
|
||||
"requests the client will negotiate");
|
||||
module_param(send_implementation_id, ushort, 0644);
|
||||
MODULE_PARM_DESC(send_implementation_id,
|
||||
"Send implementation ID with NFSv4.1 exchange_id");
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
|
|
|
@ -84,6 +84,7 @@ struct nfs_write_header *nfs_writehdr_alloc(void)
|
|||
}
|
||||
return p;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_writehdr_alloc);
|
||||
|
||||
static struct nfs_write_data *nfs_writedata_alloc(struct nfs_pgio_header *hdr,
|
||||
unsigned int pagecount)
|
||||
|
@ -115,6 +116,7 @@ void nfs_writehdr_free(struct nfs_pgio_header *hdr)
|
|||
struct nfs_write_header *whdr = container_of(hdr, struct nfs_write_header, header);
|
||||
mempool_free(whdr, nfs_wdata_mempool);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_writehdr_free);
|
||||
|
||||
void nfs_writedata_release(struct nfs_write_data *wdata)
|
||||
{
|
||||
|
@ -131,6 +133,7 @@ void nfs_writedata_release(struct nfs_write_data *wdata)
|
|||
if (atomic_dec_and_test(&hdr->refcnt))
|
||||
hdr->completion_ops->completion(hdr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_writedata_release);
|
||||
|
||||
static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
|
||||
{
|
||||
|
@ -446,7 +449,7 @@ nfs_mark_request_dirty(struct nfs_page *req)
|
|||
__set_page_dirty_nobuffers(req->wb_page);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
|
||||
#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
|
||||
/**
|
||||
* nfs_request_add_commit_list - add request to a commit list
|
||||
* @req: pointer to a struct nfs_page
|
||||
|
@ -636,7 +639,7 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr)
|
|||
hdr->release(hdr);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
|
||||
#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
|
||||
static unsigned long
|
||||
nfs_reqs_to_commit(struct nfs_commit_info *cinfo)
|
||||
{
|
||||
|
@ -1173,6 +1176,7 @@ int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
|
|||
return nfs_flush_multi(desc, hdr);
|
||||
return nfs_flush_one(desc, hdr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_generic_flush);
|
||||
|
||||
static int nfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
|
||||
{
|
||||
|
@ -1210,6 +1214,7 @@ void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
|
|||
nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops, compl_ops,
|
||||
NFS_SERVER(inode)->wsize, ioflags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_pageio_init_write);
|
||||
|
||||
void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio)
|
||||
{
|
||||
|
@ -1297,7 +1302,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
|
|||
return;
|
||||
nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, resp->count);
|
||||
|
||||
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
|
||||
#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
|
||||
if (resp->verf->committed < argp->stable && task->tk_status >= 0) {
|
||||
/* We tried a write call, but the server did not
|
||||
* commit data to stable storage even though we
|
||||
|
@ -1357,7 +1362,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
|
|||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
|
||||
#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
|
||||
static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1673,26 +1678,7 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
|
|||
{
|
||||
return nfs_commit_unstable_pages(inode, wbc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc)
|
||||
{
|
||||
int ret = nfs_write_inode(inode, wbc);
|
||||
|
||||
if (ret >= 0 && test_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags)) {
|
||||
int status;
|
||||
bool sync = true;
|
||||
|
||||
if (wbc->sync_mode == WB_SYNC_NONE)
|
||||
sync = false;
|
||||
|
||||
status = pnfs_layoutcommit_inode(inode, sync);
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
EXPORT_SYMBOL_GPL(nfs_write_inode);
|
||||
|
||||
/*
|
||||
* flush the inode to disk.
|
||||
|
@ -1708,6 +1694,7 @@ int nfs_wb_all(struct inode *inode)
|
|||
|
||||
return sync_inode(inode, &wbc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_wb_all);
|
||||
|
||||
int nfs_wb_page_cancel(struct inode *inode, struct page *page)
|
||||
{
|
||||
|
|
|
@ -191,7 +191,7 @@ struct nfs_inode {
|
|||
struct hlist_head silly_list;
|
||||
wait_queue_head_t waitqueue;
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
struct nfs4_cached_acl *nfs4_acl;
|
||||
/* NFSv4 state */
|
||||
struct list_head open_states;
|
||||
|
@ -428,7 +428,7 @@ extern __be32 root_nfs_parse_addr(char *name); /*__init*/
|
|||
* linux/fs/nfs/file.c
|
||||
*/
|
||||
extern const struct file_operations nfs_file_operations;
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
extern const struct file_operations nfs4_file_operations;
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
extern const struct address_space_operations nfs_file_aops;
|
||||
|
@ -538,7 +538,7 @@ extern void nfs_writeback_done(struct rpc_task *, struct nfs_write_data *);
|
|||
extern int nfs_wb_all(struct inode *inode);
|
||||
extern int nfs_wb_page(struct inode *inode, struct page* page);
|
||||
extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
|
||||
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
|
||||
#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
|
||||
extern int nfs_commit_inode(struct inode *, int);
|
||||
extern struct nfs_commit_data *nfs_commitdata_alloc(void);
|
||||
extern void nfs_commit_free(struct nfs_commit_data *data);
|
||||
|
|
|
@ -48,11 +48,12 @@ struct nfs_client {
|
|||
struct rpc_clnt * cl_rpcclient;
|
||||
const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */
|
||||
int cl_proto; /* Network transport protocol */
|
||||
struct nfs_subversion * cl_nfs_mod; /* pointer to nfs version module */
|
||||
|
||||
u32 cl_minorversion;/* NFSv4 minorversion */
|
||||
struct rpc_cred *cl_machine_cred;
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
u64 cl_clientid; /* constant */
|
||||
nfs4_verifier cl_confirm; /* Clientid verifier */
|
||||
unsigned long cl_state;
|
||||
|
@ -137,7 +138,7 @@ struct nfs_server {
|
|||
#endif
|
||||
|
||||
u32 pnfs_blksize; /* layout_blksize attr */
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
u32 attr_bitmask[3];/* V4 bitmask representing the set
|
||||
of attributes supported on this
|
||||
filesystem */
|
||||
|
@ -200,7 +201,7 @@ struct nfs_server {
|
|||
#define NFS4_MAX_SLOT_TABLE (256U)
|
||||
#define NFS4_NO_SLOT ((u32)-1)
|
||||
|
||||
#if defined(CONFIG_NFS_V4)
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
|
||||
/* Sessions */
|
||||
#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
|
||||
|
|
|
@ -69,7 +69,7 @@ struct nfs_server;
|
|||
struct nfs_fattr;
|
||||
struct nfs4_string;
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
int nfs_idmap_init(void);
|
||||
void nfs_idmap_quit(void);
|
||||
#else
|
||||
|
|
|
@ -824,7 +824,7 @@ struct nfs3_getaclres {
|
|||
struct posix_acl * acl_default;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
|
||||
typedef u64 clientid4;
|
||||
|
||||
|
@ -1353,6 +1353,8 @@ struct nfs_renamedata {
|
|||
struct nfs_access_entry;
|
||||
struct nfs_client;
|
||||
struct rpc_timeout;
|
||||
struct nfs_subversion;
|
||||
struct nfs_mount_info;
|
||||
struct nfs_client_initdata;
|
||||
struct nfs_pageio_descriptor;
|
||||
|
||||
|
@ -1370,6 +1372,8 @@ struct nfs_rpc_ops {
|
|||
struct nfs_fsinfo *);
|
||||
struct vfsmount *(*submount) (struct nfs_server *, struct dentry *,
|
||||
struct nfs_fh *, struct nfs_fattr *);
|
||||
struct dentry *(*try_mount) (int, const char *, struct nfs_mount_info *,
|
||||
struct nfs_subversion *);
|
||||
int (*getattr) (struct nfs_server *, struct nfs_fh *,
|
||||
struct nfs_fattr *);
|
||||
int (*setattr) (struct dentry *, struct nfs_fattr *,
|
||||
|
@ -1435,6 +1439,9 @@ struct nfs_rpc_ops {
|
|||
(*init_client) (struct nfs_client *, const struct rpc_timeout *,
|
||||
const char *, rpc_authflavor_t);
|
||||
void (*free_client) (struct nfs_client *);
|
||||
struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *);
|
||||
struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,
|
||||
struct nfs_fattr *, rpc_authflavor_t);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -251,7 +251,7 @@ static int rpcb_create_local_unix(struct net *net)
|
|||
if (IS_ERR(clnt)) {
|
||||
dprintk("RPC: failed to create AF_LOCAL rpcbind "
|
||||
"client (errno %ld).\n", PTR_ERR(clnt));
|
||||
result = -PTR_ERR(clnt);
|
||||
result = PTR_ERR(clnt);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -298,7 +298,7 @@ static int rpcb_create_local_net(struct net *net)
|
|||
if (IS_ERR(clnt)) {
|
||||
dprintk("RPC: failed to create local rpcbind "
|
||||
"client (errno %ld).\n", PTR_ERR(clnt));
|
||||
result = -PTR_ERR(clnt);
|
||||
result = PTR_ERR(clnt);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -300,8 +300,9 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task);
|
|||
/*
|
||||
* Make an RPC task runnable.
|
||||
*
|
||||
* Note: If the task is ASYNC, this must be called with
|
||||
* the spinlock held to protect the wait queue operation.
|
||||
* Note: If the task is ASYNC, and is being made runnable after sitting on an
|
||||
* rpc_wait_queue, this must be called with the queue spinlock held to protect
|
||||
* the wait queue operation.
|
||||
*/
|
||||
static void rpc_make_runnable(struct rpc_task *task)
|
||||
{
|
||||
|
@ -790,7 +791,9 @@ void rpc_execute(struct rpc_task *task)
|
|||
|
||||
static void rpc_async_schedule(struct work_struct *work)
|
||||
{
|
||||
current->flags |= PF_FSTRANS;
|
||||
__rpc_execute(container_of(work, struct rpc_task, u.tk_work));
|
||||
current->flags &= ~PF_FSTRANS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -200,6 +200,7 @@ xprt_rdma_connect_worker(struct work_struct *work)
|
|||
int rc = 0;
|
||||
|
||||
if (!xprt->shutdown) {
|
||||
current->flags |= PF_FSTRANS;
|
||||
xprt_clear_connected(xprt);
|
||||
|
||||
dprintk("RPC: %s: %sconnect\n", __func__,
|
||||
|
@ -212,10 +213,10 @@ xprt_rdma_connect_worker(struct work_struct *work)
|
|||
|
||||
out:
|
||||
xprt_wake_pending_tasks(xprt, rc);
|
||||
|
||||
out_clear:
|
||||
dprintk("RPC: %s: exit\n", __func__);
|
||||
xprt_clear_connecting(xprt);
|
||||
current->flags &= ~PF_FSTRANS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1892,6 +1892,8 @@ static void xs_local_setup_socket(struct work_struct *work)
|
|||
if (xprt->shutdown)
|
||||
goto out;
|
||||
|
||||
current->flags |= PF_FSTRANS;
|
||||
|
||||
clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
|
||||
status = __sock_create(xprt->xprt_net, AF_LOCAL,
|
||||
SOCK_STREAM, 0, &sock, 1);
|
||||
|
@ -1925,6 +1927,7 @@ static void xs_local_setup_socket(struct work_struct *work)
|
|||
out:
|
||||
xprt_clear_connecting(xprt);
|
||||
xprt_wake_pending_tasks(xprt, status);
|
||||
current->flags &= ~PF_FSTRANS;
|
||||
}
|
||||
|
||||
static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
|
||||
|
@ -1967,6 +1970,8 @@ static void xs_udp_setup_socket(struct work_struct *work)
|
|||
if (xprt->shutdown)
|
||||
goto out;
|
||||
|
||||
current->flags |= PF_FSTRANS;
|
||||
|
||||
/* Start by resetting any existing state */
|
||||
xs_reset_transport(transport);
|
||||
sock = xs_create_sock(xprt, transport,
|
||||
|
@ -1985,6 +1990,7 @@ static void xs_udp_setup_socket(struct work_struct *work)
|
|||
out:
|
||||
xprt_clear_connecting(xprt);
|
||||
xprt_wake_pending_tasks(xprt, status);
|
||||
current->flags &= ~PF_FSTRANS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2110,6 +2116,8 @@ static void xs_tcp_setup_socket(struct work_struct *work)
|
|||
if (xprt->shutdown)
|
||||
goto out;
|
||||
|
||||
current->flags |= PF_FSTRANS;
|
||||
|
||||
if (!sock) {
|
||||
clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
|
||||
sock = xs_create_sock(xprt, transport,
|
||||
|
@ -2159,6 +2167,7 @@ static void xs_tcp_setup_socket(struct work_struct *work)
|
|||
case -EINPROGRESS:
|
||||
case -EALREADY:
|
||||
xprt_clear_connecting(xprt);
|
||||
current->flags &= ~PF_FSTRANS;
|
||||
return;
|
||||
case -EINVAL:
|
||||
/* Happens, for instance, if the user specified a link
|
||||
|
@ -2171,6 +2180,7 @@ static void xs_tcp_setup_socket(struct work_struct *work)
|
|||
out:
|
||||
xprt_clear_connecting(xprt);
|
||||
xprt_wake_pending_tasks(xprt, status);
|
||||
current->flags &= ~PF_FSTRANS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue