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