You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
* git://git.linux-nfs.org/pub/linux/nfs-2.6: (28 commits) NFS: Fix a compile glitch on 64-bit systems NFS: Clean up nfs_create_request comments spkm3: initialize hash spkm3: remove bad kfree, unnecessary export spkm3: fix spkm3's use of hmac NFS4: invalidate cached acl on setacl NFS: Fix directory caching problem - with test case and patch. NFS: Set meaningful value for fattr->time_start in readdirplus results. NFS: Added support to turn off the NFSv3 READDIRPLUS RPC. SUNRPC: RPC client should retry with different versions of rpcbind SUNRPC: remove old portmapper NFS: switch NFSROOT to use new rpcbind client SUNRPC: switch the RPC server to use the new rpcbind registration API SUNRPC: switch socket-based RPC transports to use rpcbind SUNRPC: introduce rpcbind: replacement for in-kernel portmapper SUNRPC: Eliminate side effects from rpc_malloc SUNRPC: RPC buffer size estimates are too large NLM: Shrink the maximum request size of NLM4 requests NFS: Use pgoff_t in structures and functions that pass page cache offsets NFS: Clean up nfs_sync_mapping_wait() ...
This commit is contained in:
+12
@@ -1734,6 +1734,18 @@ config SUNRPC
|
||||
config SUNRPC_GSS
|
||||
tristate
|
||||
|
||||
config SUNRPC_BIND34
|
||||
bool "Support for rpcbind versions 3 & 4 (EXPERIMENTAL)"
|
||||
depends on SUNRPC && EXPERIMENTAL
|
||||
help
|
||||
Provides kernel support for querying rpcbind servers via versions 3
|
||||
and 4 of the rpcbind protocol. The kernel automatically falls back
|
||||
to version 2 if a remote rpcbind service does not support versions
|
||||
3 or 4.
|
||||
|
||||
If unsure, say N to get traditional behavior (version 2 rpcbind
|
||||
requests only).
|
||||
|
||||
config RPCSEC_GSS_KRB5
|
||||
tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)"
|
||||
depends on SUNRPC && EXPERIMENTAL
|
||||
|
||||
+4
-6
@@ -225,16 +225,13 @@ xdr_decode_stat(struct rpc_rqst *rqstp, __be32 *p, struct nsm_res *resp)
|
||||
#define SM_monres_sz 2
|
||||
#define SM_unmonres_sz 1
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) (((a) > (b))? (a) : (b))
|
||||
#endif
|
||||
|
||||
static struct rpc_procinfo nsm_procedures[] = {
|
||||
[SM_MON] = {
|
||||
.p_proc = SM_MON,
|
||||
.p_encode = (kxdrproc_t) xdr_encode_mon,
|
||||
.p_decode = (kxdrproc_t) xdr_decode_stat_res,
|
||||
.p_bufsiz = MAX(SM_mon_sz, SM_monres_sz) << 2,
|
||||
.p_arglen = SM_mon_sz,
|
||||
.p_replen = SM_monres_sz,
|
||||
.p_statidx = SM_MON,
|
||||
.p_name = "MONITOR",
|
||||
},
|
||||
@@ -242,7 +239,8 @@ static struct rpc_procinfo nsm_procedures[] = {
|
||||
.p_proc = SM_UNMON,
|
||||
.p_encode = (kxdrproc_t) xdr_encode_unmon,
|
||||
.p_decode = (kxdrproc_t) xdr_decode_stat,
|
||||
.p_bufsiz = MAX(SM_mon_id_sz, SM_unmonres_sz) << 2,
|
||||
.p_arglen = SM_mon_id_sz,
|
||||
.p_replen = SM_unmonres_sz,
|
||||
.p_statidx = SM_UNMON,
|
||||
.p_name = "UNMONITOR",
|
||||
},
|
||||
|
||||
+10
-10
@@ -510,17 +510,20 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
|
||||
# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Buffer requirements for NLM
|
||||
*/
|
||||
#define NLM_void_sz 0
|
||||
#define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
|
||||
#define NLM_caller_sz 1+XDR_QUADLEN(sizeof(utsname()->nodename))
|
||||
#define NLM_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ)
|
||||
/* #define NLM_owner_sz 1+XDR_QUADLEN(NLM_MAXOWNER) */
|
||||
#define NLM_caller_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
|
||||
#define NLM_owner_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
|
||||
#define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE)
|
||||
#define NLM_lock_sz 3+NLM_caller_sz+NLM_netobj_sz+NLM_fhandle_sz
|
||||
#define NLM_holder_sz 4+NLM_netobj_sz
|
||||
#define NLM_lock_sz 3+NLM_caller_sz+NLM_owner_sz+NLM_fhandle_sz
|
||||
#define NLM_holder_sz 4+NLM_owner_sz
|
||||
|
||||
#define NLM_testargs_sz NLM_cookie_sz+1+NLM_lock_sz
|
||||
#define NLM_lockargs_sz NLM_cookie_sz+4+NLM_lock_sz
|
||||
@@ -531,10 +534,6 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
|
||||
#define NLM_res_sz NLM_cookie_sz+1
|
||||
#define NLM_norep_sz 0
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) (((a) > (b))? (a) : (b))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For NLM, a void procedure really returns nothing
|
||||
*/
|
||||
@@ -545,7 +544,8 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
|
||||
.p_proc = NLMPROC_##proc, \
|
||||
.p_encode = (kxdrproc_t) nlmclt_encode_##argtype, \
|
||||
.p_decode = (kxdrproc_t) nlmclt_decode_##restype, \
|
||||
.p_bufsiz = MAX(NLM_##argtype##_sz, NLM_##restype##_sz) << 2, \
|
||||
.p_arglen = NLM_##argtype##_sz, \
|
||||
.p_replen = NLM_##restype##_sz, \
|
||||
.p_statidx = NLMPROC_##proc, \
|
||||
.p_name = #proc, \
|
||||
}
|
||||
|
||||
+14
-10
@@ -516,17 +516,24 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ)
|
||||
# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!"
|
||||
#endif
|
||||
|
||||
#if (NLMCLNT_OHSIZE > NLM_MAXSTRLEN)
|
||||
# error "NLM host name cannot be larger than NLM's maximum string length!"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Buffer requirements for NLM
|
||||
*/
|
||||
#define NLM4_void_sz 0
|
||||
#define NLM4_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
|
||||
#define NLM4_caller_sz 1+XDR_QUADLEN(NLM_MAXSTRLEN)
|
||||
#define NLM4_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ)
|
||||
/* #define NLM4_owner_sz 1+XDR_QUADLEN(NLM4_MAXOWNER) */
|
||||
#define NLM4_caller_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
|
||||
#define NLM4_owner_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE)
|
||||
#define NLM4_fhandle_sz 1+XDR_QUADLEN(NFS3_FHSIZE)
|
||||
#define NLM4_lock_sz 5+NLM4_caller_sz+NLM4_netobj_sz+NLM4_fhandle_sz
|
||||
#define NLM4_holder_sz 6+NLM4_netobj_sz
|
||||
#define NLM4_lock_sz 5+NLM4_caller_sz+NLM4_owner_sz+NLM4_fhandle_sz
|
||||
#define NLM4_holder_sz 6+NLM4_owner_sz
|
||||
|
||||
#define NLM4_testargs_sz NLM4_cookie_sz+1+NLM4_lock_sz
|
||||
#define NLM4_lockargs_sz NLM4_cookie_sz+4+NLM4_lock_sz
|
||||
@@ -537,10 +544,6 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
|
||||
#define NLM4_res_sz NLM4_cookie_sz+1
|
||||
#define NLM4_norep_sz 0
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a,b) (((a) > (b))? (a) : (b))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For NLM, a void procedure really returns nothing
|
||||
*/
|
||||
@@ -551,7 +554,8 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
|
||||
.p_proc = NLMPROC_##proc, \
|
||||
.p_encode = (kxdrproc_t) nlm4clt_encode_##argtype, \
|
||||
.p_decode = (kxdrproc_t) nlm4clt_decode_##restype, \
|
||||
.p_bufsiz = MAX(NLM4_##argtype##_sz, NLM4_##restype##_sz) << 2, \
|
||||
.p_arglen = NLM4_##argtype##_sz, \
|
||||
.p_replen = NLM4_##restype##_sz, \
|
||||
.p_statidx = NLMPROC_##proc, \
|
||||
.p_name = #proc, \
|
||||
}
|
||||
|
||||
+2
-1
@@ -618,7 +618,8 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
|
||||
if (clp->cl_nfsversion == 3) {
|
||||
if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
|
||||
server->namelen = NFS3_MAXNAMLEN;
|
||||
server->caps |= NFS_CAP_READDIRPLUS;
|
||||
if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
|
||||
server->caps |= NFS_CAP_READDIRPLUS;
|
||||
} else {
|
||||
if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
|
||||
server->namelen = NFS2_MAXNAMLEN;
|
||||
|
||||
@@ -154,6 +154,8 @@ typedef struct {
|
||||
decode_dirent_t decode;
|
||||
int plus;
|
||||
int error;
|
||||
unsigned long timestamp;
|
||||
int timestamp_valid;
|
||||
} nfs_readdir_descriptor_t;
|
||||
|
||||
/* Now we cache directories properly, by stuffing the dirent
|
||||
@@ -195,6 +197,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
desc->timestamp = timestamp;
|
||||
desc->timestamp_valid = 1;
|
||||
SetPageUptodate(page);
|
||||
spin_lock(&inode->i_lock);
|
||||
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
|
||||
@@ -225,6 +229,10 @@ int dir_decode(nfs_readdir_descriptor_t *desc)
|
||||
if (IS_ERR(p))
|
||||
return PTR_ERR(p);
|
||||
desc->ptr = p;
|
||||
if (desc->timestamp_valid)
|
||||
desc->entry->fattr->time_start = desc->timestamp;
|
||||
else
|
||||
desc->entry->fattr->valid &= ~NFS_ATTR_FATTR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -316,6 +324,10 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc)
|
||||
__FUNCTION__, desc->page_index,
|
||||
(long long) *desc->dir_cookie);
|
||||
|
||||
/* If we find the page in the page_cache, we cannot be sure
|
||||
* how fresh the data is, so we will ignore readdir_plus attributes.
|
||||
*/
|
||||
desc->timestamp_valid = 0;
|
||||
page = read_cache_page(inode->i_mapping, desc->page_index,
|
||||
(filler_t *)nfs_readdir_filler, desc);
|
||||
if (IS_ERR(page)) {
|
||||
@@ -468,6 +480,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
|
||||
struct rpc_cred *cred = nfs_file_cred(file);
|
||||
struct page *page = NULL;
|
||||
int status;
|
||||
unsigned long timestamp;
|
||||
|
||||
dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n",
|
||||
(unsigned long long)*desc->dir_cookie);
|
||||
@@ -477,6 +490,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
|
||||
status = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
timestamp = jiffies;
|
||||
desc->error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, *desc->dir_cookie,
|
||||
page,
|
||||
NFS_SERVER(inode)->dtsize,
|
||||
@@ -487,6 +501,8 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
|
||||
desc->page = page;
|
||||
desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */
|
||||
if (desc->error >= 0) {
|
||||
desc->timestamp = timestamp;
|
||||
desc->timestamp_valid = 1;
|
||||
if ((status = dir_decode(desc)) == 0)
|
||||
desc->entry->prev_cookie = *desc->dir_cookie;
|
||||
} else
|
||||
@@ -849,6 +865,10 @@ static int nfs_dentry_delete(struct dentry *dentry)
|
||||
static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
|
||||
{
|
||||
nfs_inode_return_delegation(inode);
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
/* drop any readdir cache as it could easily be old */
|
||||
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
|
||||
|
||||
if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
|
||||
lock_kernel();
|
||||
drop_nlink(inode);
|
||||
|
||||
+3
-2
@@ -54,6 +54,7 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "iostat.h"
|
||||
|
||||
#define NFSDBG_FACILITY NFSDBG_VFS
|
||||
@@ -271,7 +272,7 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
|
||||
bytes = min(rsize,count);
|
||||
|
||||
result = -ENOMEM;
|
||||
data = nfs_readdata_alloc(pgbase + bytes);
|
||||
data = nfs_readdata_alloc(nfs_page_array_len(pgbase, bytes));
|
||||
if (unlikely(!data))
|
||||
break;
|
||||
|
||||
@@ -602,7 +603,7 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
|
||||
bytes = min(wsize,count);
|
||||
|
||||
result = -ENOMEM;
|
||||
data = nfs_writedata_alloc(pgbase + bytes);
|
||||
data = nfs_writedata_alloc(nfs_page_array_len(pgbase, bytes));
|
||||
if (unlikely(!data))
|
||||
break;
|
||||
|
||||
|
||||
@@ -231,3 +231,15 @@ unsigned int nfs_page_length(struct page *page)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the number of pages in an array of length 'len' and
|
||||
* with a base offset of 'base'
|
||||
*/
|
||||
static inline
|
||||
unsigned int nfs_page_array_len(unsigned int base, size_t len)
|
||||
{
|
||||
return ((unsigned long)len + (unsigned long)base +
|
||||
PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -133,13 +133,15 @@ xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res)
|
||||
|
||||
#define MNT_dirpath_sz (1 + 256)
|
||||
#define MNT_fhstatus_sz (1 + 8)
|
||||
#define MNT_fhstatus3_sz (1 + 16)
|
||||
|
||||
static struct rpc_procinfo mnt_procedures[] = {
|
||||
[MNTPROC_MNT] = {
|
||||
.p_proc = MNTPROC_MNT,
|
||||
.p_encode = (kxdrproc_t) xdr_encode_dirpath,
|
||||
.p_decode = (kxdrproc_t) xdr_decode_fhstatus,
|
||||
.p_bufsiz = MNT_dirpath_sz << 2,
|
||||
.p_arglen = MNT_dirpath_sz,
|
||||
.p_replen = MNT_fhstatus_sz,
|
||||
.p_statidx = MNTPROC_MNT,
|
||||
.p_name = "MOUNT",
|
||||
},
|
||||
@@ -150,7 +152,8 @@ static struct rpc_procinfo mnt3_procedures[] = {
|
||||
.p_proc = MOUNTPROC3_MNT,
|
||||
.p_encode = (kxdrproc_t) xdr_encode_dirpath,
|
||||
.p_decode = (kxdrproc_t) xdr_decode_fhstatus3,
|
||||
.p_bufsiz = MNT_dirpath_sz << 2,
|
||||
.p_arglen = MNT_dirpath_sz,
|
||||
.p_replen = MNT_fhstatus3_sz,
|
||||
.p_statidx = MOUNTPROC3_MNT,
|
||||
.p_name = "MOUNT",
|
||||
},
|
||||
|
||||
+2
-5
@@ -687,16 +687,13 @@ nfs_stat_to_errno(int stat)
|
||||
return nfs_errtbl[i].errno;
|
||||
}
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) (((a) > (b))? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define PROC(proc, argtype, restype, timer) \
|
||||
[NFSPROC_##proc] = { \
|
||||
.p_proc = NFSPROC_##proc, \
|
||||
.p_encode = (kxdrproc_t) nfs_xdr_##argtype, \
|
||||
.p_decode = (kxdrproc_t) nfs_xdr_##restype, \
|
||||
.p_bufsiz = MAX(NFS_##argtype##_sz,NFS_##restype##_sz) << 2, \
|
||||
.p_arglen = NFS_##argtype##_sz, \
|
||||
.p_replen = NFS_##restype##_sz, \
|
||||
.p_timer = timer, \
|
||||
.p_statidx = NFSPROC_##proc, \
|
||||
.p_name = #proc, \
|
||||
|
||||
+6
-7
@@ -1102,16 +1102,13 @@ nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
|
||||
}
|
||||
#endif /* CONFIG_NFS_V3_ACL */
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) (((a) > (b))? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define PROC(proc, argtype, restype, timer) \
|
||||
[NFS3PROC_##proc] = { \
|
||||
.p_proc = NFS3PROC_##proc, \
|
||||
.p_encode = (kxdrproc_t) nfs3_xdr_##argtype, \
|
||||
.p_decode = (kxdrproc_t) nfs3_xdr_##restype, \
|
||||
.p_bufsiz = MAX(NFS3_##argtype##_sz,NFS3_##restype##_sz) << 2, \
|
||||
.p_arglen = NFS3_##argtype##_sz, \
|
||||
.p_replen = NFS3_##restype##_sz, \
|
||||
.p_timer = timer, \
|
||||
.p_statidx = NFS3PROC_##proc, \
|
||||
.p_name = #proc, \
|
||||
@@ -1153,7 +1150,8 @@ static struct rpc_procinfo nfs3_acl_procedures[] = {
|
||||
.p_proc = ACLPROC3_GETACL,
|
||||
.p_encode = (kxdrproc_t) nfs3_xdr_getaclargs,
|
||||
.p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
|
||||
.p_bufsiz = MAX(ACL3_getaclargs_sz, ACL3_getaclres_sz) << 2,
|
||||
.p_arglen = ACL3_getaclargs_sz,
|
||||
.p_replen = ACL3_getaclres_sz,
|
||||
.p_timer = 1,
|
||||
.p_name = "GETACL",
|
||||
},
|
||||
@@ -1161,7 +1159,8 @@ static struct rpc_procinfo nfs3_acl_procedures[] = {
|
||||
.p_proc = ACLPROC3_SETACL,
|
||||
.p_encode = (kxdrproc_t) nfs3_xdr_setaclargs,
|
||||
.p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
|
||||
.p_bufsiz = MAX(ACL3_setaclargs_sz, ACL3_setaclres_sz) << 2,
|
||||
.p_arglen = ACL3_setaclargs_sz,
|
||||
.p_replen = ACL3_setaclres_sz,
|
||||
.p_timer = 0,
|
||||
.p_name = "SETACL",
|
||||
},
|
||||
|
||||
+1
-2
@@ -2647,8 +2647,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
|
||||
nfs_inode_return_delegation(inode);
|
||||
buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
|
||||
ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
|
||||
if (ret == 0)
|
||||
nfs4_write_cached_acl(inode, buf, buflen);
|
||||
nfs_zap_caches(inode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+2
-5
@@ -4546,16 +4546,13 @@ nfs4_stat_to_errno(int stat)
|
||||
return stat;
|
||||
}
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) (((a) > (b))? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define PROC(proc, argtype, restype) \
|
||||
[NFSPROC4_CLNT_##proc] = { \
|
||||
.p_proc = NFSPROC4_COMPOUND, \
|
||||
.p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \
|
||||
.p_decode = (kxdrproc_t) nfs4_xdr_##restype, \
|
||||
.p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2, \
|
||||
.p_arglen = NFS4_##argtype##_sz, \
|
||||
.p_replen = NFS4_##restype##_sz, \
|
||||
.p_statidx = NFSPROC4_CLNT_##proc, \
|
||||
.p_name = #proc, \
|
||||
}
|
||||
|
||||
+1
-1
@@ -428,7 +428,7 @@ static int __init root_nfs_getport(int program, int version, int proto)
|
||||
printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n",
|
||||
program, version, NIPQUAD(servaddr));
|
||||
set_sockaddr(&sin, servaddr, 0);
|
||||
return rpc_getport_external(&sin, program, version, proto);
|
||||
return rpcb_getport_external(&sin, program, version, proto);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+140
-118
@@ -17,7 +17,8 @@
|
||||
#include <linux/nfs_page.h>
|
||||
#include <linux/nfs_fs.h>
|
||||
#include <linux/nfs_mount.h>
|
||||
#include <linux/writeback.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define NFS_PARANOIA 1
|
||||
|
||||
@@ -50,9 +51,7 @@ nfs_page_free(struct nfs_page *p)
|
||||
* @count: number of bytes to read/write
|
||||
*
|
||||
* The page must be locked by the caller. This makes sure we never
|
||||
* create two different requests for the same page, and avoids
|
||||
* a possible deadlock when we reach the hard limit on the number
|
||||
* of dirty pages.
|
||||
* create two different requests for the same page.
|
||||
* User should ensure it is safe to sleep in this function.
|
||||
*/
|
||||
struct nfs_page *
|
||||
@@ -63,16 +62,12 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct nfs_page *req;
|
||||
|
||||
/* Deal with hard limits. */
|
||||
for (;;) {
|
||||
/* try to allocate the request struct */
|
||||
req = nfs_page_alloc();
|
||||
if (req != NULL)
|
||||
break;
|
||||
|
||||
/* Try to free up at least one request in order to stay
|
||||
* below the hard limit
|
||||
*/
|
||||
if (signalled() && (server->flags & NFS_MOUNT_INTR))
|
||||
return ERR_PTR(-ERESTARTSYS);
|
||||
yield();
|
||||
@@ -223,123 +218,150 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs_coalesce_requests - Split coalesced requests out from a list.
|
||||
* @head: source list
|
||||
* @dst: destination list
|
||||
* @nmax: maximum number of requests to coalesce
|
||||
*
|
||||
* Moves a maximum of 'nmax' elements from one list to another.
|
||||
* The elements are checked to ensure that they form a contiguous set
|
||||
* of pages, and that the RPC credentials are the same.
|
||||
* nfs_pageio_init - initialise a page io descriptor
|
||||
* @desc: pointer to descriptor
|
||||
* @inode: pointer to inode
|
||||
* @doio: pointer to io function
|
||||
* @bsize: io block size
|
||||
* @io_flags: extra parameters for the io function
|
||||
*/
|
||||
int
|
||||
nfs_coalesce_requests(struct list_head *head, struct list_head *dst,
|
||||
unsigned int nmax)
|
||||
void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
|
||||
struct inode *inode,
|
||||
int (*doio)(struct inode *, struct list_head *, unsigned int, size_t, int),
|
||||
size_t bsize,
|
||||
int io_flags)
|
||||
{
|
||||
struct nfs_page *req = NULL;
|
||||
unsigned int npages = 0;
|
||||
INIT_LIST_HEAD(&desc->pg_list);
|
||||
desc->pg_bytes_written = 0;
|
||||
desc->pg_count = 0;
|
||||
desc->pg_bsize = bsize;
|
||||
desc->pg_base = 0;
|
||||
desc->pg_inode = inode;
|
||||
desc->pg_doio = doio;
|
||||
desc->pg_ioflags = io_flags;
|
||||
desc->pg_error = 0;
|
||||
}
|
||||
|
||||
while (!list_empty(head)) {
|
||||
struct nfs_page *prev = req;
|
||||
/**
|
||||
* nfs_can_coalesce_requests - test two requests for compatibility
|
||||
* @prev: pointer to nfs_page
|
||||
* @req: pointer to nfs_page
|
||||
*
|
||||
* The nfs_page structures 'prev' and 'req' are compared to ensure that the
|
||||
* page data area they describe is contiguous, and that their RPC
|
||||
* credentials, NFSv4 open state, and lockowners are the same.
|
||||
*
|
||||
* Return 'true' if this is the case, else return 'false'.
|
||||
*/
|
||||
static int nfs_can_coalesce_requests(struct nfs_page *prev,
|
||||
struct nfs_page *req)
|
||||
{
|
||||
if (req->wb_context->cred != prev->wb_context->cred)
|
||||
return 0;
|
||||
if (req->wb_context->lockowner != prev->wb_context->lockowner)
|
||||
return 0;
|
||||
if (req->wb_context->state != prev->wb_context->state)
|
||||
return 0;
|
||||
if (req->wb_index != (prev->wb_index + 1))
|
||||
return 0;
|
||||
if (req->wb_pgbase != 0)
|
||||
return 0;
|
||||
if (prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
req = nfs_list_entry(head->next);
|
||||
if (prev) {
|
||||
if (req->wb_context->cred != prev->wb_context->cred)
|
||||
break;
|
||||
if (req->wb_context->lockowner != prev->wb_context->lockowner)
|
||||
break;
|
||||
if (req->wb_context->state != prev->wb_context->state)
|
||||
break;
|
||||
if (req->wb_index != (prev->wb_index + 1))
|
||||
break;
|
||||
/**
|
||||
* nfs_pageio_do_add_request - Attempt to coalesce a request into a page list.
|
||||
* @desc: destination io descriptor
|
||||
* @req: request
|
||||
*
|
||||
* Returns true if the request 'req' was successfully coalesced into the
|
||||
* existing list of pages 'desc'.
|
||||
*/
|
||||
static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
|
||||
struct nfs_page *req)
|
||||
{
|
||||
size_t newlen = req->wb_bytes;
|
||||
|
||||
if (req->wb_pgbase != 0)
|
||||
break;
|
||||
}
|
||||
nfs_list_remove_request(req);
|
||||
nfs_list_add_request(req, dst);
|
||||
npages++;
|
||||
if (req->wb_pgbase + req->wb_bytes != PAGE_CACHE_SIZE)
|
||||
break;
|
||||
if (npages >= nmax)
|
||||
break;
|
||||
if (desc->pg_count != 0) {
|
||||
struct nfs_page *prev;
|
||||
|
||||
/*
|
||||
* FIXME: ideally we should be able to coalesce all requests
|
||||
* that are not block boundary aligned, but currently this
|
||||
* is problematic for the case of bsize < PAGE_CACHE_SIZE,
|
||||
* since nfs_flush_multi and nfs_pagein_multi assume you
|
||||
* can have only one struct nfs_page.
|
||||
*/
|
||||
if (desc->pg_bsize < PAGE_SIZE)
|
||||
return 0;
|
||||
newlen += desc->pg_count;
|
||||
if (newlen > desc->pg_bsize)
|
||||
return 0;
|
||||
prev = nfs_list_entry(desc->pg_list.prev);
|
||||
if (!nfs_can_coalesce_requests(prev, req))
|
||||
return 0;
|
||||
} else
|
||||
desc->pg_base = req->wb_pgbase;
|
||||
nfs_list_remove_request(req);
|
||||
nfs_list_add_request(req, &desc->pg_list);
|
||||
desc->pg_count = newlen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper for nfs_pageio_add_request and nfs_pageio_complete
|
||||
*/
|
||||
static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc)
|
||||
{
|
||||
if (!list_empty(&desc->pg_list)) {
|
||||
int error = desc->pg_doio(desc->pg_inode,
|
||||
&desc->pg_list,
|
||||
nfs_page_array_len(desc->pg_base,
|
||||
desc->pg_count),
|
||||
desc->pg_count,
|
||||
desc->pg_ioflags);
|
||||
if (error < 0)
|
||||
desc->pg_error = error;
|
||||
else
|
||||
desc->pg_bytes_written += desc->pg_count;
|
||||
}
|
||||
return npages;
|
||||
if (list_empty(&desc->pg_list)) {
|
||||
desc->pg_count = 0;
|
||||
desc->pg_base = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs_pageio_add_request - Attempt to coalesce a request into a page list.
|
||||
* @desc: destination io descriptor
|
||||
* @req: request
|
||||
*
|
||||
* Returns true if the request 'req' was successfully coalesced into the
|
||||
* existing list of pages 'desc'.
|
||||
*/
|
||||
int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
|
||||
struct nfs_page *req)
|
||||
{
|
||||
while (!nfs_pageio_do_add_request(desc, req)) {
|
||||
nfs_pageio_doio(desc);
|
||||
if (desc->pg_error < 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs_pageio_complete - Complete I/O on an nfs_pageio_descriptor
|
||||
* @desc: pointer to io descriptor
|
||||
*/
|
||||
void nfs_pageio_complete(struct nfs_pageio_descriptor *desc)
|
||||
{
|
||||
nfs_pageio_doio(desc);
|
||||
}
|
||||
|
||||
#define NFS_SCAN_MAXENTRIES 16
|
||||
/**
|
||||
* nfs_scan_dirty - Scan the radix tree for dirty requests
|
||||
* @mapping: pointer to address space
|
||||
* @wbc: writeback_control structure
|
||||
* @dst: Destination list
|
||||
*
|
||||
* Moves elements from one of the inode request lists.
|
||||
* If the number of requests is set to 0, the entire address_space
|
||||
* starting at index idx_start, is scanned.
|
||||
* The requests are *not* checked to ensure that they form a contiguous set.
|
||||
* You must be holding the inode's req_lock when calling this function
|
||||
*/
|
||||
long nfs_scan_dirty(struct address_space *mapping,
|
||||
struct writeback_control *wbc,
|
||||
struct list_head *dst)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(mapping->host);
|
||||
struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES];
|
||||
struct nfs_page *req;
|
||||
pgoff_t idx_start, idx_end;
|
||||
long res = 0;
|
||||
int found, i;
|
||||
|
||||
if (nfsi->ndirty == 0)
|
||||
return 0;
|
||||
if (wbc->range_cyclic) {
|
||||
idx_start = 0;
|
||||
idx_end = ULONG_MAX;
|
||||
} else if (wbc->range_end == 0) {
|
||||
idx_start = wbc->range_start >> PAGE_CACHE_SHIFT;
|
||||
idx_end = ULONG_MAX;
|
||||
} else {
|
||||
idx_start = wbc->range_start >> PAGE_CACHE_SHIFT;
|
||||
idx_end = wbc->range_end >> PAGE_CACHE_SHIFT;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
unsigned int toscan = NFS_SCAN_MAXENTRIES;
|
||||
|
||||
found = radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree,
|
||||
(void **)&pgvec[0], idx_start, toscan,
|
||||
NFS_PAGE_TAG_DIRTY);
|
||||
|
||||
/* Did we make progress? */
|
||||
if (found <= 0)
|
||||
break;
|
||||
|
||||
for (i = 0; i < found; i++) {
|
||||
req = pgvec[i];
|
||||
if (!wbc->range_cyclic && req->wb_index > idx_end)
|
||||
goto out;
|
||||
|
||||
/* Try to lock request and mark it for writeback */
|
||||
if (!nfs_set_page_writeback_locked(req))
|
||||
goto next;
|
||||
radix_tree_tag_clear(&nfsi->nfs_page_tree,
|
||||
req->wb_index, NFS_PAGE_TAG_DIRTY);
|
||||
nfsi->ndirty--;
|
||||
nfs_list_remove_request(req);
|
||||
nfs_list_add_request(req, dst);
|
||||
res++;
|
||||
if (res == LONG_MAX)
|
||||
goto out;
|
||||
next:
|
||||
idx_start = req->wb_index + 1;
|
||||
}
|
||||
}
|
||||
out:
|
||||
WARN_ON ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty));
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs_scan_list - Scan a list for matching requests
|
||||
* @nfsi: NFS inode
|
||||
@@ -355,12 +377,12 @@ out:
|
||||
* You must be holding the inode's req_lock when calling this function
|
||||
*/
|
||||
int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head,
|
||||
struct list_head *dst, unsigned long idx_start,
|
||||
struct list_head *dst, pgoff_t idx_start,
|
||||
unsigned int npages)
|
||||
{
|
||||
struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES];
|
||||
struct nfs_page *req;
|
||||
unsigned long idx_end;
|
||||
pgoff_t idx_end;
|
||||
int found, i;
|
||||
int res;
|
||||
|
||||
|
||||
+34
-58
@@ -27,7 +27,8 @@
|
||||
|
||||
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
|
||||
|
||||
static int nfs_pagein_one(struct list_head *, struct inode *);
|
||||
static int nfs_pagein_multi(struct inode *, struct list_head *, unsigned int, size_t, int);
|
||||
static int nfs_pagein_one(struct inode *, struct list_head *, unsigned int, size_t, int);
|
||||
static const struct rpc_call_ops nfs_read_partial_ops;
|
||||
static const struct rpc_call_ops nfs_read_full_ops;
|
||||
|
||||
@@ -36,9 +37,8 @@ static mempool_t *nfs_rdata_mempool;
|
||||
|
||||
#define MIN_POOL_READ (32)
|
||||
|
||||
struct nfs_read_data *nfs_readdata_alloc(size_t len)
|
||||
struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
|
||||
{
|
||||
unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, GFP_NOFS);
|
||||
|
||||
if (p) {
|
||||
@@ -133,7 +133,10 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
|
||||
memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
|
||||
|
||||
nfs_list_add_request(new, &one_request);
|
||||
nfs_pagein_one(&one_request, inode);
|
||||
if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE)
|
||||
nfs_pagein_multi(inode, &one_request, 1, len, 0);
|
||||
else
|
||||
nfs_pagein_one(inode, &one_request, 1, len, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -230,7 +233,7 @@ static void nfs_execute_read(struct nfs_read_data *data)
|
||||
* won't see the new data until our attribute cache is updated. This is more
|
||||
* or less conventional NFS client behavior.
|
||||
*/
|
||||
static int nfs_pagein_multi(struct list_head *head, struct inode *inode)
|
||||
static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags)
|
||||
{
|
||||
struct nfs_page *req = nfs_list_entry(head->next);
|
||||
struct page *page = req->wb_page;
|
||||
@@ -242,11 +245,11 @@ static int nfs_pagein_multi(struct list_head *head, struct inode *inode)
|
||||
|
||||
nfs_list_remove_request(req);
|
||||
|
||||
nbytes = req->wb_bytes;
|
||||
nbytes = count;
|
||||
do {
|
||||
size_t len = min(nbytes,rsize);
|
||||
|
||||
data = nfs_readdata_alloc(len);
|
||||
data = nfs_readdata_alloc(1);
|
||||
if (!data)
|
||||
goto out_bad;
|
||||
INIT_LIST_HEAD(&data->pages);
|
||||
@@ -258,23 +261,19 @@ static int nfs_pagein_multi(struct list_head *head, struct inode *inode)
|
||||
|
||||
ClearPageError(page);
|
||||
offset = 0;
|
||||
nbytes = req->wb_bytes;
|
||||
nbytes = count;
|
||||
do {
|
||||
data = list_entry(list.next, struct nfs_read_data, pages);
|
||||
list_del_init(&data->pages);
|
||||
|
||||
data->pagevec[0] = page;
|
||||
|
||||
if (nbytes > rsize) {
|
||||
nfs_read_rpcsetup(req, data, &nfs_read_partial_ops,
|
||||
rsize, offset);
|
||||
offset += rsize;
|
||||
nbytes -= rsize;
|
||||
} else {
|
||||
nfs_read_rpcsetup(req, data, &nfs_read_partial_ops,
|
||||
nbytes, offset);
|
||||
nbytes = 0;
|
||||
}
|
||||
if (nbytes < rsize)
|
||||
rsize = nbytes;
|
||||
nfs_read_rpcsetup(req, data, &nfs_read_partial_ops,
|
||||
rsize, offset);
|
||||
offset += rsize;
|
||||
nbytes -= rsize;
|
||||
nfs_execute_read(data);
|
||||
} while (nbytes != 0);
|
||||
|
||||
@@ -291,30 +290,24 @@ out_bad:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int nfs_pagein_one(struct list_head *head, struct inode *inode)
|
||||
static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags)
|
||||
{
|
||||
struct nfs_page *req;
|
||||
struct page **pages;
|
||||
struct nfs_read_data *data;
|
||||
unsigned int count;
|
||||
|
||||
if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE)
|
||||
return nfs_pagein_multi(head, inode);
|
||||
|
||||
data = nfs_readdata_alloc(NFS_SERVER(inode)->rsize);
|
||||
data = nfs_readdata_alloc(npages);
|
||||
if (!data)
|
||||
goto out_bad;
|
||||
|
||||
INIT_LIST_HEAD(&data->pages);
|
||||
pages = data->pagevec;
|
||||
count = 0;
|
||||
while (!list_empty(head)) {
|
||||
req = nfs_list_entry(head->next);
|
||||
nfs_list_remove_request(req);
|
||||
nfs_list_add_request(req, &data->pages);
|
||||
ClearPageError(req->wb_page);
|
||||
*pages++ = req->wb_page;
|
||||
count += req->wb_bytes;
|
||||
}
|
||||
req = nfs_list_entry(data->pages.next);
|
||||
|
||||
@@ -327,28 +320,6 @@ out_bad:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int
|
||||
nfs_pagein_list(struct list_head *head, int rpages)
|
||||
{
|
||||
LIST_HEAD(one_request);
|
||||
struct nfs_page *req;
|
||||
int error = 0;
|
||||
unsigned int pages = 0;
|
||||
|
||||
while (!list_empty(head)) {
|
||||
pages += nfs_coalesce_requests(head, &one_request, rpages);
|
||||
req = nfs_list_entry(one_request.next);
|
||||
error = nfs_pagein_one(&one_request, req->wb_context->dentry->d_inode);
|
||||
if (error < 0)
|
||||
break;
|
||||
}
|
||||
if (error >= 0)
|
||||
return pages;
|
||||
|
||||
nfs_async_read_error(head);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the callback from RPC telling us whether a reply was
|
||||
* received or some error occurred (timeout or socket shutdown).
|
||||
@@ -538,7 +509,7 @@ out_error:
|
||||
}
|
||||
|
||||
struct nfs_readdesc {
|
||||
struct list_head *head;
|
||||
struct nfs_pageio_descriptor *pgio;
|
||||
struct nfs_open_context *ctx;
|
||||
};
|
||||
|
||||
@@ -562,19 +533,21 @@ readpage_async_filler(void *data, struct page *page)
|
||||
}
|
||||
if (len < PAGE_CACHE_SIZE)
|
||||
memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
|
||||
nfs_list_add_request(new, desc->head);
|
||||
nfs_pageio_add_request(desc->pgio, new);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfs_readpages(struct file *filp, struct address_space *mapping,
|
||||
struct list_head *pages, unsigned nr_pages)
|
||||
{
|
||||
LIST_HEAD(head);
|
||||
struct nfs_pageio_descriptor pgio;
|
||||
struct nfs_readdesc desc = {
|
||||
.head = &head,
|
||||
.pgio = &pgio,
|
||||
};
|
||||
struct inode *inode = mapping->host;
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
size_t rsize = server->rsize;
|
||||
unsigned long npages;
|
||||
int ret = -ESTALE;
|
||||
|
||||
dprintk("NFS: nfs_readpages (%s/%Ld %d)\n",
|
||||
@@ -593,13 +566,16 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
|
||||
} else
|
||||
desc.ctx = get_nfs_open_context((struct nfs_open_context *)
|
||||
filp->private_data);
|
||||
if (rsize < PAGE_CACHE_SIZE)
|
||||
nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
|
||||
else
|
||||
nfs_pageio_init(&pgio, inode, nfs_pagein_one, rsize, 0);
|
||||
|
||||
ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);
|
||||
if (!list_empty(&head)) {
|
||||
int err = nfs_pagein_list(&head, server->rpages);
|
||||
if (!ret)
|
||||
nfs_add_stats(inode, NFSIOS_READPAGES, err);
|
||||
ret = err;
|
||||
}
|
||||
|
||||
nfs_pageio_complete(&pgio);
|
||||
npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
|
||||
nfs_add_stats(inode, NFSIOS_READPAGES, npages);
|
||||
put_nfs_open_context(desc.ctx);
|
||||
out:
|
||||
return ret;
|
||||
|
||||
+5
-5
@@ -204,9 +204,9 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
lock_kernel();
|
||||
|
||||
error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
|
||||
buf->f_type = NFS_SUPER_MAGIC;
|
||||
if (error < 0)
|
||||
goto out_err;
|
||||
buf->f_type = NFS_SUPER_MAGIC;
|
||||
|
||||
/*
|
||||
* Current versions of glibc do not correctly handle the
|
||||
@@ -233,15 +233,14 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
buf->f_ffree = res.afiles;
|
||||
|
||||
buf->f_namelen = server->namelen;
|
||||
out:
|
||||
|
||||
unlock_kernel();
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
dprintk("%s: statfs error = %d\n", __FUNCTION__, -error);
|
||||
buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1;
|
||||
goto out;
|
||||
|
||||
unlock_kernel();
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -291,6 +290,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
|
||||
{ NFS_MOUNT_NOAC, ",noac", "" },
|
||||
{ NFS_MOUNT_NONLM, ",nolock", "" },
|
||||
{ NFS_MOUNT_NOACL, ",noacl", "" },
|
||||
{ NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
const struct proc_nfs_info *nfs_infop;
|
||||
|
||||
+82
-176
File diff suppressed because it is too large
Load Diff
@@ -315,16 +315,13 @@ out:
|
||||
/*
|
||||
* RPC procedure tables
|
||||
*/
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) (((a) > (b))? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define PROC(proc, call, argtype, restype) \
|
||||
[NFSPROC4_CLNT_##proc] = { \
|
||||
.p_proc = NFSPROC4_CB_##call, \
|
||||
.p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \
|
||||
.p_decode = (kxdrproc_t) nfs4_xdr_##restype, \
|
||||
.p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2, \
|
||||
.p_arglen = NFS4_##argtype##_sz, \
|
||||
.p_replen = NFS4_##restype##_sz, \
|
||||
.p_statidx = NFSPROC4_CB_##call, \
|
||||
.p_name = #proc, \
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ struct nlm_wait;
|
||||
/*
|
||||
* Memory chunk for NLM client RPC request.
|
||||
*/
|
||||
#define NLMCLNT_OHSIZE (sizeof(utsname()->nodename)+10)
|
||||
#define NLMCLNT_OHSIZE ((__NEW_UTS_LEN) + 10u)
|
||||
struct nlm_rqst {
|
||||
unsigned int a_flags; /* initial RPC task flags */
|
||||
struct nlm_host * a_host; /* host handle */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user