1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * linux/fs/nfs/nfs4_fs.h |
4 | * |
5 | * Copyright (C) 2005 Trond Myklebust |
6 | * |
7 | * NFSv4-specific filesystem definitions and declarations |
8 | */ |
9 | |
10 | #ifndef __LINUX_FS_NFS_NFS4_FS_H |
11 | #define __LINUX_FS_NFS_NFS4_FS_H |
12 | |
13 | #if defined(CONFIG_NFS_V4_2) |
14 | #define NFS4_MAX_MINOR_VERSION 2 |
15 | #elif defined(CONFIG_NFS_V4_1) |
16 | #define NFS4_MAX_MINOR_VERSION 1 |
17 | #else |
18 | #define NFS4_MAX_MINOR_VERSION 0 |
19 | #endif |
20 | |
21 | #if IS_ENABLED(CONFIG_NFS_V4) |
22 | |
23 | #define NFS4_MAX_LOOP_ON_RECOVER (10) |
24 | |
25 | #include <linux/seqlock.h> |
26 | #include <linux/filelock.h> |
27 | |
28 | struct idmap; |
29 | |
30 | enum nfs4_client_state { |
31 | NFS4CLNT_MANAGER_RUNNING = 0, |
32 | NFS4CLNT_CHECK_LEASE, |
33 | NFS4CLNT_LEASE_EXPIRED, |
34 | NFS4CLNT_RECLAIM_REBOOT, |
35 | NFS4CLNT_RECLAIM_NOGRACE, |
36 | NFS4CLNT_DELEGRETURN, |
37 | NFS4CLNT_SESSION_RESET, |
38 | NFS4CLNT_LEASE_CONFIRM, |
39 | NFS4CLNT_SERVER_SCOPE_MISMATCH, |
40 | NFS4CLNT_PURGE_STATE, |
41 | NFS4CLNT_BIND_CONN_TO_SESSION, |
42 | NFS4CLNT_MOVED, |
43 | NFS4CLNT_LEASE_MOVED, |
44 | NFS4CLNT_DELEGATION_EXPIRED, |
45 | NFS4CLNT_RUN_MANAGER, |
46 | NFS4CLNT_MANAGER_AVAILABLE, |
47 | NFS4CLNT_RECALL_RUNNING, |
48 | NFS4CLNT_RECALL_ANY_LAYOUT_READ, |
49 | NFS4CLNT_RECALL_ANY_LAYOUT_RW, |
50 | NFS4CLNT_DELEGRETURN_DELAYED, |
51 | }; |
52 | |
53 | #define NFS4_RENEW_TIMEOUT 0x01 |
54 | #define NFS4_RENEW_DELEGATION_CB 0x02 |
55 | |
56 | struct nfs_seqid_counter; |
57 | struct nfs4_minor_version_ops { |
58 | u32 minor_version; |
59 | unsigned init_caps; |
60 | |
61 | int (*init_client)(struct nfs_client *); |
62 | void (*shutdown_client)(struct nfs_client *); |
63 | bool (*match_stateid)(const nfs4_stateid *, |
64 | const nfs4_stateid *); |
65 | int (*find_root_sec)(struct nfs_server *, struct nfs_fh *, |
66 | struct nfs_fsinfo *); |
67 | void (*free_lock_state)(struct nfs_server *, |
68 | struct nfs4_lock_state *); |
69 | int (*test_and_free_expired)(struct nfs_server *, |
70 | nfs4_stateid *, const struct cred *); |
71 | struct nfs_seqid * |
72 | (*alloc_seqid)(struct nfs_seqid_counter *, gfp_t); |
73 | void (*session_trunk)(struct rpc_clnt *clnt, |
74 | struct rpc_xprt *xprt, void *data); |
75 | const struct rpc_call_ops *call_sync_ops; |
76 | const struct nfs4_state_recovery_ops *reboot_recovery_ops; |
77 | const struct nfs4_state_recovery_ops *nograce_recovery_ops; |
78 | const struct nfs4_state_maintenance_ops *state_renewal_ops; |
79 | const struct nfs4_mig_recovery_ops *mig_recovery_ops; |
80 | }; |
81 | |
82 | #define NFS_SEQID_CONFIRMED 1 |
83 | struct nfs_seqid_counter { |
84 | ktime_t create_time; |
85 | int owner_id; |
86 | int flags; |
87 | u32 counter; |
88 | spinlock_t lock; /* Protects the list */ |
89 | struct list_head list; /* Defines sequence of RPC calls */ |
90 | struct rpc_wait_queue wait; /* RPC call delay queue */ |
91 | }; |
92 | |
93 | struct nfs_seqid { |
94 | struct nfs_seqid_counter *sequence; |
95 | struct list_head list; |
96 | struct rpc_task *task; |
97 | }; |
98 | |
99 | static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status) |
100 | { |
101 | if (seqid_mutating_err(err: -status)) |
102 | seqid->flags |= NFS_SEQID_CONFIRMED; |
103 | } |
104 | |
105 | /* |
106 | * NFS4 state_owners and lock_owners are simply labels for ordered |
107 | * sequences of RPC calls. Their sole purpose is to provide once-only |
108 | * semantics by allowing the server to identify replayed requests. |
109 | */ |
110 | struct nfs4_state_owner { |
111 | struct nfs_server *so_server; |
112 | struct list_head so_lru; |
113 | unsigned long so_expires; |
114 | struct rb_node so_server_node; |
115 | |
116 | const struct cred *so_cred; /* Associated cred */ |
117 | |
118 | spinlock_t so_lock; |
119 | atomic_t so_count; |
120 | unsigned long so_flags; |
121 | struct list_head so_states; |
122 | struct nfs_seqid_counter so_seqid; |
123 | struct mutex so_delegreturn_mutex; |
124 | }; |
125 | |
126 | enum { |
127 | NFS_OWNER_RECLAIM_REBOOT, |
128 | NFS_OWNER_RECLAIM_NOGRACE |
129 | }; |
130 | |
131 | #define NFS_LOCK_NEW 0 |
132 | #define NFS_LOCK_RECLAIM 1 |
133 | #define NFS_LOCK_EXPIRED 2 |
134 | |
135 | /* |
136 | * struct nfs4_state maintains the client-side state for a given |
137 | * (state_owner,inode) tuple (OPEN) or state_owner (LOCK). |
138 | * |
139 | * OPEN: |
140 | * In order to know when to OPEN_DOWNGRADE or CLOSE the state on the server, |
141 | * we need to know how many files are open for reading or writing on a |
142 | * given inode. This information too is stored here. |
143 | * |
144 | * LOCK: one nfs4_state (LOCK) to hold the lock stateid nfs4_state(OPEN) |
145 | */ |
146 | |
147 | struct nfs4_lock_state { |
148 | struct list_head ls_locks; /* Other lock stateids */ |
149 | struct nfs4_state * ls_state; /* Pointer to open state */ |
150 | #define NFS_LOCK_INITIALIZED 0 |
151 | #define NFS_LOCK_LOST 1 |
152 | #define NFS_LOCK_UNLOCKING 2 |
153 | unsigned long ls_flags; |
154 | struct nfs_seqid_counter ls_seqid; |
155 | nfs4_stateid ls_stateid; |
156 | refcount_t ls_count; |
157 | fl_owner_t ls_owner; |
158 | }; |
159 | |
160 | /* bits for nfs4_state->flags */ |
161 | enum { |
162 | LK_STATE_IN_USE, |
163 | NFS_DELEGATED_STATE, /* Current stateid is delegation */ |
164 | NFS_OPEN_STATE, /* OPEN stateid is set */ |
165 | NFS_O_RDONLY_STATE, /* OPEN stateid has read-only state */ |
166 | NFS_O_WRONLY_STATE, /* OPEN stateid has write-only state */ |
167 | NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */ |
168 | NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */ |
169 | NFS_STATE_RECLAIM_NOGRACE, /* OPEN stateid needs to recover state */ |
170 | NFS_STATE_POSIX_LOCKS, /* Posix locks are supported */ |
171 | NFS_STATE_RECOVERY_FAILED, /* OPEN stateid state recovery failed */ |
172 | NFS_STATE_MAY_NOTIFY_LOCK, /* server may CB_NOTIFY_LOCK */ |
173 | NFS_STATE_CHANGE_WAIT, /* A state changing operation is outstanding */ |
174 | NFS_CLNT_DST_SSC_COPY_STATE, /* dst server open state on client*/ |
175 | NFS_CLNT_SRC_SSC_COPY_STATE, /* src server open state on client*/ |
176 | NFS_SRV_SSC_COPY_STATE, /* ssc state on the dst server */ |
177 | }; |
178 | |
179 | struct nfs4_state { |
180 | struct list_head open_states; /* List of states for the same state_owner */ |
181 | struct list_head inode_states; /* List of states for the same inode */ |
182 | struct list_head lock_states; /* List of subservient lock stateids */ |
183 | |
184 | struct nfs4_state_owner *owner; /* Pointer to the open owner */ |
185 | struct inode *inode; /* Pointer to the inode */ |
186 | |
187 | unsigned long flags; /* Do we hold any locks? */ |
188 | spinlock_t state_lock; /* Protects the lock_states list */ |
189 | |
190 | seqlock_t seqlock; /* Protects the stateid/open_stateid */ |
191 | nfs4_stateid stateid; /* Current stateid: may be delegation */ |
192 | nfs4_stateid open_stateid; /* OPEN stateid */ |
193 | |
194 | /* The following 3 fields are protected by owner->so_lock */ |
195 | unsigned int n_rdonly; /* Number of read-only references */ |
196 | unsigned int n_wronly; /* Number of write-only references */ |
197 | unsigned int n_rdwr; /* Number of read/write references */ |
198 | fmode_t state; /* State on the server (R,W, or RW) */ |
199 | refcount_t count; |
200 | |
201 | wait_queue_head_t waitq; |
202 | struct rcu_head rcu_head; |
203 | }; |
204 | |
205 | |
206 | struct nfs4_exception { |
207 | struct nfs4_state *state; |
208 | struct inode *inode; |
209 | nfs4_stateid *stateid; |
210 | long timeout; |
211 | unsigned short retrans; |
212 | unsigned char task_is_privileged : 1; |
213 | unsigned char delay : 1, |
214 | recovering : 1, |
215 | retry : 1; |
216 | bool interruptible; |
217 | }; |
218 | |
219 | struct nfs4_state_recovery_ops { |
220 | int owner_flag_bit; |
221 | int state_flag_bit; |
222 | int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *); |
223 | int (*recover_lock)(struct nfs4_state *, struct file_lock *); |
224 | int (*establish_clid)(struct nfs_client *, const struct cred *); |
225 | int (*reclaim_complete)(struct nfs_client *, const struct cred *); |
226 | int (*detect_trunking)(struct nfs_client *, struct nfs_client **, |
227 | const struct cred *); |
228 | }; |
229 | |
230 | struct nfs4_opendata { |
231 | struct kref kref; |
232 | struct nfs_openargs o_arg; |
233 | struct nfs_openres o_res; |
234 | struct nfs_open_confirmargs c_arg; |
235 | struct nfs_open_confirmres c_res; |
236 | struct nfs4_string owner_name; |
237 | struct nfs4_string group_name; |
238 | struct nfs4_label *a_label; |
239 | struct nfs_fattr f_attr; |
240 | struct dentry *dir; |
241 | struct dentry *dentry; |
242 | struct nfs4_state_owner *owner; |
243 | struct nfs4_state *state; |
244 | struct iattr attrs; |
245 | struct nfs4_layoutget *lgp; |
246 | unsigned long timestamp; |
247 | bool rpc_done; |
248 | bool file_created; |
249 | bool is_recover; |
250 | bool cancelled; |
251 | int rpc_status; |
252 | }; |
253 | |
254 | struct nfs4_add_xprt_data { |
255 | struct nfs_client *clp; |
256 | const struct cred *cred; |
257 | }; |
258 | |
259 | struct nfs4_state_maintenance_ops { |
260 | int (*sched_state_renewal)(struct nfs_client *, const struct cred *, unsigned); |
261 | const struct cred * (*get_state_renewal_cred)(struct nfs_client *); |
262 | int (*renew_lease)(struct nfs_client *, const struct cred *); |
263 | }; |
264 | |
265 | struct nfs4_mig_recovery_ops { |
266 | int (*get_locations)(struct nfs_server *, struct nfs_fh *, |
267 | struct nfs4_fs_locations *, struct page *, const struct cred *); |
268 | int (*fsid_present)(struct inode *, const struct cred *); |
269 | }; |
270 | |
271 | extern const struct dentry_operations nfs4_dentry_operations; |
272 | |
273 | /* dir.c */ |
274 | int nfs_atomic_open(struct inode *, struct dentry *, struct file *, |
275 | unsigned, umode_t); |
276 | |
277 | /* fs_context.c */ |
278 | extern struct file_system_type nfs4_fs_type; |
279 | |
280 | /* nfs4namespace.c */ |
281 | struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *, |
282 | const struct qstr *); |
283 | int nfs4_submount(struct fs_context *, struct nfs_server *); |
284 | int nfs4_replace_transport(struct nfs_server *server, |
285 | const struct nfs4_fs_locations *locations); |
286 | size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr_storage *ss, |
287 | size_t salen, struct net *net, int port); |
288 | /* nfs4proc.c */ |
289 | extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *); |
290 | extern int nfs4_async_handle_error(struct rpc_task *task, |
291 | struct nfs_server *server, |
292 | struct nfs4_state *state, long *timeout); |
293 | extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *, |
294 | struct rpc_message *, struct nfs4_sequence_args *, |
295 | struct nfs4_sequence_res *, int); |
296 | extern void nfs4_init_sequence(struct nfs4_sequence_args *, struct nfs4_sequence_res *, int, int); |
297 | extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, const struct cred *, struct nfs4_setclientid_res *); |
298 | extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, const struct cred *); |
299 | extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *, bool); |
300 | extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, const struct cred *cred); |
301 | extern int nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred); |
302 | extern int nfs4_destroy_clientid(struct nfs_client *clp); |
303 | extern int nfs4_init_clientid(struct nfs_client *, const struct cred *); |
304 | extern int nfs41_init_clientid(struct nfs_client *, const struct cred *); |
305 | extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait); |
306 | extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); |
307 | extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *, |
308 | struct nfs4_fs_locations *, struct page *); |
309 | extern int nfs4_proc_get_locations(struct nfs_server *, struct nfs_fh *, |
310 | struct nfs4_fs_locations *, |
311 | struct page *page, const struct cred *); |
312 | extern int nfs4_proc_fsid_present(struct inode *, const struct cred *); |
313 | extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, |
314 | struct dentry *, |
315 | struct nfs_fh *, |
316 | struct nfs_fattr *); |
317 | extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); |
318 | extern const struct xattr_handler * const nfs4_xattr_handlers[]; |
319 | extern int nfs4_set_rw_stateid(nfs4_stateid *stateid, |
320 | const struct nfs_open_context *ctx, |
321 | const struct nfs_lock_context *l_ctx, |
322 | fmode_t fmode); |
323 | extern void nfs4_bitmask_set(__u32 bitmask[], const __u32 src[], |
324 | struct inode *inode, unsigned long cache_validity); |
325 | extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, |
326 | struct nfs_fattr *fattr, struct inode *inode); |
327 | extern int update_open_stateid(struct nfs4_state *state, |
328 | const nfs4_stateid *open_stateid, |
329 | const nfs4_stateid *deleg_stateid, |
330 | fmode_t fmode); |
331 | extern int nfs4_proc_setlease(struct file *file, int arg, |
332 | struct file_lease **lease, void **priv); |
333 | extern int nfs4_proc_get_lease_time(struct nfs_client *clp, |
334 | struct nfs_fsinfo *fsinfo); |
335 | extern void nfs4_update_changeattr(struct inode *dir, |
336 | struct nfs4_change_info *cinfo, |
337 | unsigned long timestamp, |
338 | unsigned long cache_validity); |
339 | extern int nfs4_buf_to_pages_noslab(const void *buf, size_t buflen, |
340 | struct page **pages); |
341 | |
342 | #if defined(CONFIG_NFS_V4_1) |
343 | extern int nfs41_sequence_done(struct rpc_task *, struct nfs4_sequence_res *); |
344 | extern int nfs4_proc_create_session(struct nfs_client *, const struct cred *); |
345 | extern int nfs4_proc_destroy_session(struct nfs4_session *, const struct cred *); |
346 | extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, |
347 | bool sync); |
348 | extern int nfs4_detect_session_trunking(struct nfs_client *clp, |
349 | struct nfs41_exchange_id_res *res, struct rpc_xprt *xprt); |
350 | |
351 | static inline bool |
352 | is_ds_only_client(struct nfs_client *clp) |
353 | { |
354 | return (clp->cl_exchange_flags & EXCHGID4_FLAG_MASK_PNFS) == |
355 | EXCHGID4_FLAG_USE_PNFS_DS; |
356 | } |
357 | |
358 | static inline bool |
359 | is_ds_client(struct nfs_client *clp) |
360 | { |
361 | return clp->cl_exchange_flags & EXCHGID4_FLAG_USE_PNFS_DS; |
362 | } |
363 | |
364 | static inline bool |
365 | _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode, |
366 | struct rpc_clnt **clntp, struct rpc_message *msg) |
367 | { |
368 | rpc_authflavor_t flavor; |
369 | |
370 | if (sp4_mode == NFS_SP4_MACH_CRED_CLEANUP || |
371 | sp4_mode == NFS_SP4_MACH_CRED_PNFS_CLEANUP) { |
372 | /* Using machine creds for cleanup operations |
373 | * is only relevent if the client credentials |
374 | * might expire. So don't bother for |
375 | * RPC_AUTH_UNIX. If file was only exported to |
376 | * sec=sys, the PUTFH would fail anyway. |
377 | */ |
378 | if ((*clntp)->cl_auth->au_flavor == RPC_AUTH_UNIX) |
379 | return false; |
380 | } |
381 | if (test_bit(sp4_mode, &clp->cl_sp4_flags)) { |
382 | msg->rpc_cred = rpc_machine_cred(); |
383 | |
384 | flavor = clp->cl_rpcclient->cl_auth->au_flavor; |
385 | WARN_ON_ONCE(flavor != RPC_AUTH_GSS_KRB5I && |
386 | flavor != RPC_AUTH_GSS_KRB5P); |
387 | *clntp = clp->cl_rpcclient; |
388 | |
389 | return true; |
390 | } |
391 | return false; |
392 | } |
393 | |
394 | /* |
395 | * Function responsible for determining if an rpc_message should use the |
396 | * machine cred under SP4_MACH_CRED and if so switching the credential and |
397 | * authflavor (using the nfs_client's rpc_clnt which will be krb5i/p). |
398 | * Should be called before rpc_call_sync/rpc_call_async. |
399 | */ |
400 | static inline void |
401 | nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode, |
402 | struct rpc_clnt **clntp, struct rpc_message *msg) |
403 | { |
404 | _nfs4_state_protect(clp, sp4_mode, clntp, msg); |
405 | } |
406 | |
407 | /* |
408 | * Special wrapper to nfs4_state_protect for write. |
409 | * If WRITE can use machine cred but COMMIT cannot, make sure all writes |
410 | * that use machine cred use NFS_FILE_SYNC. |
411 | */ |
412 | static inline void |
413 | nfs4_state_protect_write(struct nfs_client *clp, struct rpc_clnt **clntp, |
414 | struct rpc_message *msg, struct nfs_pgio_header *hdr) |
415 | { |
416 | if (_nfs4_state_protect(clp, NFS_SP4_MACH_CRED_WRITE, clntp, msg) && |
417 | !test_bit(NFS_SP4_MACH_CRED_COMMIT, &clp->cl_sp4_flags)) |
418 | hdr->args.stable = NFS_FILE_SYNC; |
419 | } |
420 | #else /* CONFIG_NFS_v4_1 */ |
421 | static inline bool |
422 | is_ds_only_client(struct nfs_client *clp) |
423 | { |
424 | return false; |
425 | } |
426 | |
427 | static inline bool |
428 | is_ds_client(struct nfs_client *clp) |
429 | { |
430 | return false; |
431 | } |
432 | |
433 | static inline void |
434 | nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_flags, |
435 | struct rpc_clnt **clntp, struct rpc_message *msg) |
436 | { |
437 | } |
438 | |
439 | static inline void |
440 | nfs4_state_protect_write(struct nfs_client *clp, struct rpc_clnt **clntp, |
441 | struct rpc_message *msg, struct nfs_pgio_header *hdr) |
442 | { |
443 | } |
444 | #endif /* CONFIG_NFS_V4_1 */ |
445 | |
446 | extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[]; |
447 | |
448 | extern const u32 nfs4_fattr_bitmap[3]; |
449 | extern const u32 nfs4_statfs_bitmap[3]; |
450 | extern const u32 nfs4_pathconf_bitmap[3]; |
451 | extern const u32 nfs4_fsinfo_bitmap[3]; |
452 | extern const u32 nfs4_fs_locations_bitmap[3]; |
453 | |
454 | void nfs40_shutdown_client(struct nfs_client *); |
455 | void nfs41_shutdown_client(struct nfs_client *); |
456 | int nfs40_init_client(struct nfs_client *); |
457 | int nfs41_init_client(struct nfs_client *); |
458 | void nfs4_free_client(struct nfs_client *); |
459 | |
460 | struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *); |
461 | |
462 | /* nfs4renewd.c */ |
463 | extern void nfs4_schedule_state_renewal(struct nfs_client *); |
464 | extern void nfs4_kill_renewd(struct nfs_client *); |
465 | extern void nfs4_renew_state(struct work_struct *); |
466 | extern void nfs4_set_lease_period(struct nfs_client *clp, unsigned long lease); |
467 | |
468 | |
469 | /* nfs4state.c */ |
470 | extern const nfs4_stateid current_stateid; |
471 | |
472 | const struct cred *nfs4_get_clid_cred(struct nfs_client *clp); |
473 | const struct cred *nfs4_get_machine_cred(struct nfs_client *clp); |
474 | const struct cred *nfs4_get_renew_cred(struct nfs_client *clp); |
475 | int nfs4_discover_server_trunking(struct nfs_client *clp, |
476 | struct nfs_client **); |
477 | int nfs40_discover_server_trunking(struct nfs_client *clp, |
478 | struct nfs_client **, const struct cred *); |
479 | #if defined(CONFIG_NFS_V4_1) |
480 | int nfs41_discover_server_trunking(struct nfs_client *clp, |
481 | struct nfs_client **, const struct cred *); |
482 | extern void nfs4_schedule_session_recovery(struct nfs4_session *, int); |
483 | extern void nfs41_notify_server(struct nfs_client *); |
484 | bool nfs4_check_serverowner_major_id(struct nfs41_server_owner *o1, |
485 | struct nfs41_server_owner *o2); |
486 | #else |
487 | static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err) |
488 | { |
489 | } |
490 | #endif /* CONFIG_NFS_V4_1 */ |
491 | |
492 | extern struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *, const struct cred *, gfp_t); |
493 | extern void nfs4_put_state_owner(struct nfs4_state_owner *); |
494 | extern void nfs4_purge_state_owners(struct nfs_server *, struct list_head *); |
495 | extern void nfs4_free_state_owners(struct list_head *head); |
496 | extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *); |
497 | extern void nfs4_put_open_state(struct nfs4_state *); |
498 | extern void nfs4_close_state(struct nfs4_state *, fmode_t); |
499 | extern void nfs4_close_sync(struct nfs4_state *, fmode_t); |
500 | extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t); |
501 | extern void nfs_inode_find_state_and_recover(struct inode *inode, |
502 | const nfs4_stateid *stateid); |
503 | extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *, struct nfs4_state *); |
504 | extern void nfs4_schedule_lease_recovery(struct nfs_client *); |
505 | extern int nfs4_wait_clnt_recover(struct nfs_client *clp); |
506 | extern int nfs4_client_recover_expired_lease(struct nfs_client *clp); |
507 | extern void nfs4_schedule_state_manager(struct nfs_client *); |
508 | extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp); |
509 | extern int nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *); |
510 | extern int nfs4_schedule_migration_recovery(const struct nfs_server *); |
511 | extern void nfs4_schedule_lease_moved_recovery(struct nfs_client *); |
512 | extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags, bool); |
513 | extern void nfs41_handle_server_scope(struct nfs_client *, |
514 | struct nfs41_server_scope **); |
515 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); |
516 | extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); |
517 | extern int nfs4_select_rw_stateid(struct nfs4_state *, fmode_t, |
518 | const struct nfs_lock_context *, nfs4_stateid *, |
519 | const struct cred **); |
520 | extern bool nfs4_copy_open_stateid(nfs4_stateid *dst, |
521 | struct nfs4_state *state); |
522 | |
523 | extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask); |
524 | extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task); |
525 | extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid); |
526 | extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid); |
527 | extern void nfs_release_seqid(struct nfs_seqid *seqid); |
528 | extern void nfs_free_seqid(struct nfs_seqid *seqid); |
529 | extern int nfs4_setup_sequence(struct nfs_client *client, |
530 | struct nfs4_sequence_args *args, |
531 | struct nfs4_sequence_res *res, |
532 | struct rpc_task *task); |
533 | extern int nfs4_sequence_done(struct rpc_task *task, |
534 | struct nfs4_sequence_res *res); |
535 | |
536 | extern void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp); |
537 | extern int nfs4_proc_commit(struct file *dst, __u64 offset, __u32 count, struct nfs_commitres *res); |
538 | extern const nfs4_stateid zero_stateid; |
539 | extern const nfs4_stateid invalid_stateid; |
540 | |
541 | /* nfs4super.c */ |
542 | struct nfs_mount_info; |
543 | extern struct nfs_subversion nfs_v4; |
544 | extern bool nfs4_disable_idmapping; |
545 | extern unsigned short max_session_slots; |
546 | extern unsigned short max_session_cb_slots; |
547 | extern unsigned short send_implementation_id; |
548 | extern bool recover_lost_locks; |
549 | extern short nfs_delay_retrans; |
550 | |
551 | #define NFS4_CLIENT_ID_UNIQ_LEN (64) |
552 | extern char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN]; |
553 | |
554 | extern int nfs4_try_get_tree(struct fs_context *); |
555 | extern int nfs4_get_referral_tree(struct fs_context *); |
556 | |
557 | /* nfs4sysctl.c */ |
558 | #ifdef CONFIG_SYSCTL |
559 | int nfs4_register_sysctl(void); |
560 | void nfs4_unregister_sysctl(void); |
561 | #else |
562 | static inline int nfs4_register_sysctl(void) |
563 | { |
564 | return 0; |
565 | } |
566 | |
567 | static inline void nfs4_unregister_sysctl(void) |
568 | { |
569 | } |
570 | #endif |
571 | |
572 | /* nfs4xdr.c */ |
573 | extern const struct rpc_procinfo nfs4_procedures[]; |
574 | |
575 | #ifdef CONFIG_NFS_V4_2 |
576 | extern const u32 nfs42_maxsetxattr_overhead; |
577 | extern const u32 nfs42_maxgetxattr_overhead; |
578 | extern const u32 nfs42_maxlistxattrs_overhead; |
579 | #endif |
580 | |
581 | struct nfs4_mount_data; |
582 | |
583 | /* callback_xdr.c */ |
584 | extern const struct svc_version nfs4_callback_version1; |
585 | extern const struct svc_version nfs4_callback_version4; |
586 | |
587 | static inline void nfs4_stateid_copy(nfs4_stateid *dst, const nfs4_stateid *src) |
588 | { |
589 | memcpy(dst->data, src->data, sizeof(dst->data)); |
590 | dst->type = src->type; |
591 | } |
592 | |
593 | static inline bool nfs4_stateid_match(const nfs4_stateid *dst, const nfs4_stateid *src) |
594 | { |
595 | if (dst->type != src->type) |
596 | return false; |
597 | return memcmp(p: dst->data, q: src->data, size: sizeof(dst->data)) == 0; |
598 | } |
599 | |
600 | static inline bool nfs4_stateid_match_other(const nfs4_stateid *dst, const nfs4_stateid *src) |
601 | { |
602 | return memcmp(p: dst->other, q: src->other, NFS4_STATEID_OTHER_SIZE) == 0; |
603 | } |
604 | |
605 | static inline bool nfs4_stateid_is_newer(const nfs4_stateid *s1, const nfs4_stateid *s2) |
606 | { |
607 | return (s32)(be32_to_cpu(s1->seqid) - be32_to_cpu(s2->seqid)) > 0; |
608 | } |
609 | |
610 | static inline bool nfs4_stateid_is_next(const nfs4_stateid *s1, const nfs4_stateid *s2) |
611 | { |
612 | u32 seq1 = be32_to_cpu(s1->seqid); |
613 | u32 seq2 = be32_to_cpu(s2->seqid); |
614 | |
615 | return seq2 == seq1 + 1U || (seq2 == 1U && seq1 == 0xffffffffU); |
616 | } |
617 | |
618 | static inline bool nfs4_stateid_match_or_older(const nfs4_stateid *dst, const nfs4_stateid *src) |
619 | { |
620 | return nfs4_stateid_match_other(dst, src) && |
621 | !(src->seqid && nfs4_stateid_is_newer(s1: dst, s2: src)); |
622 | } |
623 | |
624 | static inline void nfs4_stateid_seqid_inc(nfs4_stateid *s1) |
625 | { |
626 | u32 seqid = be32_to_cpu(s1->seqid); |
627 | |
628 | if (++seqid == 0) |
629 | ++seqid; |
630 | s1->seqid = cpu_to_be32(seqid); |
631 | } |
632 | |
633 | static inline bool nfs4_valid_open_stateid(const struct nfs4_state *state) |
634 | { |
635 | return test_bit(NFS_STATE_RECOVERY_FAILED, &state->flags) == 0; |
636 | } |
637 | |
638 | static inline bool nfs4_state_match_open_stateid_other(const struct nfs4_state *state, |
639 | const nfs4_stateid *stateid) |
640 | { |
641 | return test_bit(NFS_OPEN_STATE, &state->flags) && |
642 | nfs4_stateid_match_other(dst: &state->open_stateid, src: stateid); |
643 | } |
644 | |
645 | /* nfs42xattr.c */ |
646 | #ifdef CONFIG_NFS_V4_2 |
647 | extern int __init nfs4_xattr_cache_init(void); |
648 | extern void nfs4_xattr_cache_exit(void); |
649 | extern void nfs4_xattr_cache_add(struct inode *inode, const char *name, |
650 | const char *buf, struct page **pages, |
651 | ssize_t buflen); |
652 | extern void nfs4_xattr_cache_remove(struct inode *inode, const char *name); |
653 | extern ssize_t nfs4_xattr_cache_get(struct inode *inode, const char *name, |
654 | char *buf, ssize_t buflen); |
655 | extern void nfs4_xattr_cache_set_list(struct inode *inode, const char *buf, |
656 | ssize_t buflen); |
657 | extern ssize_t nfs4_xattr_cache_list(struct inode *inode, char *buf, |
658 | ssize_t buflen); |
659 | extern void nfs4_xattr_cache_zap(struct inode *inode); |
660 | #else |
661 | static inline void nfs4_xattr_cache_zap(struct inode *inode) |
662 | { |
663 | } |
664 | #endif /* CONFIG_NFS_V4_2 */ |
665 | |
666 | #else /* CONFIG_NFS_V4 */ |
667 | |
668 | #define nfs4_close_state(a, b) do { } while (0) |
669 | #define nfs4_close_sync(a, b) do { } while (0) |
670 | #define nfs4_state_protect(a, b, c, d) do { } while (0) |
671 | #define nfs4_state_protect_write(a, b, c, d) do { } while (0) |
672 | |
673 | |
674 | #endif /* CONFIG_NFS_V4 */ |
675 | #endif /* __LINUX_FS_NFS_NFS4_FS.H */ |
676 | |