summaryrefslogtreecommitdiffstats
path: root/include/linux/nfsd/nfsd.h
blob: 51c231a1e5a669457ef5a4aef34207ad74a78b37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
/*
 * linux/include/linux/nfsd/nfsd.h
 *
 * Hodge-podge collection of knfsd-related stuff.
 * I will sort this out later.
 *
 * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
 */

#ifndef LINUX_NFSD_NFSD_H
#define LINUX_NFSD_NFSD_H

#include <linux/config.h>
#include <linux/types.h>
#include <linux/unistd.h>
#include <linux/dirent.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/auth.h>
#include <linux/nfsd/stats.h>
#include <linux/nfsd/interface.h>
/*
 * nfsd version
 */
#define NFSD_VERSION		"0.5"
#define NFSD_SUPPORTED_MINOR_VERSION	0

#ifdef __KERNEL__
/*
 * Special flags for nfsd_permission. These must be different from MAY_READ,
 * MAY_WRITE, and MAY_EXEC.
 */
#define MAY_NOP			0
#define MAY_SATTR		8
#define MAY_TRUNC		16
#define MAY_LOCK		32
#define MAY_OWNER_OVERRIDE	64
#define	MAY_LOCAL_ACCESS	128 /* IRIX doing local access check on device special file*/
#if (MAY_SATTR | MAY_TRUNC | MAY_LOCK | MAY_OWNER_OVERRIDE | MAY_LOCAL_ACCESS) & (MAY_READ | MAY_WRITE | MAY_EXEC)
# error "please use a different value for MAY_SATTR or MAY_TRUNC or MAY_LOCK or MAY_LOCAL_ACCESS or MAY_OWNER_OVERRIDE."
#endif
#define MAY_CREATE		(MAY_EXEC|MAY_WRITE)
#define MAY_REMOVE		(MAY_EXEC|MAY_WRITE|MAY_TRUNC)

/*
 * Callback function for readdir
 */
struct readdir_cd {
	int			err;	/* 0, nfserr, or nfserr_eof */
};
typedef int		(*encode_dent_fn)(struct readdir_cd *, const char *,
						int, loff_t, ino_t, unsigned int);
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,
				nfsd_version4;
extern struct svc_serv		*nfsd_serv;
/*
 * Function prototypes.
 */
int		nfsd_svc(unsigned short port, int nrservs);
int		nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp);

/* 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);
int		nfsd_lookup(struct svc_rqst *, struct svc_fh *,
				const char *, int, struct svc_fh *);
int		nfsd_setattr(struct svc_rqst *, struct svc_fh *,
				struct iattr *, int, time_t);
#ifdef CONFIG_NFSD_V4
int             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 */
int		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
int		nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
int		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		nfsd_commit(struct svc_rqst *, struct svc_fh *,
				loff_t, unsigned long);
#endif /* CONFIG_NFSD_V3 */
int		nfsd_open(struct svc_rqst *, struct svc_fh *, int,
				int, struct file **);
void		nfsd_close(struct file *);
int 		nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *,
				loff_t, struct kvec *, int, unsigned long *);
int 		nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
				loff_t, struct kvec *,int, unsigned long, int *);
int		nfsd_readlink(struct svc_rqst *, struct svc_fh *,
				char *, int *);
int		nfsd_symlink(struct svc_rqst *, struct svc_fh *,
				char *name, int len, char *path, int plen,
				struct svc_fh *res, struct iattr *);
int		nfsd_link(struct svc_rqst *, struct svc_fh *,
				char *, int, struct svc_fh *);
int		nfsd_rename(struct svc_rqst *,
				struct svc_fh *, char *, int,
				struct svc_fh *, char *, int);
int		nfsd_remove(struct svc_rqst *,
				struct svc_fh *, char *, int);
int		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);
int		nfsd_readdir(struct svc_rqst *, struct svc_fh *,
			     loff_t *, struct readdir_cd *, encode_dent_fn);
int		nfsd_statfs(struct svc_rqst *, struct svc_fh *,
				struct kstatfs *);

int		nfsd_notify_change(struct inode *, struct iattr *);
int		nfsd_permission(struct svc_export *, struct dentry *, int);
void		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;
#else
#define nfsd_acl_version2 NULL
#endif
#ifdef CONFIG_NFSD_V3_ACL
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


