.. | .. |
---|
17 | 17 | #include <linux/nfs3.h> |
---|
18 | 18 | #include <linux/nfs4.h> |
---|
19 | 19 | #include <linux/sunrpc/svc.h> |
---|
| 20 | +#include <linux/sunrpc/svc_xprt.h> |
---|
20 | 21 | #include <linux/sunrpc/msg_prot.h> |
---|
| 22 | +#include <linux/sunrpc/addr.h> |
---|
21 | 23 | |
---|
22 | 24 | #include <uapi/linux/nfsd/debug.h> |
---|
23 | 25 | |
---|
| 26 | +#include "netns.h" |
---|
24 | 27 | #include "stats.h" |
---|
25 | 28 | #include "export.h" |
---|
26 | 29 | |
---|
.. | .. |
---|
73 | 76 | /* |
---|
74 | 77 | * Function prototypes. |
---|
75 | 78 | */ |
---|
76 | | -int nfsd_svc(int nrservs, struct net *net); |
---|
| 79 | +int nfsd_svc(int nrservs, struct net *net, const struct cred *cred); |
---|
77 | 80 | int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp); |
---|
78 | 81 | |
---|
79 | 82 | int nfsd_nrthreads(struct net *); |
---|
.. | .. |
---|
82 | 85 | int nfsd_set_nrthreads(int n, int *, struct net *); |
---|
83 | 86 | int nfsd_pool_stats_open(struct inode *, struct file *); |
---|
84 | 87 | int nfsd_pool_stats_release(struct inode *, struct file *); |
---|
| 88 | +void nfsd_shutdown_threads(struct net *net); |
---|
85 | 89 | |
---|
86 | 90 | void nfsd_destroy(struct net *net); |
---|
| 91 | + |
---|
| 92 | +bool i_am_nfsd(void); |
---|
| 93 | + |
---|
| 94 | +struct nfsdfs_client { |
---|
| 95 | + struct kref cl_ref; |
---|
| 96 | + void (*cl_release)(struct kref *kref); |
---|
| 97 | +}; |
---|
| 98 | + |
---|
| 99 | +struct nfsdfs_client *get_nfsdfs_client(struct inode *); |
---|
| 100 | +struct dentry *nfsd_client_mkdir(struct nfsd_net *nn, |
---|
| 101 | + struct nfsdfs_client *ncl, u32 id, const struct tree_descr *); |
---|
| 102 | +void nfsd_client_rmdir(struct dentry *dentry); |
---|
| 103 | + |
---|
87 | 104 | |
---|
88 | 105 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) |
---|
89 | 106 | #ifdef CONFIG_NFSD_V2_ACL |
---|
.. | .. |
---|
98 | 115 | #endif |
---|
99 | 116 | #endif |
---|
100 | 117 | |
---|
| 118 | +struct nfsd_net; |
---|
| 119 | + |
---|
101 | 120 | enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL }; |
---|
102 | | -int nfsd_vers(int vers, enum vers_op change); |
---|
103 | | -int nfsd_minorversion(u32 minorversion, enum vers_op change); |
---|
104 | | -void nfsd_reset_versions(void); |
---|
| 121 | +int nfsd_vers(struct nfsd_net *nn, int vers, enum vers_op change); |
---|
| 122 | +int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change); |
---|
| 123 | +void nfsd_reset_versions(struct nfsd_net *nn); |
---|
105 | 124 | int nfsd_create_serv(struct net *net); |
---|
106 | 125 | |
---|
107 | 126 | extern int nfsd_max_blksize; |
---|
.. | .. |
---|
109 | 128 | static inline int nfsd_v4client(struct svc_rqst *rq) |
---|
110 | 129 | { |
---|
111 | 130 | return rq->rq_prog == NFS_PROGRAM && rq->rq_vers == 4; |
---|
| 131 | +} |
---|
| 132 | +static inline struct user_namespace * |
---|
| 133 | +nfsd_user_namespace(const struct svc_rqst *rqstp) |
---|
| 134 | +{ |
---|
| 135 | + const struct cred *cred = rqstp->rq_xprt->xpt_cred; |
---|
| 136 | + return cred ? cred->user_ns : &init_user_ns; |
---|
112 | 137 | } |
---|
113 | 138 | |
---|
114 | 139 | /* |
---|
.. | .. |
---|
122 | 147 | int nfs4_state_start_net(struct net *net); |
---|
123 | 148 | void nfs4_state_shutdown(void); |
---|
124 | 149 | void nfs4_state_shutdown_net(struct net *net); |
---|
125 | | -void nfs4_reset_lease(time_t leasetime); |
---|
126 | 150 | int nfs4_reset_recoverydir(char *recdir); |
---|
127 | 151 | char * nfs4_recoverydir(void); |
---|
128 | 152 | bool nfsd4_spo_must_allow(struct svc_rqst *rqstp); |
---|
.. | .. |
---|
133 | 157 | static inline int nfs4_state_start_net(struct net *net) { return 0; } |
---|
134 | 158 | static inline void nfs4_state_shutdown(void) { } |
---|
135 | 159 | static inline void nfs4_state_shutdown_net(struct net *net) { } |
---|
136 | | -static inline void nfs4_reset_lease(time_t leasetime) { } |
---|
137 | 160 | static inline int nfs4_reset_recoverydir(char *recdir) { return 0; } |
---|
138 | 161 | static inline char * nfs4_recoverydir(void) {return NULL; } |
---|
139 | 162 | static inline bool nfsd4_spo_must_allow(struct svc_rqst *rqstp) |
---|
.. | .. |
---|
260 | 283 | #define nfserr_union_notsupp cpu_to_be32(NFS4ERR_UNION_NOTSUPP) |
---|
261 | 284 | #define nfserr_offload_denied cpu_to_be32(NFS4ERR_OFFLOAD_DENIED) |
---|
262 | 285 | #define nfserr_wrong_lfs cpu_to_be32(NFS4ERR_WRONG_LFS) |
---|
263 | | -#define nfserr_badlabel cpu_to_be32(NFS4ERR_BADLABEL) |
---|
| 286 | +#define nfserr_badlabel cpu_to_be32(NFS4ERR_BADLABEL) |
---|
| 287 | +#define nfserr_file_open cpu_to_be32(NFS4ERR_FILE_OPEN) |
---|
| 288 | +#define nfserr_xattr2big cpu_to_be32(NFS4ERR_XATTR2BIG) |
---|
| 289 | +#define nfserr_noxattr cpu_to_be32(NFS4ERR_NOXATTR) |
---|
264 | 290 | |
---|
265 | 291 | /* error codes for internal use */ |
---|
266 | 292 | /* if a request fails due to kmalloc failure, it gets dropped. |
---|
.. | .. |
---|
362 | 388 | (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \ |
---|
363 | 389 | FATTR4_WORD2_CHANGE_ATTR_TYPE | \ |
---|
364 | 390 | FATTR4_WORD2_MODE_UMASK | \ |
---|
365 | | - NFSD4_2_SECURITY_ATTRS) |
---|
| 391 | + NFSD4_2_SECURITY_ATTRS | \ |
---|
| 392 | + FATTR4_WORD2_XATTR_SUPPORT) |
---|
366 | 393 | |
---|
367 | 394 | extern const u32 nfsd_suppattrs[3][3]; |
---|
368 | 395 | |
---|
| 396 | +static inline __be32 nfsd4_set_netaddr(struct sockaddr *addr, |
---|
| 397 | + struct nfs42_netaddr *netaddr) |
---|
| 398 | +{ |
---|
| 399 | + struct sockaddr_in *sin = (struct sockaddr_in *)addr; |
---|
| 400 | + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; |
---|
| 401 | + unsigned int port; |
---|
| 402 | + size_t ret_addr, ret_port; |
---|
| 403 | + |
---|
| 404 | + switch (addr->sa_family) { |
---|
| 405 | + case AF_INET: |
---|
| 406 | + port = ntohs(sin->sin_port); |
---|
| 407 | + sprintf(netaddr->netid, "tcp"); |
---|
| 408 | + netaddr->netid_len = 3; |
---|
| 409 | + break; |
---|
| 410 | + case AF_INET6: |
---|
| 411 | + port = ntohs(sin6->sin6_port); |
---|
| 412 | + sprintf(netaddr->netid, "tcp6"); |
---|
| 413 | + netaddr->netid_len = 4; |
---|
| 414 | + break; |
---|
| 415 | + default: |
---|
| 416 | + return nfserr_inval; |
---|
| 417 | + } |
---|
| 418 | + ret_addr = rpc_ntop(addr, netaddr->addr, sizeof(netaddr->addr)); |
---|
| 419 | + ret_port = snprintf(netaddr->addr + ret_addr, |
---|
| 420 | + RPCBIND_MAXUADDRLEN + 1 - ret_addr, |
---|
| 421 | + ".%u.%u", port >> 8, port & 0xff); |
---|
| 422 | + WARN_ON(ret_port >= RPCBIND_MAXUADDRLEN + 1 - ret_addr); |
---|
| 423 | + netaddr->addr_len = ret_addr + ret_port; |
---|
| 424 | + return 0; |
---|
| 425 | +} |
---|
| 426 | + |
---|
369 | 427 | static inline bool bmval_is_subset(const u32 *bm1, const u32 *bm2) |
---|
370 | 428 | { |
---|
371 | 429 | return !((bm1[0] & ~bm2[0]) || |
---|