Merge branch 'for-2.6.33' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.33' of git://linux-nfs.org/~bfields/linux: (42 commits) nfsd: remove pointless paths in file headers nfsd: move most of nfsfh.h to fs/nfsd nfsd: remove unused field rq_reffh nfsd: enable V4ROOT exports nfsd: make V4ROOT exports read-only nfsd: restrict filehandles accepted in V4ROOT case nfsd: allow exports of symlinks nfsd: filter readdir results in V4ROOT case nfsd: filter lookup results in V4ROOT case nfsd4: don't continue "under" mounts in V4ROOT case nfsd: introduce export flag for v4 pseudoroot nfsd: let "insecure" flag vary by pseudoflavor nfsd: new interface to advertise export features nfsd: Move private headers to source directory vfs: nfsctl.c un-used nfsd #includes lockd: Remove un-used nfsd headers #includes s390: remove un-used nfsd #includes sparc: remove un-used nfsd #includes parsic: remove un-used nfsd #includes compat.c: Remove dependence on nfsd private headers ...
This commit is contained in:
commit
37c24b37fb
63 changed files with 721 additions and 865 deletions
|
@ -1,7 +1,5 @@
|
|||
00-INDEX
|
||||
- this file (info on some of the filesystems supported by linux).
|
||||
Exporting
|
||||
- explanation of how to make filesystems exportable.
|
||||
Locking
|
||||
- info on locking rules as they pertain to Linux VFS.
|
||||
9p.txt
|
||||
|
@ -68,12 +66,8 @@ mandatory-locking.txt
|
|||
- info on the Linux implementation of Sys V mandatory file locking.
|
||||
ncpfs.txt
|
||||
- info on Novell Netware(tm) filesystem using NCP protocol.
|
||||
nfs41-server.txt
|
||||
- info on the Linux server implementation of NFSv4 minor version 1.
|
||||
nfs-rdma.txt
|
||||
- how to install and setup the Linux NFS/RDMA client and server software.
|
||||
nfsroot.txt
|
||||
- short guide on setting up a diskless box with NFS root filesystem.
|
||||
nfs/
|
||||
- nfs-related documentation.
|
||||
nilfs2.txt
|
||||
- info and mount options for the NILFS2 filesystem.
|
||||
ntfs.txt
|
||||
|
@ -92,8 +86,6 @@ relay.txt
|
|||
- info on relay, for efficient streaming from kernel to user space.
|
||||
romfs.txt
|
||||
- description of the ROMFS filesystem.
|
||||
rpc-cache.txt
|
||||
- introduction to the caching mechanisms in the sunrpc layer.
|
||||
seq_file.txt
|
||||
- how to use the seq_file API
|
||||
sharedsubtree.txt
|
||||
|
|
16
Documentation/filesystems/nfs/00-INDEX
Normal file
16
Documentation/filesystems/nfs/00-INDEX
Normal file
|
@ -0,0 +1,16 @@
|
|||
00-INDEX
|
||||
- this file (nfs-related documentation).
|
||||
Exporting
|
||||
- explanation of how to make filesystems exportable.
|
||||
knfsd-stats.txt
|
||||
- statistics which the NFS server makes available to user space.
|
||||
nfs.txt
|
||||
- nfs client, and DNS resolution for fs_locations.
|
||||
nfs41-server.txt
|
||||
- info on the Linux server implementation of NFSv4 minor version 1.
|
||||
nfs-rdma.txt
|
||||
- how to install and setup the Linux NFS/RDMA client and server software
|
||||
nfsroot.txt
|
||||
- short guide on setting up a diskless box with NFS root filesystem.
|
||||
rpc-cache.txt
|
||||
- introduction to the caching mechanisms in the sunrpc layer.
|
|
@ -41,7 +41,7 @@ interoperability problems with future clients. Known issues:
|
|||
conformant with the spec (for example, we don't use kerberos
|
||||
on the backchannel correctly).
|
||||
- no trunking support: no clients currently take advantage of
|
||||
trunking, but this is a mandatory failure, and its use is
|
||||
trunking, but this is a mandatory feature, and its use is
|
||||
recommended to clients in a number of places. (E.g. to ensure
|
||||
timely renewal in case an existing connection's retry timeouts
|
||||
have gotten too long; see section 8.3 of the draft.)
|
||||
|
@ -213,3 +213,10 @@ The following cases aren't supported yet:
|
|||
DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID.
|
||||
* DESTROY_SESSION MUST be the final operation in the COMPOUND request.
|
||||
|
||||
Nonstandard compound limitations:
|
||||
* No support for a sessions fore channel RPC compound that requires both a
|
||||
ca_maxrequestsize request and a ca_maxresponsesize reply, so we may
|
||||
fail to live up to the promise we made in CREATE_SESSION fore channel
|
||||
negotiation.
|
||||
* No more than one IO operation (read, write, readdir) allowed per
|
||||
compound.
|
|
@ -140,7 +140,7 @@ Callers of notify_change() need ->i_mutex now.
|
|||
New super_block field "struct export_operations *s_export_op" for
|
||||
explicit support for exporting, e.g. via NFS. The structure is fully
|
||||
documented at its declaration in include/linux/fs.h, and in
|
||||
Documentation/filesystems/Exporting.
|
||||
Documentation/filesystems/nfs/Exporting.
|
||||
|
||||
Briefly it allows for the definition of decode_fh and encode_fh operations
|
||||
to encode and decode filehandles, and allows the filesystem to use
|
||||
|
|
|
@ -1032,7 +1032,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
No delay
|
||||
|
||||
ip= [IP_PNP]
|
||||
See Documentation/filesystems/nfsroot.txt.
|
||||
See Documentation/filesystems/nfs/nfsroot.txt.
|
||||
|
||||
ip2= [HW] Set IO/IRQ pairs for up to 4 IntelliPort boards
|
||||
See comment before ip2_setup() in
|
||||
|
@ -1553,10 +1553,10 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
going to be removed in 2.6.29.
|
||||
|
||||
nfsaddrs= [NFS]
|
||||
See Documentation/filesystems/nfsroot.txt.
|
||||
See Documentation/filesystems/nfs/nfsroot.txt.
|
||||
|
||||
nfsroot= [NFS] nfs root filesystem for disk-less boxes.
|
||||
See Documentation/filesystems/nfsroot.txt.
|
||||
See Documentation/filesystems/nfs/nfsroot.txt.
|
||||
|
||||
nfs.callback_tcpport=
|
||||
[NFS] set the TCP port on which the NFSv4 callback
|
||||
|
|
|
@ -26,13 +26,7 @@
|
|||
#include <linux/shm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/nfs_fs.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include <linux/nfsd/xdr.h>
|
||||
#include <linux/nfsd/syscall.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/stat.h>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* See Documentation/filesystems/Exporting
|
||||
* See Documentation/filesystems/nfs/Exporting
|
||||
* and examples in fs/exportfs
|
||||
*
|
||||
* Since cifs is a network file system, an "fsid" must be included for
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
#include <linux/dirent.h>
|
||||
#include <linux/fsnotify.h>
|
||||
#include <linux/highuid.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/syscall.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/rwsem.h>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* and for mapping back from file handles to dentries.
|
||||
*
|
||||
* For details on why we do all the strange and hairy things in here
|
||||
* take a look at Documentation/filesystems/Exporting.
|
||||
* take a look at Documentation/filesystems/nfs/Exporting.
|
||||
*/
|
||||
#include <linux/exportfs.h>
|
||||
#include <linux/fs.h>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
* The following files are helpful:
|
||||
*
|
||||
* Documentation/filesystems/Exporting
|
||||
* Documentation/filesystems/nfs/Exporting
|
||||
* fs/exportfs/expfs.c.
|
||||
*/
|
||||
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
#include <linux/time.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/lockd/lockd.h>
|
||||
#include <linux/lockd/share.h>
|
||||
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
#include <linux/time.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/lockd/lockd.h>
|
||||
#include <linux/lockd/share.h>
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ config ROOT_NFS
|
|||
If you want your system to mount its root file system via NFS,
|
||||
choose Y here. This is common practice for managing systems
|
||||
without local permanent storage. For details, read
|
||||
<file:Documentation/filesystems/nfsroot.txt>.
|
||||
<file:Documentation/filesystems/nfs/nfsroot.txt>.
|
||||
|
||||
Most people say N here.
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/syscall.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/sched.h>
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
/*
|
||||
* linux/fs/nfsd/auth.c
|
||||
*
|
||||
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
|
||||
*/
|
||||
/* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/sunrpc/svcauth.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/export.h>
|
||||
#include "nfsd.h"
|
||||
#include "auth.h"
|
||||
|
||||
int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* include/linux/nfsd/cache.h
|
||||
*
|
||||
* Request reply cache. This was heavily inspired by the
|
||||
* implementation in 4.3BSD/4.4BSD.
|
||||
*
|
||||
|
@ -10,8 +8,7 @@
|
|||
#ifndef NFSCACHE_H
|
||||
#define NFSCACHE_H
|
||||
|
||||
#include <linux/in.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
|
||||
/*
|
||||
* Representation of a reply cache entry.
|
|
@ -1,7 +1,5 @@
|
|||
#define MSNFS /* HACK HACK */
|
||||
/*
|
||||
* linux/fs/nfsd/export.c
|
||||
*
|
||||
* NFS exporting and validation.
|
||||
*
|
||||
* We maintain a list of clients, each of which has a list of
|
||||
|
@ -14,29 +12,16 @@
|
|||
* Copyright (C) 1995, 1996 Olaf Kirch, <okir@monad.swb.de>
|
||||
*/
|
||||
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/hash.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/exportfs.h>
|
||||
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/nfsfh.h>
|
||||
#include <linux/nfsd/syscall.h>
|
||||
#include <linux/lockd/bind.h>
|
||||
#include <linux/sunrpc/msg_prot.h>
|
||||
#include <linux/sunrpc/gss_api.h>
|
||||
#include <net/ipv6.h>
|
||||
|
||||
#include "nfsd.h"
|
||||
#include "nfsfh.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_EXPORT
|
||||
|
||||
typedef struct auth_domain svc_client;
|
||||
|
@ -369,16 +354,25 @@ static struct svc_export *svc_export_update(struct svc_export *new,
|
|||
struct svc_export *old);
|
||||
static struct svc_export *svc_export_lookup(struct svc_export *);
|
||||
|
||||
static int check_export(struct inode *inode, int flags, unsigned char *uuid)
|
||||
static int check_export(struct inode *inode, int *flags, unsigned char *uuid)
|
||||
{
|
||||
|
||||
/* We currently export only dirs and regular files.
|
||||
* This is what umountd does.
|
||||
/*
|
||||
* We currently export only dirs, regular files, and (for v4
|
||||
* pseudoroot) symlinks.
|
||||
*/
|
||||
if (!S_ISDIR(inode->i_mode) &&
|
||||
!S_ISLNK(inode->i_mode) &&
|
||||
!S_ISREG(inode->i_mode))
|
||||
return -ENOTDIR;
|
||||
|
||||
/*
|
||||
* Mountd should never pass down a writeable V4ROOT export, but,
|
||||
* just to make sure:
|
||||
*/
|
||||
if (*flags & NFSEXP_V4ROOT)
|
||||
*flags |= NFSEXP_READONLY;
|
||||
|
||||
/* There are two requirements on a filesystem to be exportable.
|
||||
* 1: We must be able to identify the filesystem from a number.
|
||||
* either a device number (so FS_REQUIRES_DEV needed)
|
||||
|
@ -387,7 +381,7 @@ static int check_export(struct inode *inode, int flags, unsigned char *uuid)
|
|||
* This means that s_export_op must be set.
|
||||
*/
|
||||
if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) &&
|
||||
!(flags & NFSEXP_FSID) &&
|
||||
!(*flags & NFSEXP_FSID) &&
|
||||
uuid == NULL) {
|
||||
dprintk("exp_export: export of non-dev fs without fsid\n");
|
||||
return -EINVAL;
|
||||
|
@ -602,7 +596,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
|
|||
goto out4;
|
||||
}
|
||||
|
||||
err = check_export(exp.ex_path.dentry->d_inode, exp.ex_flags,
|
||||
err = check_export(exp.ex_path.dentry->d_inode, &exp.ex_flags,
|
||||
exp.ex_uuid);
|
||||
if (err)
|
||||
goto out4;
|
||||
|
@ -1041,7 +1035,7 @@ exp_export(struct nfsctl_export *nxp)
|
|||
goto finish;
|
||||
}
|
||||
|
||||
err = check_export(path.dentry->d_inode, nxp->ex_flags, NULL);
|
||||
err = check_export(path.dentry->d_inode, &nxp->ex_flags, NULL);
|
||||
if (err) goto finish;
|
||||
|
||||
err = -ENOMEM;
|
||||
|
@ -1320,6 +1314,23 @@ rqst_exp_parent(struct svc_rqst *rqstp, struct path *path)
|
|||
return exp;
|
||||
}
|
||||
|
||||
static struct svc_export *find_fsidzero_export(struct svc_rqst *rqstp)
|
||||
{
|
||||
struct svc_export *exp;
|
||||
u32 fsidv[2];
|
||||
|
||||
mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL);
|
||||
|
||||
exp = rqst_exp_find(rqstp, FSID_NUM, fsidv);
|
||||
/*
|
||||
* We shouldn't have accepting an nfsv4 request at all if we
|
||||
* don't have a pseudoexport!:
|
||||
*/
|
||||
if (IS_ERR(exp) && PTR_ERR(exp) == -ENOENT)
|
||||
exp = ERR_PTR(-ESERVERFAULT);
|
||||
return exp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when we need the filehandle for the root of the pseudofs,
|
||||
* for a given NFSv4 client. The root is defined to be the
|
||||
|
@ -1330,11 +1341,8 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp)
|
|||
{
|
||||
struct svc_export *exp;
|
||||
__be32 rv;
|
||||
u32 fsidv[2];
|
||||
|
||||
mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL);
|
||||
|
||||
exp = rqst_exp_find(rqstp, FSID_NUM, fsidv);
|
||||
exp = find_fsidzero_export(rqstp);
|
||||
if (IS_ERR(exp))
|
||||
return nfserrno(PTR_ERR(exp));
|
||||
rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL);
|
||||
|
@ -1425,6 +1433,7 @@ static struct flags {
|
|||
{ NFSEXP_CROSSMOUNT, {"crossmnt", ""}},
|
||||
{ NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
|
||||
{ NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
|
||||
{ NFSEXP_V4ROOT, {"v4root", ""}},
|
||||
#ifdef MSNFS
|
||||
{ NFSEXP_MSNFS, {"msnfs", ""}},
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/fs/nfsd/lockd.c
|
||||
*
|
||||
* This file contains all the stubs needed when communicating with lockd.
|
||||
* This level of indirection is necessary so we can run nfsd+lockd without
|
||||
* requiring the nfs client to be compiled in/loaded, and vice versa.
|
||||
|
@ -8,14 +6,10 @@
|
|||
* Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/lockd/bind.h>
|
||||
#include "nfsd.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_LOCKD
|
||||
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfs2acl.c
|
||||
*
|
||||
* Process version 2 NFSACL requests.
|
||||
*
|
||||
* Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de>
|
||||
*/
|
||||
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfs.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include <linux/nfsd/xdr.h>
|
||||
#include <linux/nfsd/xdr3.h>
|
||||
#include <linux/posix_acl.h>
|
||||
#include "nfsd.h"
|
||||
/* FIXME: nfsacl.h is a broken header */
|
||||
#include <linux/nfsacl.h>
|
||||
#include "cache.h"
|
||||
#include "xdr3.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_PROC
|
||||
#define RETURN_STATUS(st) { resp->status = (st); return (st); }
|
||||
|
@ -217,6 +213,16 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p,
|
|||
* XDR encode functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* There must be an encoding function for void results so svc_process
|
||||
* will work properly.
|
||||
*/
|
||||
int
|
||||
nfsaclsvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
|
||||
{
|
||||
return xdr_ressize_check(rqstp, p);
|
||||
}
|
||||
|
||||
/* GETACL */
|
||||
static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
|
||||
struct nfsd3_getaclres *resp)
|
||||
|
@ -308,7 +314,6 @@ static int nfsaclsvc_release_access(struct svc_rqst *rqstp, __be32 *p,
|
|||
}
|
||||
|
||||
#define nfsaclsvc_decode_voidargs NULL
|
||||
#define nfsaclsvc_encode_voidres NULL
|
||||
#define nfsaclsvc_release_void NULL
|
||||
#define nfsd3_fhandleargs nfsd_fhandle
|
||||
#define nfsd3_attrstatres nfsd_attrstat
|
||||
|
@ -346,5 +351,5 @@ struct svc_version nfsd_acl_version2 = {
|
|||
.vs_proc = nfsd_acl_procedures2,
|
||||
.vs_dispatch = nfsd_dispatch,
|
||||
.vs_xdrsize = NFS3_SVC_XDRSIZE,
|
||||
.vs_hidden = 1,
|
||||
.vs_hidden = 0,
|
||||
};
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfs3acl.c
|
||||
*
|
||||
* Process version 3 NFSACL requests.
|
||||
*
|
||||
* Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de>
|
||||
*/
|
||||
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfs3.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include <linux/nfsd/xdr3.h>
|
||||
#include <linux/posix_acl.h>
|
||||
#include "nfsd.h"
|
||||
/* FIXME: nfsacl.h is a broken header */
|
||||
#include <linux/nfsacl.h>
|
||||
#include "cache.h"
|
||||
#include "xdr3.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define RETURN_STATUS(st) { resp->status = (st); return (st); }
|
||||
|
||||
|
@ -264,6 +261,6 @@ struct svc_version nfsd_acl_version3 = {
|
|||
.vs_proc = nfsd_acl_procedures3,
|
||||
.vs_dispatch = nfsd_dispatch,
|
||||
.vs_xdrsize = NFS3_SVC_XDRSIZE,
|
||||
.vs_hidden = 1,
|
||||
.vs_hidden = 0,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,30 +1,16 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfs3proc.c
|
||||
*
|
||||
* Process version 3 NFS requests.
|
||||
*
|
||||
* Copyright (C) 1996, 1997, 1998 Olaf Kirch <okir@monad.swb.de>
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/ext2_fs.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/magic.h>
|
||||
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include <linux/nfsd/xdr3.h>
|
||||
#include <linux/nfs3.h>
|
||||
#include "cache.h"
|
||||
#include "xdr3.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_PROC
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfs3xdr.c
|
||||
*
|
||||
* XDR support for nfsd/protocol version 3.
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
|
||||
|
@ -8,19 +6,8 @@
|
|||
* 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()!
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/nfs3.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/sunrpc/xdr.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/xdr3.h>
|
||||
#include "xdr3.h"
|
||||
#include "auth.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_XDR
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* fs/nfs4acl/acl.c
|
||||
*
|
||||
* Common NFSv4 ACL handling code.
|
||||
*
|
||||
* Copyright (c) 2002, 2003 The Regents of the University of Michigan.
|
||||
|
@ -36,15 +34,7 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nfs_fs.h>
|
||||
#include <linux/posix_acl.h>
|
||||
#include <linux/nfs4.h>
|
||||
#include <linux/nfs4_acl.h>
|
||||
|
||||
|
||||
|
@ -389,7 +379,7 @@ sort_pacl(struct posix_acl *pacl)
|
|||
sort_pacl_range(pacl, 1, i-1);
|
||||
|
||||
BUG_ON(pacl->a_entries[i].e_tag != ACL_GROUP_OBJ);
|
||||
j = i++;
|
||||
j = ++i;
|
||||
while (pacl->a_entries[j].e_tag == ACL_GROUP)
|
||||
j++;
|
||||
sort_pacl_range(pacl, i, j-1);
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfs4callback.c
|
||||
*
|
||||
* Copyright (c) 2001 The Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -33,22 +31,9 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/sunrpc/xdr.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/sunrpc/svcsock.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/state.h>
|
||||
#include <linux/sunrpc/sched.h>
|
||||
#include <linux/nfs4.h>
|
||||
#include <linux/sunrpc/xprtsock.h>
|
||||
#include "nfsd.h"
|
||||
#include "state.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_PROC
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* fs/nfsd/nfs4idmap.c
|
||||
*
|
||||
* Mapping of UID/GIDs to name and vice versa.
|
||||
*
|
||||
* Copyright (c) 2002, 2003 The Regents of the University of
|
||||
|
@ -35,22 +33,9 @@
|
|||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/nfs.h>
|
||||
#include <linux/nfs4.h>
|
||||
#include <linux/nfs_fs.h>
|
||||
#include <linux/nfs_page.h>
|
||||
#include <linux/sunrpc/cache.h>
|
||||
#include <linux/nfsd_idmap.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/sunrpc/svcauth.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
/*
|
||||
* Cache entry
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* fs/nfsd/nfs4proc.c
|
||||
*
|
||||
* Server-side procedures for NFSv4.
|
||||
*
|
||||
* Copyright (c) 2002 The Regents of the University of Michigan.
|
||||
|
@ -34,20 +32,11 @@
|
|||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/param.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/file.h>
|
||||
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include <linux/nfs4.h>
|
||||
#include <linux/nfsd/state.h>
|
||||
#include <linux/nfsd/xdr4.h>
|
||||
#include <linux/nfs4_acl.h>
|
||||
#include <linux/sunrpc/gss_api.h>
|
||||
#include "cache.h"
|
||||
#include "xdr4.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_PROC
|
||||
|
||||
|
@ -170,7 +159,7 @@ do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
|
|||
accmode |= NFSD_MAY_READ;
|
||||
if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
|
||||
accmode |= (NFSD_MAY_WRITE | NFSD_MAY_TRUNC);
|
||||
if (open->op_share_deny & NFS4_SHARE_DENY_WRITE)
|
||||
if (open->op_share_deny & NFS4_SHARE_DENY_READ)
|
||||
accmode |= NFSD_MAY_WRITE;
|
||||
|
||||
status = fh_verify(rqstp, current_fh, S_IFREG, accmode);
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfs4recover.c
|
||||
*
|
||||
* Copyright (c) 2004 The Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -33,20 +31,14 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfs4.h>
|
||||
#include <linux/nfsd/state.h>
|
||||
#include <linux/nfsd/xdr4.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/namei.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mount.h>
|
||||
|
||||
#include "nfsd.h"
|
||||
#include "state.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_PROC
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfs4state.c
|
||||
*
|
||||
* Copyright (c) 2001 The Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -34,28 +32,14 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/param.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/nfs4.h>
|
||||
#include <linux/nfsd/state.h>
|
||||
#include <linux/nfsd/xdr4.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/lockd/bind.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sunrpc/svcauth_gss.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include "xdr4.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_PROC
|
||||
|
||||
|
@ -477,13 +461,14 @@ static int set_forechannel_drc_size(struct nfsd4_channel_attrs *fchan)
|
|||
|
||||
/*
|
||||
* fchan holds the client values on input, and the server values on output
|
||||
* sv_max_mesg is the maximum payload plus one page for overhead.
|
||||
*/
|
||||
static int init_forechannel_attrs(struct svc_rqst *rqstp,
|
||||
struct nfsd4_channel_attrs *session_fchan,
|
||||
struct nfsd4_channel_attrs *fchan)
|
||||
{
|
||||
int status = 0;
|
||||
__u32 maxcount = svc_max_payload(rqstp);
|
||||
__u32 maxcount = nfsd_serv->sv_max_mesg;
|
||||
|
||||
/* headerpadsz set to zero in encode routine */
|
||||
|
||||
|
@ -523,6 +508,15 @@ free_session_slots(struct nfsd4_session *ses)
|
|||
kfree(ses->se_slots[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't actually need to cache the rpc and session headers, so we
|
||||
* can allocate a little less for each slot:
|
||||
*/
|
||||
static inline int slot_bytes(struct nfsd4_channel_attrs *ca)
|
||||
{
|
||||
return ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ;
|
||||
}
|
||||
|
||||
static int
|
||||
alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp,
|
||||
struct nfsd4_create_session *cses)
|
||||
|
@ -554,7 +548,7 @@ alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp,
|
|||
memcpy(new, &tmp, sizeof(*new));
|
||||
|
||||
/* allocate each struct nfsd4_slot and data cache in one piece */
|
||||
cachesize = new->se_fchannel.maxresp_cached - NFSD_MIN_HDR_SEQ_SZ;
|
||||
cachesize = slot_bytes(&new->se_fchannel);
|
||||
for (i = 0; i < new->se_fchannel.maxreqs; i++) {
|
||||
sp = kzalloc(sizeof(*sp) + cachesize, GFP_KERNEL);
|
||||
if (!sp)
|
||||
|
@ -628,10 +622,12 @@ void
|
|||
free_session(struct kref *kref)
|
||||
{
|
||||
struct nfsd4_session *ses;
|
||||
int mem;
|
||||
|
||||
ses = container_of(kref, struct nfsd4_session, se_ref);
|
||||
spin_lock(&nfsd_drc_lock);
|
||||
nfsd_drc_mem_used -= ses->se_fchannel.maxreqs * NFSD_SLOT_CACHE_SIZE;
|
||||
mem = ses->se_fchannel.maxreqs * slot_bytes(&ses->se_fchannel);
|
||||
nfsd_drc_mem_used -= mem;
|
||||
spin_unlock(&nfsd_drc_lock);
|
||||
free_session_slots(ses);
|
||||
kfree(ses);
|
||||
|
@ -2404,11 +2400,8 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
|
|||
|
||||
memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid));
|
||||
|
||||
dprintk("NFSD: delegation stateid=(%08x/%08x/%08x/%08x)\n\n",
|
||||
dp->dl_stateid.si_boot,
|
||||
dp->dl_stateid.si_stateownerid,
|
||||
dp->dl_stateid.si_fileid,
|
||||
dp->dl_stateid.si_generation);
|
||||
dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
|
||||
STATEID_VAL(&dp->dl_stateid));
|
||||
out:
|
||||
if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS
|
||||
&& flag == NFS4_OPEN_DELEGATE_NONE
|
||||
|
@ -2498,9 +2491,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
|
|||
|
||||
status = nfs_ok;
|
||||
|
||||
dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n",
|
||||
stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
|
||||
stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
|
||||
dprintk("%s: stateid=" STATEID_FMT "\n", __func__,
|
||||
STATEID_VAL(&stp->st_stateid));
|
||||
out:
|
||||
if (fp)
|
||||
put_nfs4_file(fp);
|
||||
|
@ -2666,9 +2658,8 @@ STALE_STATEID(stateid_t *stateid)
|
|||
{
|
||||
if (time_after((unsigned long)boot_time,
|
||||
(unsigned long)stateid->si_boot)) {
|
||||
dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
|
||||
stateid->si_boot, stateid->si_stateownerid,
|
||||
stateid->si_fileid, stateid->si_generation);
|
||||
dprintk("NFSD: stale stateid " STATEID_FMT "!\n",
|
||||
STATEID_VAL(stateid));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -2680,9 +2671,8 @@ EXPIRED_STATEID(stateid_t *stateid)
|
|||
if (time_before((unsigned long)boot_time,
|
||||
((unsigned long)stateid->si_boot)) &&
|
||||
time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) {
|
||||
dprintk("NFSD: expired stateid (%08x/%08x/%08x/%08x)!\n",
|
||||
stateid->si_boot, stateid->si_stateownerid,
|
||||
stateid->si_fileid, stateid->si_generation);
|
||||
dprintk("NFSD: expired stateid " STATEID_FMT "!\n",
|
||||
STATEID_VAL(stateid));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -2696,9 +2686,8 @@ stateid_error_map(stateid_t *stateid)
|
|||
if (EXPIRED_STATEID(stateid))
|
||||
return nfserr_expired;
|
||||
|
||||
dprintk("NFSD: bad stateid (%08x/%08x/%08x/%08x)!\n",
|
||||
stateid->si_boot, stateid->si_stateownerid,
|
||||
stateid->si_fileid, stateid->si_generation);
|
||||
dprintk("NFSD: bad stateid " STATEID_FMT "!\n",
|
||||
STATEID_VAL(stateid));
|
||||
return nfserr_bad_stateid;
|
||||
}
|
||||
|
||||
|
@ -2884,10 +2873,8 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
|
|||
struct svc_fh *current_fh = &cstate->current_fh;
|
||||
__be32 status;
|
||||
|
||||
dprintk("NFSD: preprocess_seqid_op: seqid=%d "
|
||||
"stateid = (%08x/%08x/%08x/%08x)\n", seqid,
|
||||
stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
|
||||
stateid->si_generation);
|
||||
dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__,
|
||||
seqid, STATEID_VAL(stateid));
|
||||
|
||||
*stpp = NULL;
|
||||
*sopp = NULL;
|
||||
|
@ -3019,12 +3006,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||
sop->so_confirmed = 1;
|
||||
update_stateid(&stp->st_stateid);
|
||||
memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t));
|
||||
dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d "
|
||||
"stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid,
|
||||
stp->st_stateid.si_boot,
|
||||
stp->st_stateid.si_stateownerid,
|
||||
stp->st_stateid.si_fileid,
|
||||
stp->st_stateid.si_generation);
|
||||
dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
|
||||
__func__, oc->oc_seqid, STATEID_VAL(&stp->st_stateid));
|
||||
|
||||
nfsd4_create_clid_dir(sop->so_client);
|
||||
out:
|
||||
|
@ -3283,9 +3266,8 @@ find_delegation_stateid(struct inode *ino, stateid_t *stid)
|
|||
struct nfs4_file *fp;
|
||||
struct nfs4_delegation *dl;
|
||||
|
||||
dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n",
|
||||
stid->si_boot, stid->si_stateownerid,
|
||||
stid->si_fileid, stid->si_generation);
|
||||
dprintk("NFSD: %s: stateid=" STATEID_FMT "\n", __func__,
|
||||
STATEID_VAL(stid));
|
||||
|
||||
fp = find_file(ino);
|
||||
if (!fp)
|
||||
|
|
|
@ -40,24 +40,16 @@
|
|||
* at the end of nfs4svc_decode_compoundargs.
|
||||
*/
|
||||
|
||||
#include <linux/param.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/statfs.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/sunrpc/xdr.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/state.h>
|
||||
#include <linux/nfsd/xdr4.h>
|
||||
#include <linux/nfsd_idmap.h>
|
||||
#include <linux/nfs4.h>
|
||||
#include <linux/nfs4_acl.h>
|
||||
#include <linux/sunrpc/gss_api.h>
|
||||
#include <linux/sunrpc/svcauth_gss.h>
|
||||
|
||||
#include "xdr4.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_XDR
|
||||
|
||||
/*
|
||||
|
@ -2204,11 +2196,14 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
|
|||
* we will not follow the cross mount and will fill the attribtutes
|
||||
* directly from the mountpoint dentry.
|
||||
*/
|
||||
if (d_mountpoint(dentry) && !attributes_need_mount(cd->rd_bmval))
|
||||
ignore_crossmnt = 1;
|
||||
else if (d_mountpoint(dentry)) {
|
||||
if (nfsd_mountpoint(dentry, exp)) {
|
||||
int err;
|
||||
|
||||
if (!(exp->ex_flags & NFSEXP_V4ROOT)
|
||||
&& !attributes_need_mount(cd->rd_bmval)) {
|
||||
ignore_crossmnt = 1;
|
||||
goto out_encode;
|
||||
}
|
||||
/*
|
||||
* Why the heck aren't we just using nfsd_lookup??
|
||||
* Different "."/".." handling? Something else?
|
||||
|
@ -2224,6 +2219,7 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
|
|||
goto out_put;
|
||||
|
||||
}
|
||||
out_encode:
|
||||
nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval,
|
||||
cd->rd_rqstp, ignore_crossmnt);
|
||||
out_put:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfscache.c
|
||||
*
|
||||
* Request reply cache. This is currently a global cache, but this may
|
||||
* change in the future and be a per-client cache.
|
||||
*
|
||||
|
@ -10,16 +8,8 @@
|
|||
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include "nfsd.h"
|
||||
#include "cache.h"
|
||||
|
||||
/* Size of reply cache. Common values are:
|
||||
* 4.3BSD: 128
|
||||
|
|
|
@ -1,46 +1,20 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfsctl.c
|
||||
*
|
||||
* Syscall interface to knfsd.
|
||||
*
|
||||
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#include <linux/nfs.h>
|
||||
#include <linux/nfsd_idmap.h>
|
||||
#include <linux/lockd/bind.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/sunrpc/svcsock.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include <linux/nfsd/xdr.h>
|
||||
#include <linux/nfsd/syscall.h>
|
||||
#include <linux/lockd/lockd.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <net/ipv6.h>
|
||||
#include "nfsd.h"
|
||||
#include "cache.h"
|
||||
|
||||
/*
|
||||
* We have a single directory with 9 nodes in it.
|
||||
|
@ -55,6 +29,7 @@ enum {
|
|||
NFSD_Getfd,
|
||||
NFSD_Getfs,
|
||||
NFSD_List,
|
||||
NFSD_Export_features,
|
||||
NFSD_Fh,
|
||||
NFSD_FO_UnlockIP,
|
||||
NFSD_FO_UnlockFS,
|
||||
|
@ -173,6 +148,24 @@ static const struct file_operations exports_operations = {
|
|||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int export_features_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_printf(m, "0x%x 0x%x\n", NFSEXP_ALLFLAGS, NFSEXP_SECINFO_FLAGS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int export_features_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, export_features_show, NULL);
|
||||
}
|
||||
|
||||
static struct file_operations export_features_operations = {
|
||||
.open = export_features_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
|
||||
extern int nfsd_pool_stats_release(struct inode *inode, struct file *file);
|
||||
|
||||
|
@ -1330,6 +1323,8 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
|
|||
[NFSD_Getfd] = {".getfd", &transaction_ops, S_IWUSR|S_IRUSR},
|
||||
[NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR},
|
||||
[NFSD_List] = {"exports", &exports_operations, S_IRUGO},
|
||||
[NFSD_Export_features] = {"export_features",
|
||||
&export_features_operations, S_IRUGO},
|
||||
[NFSD_FO_UnlockIP] = {"unlock_ip",
|
||||
&transaction_ops, S_IWUSR|S_IRUSR},
|
||||
[NFSD_FO_UnlockFS] = {"unlock_filesystem",
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/include/linux/nfsd/nfsd.h
|
||||
*
|
||||
* Hodge-podge collection of knfsd-related stuff.
|
||||
* I will sort this out later.
|
||||
*
|
||||
|
@ -11,13 +9,9 @@
|
|||
#define LINUX_NFSD_NFSD_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/posix_acl.h>
|
||||
#include <linux/mount.h>
|
||||
|
||||
#include <linux/nfsd/debug.h>
|
||||
#include <linux/nfsd/nfsfh.h>
|
||||
#include <linux/nfsd/export.h>
|
||||
#include <linux/nfsd/stats.h>
|
||||
/*
|
||||
|
@ -25,30 +19,10 @@
|
|||
*/
|
||||
#define NFSD_SUPPORTED_MINOR_VERSION 1
|
||||
|
||||
/*
|
||||
* Flags for nfsd_permission
|
||||
*/
|
||||
#define NFSD_MAY_NOP 0
|
||||
#define NFSD_MAY_EXEC 1 /* == MAY_EXEC */
|
||||
#define NFSD_MAY_WRITE 2 /* == MAY_WRITE */
|
||||
#define NFSD_MAY_READ 4 /* == MAY_READ */
|
||||
#define NFSD_MAY_SATTR 8
|
||||
#define NFSD_MAY_TRUNC 16
|
||||
#define NFSD_MAY_LOCK 32
|
||||
#define NFSD_MAY_OWNER_OVERRIDE 64
|
||||
#define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/
|
||||
#define NFSD_MAY_BYPASS_GSS_ON_ROOT 256
|
||||
|
||||
#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
|
||||
#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
|
||||
|
||||
/*
|
||||
* Callback function for readdir
|
||||
*/
|
||||
struct readdir_cd {
|
||||
__be32 err; /* 0, nfserr, or nfserr_eof */
|
||||
};
|
||||
typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int);
|
||||
|
||||
|
||||
extern struct svc_program nfsd_program;
|
||||
extern struct svc_version nfsd_version2, nfsd_version3,
|
||||
|
@ -73,69 +47,6 @@ int nfsd_nrpools(void);
|
|||
int nfsd_get_nrthreads(int n, int *);
|
||||
int nfsd_set_nrthreads(int n, int *);
|
||||
|
||||
/* nfsd/vfs.c */
|
||||
int fh_lock_parent(struct svc_fh *, struct dentry *);
|
||||
int nfsd_racache_init(int);
|
||||
void nfsd_racache_shutdown(void);
|
||||
int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
|
||||
struct svc_export **expp);
|
||||
__be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *,
|
||||
const char *, unsigned int, struct svc_fh *);
|
||||
__be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *,
|
||||
const char *, unsigned int,
|
||||
struct svc_export **, struct dentry **);
|
||||
__be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *,
|
||||
struct iattr *, int, time_t);
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
__be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
|
||||
struct nfs4_acl *);
|
||||
int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **);
|
||||
#endif /* CONFIG_NFSD_V4 */
|
||||
__be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
|
||||
char *name, int len, struct iattr *attrs,
|
||||
int type, dev_t rdev, struct svc_fh *res);
|
||||
#ifdef CONFIG_NFSD_V3
|
||||
__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
|
||||
__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *,
|
||||
char *name, int len, struct iattr *attrs,
|
||||
struct svc_fh *res, int createmode,
|
||||
u32 *verifier, int *truncp, int *created);
|
||||
__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
|
||||
loff_t, unsigned long);
|
||||
#endif /* CONFIG_NFSD_V3 */
|
||||
__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int,
|
||||
int, struct file **);
|
||||
void nfsd_close(struct file *);
|
||||
__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *,
|
||||
loff_t, struct kvec *, int, unsigned long *);
|
||||
__be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
|
||||
loff_t, struct kvec *,int, unsigned long *, int *);
|
||||
__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *,
|
||||
char *, int *);
|
||||
__be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *,
|
||||
char *name, int len, char *path, int plen,
|
||||
struct svc_fh *res, struct iattr *);
|
||||
__be32 nfsd_link(struct svc_rqst *, struct svc_fh *,
|
||||
char *, int, struct svc_fh *);
|
||||
__be32 nfsd_rename(struct svc_rqst *,
|
||||
struct svc_fh *, char *, int,
|
||||
struct svc_fh *, char *, int);
|
||||
__be32 nfsd_remove(struct svc_rqst *,
|
||||
struct svc_fh *, char *, int);
|
||||
__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type,
|
||||
char *name, int len);
|
||||
int nfsd_truncate(struct svc_rqst *, struct svc_fh *,
|
||||
unsigned long size);
|
||||
__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
|
||||
loff_t *, struct readdir_cd *, filldir_t);
|
||||
__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
|
||||
struct kstatfs *, int access);
|
||||
|
||||
int nfsd_notify_change(struct inode *, struct iattr *);
|
||||
__be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
|
||||
struct dentry *, int);
|
||||
int nfsd_sync_dir(struct dentry *dp);
|
||||
|
||||
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
|
||||
#ifdef CONFIG_NFSD_V2_ACL
|
||||
extern struct svc_version nfsd_acl_version2;
|
||||
|
@ -147,8 +58,6 @@ extern struct svc_version nfsd_acl_version3;
|
|||
#else
|
||||
#define nfsd_acl_version3 NULL
|
||||
#endif
|
||||
struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
|
||||
int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
|
||||
#endif
|
||||
|
||||
enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
|
||||
|
@ -159,6 +68,11 @@ int nfsd_create_serv(void);
|
|||
|
||||
extern int nfsd_max_blksize;
|
||||
|
||||
static inline int nfsd_v4client(struct svc_rqst *rq)
|
||||
{
|
||||
return rq->rq_prog == NFS_PROGRAM && rq->rq_vers == 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* NFSv4 State
|
||||
*/
|
102
fs/nfsd/nfsfh.c
102
fs/nfsd/nfsfh.c
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfsfh.c
|
||||
*
|
||||
* NFS server file handle treatment.
|
||||
*
|
||||
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
|
||||
|
@ -9,19 +7,11 @@
|
|||
* ... and again Southern-Winter 2001 to support export_operations
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/exportfs.h>
|
||||
#include <linux/mount.h>
|
||||
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/sunrpc/svcauth_gss.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include "nfsd.h"
|
||||
#include "vfs.h"
|
||||
#include "auth.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_FH
|
||||
|
@ -96,8 +86,10 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type)
|
|||
static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
|
||||
struct svc_export *exp)
|
||||
{
|
||||
int flags = nfsexp_flags(rqstp, exp);
|
||||
|
||||
/* Check if the request originated from a secure port. */
|
||||
if (!rqstp->rq_secure && EX_SECURE(exp)) {
|
||||
if (!rqstp->rq_secure && (flags & NFSEXP_INSECURE_PORT)) {
|
||||
RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
|
||||
dprintk(KERN_WARNING
|
||||
"nfsd: request from insecure port %s!\n",
|
||||
|
@ -109,6 +101,36 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
|
|||
return nfserrno(nfsd_setuser(rqstp, exp));
|
||||
}
|
||||
|
||||
static inline __be32 check_pseudo_root(struct svc_rqst *rqstp,
|
||||
struct dentry *dentry, struct svc_export *exp)
|
||||
{
|
||||
if (!(exp->ex_flags & NFSEXP_V4ROOT))
|
||||
return nfs_ok;
|
||||
/*
|
||||
* v2/v3 clients have no need for the V4ROOT export--they use
|
||||
* the mount protocl instead; also, further V4ROOT checks may be
|
||||
* in v4-specific code, in which case v2/v3 clients could bypass
|
||||
* them.
|
||||
*/
|
||||
if (!nfsd_v4client(rqstp))
|
||||
return nfserr_stale;
|
||||
/*
|
||||
* We're exposing only the directories and symlinks that have to be
|
||||
* traversed on the way to real exports:
|
||||
*/
|
||||
if (unlikely(!S_ISDIR(dentry->d_inode->i_mode) &&
|
||||
!S_ISLNK(dentry->d_inode->i_mode)))
|
||||
return nfserr_stale;
|
||||
/*
|
||||
* A pseudoroot export gives permission to access only one
|
||||
* single directory; the kernel has to make another upcall
|
||||
* before granting access to anything else under it:
|
||||
*/
|
||||
if (unlikely(dentry != exp->ex_path.dentry))
|
||||
return nfserr_stale;
|
||||
return nfs_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the given filehandle to look up the corresponding export and
|
||||
* dentry. On success, the results are used to set fh_export and
|
||||
|
@ -232,14 +254,6 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) {
|
||||
error = nfsd_setuser_and_check_port(rqstp, exp);
|
||||
if (error) {
|
||||
dput(dentry);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (S_ISDIR(dentry->d_inode->i_mode) &&
|
||||
(dentry->d_flags & DCACHE_DISCONNECTED)) {
|
||||
printk("nfsd: find_fh_dentry returned a DISCONNECTED directory: %s/%s\n",
|
||||
|
@ -294,28 +308,32 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
|
|||
error = nfsd_set_fh_dentry(rqstp, fhp);
|
||||
if (error)
|
||||
goto out;
|
||||
dentry = fhp->fh_dentry;
|
||||
exp = fhp->fh_export;
|
||||
} else {
|
||||
/*
|
||||
* just rechecking permissions
|
||||
* (e.g. nfsproc_create calls fh_verify, then nfsd_create
|
||||
* does as well)
|
||||
*/
|
||||
dprintk("nfsd: fh_verify - just checking\n");
|
||||
dentry = fhp->fh_dentry;
|
||||
exp = fhp->fh_export;
|
||||
/*
|
||||
* Set user creds for this exportpoint; necessary even
|
||||
* in the "just checking" case because this may be a
|
||||
* filehandle that was created by fh_compose, and that
|
||||
* is about to be used in another nfsv4 compound
|
||||
* operation.
|
||||
*/
|
||||
error = nfsd_setuser_and_check_port(rqstp, exp);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
dentry = fhp->fh_dentry;
|
||||
exp = fhp->fh_export;
|
||||
/*
|
||||
* We still have to do all these permission checks, even when
|
||||
* fh_dentry is already set:
|
||||
* - fh_verify may be called multiple times with different
|
||||
* "access" arguments (e.g. nfsd_proc_create calls
|
||||
* fh_verify(...,NFSD_MAY_EXEC) first, then later (in
|
||||
* nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE).
|
||||
* - in the NFSv4 case, the filehandle may have been filled
|
||||
* in by fh_compose, and given a dentry, but further
|
||||
* compound operations performed with that filehandle
|
||||
* still need permissions checks. In the worst case, a
|
||||
* mountpoint crossing may have changed the export
|
||||
* options, and we may now need to use a different uid
|
||||
* (for example, if different id-squashing options are in
|
||||
* effect on the new filesystem).
|
||||
*/
|
||||
error = check_pseudo_root(rqstp, dentry, exp);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = nfsd_setuser_and_check_port(rqstp, exp);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type);
|
||||
if (error)
|
||||
|
|
208
fs/nfsd/nfsfh.h
Normal file
208
fs/nfsd/nfsfh.h
Normal file
|
@ -0,0 +1,208 @@
|
|||
/* Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> */
|
||||
|
||||
#ifndef _LINUX_NFSD_FH_INT_H
|
||||
#define _LINUX_NFSD_FH_INT_H
|
||||
|
||||
#include <linux/nfsd/nfsfh.h>
|
||||
|
||||
enum nfsd_fsid {
|
||||
FSID_DEV = 0,
|
||||
FSID_NUM,
|
||||
FSID_MAJOR_MINOR,
|
||||
FSID_ENCODE_DEV,
|
||||
FSID_UUID4_INUM,
|
||||
FSID_UUID8,
|
||||
FSID_UUID16,
|
||||
FSID_UUID16_INUM,
|
||||
};
|
||||
|
||||
enum fsid_source {
|
||||
FSIDSOURCE_DEV,
|
||||
FSIDSOURCE_FSID,
|
||||
FSIDSOURCE_UUID,
|
||||
};
|
||||
extern enum fsid_source fsid_source(struct svc_fh *fhp);
|
||||
|
||||
|
||||
/* This might look a little large to "inline" but in all calls except
|
||||
* one, 'vers' is constant so moste of the function disappears.
|
||||
*/
|
||||
static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino,
|
||||
u32 fsid, unsigned char *uuid)
|
||||
{
|
||||
u32 *up;
|
||||
switch(vers) {
|
||||
case FSID_DEV:
|
||||
fsidv[0] = htonl((MAJOR(dev)<<16) |
|
||||
MINOR(dev));
|
||||
fsidv[1] = ino_t_to_u32(ino);
|
||||
break;
|
||||
case FSID_NUM:
|
||||
fsidv[0] = fsid;
|
||||
break;
|
||||
case FSID_MAJOR_MINOR:
|
||||
fsidv[0] = htonl(MAJOR(dev));
|
||||
fsidv[1] = htonl(MINOR(dev));
|
||||
fsidv[2] = ino_t_to_u32(ino);
|
||||
break;
|
||||
|
||||
case FSID_ENCODE_DEV:
|
||||
fsidv[0] = new_encode_dev(dev);
|
||||
fsidv[1] = ino_t_to_u32(ino);
|
||||
break;
|
||||
|
||||
case FSID_UUID4_INUM:
|
||||
/* 4 byte fsid and inode number */
|
||||
up = (u32*)uuid;
|
||||
fsidv[0] = ino_t_to_u32(ino);
|
||||
fsidv[1] = up[0] ^ up[1] ^ up[2] ^ up[3];
|
||||
break;
|
||||
|
||||
case FSID_UUID8:
|
||||
/* 8 byte fsid */
|
||||
up = (u32*)uuid;
|
||||
fsidv[0] = up[0] ^ up[2];
|
||||
fsidv[1] = up[1] ^ up[3];
|
||||
break;
|
||||
|
||||
case FSID_UUID16:
|
||||
/* 16 byte fsid - NFSv3+ only */
|
||||
memcpy(fsidv, uuid, 16);
|
||||
break;
|
||||
|
||||
case FSID_UUID16_INUM:
|
||||
/* 8 byte inode and 16 byte fsid */
|
||||
*(u64*)fsidv = (u64)ino;
|
||||
memcpy(fsidv+2, uuid, 16);
|
||||
break;
|
||||
default: BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline int key_len(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case FSID_DEV: return 8;
|
||||
case FSID_NUM: return 4;
|
||||
case FSID_MAJOR_MINOR: return 12;
|
||||
case FSID_ENCODE_DEV: return 8;
|
||||
case FSID_UUID4_INUM: return 8;
|
||||
case FSID_UUID8: return 8;
|
||||
case FSID_UUID16: return 16;
|
||||
case FSID_UUID16_INUM: return 24;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Shorthand for dprintk()'s
|
||||
*/
|
||||
extern char * SVCFH_fmt(struct svc_fh *fhp);
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
__be32 fh_verify(struct svc_rqst *, struct svc_fh *, int, int);
|
||||
__be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
|
||||
__be32 fh_update(struct svc_fh *);
|
||||
void fh_put(struct svc_fh *);
|
||||
|
||||
static __inline__ struct svc_fh *
|
||||
fh_copy(struct svc_fh *dst, struct svc_fh *src)
|
||||
{
|
||||
WARN_ON(src->fh_dentry || src->fh_locked);
|
||||
|
||||
*dst = *src;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src)
|
||||
{
|
||||
dst->fh_size = src->fh_size;
|
||||
memcpy(&dst->fh_base, &src->fh_base, src->fh_size);
|
||||
}
|
||||
|
||||
static __inline__ struct svc_fh *
|
||||
fh_init(struct svc_fh *fhp, int maxsize)
|
||||
{
|
||||
memset(fhp, 0, sizeof(*fhp));
|
||||
fhp->fh_maxsize = maxsize;
|
||||
return fhp;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFSD_V3
|
||||
/*
|
||||
* Fill in the pre_op attr for the wcc data
|
||||
*/
|
||||
static inline void
|
||||
fill_pre_wcc(struct svc_fh *fhp)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
inode = fhp->fh_dentry->d_inode;
|
||||
if (!fhp->fh_pre_saved) {
|
||||
fhp->fh_pre_mtime = inode->i_mtime;
|
||||
fhp->fh_pre_ctime = inode->i_ctime;
|
||||
fhp->fh_pre_size = inode->i_size;
|
||||
fhp->fh_pre_change = inode->i_version;
|
||||
fhp->fh_pre_saved = 1;
|
||||
}
|
||||
}
|
||||
|
||||
extern void fill_post_wcc(struct svc_fh *);
|
||||
#else
|
||||
#define fill_pre_wcc(ignored)
|
||||
#define fill_post_wcc(notused)
|
||||
#endif /* CONFIG_NFSD_V3 */
|
||||
|
||||
|
||||
/*
|
||||
* Lock a file handle/inode
|
||||
* NOTE: both fh_lock and fh_unlock are done "by hand" in
|
||||
* vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once
|
||||
* so, any changes here should be reflected there.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
|
||||
{
|
||||
struct dentry *dentry = fhp->fh_dentry;
|
||||
struct inode *inode;
|
||||
|
||||
BUG_ON(!dentry);
|
||||
|
||||
if (fhp->fh_locked) {
|
||||
printk(KERN_WARNING "fh_lock: %s/%s already locked!\n",
|
||||
dentry->d_parent->d_name.name, dentry->d_name.name);
|
||||
return;
|
||||
}
|
||||
|
||||
inode = dentry->d_inode;
|
||||
mutex_lock_nested(&inode->i_mutex, subclass);
|
||||
fill_pre_wcc(fhp);
|
||||
fhp->fh_locked = 1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fh_lock(struct svc_fh *fhp)
|
||||
{
|
||||
fh_lock_nested(fhp, I_MUTEX_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlock a file handle/inode
|
||||
*/
|
||||
static inline void
|
||||
fh_unlock(struct svc_fh *fhp)
|
||||
{
|
||||
BUG_ON(!fhp->fh_dentry);
|
||||
|
||||
if (fhp->fh_locked) {
|
||||
fill_post_wcc(fhp);
|
||||
mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex);
|
||||
fhp->fh_locked = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _LINUX_NFSD_FH_INT_H */
|
|
@ -1,29 +1,14 @@
|
|||
/*
|
||||
* nfsproc2.c Process version 2 NFS requests.
|
||||
* linux/fs/nfsd/nfs2proc.c
|
||||
*
|
||||
* Process version 2 NFS requests.
|
||||
*
|
||||
* Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include <linux/nfsd/xdr.h>
|
||||
#include "cache.h"
|
||||
#include "xdr.h"
|
||||
#include "vfs.h"
|
||||
|
||||
typedef struct svc_rqst svc_rqst;
|
||||
typedef struct svc_buf svc_buf;
|
||||
|
@ -758,6 +743,7 @@ nfserrno (int errno)
|
|||
{ nfserr_io, -ETXTBSY },
|
||||
{ nfserr_notsupp, -EOPNOTSUPP },
|
||||
{ nfserr_toosmall, -ETOOSMALL },
|
||||
{ nfserr_serverfault, -ESERVERFAULT },
|
||||
};
|
||||
int i;
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfssvc.c
|
||||
*
|
||||
* Central processing for nfsd.
|
||||
*
|
||||
* Authors: Olaf Kirch (okir@monad.swb.de)
|
||||
|
@ -8,33 +6,19 @@
|
|||
* Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/nfs.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/fs_struct.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/swap.h>
|
||||
|
||||
#include <linux/sunrpc/types.h>
|
||||
#include <linux/sunrpc/stats.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/sunrpc/svcsock.h>
|
||||
#include <linux/sunrpc/cache.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/stats.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include <linux/nfsd/syscall.h>
|
||||
#include <linux/lockd/bind.h>
|
||||
#include <linux/nfsacl.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include "nfsd.h"
|
||||
#include "cache.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_SVC
|
||||
|
||||
|
|
|
@ -1,20 +1,10 @@
|
|||
/*
|
||||
* linux/fs/nfsd/nfsxdr.c
|
||||
*
|
||||
* XDR support for nfsd
|
||||
*
|
||||
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/nfs.h>
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/sunrpc/xdr.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/xdr.h>
|
||||
#include <linux/mm.h>
|
||||
#include "xdr.h"
|
||||
#include "auth.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_XDR
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/include/nfsd/state.h
|
||||
*
|
||||
* Copyright (c) 2001 The Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -37,9 +35,8 @@
|
|||
#ifndef _NFSD4_STATE_H
|
||||
#define _NFSD4_STATE_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/nfsd/nfsfh.h>
|
||||
#include "nfsfh.h"
|
||||
|
||||
typedef struct {
|
||||
u32 cl_boot;
|
||||
|
@ -60,6 +57,13 @@ typedef struct {
|
|||
#define si_stateownerid si_opaque.so_stateownerid
|
||||
#define si_fileid si_opaque.so_fileid
|
||||
|
||||
#define STATEID_FMT "(%08x/%08x/%08x/%08x)"
|
||||
#define STATEID_VAL(s) \
|
||||
(s)->si_boot, \
|
||||
(s)->si_stateownerid, \
|
||||
(s)->si_fileid, \
|
||||
(s)->si_generation
|
||||
|
||||
struct nfsd4_cb_sequence {
|
||||
/* args/res */
|
||||
u32 cbs_minorversion;
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/fs/nfsd/stats.c
|
||||
*
|
||||
* procfs-based user access to knfsd statistics
|
||||
*
|
||||
* /proc/net/rpc/nfsd
|
||||
|
@ -23,18 +21,13 @@
|
|||
* Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/sunrpc/stats.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/stats.h>
|
||||
|
||||
#include "nfsd.h"
|
||||
|
||||
struct nfsd_stats nfsdstats;
|
||||
struct svc_stat nfsd_svcstats = {
|
||||
.program = &nfsd_program,
|
||||
|
|
138
fs/nfsd/vfs.c
138
fs/nfsd/vfs.c
|
@ -1,7 +1,5 @@
|
|||
#define MSNFS /* HACK HACK */
|
||||
/*
|
||||
* linux/fs/nfsd/vfs.c
|
||||
*
|
||||
* File operations used by nfsd. Some of these have been ripped from
|
||||
* other parts of the kernel because they weren't exported, others
|
||||
* are partial duplicates with added or changed functionality.
|
||||
|
@ -16,49 +14,32 @@
|
|||
* Zerocpy NFS support (C) 2002 Hirokazu Takahashi <taka@valinux.co.jp>
|
||||
*/
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/splice.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#ifdef CONFIG_NFSD_V3
|
||||
#include <linux/nfs3.h>
|
||||
#include <linux/nfsd/xdr3.h>
|
||||
#endif /* CONFIG_NFSD_V3 */
|
||||
#include <linux/nfsd/nfsfh.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/fsnotify.h>
|
||||
#include <linux/posix_acl.h>
|
||||
#include <linux/posix_acl_xattr.h>
|
||||
#include <linux/xattr.h>
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
#include <linux/nfs4.h>
|
||||
#include <linux/nfs4_acl.h>
|
||||
#include <linux/nfsd_idmap.h>
|
||||
#include <linux/security.h>
|
||||
#endif /* CONFIG_NFSD_V4 */
|
||||
#include <linux/jhash.h>
|
||||
#include <linux/ima.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#ifdef CONFIG_NFSD_V3
|
||||
#include "xdr3.h"
|
||||
#endif /* CONFIG_NFSD_V3 */
|
||||
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
#include <linux/nfs4_acl.h>
|
||||
#include <linux/nfsd_idmap.h>
|
||||
#endif /* CONFIG_NFSD_V4 */
|
||||
|
||||
#include "nfsd.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_FILEOP
|
||||
|
||||
|
||||
|
@ -89,12 +70,6 @@ struct raparm_hbucket {
|
|||
#define RAPARM_HASH_MASK (RAPARM_HASH_SIZE-1)
|
||||
static struct raparm_hbucket raparm_hash[RAPARM_HASH_SIZE];
|
||||
|
||||
static inline int
|
||||
nfsd_v4client(struct svc_rqst *rq)
|
||||
{
|
||||
return rq->rq_prog == NFS_PROGRAM && rq->rq_vers == 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from nfsd_lookup and encode_dirent. Check if we have crossed
|
||||
* a mount point.
|
||||
|
@ -116,8 +91,16 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
|
|||
|
||||
exp2 = rqst_exp_get_by_name(rqstp, &path);
|
||||
if (IS_ERR(exp2)) {
|
||||
if (PTR_ERR(exp2) != -ENOENT)
|
||||
err = PTR_ERR(exp2);
|
||||
err = PTR_ERR(exp2);
|
||||
/*
|
||||
* We normally allow NFS clients to continue
|
||||
* "underneath" a mountpoint that is not exported.
|
||||
* The exception is V4ROOT, where no traversal is ever
|
||||
* allowed without an explicit export of the new
|
||||
* directory.
|
||||
*/
|
||||
if (err == -ENOENT && !(exp->ex_flags & NFSEXP_V4ROOT))
|
||||
err = 0;
|
||||
path_put(&path);
|
||||
goto out;
|
||||
}
|
||||
|
@ -141,6 +124,53 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
static void follow_to_parent(struct path *path)
|
||||
{
|
||||
struct dentry *dp;
|
||||
|
||||
while (path->dentry == path->mnt->mnt_root && follow_up(path))
|
||||
;
|
||||
dp = dget_parent(path->dentry);
|
||||
dput(path->dentry);
|
||||
path->dentry = dp;
|
||||
}
|
||||
|
||||
static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, struct svc_export **exp, struct dentry **dentryp)
|
||||
{
|
||||
struct svc_export *exp2;
|
||||
struct path path = {.mnt = mntget((*exp)->ex_path.mnt),
|
||||
.dentry = dget(dparent)};
|
||||
|
||||
follow_to_parent(&path);
|
||||
|
||||
exp2 = rqst_exp_parent(rqstp, &path);
|
||||
if (PTR_ERR(exp2) == -ENOENT) {
|
||||
*dentryp = dget(dparent);
|
||||
} else if (IS_ERR(exp2)) {
|
||||
path_put(&path);
|
||||
return PTR_ERR(exp2);
|
||||
} else {
|
||||
*dentryp = dget(path.dentry);
|
||||
exp_put(*exp);
|
||||
*exp = exp2;
|
||||
}
|
||||
path_put(&path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* For nfsd purposes, we treat V4ROOT exports as though there was an
|
||||
* export at *every* directory.
|
||||
*/
|
||||
int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp)
|
||||
{
|
||||
if (d_mountpoint(dentry))
|
||||
return 1;
|
||||
if (!(exp->ex_flags & NFSEXP_V4ROOT))
|
||||
return 0;
|
||||
return dentry->d_inode != NULL;
|
||||
}
|
||||
|
||||
__be32
|
||||
nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
||||
const char *name, unsigned int len,
|
||||
|
@ -169,35 +199,13 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||
dentry = dget(dparent);
|
||||
else if (dparent != exp->ex_path.dentry)
|
||||
dentry = dget_parent(dparent);
|
||||
else if (!EX_NOHIDE(exp))
|
||||
else if (!EX_NOHIDE(exp) && !nfsd_v4client(rqstp))
|
||||
dentry = dget(dparent); /* .. == . just like at / */
|
||||
else {
|
||||
/* checking mountpoint crossing is very different when stepping up */
|
||||
struct svc_export *exp2 = NULL;
|
||||
struct dentry *dp;
|
||||
struct path path = {.mnt = mntget(exp->ex_path.mnt),
|
||||
.dentry = dget(dparent)};
|
||||
|
||||
while (path.dentry == path.mnt->mnt_root &&
|
||||
follow_up(&path))
|
||||
;
|
||||
dp = dget_parent(path.dentry);
|
||||
dput(path.dentry);
|
||||
path.dentry = dp;
|
||||
|
||||
exp2 = rqst_exp_parent(rqstp, &path);
|
||||
if (PTR_ERR(exp2) == -ENOENT) {
|
||||
dentry = dget(dparent);
|
||||
} else if (IS_ERR(exp2)) {
|
||||
host_err = PTR_ERR(exp2);
|
||||
path_put(&path);
|
||||
host_err = nfsd_lookup_parent(rqstp, dparent, &exp, &dentry);
|
||||
if (host_err)
|
||||
goto out_nfserr;
|
||||
} else {
|
||||
dentry = dget(path.dentry);
|
||||
exp_put(exp);
|
||||
exp = exp2;
|
||||
}
|
||||
path_put(&path);
|
||||
}
|
||||
} else {
|
||||
fh_lock(fhp);
|
||||
|
@ -208,7 +216,7 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||
/*
|
||||
* check if we have crossed a mount point ...
|
||||
*/
|
||||
if (d_mountpoint(dentry)) {
|
||||
if (nfsd_mountpoint(dentry, exp)) {
|
||||
if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
|
||||
dput(dentry);
|
||||
goto out_nfserr;
|
||||
|
|
101
fs/nfsd/vfs.h
Normal file
101
fs/nfsd/vfs.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
|
||||
*/
|
||||
|
||||
#ifndef LINUX_NFSD_VFS_H
|
||||
#define LINUX_NFSD_VFS_H
|
||||
|
||||
#include "nfsfh.h"
|
||||
|
||||
/*
|
||||
* Flags for nfsd_permission
|
||||
*/
|
||||
#define NFSD_MAY_NOP 0
|
||||
#define NFSD_MAY_EXEC 1 /* == MAY_EXEC */
|
||||
#define NFSD_MAY_WRITE 2 /* == MAY_WRITE */
|
||||
#define NFSD_MAY_READ 4 /* == MAY_READ */
|
||||
#define NFSD_MAY_SATTR 8
|
||||
#define NFSD_MAY_TRUNC 16
|
||||
#define NFSD_MAY_LOCK 32
|
||||
#define NFSD_MAY_OWNER_OVERRIDE 64
|
||||
#define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/
|
||||
#define NFSD_MAY_BYPASS_GSS_ON_ROOT 256
|
||||
|
||||
#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
|
||||
#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
|
||||
|
||||
/*
|
||||
* Callback function for readdir
|
||||
*/
|
||||
typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int);
|
||||
|
||||
/* nfsd/vfs.c */
|
||||
int fh_lock_parent(struct svc_fh *, struct dentry *);
|
||||
int nfsd_racache_init(int);
|
||||
void nfsd_racache_shutdown(void);
|
||||
int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
|
||||
struct svc_export **expp);
|
||||
__be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *,
|
||||
const char *, unsigned int, struct svc_fh *);
|
||||
__be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *,
|
||||
const char *, unsigned int,
|
||||
struct svc_export **, struct dentry **);
|
||||
__be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *,
|
||||
struct iattr *, int, time_t);
|
||||
int nfsd_mountpoint(struct dentry *, struct svc_export *);
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
__be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
|
||||
struct nfs4_acl *);
|
||||
int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **);
|
||||
#endif /* CONFIG_NFSD_V4 */
|
||||
__be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
|
||||
char *name, int len, struct iattr *attrs,
|
||||
int type, dev_t rdev, struct svc_fh *res);
|
||||
#ifdef CONFIG_NFSD_V3
|
||||
__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
|
||||
__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *,
|
||||
char *name, int len, struct iattr *attrs,
|
||||
struct svc_fh *res, int createmode,
|
||||
u32 *verifier, int *truncp, int *created);
|
||||
__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
|
||||
loff_t, unsigned long);
|
||||
#endif /* CONFIG_NFSD_V3 */
|
||||
__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int,
|
||||
int, struct file **);
|
||||
void nfsd_close(struct file *);
|
||||
__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *,
|
||||
loff_t, struct kvec *, int, unsigned long *);
|
||||
__be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
|
||||
loff_t, struct kvec *,int, unsigned long *, int *);
|
||||
__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *,
|
||||
char *, int *);
|
||||
__be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *,
|
||||
char *name, int len, char *path, int plen,
|
||||
struct svc_fh *res, struct iattr *);
|
||||
__be32 nfsd_link(struct svc_rqst *, struct svc_fh *,
|
||||
char *, int, struct svc_fh *);
|
||||
__be32 nfsd_rename(struct svc_rqst *,
|
||||
struct svc_fh *, char *, int,
|
||||
struct svc_fh *, char *, int);
|
||||
__be32 nfsd_remove(struct svc_rqst *,
|
||||
struct svc_fh *, char *, int);
|
||||
__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type,
|
||||
char *name, int len);
|
||||
int nfsd_truncate(struct svc_rqst *, struct svc_fh *,
|
||||
unsigned long size);
|
||||
__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
|
||||
loff_t *, struct readdir_cd *, filldir_t);
|
||||
__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
|
||||
struct kstatfs *, int access);
|
||||
|
||||
int nfsd_notify_change(struct inode *, struct iattr *);
|
||||
__be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
|
||||
struct dentry *, int);
|
||||
int nfsd_sync_dir(struct dentry *dp);
|
||||
|
||||
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
|
||||
struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
|
||||
int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
|
||||
#endif
|
||||
|
||||
#endif /* LINUX_NFSD_VFS_H */
|
|
@ -1,15 +1,11 @@
|
|||
/*
|
||||
* linux/include/linux/nfsd/xdr.h
|
||||
*
|
||||
* XDR types for nfsd. This is mainly a typing exercise.
|
||||
*/
|
||||
/* XDR types for nfsd. This is mainly a typing exercise. */
|
||||
|
||||
#ifndef LINUX_NFSD_H
|
||||
#define LINUX_NFSD_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/nfs.h>
|
||||
#include "nfsd.h"
|
||||
#include "nfsfh.h"
|
||||
|
||||
struct nfsd_fhandle {
|
||||
struct svc_fh fh;
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/include/linux/nfsd/xdr3.h
|
||||
*
|
||||
* XDR types for NFSv3 in nfsd.
|
||||
*
|
||||
* Copyright (C) 1996-1998, Olaf Kirch <okir@monad.swb.de>
|
||||
|
@ -9,7 +7,7 @@
|
|||
#ifndef _LINUX_NFSD_XDR3_H
|
||||
#define _LINUX_NFSD_XDR3_H
|
||||
|
||||
#include <linux/nfsd/xdr.h>
|
||||
#include "xdr.h"
|
||||
|
||||
struct nfsd3_sattrargs {
|
||||
struct svc_fh fh;
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* include/linux/nfsd/xdr4.h
|
||||
*
|
||||
* Server-side types for NFSv4.
|
||||
*
|
||||
* Copyright (c) 2002 The Regents of the University of Michigan.
|
||||
|
@ -39,7 +37,8 @@
|
|||
#ifndef _LINUX_NFSD_XDR4_H
|
||||
#define _LINUX_NFSD_XDR4_H
|
||||
|
||||
#include <linux/nfs4.h>
|
||||
#include "state.h"
|
||||
#include "nfsd.h"
|
||||
|
||||
#define NFSD4_MAX_TAGLEN 128
|
||||
#define XDR_LEN(n) (((n) + 3) & ~3)
|
|
@ -97,7 +97,7 @@ struct fid {
|
|||
* @get_name: find the name for a given inode in a given directory
|
||||
* @get_parent: find the parent of a given directory
|
||||
*
|
||||
* See Documentation/filesystems/Exporting for details on how to use
|
||||
* See Documentation/filesystems/nfs/Exporting for details on how to use
|
||||
* this interface correctly.
|
||||
*
|
||||
* encode_fh:
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _LINUX_NFS_XDR_H
|
||||
|
||||
#include <linux/nfsacl.h>
|
||||
#include <linux/nfs3.h>
|
||||
|
||||
/*
|
||||
* To change the maximum rsize and wsize supported by the NFS client, adjust
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/posix_acl.h>
|
||||
#include <linux/sunrpc/xdr.h>
|
||||
|
||||
/* Maximum number of ACL entries over NFS */
|
||||
#define NFS_ACL_MAX_ENTRIES 1024
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
# include <linux/types.h>
|
||||
#ifdef __KERNEL__
|
||||
# include <linux/in.h>
|
||||
# include <linux/nfsd/nfsfh.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -39,11 +39,23 @@
|
|||
#define NFSEXP_FSID 0x2000
|
||||
#define NFSEXP_CROSSMOUNT 0x4000
|
||||
#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */
|
||||
#define NFSEXP_ALLFLAGS 0xFE3F
|
||||
/*
|
||||
* The NFSEXP_V4ROOT flag causes the kernel to give access only to NFSv4
|
||||
* clients, and only to the single directory that is the root of the
|
||||
* export; further lookup and readdir operations are treated as if every
|
||||
* subdirectory was a mountpoint, and ignored if they are not themselves
|
||||
* exported. This is used by nfsd and mountd to construct the NFSv4
|
||||
* pseudofilesystem, which provides access only to paths leading to each
|
||||
* exported filesystem.
|
||||
*/
|
||||
#define NFSEXP_V4ROOT 0x10000
|
||||
/* All flags that we claim to support. (Note we don't support NOACL.) */
|
||||
#define NFSEXP_ALLFLAGS 0x17E3F
|
||||
|
||||
/* The flags that may vary depending on security flavor: */
|
||||
#define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \
|
||||
| NFSEXP_ALLSQUASH)
|
||||
| NFSEXP_ALLSQUASH \
|
||||
| NFSEXP_INSECURE_PORT)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
|
@ -108,7 +120,6 @@ struct svc_expkey {
|
|||
struct path ek_path;
|
||||
};
|
||||
|
||||
#define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT))
|
||||
#define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
|
||||
#define EX_NOHIDE(exp) ((exp)->ex_flags & NFSEXP_NOHIDE)
|
||||
#define EX_WGATHER(exp) ((exp)->ex_flags & NFSEXP_GATHERED_WRITES)
|
||||
|
|
|
@ -16,11 +16,9 @@
|
|||
|
||||
# include <linux/types.h>
|
||||
#ifdef __KERNEL__
|
||||
# include <linux/string.h>
|
||||
# include <linux/fs.h>
|
||||
# include <linux/sunrpc/svc.h>
|
||||
#endif
|
||||
#include <linux/nfsd/const.h>
|
||||
#include <linux/nfsd/debug.h>
|
||||
|
||||
/*
|
||||
* This is the old "dentry style" Linux NFSv2 file handle.
|
||||
|
@ -164,208 +162,6 @@ typedef struct svc_fh {
|
|||
|
||||
} svc_fh;
|
||||
|
||||
enum nfsd_fsid {
|
||||
FSID_DEV = 0,
|
||||
FSID_NUM,
|
||||
FSID_MAJOR_MINOR,
|
||||
FSID_ENCODE_DEV,
|
||||
FSID_UUID4_INUM,
|
||||
FSID_UUID8,
|
||||
FSID_UUID16,
|
||||
FSID_UUID16_INUM,
|
||||
};
|
||||
|
||||
enum fsid_source {
|
||||
FSIDSOURCE_DEV,
|
||||
FSIDSOURCE_FSID,
|
||||
FSIDSOURCE_UUID,
|
||||
};
|
||||
extern enum fsid_source fsid_source(struct svc_fh *fhp);
|
||||
|
||||
|
||||
/* This might look a little large to "inline" but in all calls except
|
||||
* one, 'vers' is constant so moste of the function disappears.
|
||||
*/
|
||||
static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino,
|
||||
u32 fsid, unsigned char *uuid)
|
||||
{
|
||||
u32 *up;
|
||||
switch(vers) {
|
||||
case FSID_DEV:
|
||||
fsidv[0] = htonl((MAJOR(dev)<<16) |
|
||||
MINOR(dev));
|
||||
fsidv[1] = ino_t_to_u32(ino);
|
||||
break;
|
||||
case FSID_NUM:
|
||||
fsidv[0] = fsid;
|
||||
break;
|
||||
case FSID_MAJOR_MINOR:
|
||||
fsidv[0] = htonl(MAJOR(dev));
|
||||
fsidv[1] = htonl(MINOR(dev));
|
||||
fsidv[2] = ino_t_to_u32(ino);
|
||||
break;
|
||||
|
||||
case FSID_ENCODE_DEV:
|
||||
fsidv[0] = new_encode_dev(dev);
|
||||
fsidv[1] = ino_t_to_u32(ino);
|
||||
break;
|
||||
|
||||
case FSID_UUID4_INUM:
|
||||
/* 4 byte fsid and inode number */
|
||||
up = (u32*)uuid;
|
||||
fsidv[0] = ino_t_to_u32(ino);
|
||||
fsidv[1] = up[0] ^ up[1] ^ up[2] ^ up[3];
|
||||
break;
|
||||
|
||||
case FSID_UUID8:
|
||||
/* 8 byte fsid */
|
||||
up = (u32*)uuid;
|
||||
fsidv[0] = up[0] ^ up[2];
|
||||
fsidv[1] = up[1] ^ up[3];
|
||||
break;
|
||||
|
||||
case FSID_UUID16:
|
||||
/* 16 byte fsid - NFSv3+ only */
|
||||
memcpy(fsidv, uuid, 16);
|
||||
break;
|
||||
|
||||
case FSID_UUID16_INUM:
|
||||
/* 8 byte inode and 16 byte fsid */
|
||||
*(u64*)fsidv = (u64)ino;
|
||||
memcpy(fsidv+2, uuid, 16);
|
||||
break;
|
||||
default: BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline int key_len(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case FSID_DEV: return 8;
|
||||
case FSID_NUM: return 4;
|
||||
case FSID_MAJOR_MINOR: return 12;
|
||||
case FSID_ENCODE_DEV: return 8;
|
||||
case FSID_UUID4_INUM: return 8;
|
||||
case FSID_UUID8: return 8;
|
||||
case FSID_UUID16: return 16;
|
||||
case FSID_UUID16_INUM: return 24;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Shorthand for dprintk()'s
|
||||
*/
|
||||
extern char * SVCFH_fmt(struct svc_fh *fhp);
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
__be32 fh_verify(struct svc_rqst *, struct svc_fh *, int, int);
|
||||
__be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
|
||||
__be32 fh_update(struct svc_fh *);
|
||||
void fh_put(struct svc_fh *);
|
||||
|
||||
static __inline__ struct svc_fh *
|
||||
fh_copy(struct svc_fh *dst, struct svc_fh *src)
|
||||
{
|
||||
WARN_ON(src->fh_dentry || src->fh_locked);
|
||||
|
||||
*dst = *src;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src)
|
||||
{
|
||||
dst->fh_size = src->fh_size;
|
||||
memcpy(&dst->fh_base, &src->fh_base, src->fh_size);
|
||||
}
|
||||
|
||||
static __inline__ struct svc_fh *
|
||||
fh_init(struct svc_fh *fhp, int maxsize)
|
||||
{
|
||||
memset(fhp, 0, sizeof(*fhp));
|
||||
fhp->fh_maxsize = maxsize;
|
||||
return fhp;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFSD_V3
|
||||
/*
|
||||
* Fill in the pre_op attr for the wcc data
|
||||
*/
|
||||
static inline void
|
||||
fill_pre_wcc(struct svc_fh *fhp)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
inode = fhp->fh_dentry->d_inode;
|
||||
if (!fhp->fh_pre_saved) {
|
||||
fhp->fh_pre_mtime = inode->i_mtime;
|
||||
fhp->fh_pre_ctime = inode->i_ctime;
|
||||
fhp->fh_pre_size = inode->i_size;
|
||||
fhp->fh_pre_change = inode->i_version;
|
||||
fhp->fh_pre_saved = 1;
|
||||
}
|
||||
}
|
||||
|
||||
extern void fill_post_wcc(struct svc_fh *);
|
||||
#else
|
||||
#define fill_pre_wcc(ignored)
|
||||
#define fill_post_wcc(notused)
|
||||
#endif /* CONFIG_NFSD_V3 */
|
||||
|
||||
|
||||
/*
|
||||
* Lock a file handle/inode
|
||||
* NOTE: both fh_lock and fh_unlock are done "by hand" in
|
||||
* vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once
|
||||
* so, any changes here should be reflected there.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
|
||||
{
|
||||
struct dentry *dentry = fhp->fh_dentry;
|
||||
struct inode *inode;
|
||||
|
||||
dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n",
|
||||
SVCFH_fmt(fhp), fhp->fh_locked);
|
||||
|
||||
BUG_ON(!dentry);
|
||||
|
||||
if (fhp->fh_locked) {
|
||||
printk(KERN_WARNING "fh_lock: %s/%s already locked!\n",
|
||||
dentry->d_parent->d_name.name, dentry->d_name.name);
|
||||
return;
|
||||
}
|
||||
|
||||
inode = dentry->d_inode;
|
||||
mutex_lock_nested(&inode->i_mutex, subclass);
|
||||
fill_pre_wcc(fhp);
|
||||
fhp->fh_locked = 1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fh_lock(struct svc_fh *fhp)
|
||||
{
|
||||
fh_lock_nested(fhp, I_MUTEX_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlock a file handle/inode
|
||||
*/
|
||||
static inline void
|
||||
fh_unlock(struct svc_fh *fhp)
|
||||
{
|
||||
BUG_ON(!fhp->fh_dentry);
|
||||
|
||||
if (fhp->fh_locked) {
|
||||
fill_post_wcc(fhp);
|
||||
mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex);
|
||||
fhp->fh_locked = 0;
|
||||
}
|
||||
}
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
||||
|
|
|
@ -9,14 +9,8 @@
|
|||
#ifndef NFSD_SYSCALL_H
|
||||
#define NFSD_SYSCALL_H
|
||||
|
||||
# include <linux/types.h>
|
||||
#ifdef __KERNEL__
|
||||
# include <linux/in.h>
|
||||
#endif
|
||||
#include <linux/posix_types.h>
|
||||
#include <linux/nfsd/const.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/nfsd/export.h>
|
||||
#include <linux/nfsd/nfsfh.h>
|
||||
|
||||
/*
|
||||
* Version of the syscall interface
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/timer.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
/*
|
||||
* Enable RPC debugging/profiling.
|
||||
*/
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#ifndef _LINUX_SUNRPC_RPC_RDMA_H
|
||||
#define _LINUX_SUNRPC_RPC_RDMA_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct rpcrdma_segment {
|
||||
__be32 rs_handle; /* Registered memory handle */
|
||||
__be32 rs_length; /* Length of the chunk in bytes */
|
||||
|
|
|
@ -29,7 +29,6 @@ struct svc_pool_stats {
|
|||
unsigned long packets;
|
||||
unsigned long sockets_queued;
|
||||
unsigned long threads_woken;
|
||||
unsigned long overloads_avoided;
|
||||
unsigned long threads_timedout;
|
||||
};
|
||||
|
||||
|
@ -50,7 +49,6 @@ struct svc_pool {
|
|||
struct list_head sp_sockets; /* pending sockets */
|
||||
unsigned int sp_nrthreads; /* # of threads in pool */
|
||||
struct list_head sp_all_threads; /* all server threads */
|
||||
int sp_nwaking; /* number of threads woken but not yet active */
|
||||
struct svc_pool_stats sp_stats; /* statistics on pool operation */
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
||||
|
@ -275,16 +273,11 @@ struct svc_rqst {
|
|||
struct auth_domain * rq_client; /* RPC peer info */
|
||||
struct auth_domain * rq_gssclient; /* "gss/"-style peer info */
|
||||
struct svc_cacherep * rq_cacherep; /* cache info */
|
||||
struct knfsd_fh * rq_reffh; /* Referrence filehandle, used to
|
||||
* determine what device number
|
||||
* to report (real or virtual)
|
||||
*/
|
||||
int rq_splice_ok; /* turned off in gss privacy
|
||||
* to prevent encrypting page
|
||||
* cache pages */
|
||||
wait_queue_head_t rq_wait; /* synchronization */
|
||||
struct task_struct *rq_task; /* service thread */
|
||||
int rq_waking; /* 1 if thread is being woken */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -166,7 +166,7 @@ config IP_PNP_DHCP
|
|||
|
||||
If unsure, say Y. Note that if you want to use DHCP, a DHCP server
|
||||
must be operating on your network. Read
|
||||
<file:Documentation/filesystems/nfsroot.txt> for details.
|
||||
<file:Documentation/filesystems/nfs/nfsroot.txt> for details.
|
||||
|
||||
config IP_PNP_BOOTP
|
||||
bool "IP: BOOTP support"
|
||||
|
@ -181,7 +181,7 @@ config IP_PNP_BOOTP
|
|||
does BOOTP itself, providing all necessary information on the kernel
|
||||
command line, you can say N here. If unsure, say Y. Note that if you
|
||||
want to use BOOTP, a BOOTP server must be operating on your network.
|
||||
Read <file:Documentation/filesystems/nfsroot.txt> for details.
|
||||
Read <file:Documentation/filesystems/nfs/nfsroot.txt> for details.
|
||||
|
||||
config IP_PNP_RARP
|
||||
bool "IP: RARP support"
|
||||
|
@ -194,7 +194,7 @@ config IP_PNP_RARP
|
|||
older protocol which is being obsoleted by BOOTP and DHCP), say Y
|
||||
here. Note that if you want to use RARP, a RARP server must be
|
||||
operating on your network. Read
|
||||
<file:Documentation/filesystems/nfsroot.txt> for details.
|
||||
<file:Documentation/filesystems/nfs/nfsroot.txt> for details.
|
||||
|
||||
# not yet ready..
|
||||
# bool ' IP: ARP support' CONFIG_IP_PNP_ARP
|
||||
|
|
|
@ -1446,7 +1446,7 @@ late_initcall(ip_auto_config);
|
|||
|
||||
/*
|
||||
* Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel
|
||||
* command line parameter. See Documentation/filesystems/nfsroot.txt.
|
||||
* command line parameter. See Documentation/filesystems/nfs/nfsroot.txt.
|
||||
*/
|
||||
static int __init ic_proto_name(char *name)
|
||||
{
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
#define RPCDBG_FACILITY RPCDBG_SVCXPRT
|
||||
|
||||
#define SVC_MAX_WAKING 5
|
||||
|
||||
static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt);
|
||||
static int svc_deferred_recv(struct svc_rqst *rqstp);
|
||||
static struct cache_deferred_req *svc_defer(struct cache_req *req);
|
||||
|
@ -306,7 +304,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
|
|||
struct svc_pool *pool;
|
||||
struct svc_rqst *rqstp;
|
||||
int cpu;
|
||||
int thread_avail;
|
||||
|
||||
if (!(xprt->xpt_flags &
|
||||
((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED))))
|
||||
|
@ -318,6 +315,12 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
|
|||
|
||||
spin_lock_bh(&pool->sp_lock);
|
||||
|
||||
if (!list_empty(&pool->sp_threads) &&
|
||||
!list_empty(&pool->sp_sockets))
|
||||
printk(KERN_ERR
|
||||
"svc_xprt_enqueue: "
|
||||
"threads and transports both waiting??\n");
|
||||
|
||||
if (test_bit(XPT_DEAD, &xprt->xpt_flags)) {
|
||||
/* Don't enqueue dead transports */
|
||||
dprintk("svc: transport %p is dead, not enqueued\n", xprt);
|
||||
|
@ -358,15 +361,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
|
|||
}
|
||||
|
||||
process:
|
||||
/* Work out whether threads are available */
|
||||
thread_avail = !list_empty(&pool->sp_threads); /* threads are asleep */
|
||||
if (pool->sp_nwaking >= SVC_MAX_WAKING) {
|
||||
/* too many threads are runnable and trying to wake up */
|
||||
thread_avail = 0;
|
||||
pool->sp_stats.overloads_avoided++;
|
||||
}
|
||||
|
||||
if (thread_avail) {
|
||||
if (!list_empty(&pool->sp_threads)) {
|
||||
rqstp = list_entry(pool->sp_threads.next,
|
||||
struct svc_rqst,
|
||||
rq_list);
|
||||
|
@ -381,8 +376,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
|
|||
svc_xprt_get(xprt);
|
||||
rqstp->rq_reserved = serv->sv_max_mesg;
|
||||
atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
|
||||
rqstp->rq_waking = 1;
|
||||
pool->sp_nwaking++;
|
||||
pool->sp_stats.threads_woken++;
|
||||
BUG_ON(xprt->xpt_pool != pool);
|
||||
wake_up(&rqstp->rq_wait);
|
||||
|
@ -651,11 +644,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
|
|||
return -EINTR;
|
||||
|
||||
spin_lock_bh(&pool->sp_lock);
|
||||
if (rqstp->rq_waking) {
|
||||
rqstp->rq_waking = 0;
|
||||
pool->sp_nwaking--;
|
||||
BUG_ON(pool->sp_nwaking < 0);
|
||||
}
|
||||
xprt = svc_xprt_dequeue(pool);
|
||||
if (xprt) {
|
||||
rqstp->rq_xprt = xprt;
|
||||
|
@ -1204,16 +1192,15 @@ static int svc_pool_stats_show(struct seq_file *m, void *p)
|
|||
struct svc_pool *pool = p;
|
||||
|
||||
if (p == SEQ_START_TOKEN) {
|
||||
seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken overloads-avoided threads-timedout\n");
|
||||
seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken threads-timedout\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
seq_printf(m, "%u %lu %lu %lu %lu %lu\n",
|
||||
seq_printf(m, "%u %lu %lu %lu %lu\n",
|
||||
pool->sp_id,
|
||||
pool->sp_stats.packets,
|
||||
pool->sp_stats.sockets_queued,
|
||||
pool->sp_stats.threads_woken,
|
||||
pool->sp_stats.overloads_avoided,
|
||||
pool->sp_stats.threads_timedout);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -655,23 +655,25 @@ static struct unix_gid *unix_gid_lookup(uid_t uid)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int unix_gid_find(uid_t uid, struct group_info **gip,
|
||||
struct svc_rqst *rqstp)
|
||||
static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp)
|
||||
{
|
||||
struct unix_gid *ug = unix_gid_lookup(uid);
|
||||
struct unix_gid *ug;
|
||||
struct group_info *gi;
|
||||
int ret;
|
||||
|
||||
ug = unix_gid_lookup(uid);
|
||||
if (!ug)
|
||||
return -EAGAIN;
|
||||
switch (cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle)) {
|
||||
return ERR_PTR(-EAGAIN);
|
||||
ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle);
|
||||
switch (ret) {
|
||||
case -ENOENT:
|
||||
*gip = NULL;
|
||||
return 0;
|
||||
return ERR_PTR(-ENOENT);
|
||||
case 0:
|
||||
*gip = ug->gi;
|
||||
get_group_info(*gip);
|
||||
gi = get_group_info(ug->gi);
|
||||
cache_put(&ug->h, &unix_gid_cache);
|
||||
return 0;
|
||||
return gi;
|
||||
default:
|
||||
return -EAGAIN;
|
||||
return ERR_PTR(-EAGAIN);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -681,6 +683,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
|
|||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6, sin6_storage;
|
||||
struct ip_map *ipm;
|
||||
struct group_info *gi;
|
||||
struct svc_cred *cred = &rqstp->rq_cred;
|
||||
|
||||
switch (rqstp->rq_addr.ss_family) {
|
||||
case AF_INET:
|
||||
|
@ -721,6 +725,17 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
|
|||
ip_map_cached_put(rqstp, ipm);
|
||||
break;
|
||||
}
|
||||
|
||||
gi = unix_gid_find(cred->cr_uid, rqstp);
|
||||
switch (PTR_ERR(gi)) {
|
||||
case -EAGAIN:
|
||||
return SVC_DROP;
|
||||
case -ENOENT:
|
||||
break;
|
||||
default:
|
||||
put_group_info(cred->cr_group_info);
|
||||
cred->cr_group_info = gi;
|
||||
}
|
||||
return SVC_OK;
|
||||
}
|
||||
|
||||
|
@ -817,19 +832,11 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
|
|||
slen = svc_getnl(argv); /* gids length */
|
||||
if (slen > 16 || (len -= (slen + 2)*4) < 0)
|
||||
goto badcred;
|
||||
if (unix_gid_find(cred->cr_uid, &cred->cr_group_info, rqstp)
|
||||
== -EAGAIN)
|
||||
cred->cr_group_info = groups_alloc(slen);
|
||||
if (cred->cr_group_info == NULL)
|
||||
return SVC_DROP;
|
||||
if (cred->cr_group_info == NULL) {
|
||||
cred->cr_group_info = groups_alloc(slen);
|
||||
if (cred->cr_group_info == NULL)
|
||||
return SVC_DROP;
|
||||
for (i = 0; i < slen; i++)
|
||||
GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
|
||||
} else {
|
||||
for (i = 0; i < slen ; i++)
|
||||
svc_getnl(argv);
|
||||
}
|
||||
for (i = 0; i < slen; i++)
|
||||
GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
|
||||
if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
|
||||
*authp = rpc_autherr_badverf;
|
||||
return SVC_DENIED;
|
||||
|
|
Loading…
Reference in a new issue