/* 
 * NFSv4 State
 */
#ifdef CONFIG_NFSD_V4
void nfs4_state_init(void);
int nfs4_state_start(void);
void nfs4_state_shutdown(void);
time_t nfs4_lease_time(void);
void nfs4_reset_lease(time_t leasetime);
int nfs4_reset_recoverydir(char *recdir);
#else
static inline void nfs4_state_init(void){};
static inline int nfs4_state_start(void){return 0;}
static inline void nfs4_state_shutdown(void){}
static inline time_t nfs4_lease_time(void){return 0;}
static inline void nfs4_reset_lease(time_t leasetime){}
static inline int nfs4_reset_recoverydir(char *recdir) {return 0;}
#endif

/*
 * lockd binding
 */
void		nfsd_lockd_init(void);
void		nfsd_lockd_shutdown(void);


/*
 * These macros provide pre-xdr'ed values for faster operation.
 */
#define	nfs_ok			__constant_htonl(NFS_OK)
#define	nfserr_perm		__constant_htonl(NFSERR_PERM)
#define	nfserr_noent		__constant_htonl(NFSERR_NOENT)
#define	nfserr_io		__constant_htonl(NFSERR_IO)
#define	nfserr_nxio		__constant_htonl(NFSERR_NXIO)
#define	nfserr_eagain		__constant_htonl(NFSERR_EAGAIN)
#define	nfserr_acces		__constant_htonl(NFSERR_ACCES)
#define	nfserr_exist		__constant_htonl(NFSERR_EXIST)
#define	nfserr_xdev		__constant_htonl(NFSERR_XDEV)
#define	nfserr_nodev		__constant_htonl(NFSERR_NODEV)
#define	nfserr_notdir		__constant_htonl(NFSERR_NOTDIR)
#define	nfserr_isdir		__constant_htonl(NFSERR_ISDIR)
#define	nfserr_inval		__constant_htonl(NFSERR_INVAL)
#define	nfserr_fbig		__constant_htonl(NFSERR_FBIG)
#define	nfserr_nospc		__constant_htonl(NFSERR_NOSPC)
#define	nfserr_rofs		__constant_htonl(NFSERR_ROFS)
#define	nfserr_mlink		__constant_htonl(NFSERR_MLINK)
#define	nfserr_opnotsupp	__constant_htonl(NFSERR_OPNOTSUPP)
#define	nfserr_nametoolong	__constant_htonl(NFSERR_NAMETOOLONG)
#define	nfserr_notempty		__constant_htonl(NFSERR_NOTEMPTY)
#define	nfserr_dquot		__constant_htonl(NFSERR_DQUOT)
#define	nfserr_stale		__constant_htonl(NFSERR_STALE)
#define	nfserr_remote		__constant_htonl(NFSERR_REMOTE)
#define	nfserr_wflush		__constant_htonl(NFSERR_WFLUSH)
#define	nfserr_badhandle	__constant_htonl(NFSERR_BADHANDLE)
#define	nfserr_notsync		__constant_htonl(NFSERR_NOT_SYNC)
#define	nfserr_badcookie	__constant_htonl(NFSERR_BAD_COOKIE)
#define	nfserr_notsupp		__constant_htonl(NFSERR_NOTSUPP)
#define	nfserr_toosmall		__constant_htonl(NFSERR_TOOSMALL)
#define	nfserr_serverfault	__constant_htonl(NFSERR_SERVERFAULT)
#define	nfserr_badtype		__constant_htonl(NFSERR_BADTYPE)
#define	nfserr_jukebox		__constant_htonl(NFSERR_JUKEBOX)
#define	nfserr_denied		__constant_htonl(NFSERR_DENIED)
#define	nfserr_deadlock		__constant_htonl(NFSERR_DEADLOCK)
#define nfserr_expired          __constant_htonl(NFSERR_EXPIRED)
#define	nfserr_bad_cookie	__constant_htonl(NFSERR_BAD_COOKIE)
#define	nfserr_same		__constant_htonl(NFSERR_SAME)
#define	nfserr_clid_inuse	__constant_htonl(NFSERR_CLID_INUSE)
#define	nfserr_stale_clientid	__constant_htonl(NFSERR_STALE_CLIENTID)
#define	nfserr_resource		__constant_htonl(NFSERR_RESOURCE)
#define	nfserr_nofilehandle	__constant_htonl(NFSERR_NOFILEHANDLE)
#define	nfserr_minor_vers_mismatch	__constant_htonl(NFSERR_MINOR_VERS_MISMATCH)
#define nfserr_share_denied	__constant_htonl(NFSERR_SHARE_DENIED)
#define nfserr_stale_stateid	__constant_htonl(NFSERR_STALE_STATEID)
#define nfserr_old_stateid	__constant_htonl(NFSERR_OLD_STATEID)
#define nfserr_bad_stateid	__constant_htonl(NFSERR_BAD_STATEID)
#define nfserr_bad_seqid	__constant_htonl(NFSERR_BAD_SEQID)
#define	nfserr_symlink		__constant_htonl(NFSERR_SYMLINK)
#define	nfserr_not_same		__constant_htonl(NFSERR_NOT_SAME)
#define	nfserr_restorefh	__constant_htonl(NFSERR_RESTOREFH)
#define	nfserr_attrnotsupp	__constant_htonl(NFSERR_ATTRNOTSUPP)
#define	nfserr_bad_xdr		__constant_htonl(NFSERR_BAD_XDR)
#define	nfserr_openmode		__constant_htonl(NFSERR_OPENMODE)
#define	nfserr_locks_held	__constant_htonl(NFSERR_LOCKS_HELD)
#define	nfserr_op_illegal	__constant_htonl(NFSERR_OP_ILLEGAL)
#define	nfserr_grace		__constant_htonl(NFSERR_GRACE)
#define	nfserr_no_grace		__constant_htonl(NFSERR_NO_GRACE)
#define	nfserr_reclaim_bad	__constant_htonl(NFSERR_RECLAIM_BAD)
#define	nfserr_badname		__constant_htonl(NFSERR_BADNAME)
#define	nfserr_cb_path_down	__constant_htonl(NFSERR_CB_PATH_DOWN)
#define	nfserr_locked		__constant_htonl(NFSERR_LOCKED)

/* error codes for internal use */
/* if a request fails due to kmalloc failure, it gets dropped.
 *  Client should resend eventually
 */
#define	nfserr_dropit		__constant_htonl(30000)
/* end-of-file indicator in readdir */
#define	nfserr_eof		__constant_htonl(30001)

/* Check for dir entries '.' and '..' */
#define isdotent(n, l)	(l < 3 && n[0] == '.' && (l == 1 || n[1] == '.'))

/*
 * Time of server startup
 */
extern struct timeval	nfssvc_boot;

static inline int is_fsid(struct svc_fh *fh, struct knfsd_fh *reffh)
{
	if (fh->fh_export->ex_flags & NFSEXP_FSID) {
		struct vfsmount *mnt = fh->fh_export->ex_mnt;
		if (!old_valid_dev(mnt->mnt_sb->s_dev) ||
		    (reffh->fh_version == 1 && reffh->fh_fsid_type == 1))
			return 1;
	}
	return 0;
}


#ifdef CONFIG_NFSD_V4

/* before processing a COMPOUND operation, we have to check that there
 * is enough space in the buffer for XDR encode to succeed.  otherwise,
 * we might process an operation with side effects, and be unable to
 * tell the client that the operation succeeded.
 *
 * COMPOUND_SLACK_SPACE - this is the minimum amount of buffer space
 * needed to encode an "ordinary" _successful_ operation.  (GETATTR,
 * READ, READDIR, and READLINK have their own buffer checks.)  if we
 * fall below this level, we fail the next operation with NFS4ERR_RESOURCE.
 *
 * COMPOUND_ERR_SLACK_SPACE - this is the minimum amount of buffer space
 * needed to encode an operation which has failed with NFS4ERR_RESOURCE.
 * care is taken to ensure that we never fall below this level for any
 * reason.
 */
#define	COMPOUND_SLACK_SPACE		140    /* OP_GETFH */
#define COMPOUND_ERR_SLACK_SPACE	12     /* OP_SETATTR */

#define NFSD_LEASE_TIME                 (nfs4_lease_time())
#define NFSD_LAUNDROMAT_MINTIMEOUT      10   /* seconds */

/*
 * The following attributes are currently not supported by the NFSv4 server:
 *    ARCHIVE       (deprecated anyway)
 *    FS_LOCATIONS  (will be supported eventually)
 *    HIDDEN        (unlikely to be supported any time soon)
 *    MIMETYPE      (unlikely to be supported any time soon)
 *    QUOTA_*       (will be supported in a forthcoming patch)
 *    SYSTEM        (unlikely to be supported any time soon)
 *    TIME_BACKUP   (unlikely to be supported any time soon)
 *    TIME_CREATE   (unlikely to be supported any time soon)
 */
#define NFSD_SUPPORTED_ATTRS_WORD0                                                          \
(FATTR4_WORD0_SUPPORTED_ATTRS   | FATTR4_WORD0_TYPE         | FATTR4_WORD0_FH_EXPIRE_TYPE   \
 | FATTR4_WORD0_CHANGE          | FATTR4_WORD0_SIZE         | FATTR4_WORD0_LINK_SUPPORT     \
 | FATTR4_WORD0_SYMLINK_SUPPORT | FATTR4_WORD0_NAMED_ATTR   | FATTR4_WORD0_FSID             \
 | FATTR4_WORD0_UNIQUE_HANDLES  | FATTR4_WORD0_LEASE_TIME   | FATTR4_WORD0_RDATTR_ERROR     \
 | FATTR4_WORD0_ACLSUPPORT      | FATTR4_WORD0_CANSETTIME   | FATTR4_WORD0_CASE_INSENSITIVE \
 | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED                             \
 | FATTR4_WORD0_FILEHANDLE      | FATTR4_WORD0_FILEID       | FATTR4_WORD0_FILES_AVAIL      \
 | FATTR4_WORD0_FILES_FREE      | FATTR4_WORD0_FILES_TOTAL  | FATTR4_WORD0_HOMOGENEOUS      \
 | FATTR4_WORD0_MAXFILESIZE     | FATTR4_WORD0_MAXLINK      | FATTR4_WORD0_MAXNAME          \
 | FATTR4_WORD0_MAXREAD         | FATTR4_WORD0_MAXWRITE     | FATTR4_WORD0_ACL)

#define NFSD_SUPPORTED_ATTRS_WORD1                                                          \
(FATTR4_WORD1_MODE              | FATTR4_WORD1_NO_TRUNC     | FATTR4_WORD1_NUMLINKS         \
 | FATTR4_WORD1_OWNER	        | FATTR4_WORD1_OWNER_GROUP  | FATTR4_WORD1_RAWDEV           \
 | FATTR4_WORD1_SPACE_AVAIL     | FATTR4_WORD1_SPACE_FREE   | FATTR4_WORD1_SPACE_TOTAL      \
 | FATTR4_WORD1_SPACE_USED      | FATTR4_WORD1_TIME_ACCESS  | FATTR4_WORD1_TIME_ACCESS_SET  \
 | FATTR4_WORD1_TIME_DELTA   | FATTR4_WORD1_TIME_METADATA    \
 | FATTR4_WORD1_TIME_MODIFY     | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID)

/* These will return ERR_INVAL if specified in GETATTR or READDIR. */
#define NFSD_WRITEONLY_ATTRS_WORD1							    \
(FATTR4_WORD1_TIME_ACCESS_SET   | FATTR4_WORD1_TIME_MODIFY_SET)

/* These are the only attrs allowed in CREATE/OPEN/SETATTR. */
#define NFSD_WRITEABLE_ATTRS_WORD0                                                          \
(FATTR4_WORD0_SIZE              | FATTR4_WORD0_ACL                                         )
#define NFSD_WRITEABLE_ATTRS_WORD1                                                          \
(FATTR4_WORD1_MODE              | FATTR4_WORD1_OWNER         | FATTR4_WORD1_OWNER_GROUP     \
 | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY_SET)

#endif /* CONFIG_NFSD_V4 */

#endif /* __KERNEL__ */

#endif /* LINUX_NFSD_NFSD_H */