1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_FILELOCK_H |
3 | #define _LINUX_FILELOCK_H |
4 | |
5 | #include <linux/fs.h> |
6 | |
7 | #define FL_POSIX 1 |
8 | #define FL_FLOCK 2 |
9 | #define FL_DELEG 4 /* NFSv4 delegation */ |
10 | #define FL_ACCESS 8 /* not trying to lock, just looking */ |
11 | #define FL_EXISTS 16 /* when unlocking, test for existence */ |
12 | #define FL_LEASE 32 /* lease held on this file */ |
13 | #define FL_CLOSE 64 /* unlock on close */ |
14 | #define FL_SLEEP 128 /* A blocking lock */ |
15 | #define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */ |
16 | #define FL_UNLOCK_PENDING 512 /* Lease is being broken */ |
17 | #define FL_OFDLCK 1024 /* lock is "owned" by struct file */ |
18 | #define FL_LAYOUT 2048 /* outstanding pNFS layout */ |
19 | #define FL_RECLAIM 4096 /* reclaiming from a reboot server */ |
20 | |
21 | #define FL_CLOSE_POSIX (FL_POSIX | FL_CLOSE) |
22 | |
23 | /* |
24 | * Special return value from posix_lock_file() and vfs_lock_file() for |
25 | * asynchronous locking. |
26 | */ |
27 | #define FILE_LOCK_DEFERRED 1 |
28 | |
29 | struct file_lock; |
30 | struct file_lease; |
31 | |
32 | struct file_lock_operations { |
33 | void (*fl_copy_lock)(struct file_lock *, struct file_lock *); |
34 | void (*fl_release_private)(struct file_lock *); |
35 | }; |
36 | |
37 | struct lock_manager_operations { |
38 | void *lm_mod_owner; |
39 | fl_owner_t (*lm_get_owner)(fl_owner_t); |
40 | void (*lm_put_owner)(fl_owner_t); |
41 | void (*lm_notify)(struct file_lock *); /* unblock callback */ |
42 | int (*lm_grant)(struct file_lock *, int); |
43 | bool (*lm_lock_expirable)(struct file_lock *cfl); |
44 | void (*lm_expire_lock)(void); |
45 | }; |
46 | |
47 | struct lease_manager_operations { |
48 | bool (*lm_break)(struct file_lease *); |
49 | int (*lm_change)(struct file_lease *, int, struct list_head *); |
50 | void (*lm_setup)(struct file_lease *, void **); |
51 | bool (*lm_breaker_owns_lease)(struct file_lease *); |
52 | }; |
53 | |
54 | struct lock_manager { |
55 | struct list_head list; |
56 | /* |
57 | * NFSv4 and up also want opens blocked during the grace period; |
58 | * NLM doesn't care: |
59 | */ |
60 | bool block_opens; |
61 | }; |
62 | |
63 | struct net; |
64 | void locks_start_grace(struct net *, struct lock_manager *); |
65 | void locks_end_grace(struct lock_manager *); |
66 | bool locks_in_grace(struct net *); |
67 | bool opens_in_grace(struct net *); |
68 | |
69 | /* |
70 | * struct file_lock has a union that some filesystems use to track |
71 | * their own private info. The NFS side of things is defined here: |
72 | */ |
73 | #include <linux/nfs_fs_i.h> |
74 | |
75 | /* |
76 | * struct file_lock represents a generic "file lock". It's used to represent |
77 | * POSIX byte range locks, BSD (flock) locks, and leases. It's important to |
78 | * note that the same struct is used to represent both a request for a lock and |
79 | * the lock itself, but the same object is never used for both. |
80 | * |
81 | * FIXME: should we create a separate "struct lock_request" to help distinguish |
82 | * these two uses? |
83 | * |
84 | * The varous i_flctx lists are ordered by: |
85 | * |
86 | * 1) lock owner |
87 | * 2) lock range start |
88 | * 3) lock range end |
89 | * |
90 | * Obviously, the last two criteria only matter for POSIX locks. |
91 | */ |
92 | |
93 | struct file_lock_core { |
94 | struct file_lock_core *flc_blocker; /* The lock that is blocking us */ |
95 | struct list_head flc_list; /* link into file_lock_context */ |
96 | struct hlist_node flc_link; /* node in global lists */ |
97 | struct list_head flc_blocked_requests; /* list of requests with |
98 | * ->fl_blocker pointing here |
99 | */ |
100 | struct list_head flc_blocked_member; /* node in |
101 | * ->fl_blocker->fl_blocked_requests |
102 | */ |
103 | fl_owner_t flc_owner; |
104 | unsigned int flc_flags; |
105 | unsigned char flc_type; |
106 | pid_t flc_pid; |
107 | int flc_link_cpu; /* what cpu's list is this on? */ |
108 | wait_queue_head_t flc_wait; |
109 | struct file *flc_file; |
110 | }; |
111 | |
112 | struct file_lock { |
113 | struct file_lock_core c; |
114 | loff_t fl_start; |
115 | loff_t fl_end; |
116 | |
117 | const struct file_lock_operations *fl_ops; /* Callbacks for filesystems */ |
118 | const struct lock_manager_operations *fl_lmops; /* Callbacks for lockmanagers */ |
119 | union { |
120 | struct nfs_lock_info nfs_fl; |
121 | struct nfs4_lock_info nfs4_fl; |
122 | struct { |
123 | struct list_head link; /* link in AFS vnode's pending_locks list */ |
124 | int state; /* state of grant or error if -ve */ |
125 | unsigned int debug_id; |
126 | } afs; |
127 | struct { |
128 | struct inode *inode; |
129 | } ceph; |
130 | } fl_u; |
131 | } __randomize_layout; |
132 | |
133 | struct file_lease { |
134 | struct file_lock_core c; |
135 | struct fasync_struct * fl_fasync; /* for lease break notifications */ |
136 | /* for lease breaks: */ |
137 | unsigned long fl_break_time; |
138 | unsigned long fl_downgrade_time; |
139 | const struct lease_manager_operations *fl_lmops; /* Callbacks for lease managers */ |
140 | } __randomize_layout; |
141 | |
142 | struct file_lock_context { |
143 | spinlock_t flc_lock; |
144 | struct list_head flc_flock; |
145 | struct list_head flc_posix; |
146 | struct list_head flc_lease; |
147 | }; |
148 | |
149 | #ifdef CONFIG_FILE_LOCKING |
150 | int fcntl_getlk(struct file *, unsigned int, struct flock *); |
151 | int fcntl_setlk(unsigned int, struct file *, unsigned int, |
152 | struct flock *); |
153 | |
154 | #if BITS_PER_LONG == 32 |
155 | int fcntl_getlk64(struct file *, unsigned int, struct flock64 *); |
156 | int fcntl_setlk64(unsigned int, struct file *, unsigned int, |
157 | struct flock64 *); |
158 | #endif |
159 | |
160 | int fcntl_setlease(unsigned int fd, struct file *filp, int arg); |
161 | int fcntl_getlease(struct file *filp); |
162 | |
163 | static inline bool lock_is_unlock(struct file_lock *fl) |
164 | { |
165 | return fl->c.flc_type == F_UNLCK; |
166 | } |
167 | |
168 | static inline bool lock_is_read(struct file_lock *fl) |
169 | { |
170 | return fl->c.flc_type == F_RDLCK; |
171 | } |
172 | |
173 | static inline bool lock_is_write(struct file_lock *fl) |
174 | { |
175 | return fl->c.flc_type == F_WRLCK; |
176 | } |
177 | |
178 | static inline void locks_wake_up(struct file_lock *fl) |
179 | { |
180 | wake_up(&fl->c.flc_wait); |
181 | } |
182 | |
183 | /* fs/locks.c */ |
184 | void locks_free_lock_context(struct inode *inode); |
185 | void locks_free_lock(struct file_lock *fl); |
186 | void locks_init_lock(struct file_lock *); |
187 | struct file_lock *locks_alloc_lock(void); |
188 | void locks_copy_lock(struct file_lock *, struct file_lock *); |
189 | void locks_copy_conflock(struct file_lock *, struct file_lock *); |
190 | void locks_remove_posix(struct file *, fl_owner_t); |
191 | void locks_remove_file(struct file *); |
192 | void locks_release_private(struct file_lock *); |
193 | void posix_test_lock(struct file *, struct file_lock *); |
194 | int posix_lock_file(struct file *, struct file_lock *, struct file_lock *); |
195 | int locks_delete_block(struct file_lock *); |
196 | int vfs_test_lock(struct file *, struct file_lock *); |
197 | int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *); |
198 | int vfs_cancel_lock(struct file *filp, struct file_lock *fl); |
199 | bool vfs_inode_has_locks(struct inode *inode); |
200 | int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl); |
201 | |
202 | void locks_init_lease(struct file_lease *); |
203 | void locks_free_lease(struct file_lease *fl); |
204 | struct file_lease *locks_alloc_lease(void); |
205 | int __break_lease(struct inode *inode, unsigned int flags, unsigned int type); |
206 | void lease_get_mtime(struct inode *, struct timespec64 *time); |
207 | int generic_setlease(struct file *, int, struct file_lease **, void **priv); |
208 | int kernel_setlease(struct file *, int, struct file_lease **, void **); |
209 | int vfs_setlease(struct file *, int, struct file_lease **, void **); |
210 | int lease_modify(struct file_lease *, int, struct list_head *); |
211 | |
212 | struct notifier_block; |
213 | int lease_register_notifier(struct notifier_block *); |
214 | void lease_unregister_notifier(struct notifier_block *); |
215 | |
216 | struct files_struct; |
217 | void show_fd_locks(struct seq_file *f, |
218 | struct file *filp, struct files_struct *files); |
219 | bool locks_owner_has_blockers(struct file_lock_context *flctx, |
220 | fl_owner_t owner); |
221 | |
222 | static inline struct file_lock_context * |
223 | locks_inode_context(const struct inode *inode) |
224 | { |
225 | return smp_load_acquire(&inode->i_flctx); |
226 | } |
227 | |
228 | #else /* !CONFIG_FILE_LOCKING */ |
229 | static inline int fcntl_getlk(struct file *file, unsigned int cmd, |
230 | struct flock __user *user) |
231 | { |
232 | return -EINVAL; |
233 | } |
234 | |
235 | static inline int fcntl_setlk(unsigned int fd, struct file *file, |
236 | unsigned int cmd, struct flock __user *user) |
237 | { |
238 | return -EACCES; |
239 | } |
240 | |
241 | #if BITS_PER_LONG == 32 |
242 | static inline int fcntl_getlk64(struct file *file, unsigned int cmd, |
243 | struct flock64 *user) |
244 | { |
245 | return -EINVAL; |
246 | } |
247 | |
248 | static inline int fcntl_setlk64(unsigned int fd, struct file *file, |
249 | unsigned int cmd, struct flock64 *user) |
250 | { |
251 | return -EACCES; |
252 | } |
253 | #endif |
254 | static inline int fcntl_setlease(unsigned int fd, struct file *filp, int arg) |
255 | { |
256 | return -EINVAL; |
257 | } |
258 | |
259 | static inline int fcntl_getlease(struct file *filp) |
260 | { |
261 | return F_UNLCK; |
262 | } |
263 | |
264 | static inline bool lock_is_unlock(struct file_lock *fl) |
265 | { |
266 | return false; |
267 | } |
268 | |
269 | static inline bool lock_is_read(struct file_lock *fl) |
270 | { |
271 | return false; |
272 | } |
273 | |
274 | static inline bool lock_is_write(struct file_lock *fl) |
275 | { |
276 | return false; |
277 | } |
278 | |
279 | static inline void locks_wake_up(struct file_lock *fl) |
280 | { |
281 | } |
282 | |
283 | static inline void |
284 | locks_free_lock_context(struct inode *inode) |
285 | { |
286 | } |
287 | |
288 | static inline void locks_init_lock(struct file_lock *fl) |
289 | { |
290 | return; |
291 | } |
292 | |
293 | static inline void locks_init_lease(struct file_lease *fl) |
294 | { |
295 | return; |
296 | } |
297 | |
298 | static inline void locks_copy_conflock(struct file_lock *new, struct file_lock *fl) |
299 | { |
300 | return; |
301 | } |
302 | |
303 | static inline void locks_copy_lock(struct file_lock *new, struct file_lock *fl) |
304 | { |
305 | return; |
306 | } |
307 | |
308 | static inline void locks_remove_posix(struct file *filp, fl_owner_t owner) |
309 | { |
310 | return; |
311 | } |
312 | |
313 | static inline void locks_remove_file(struct file *filp) |
314 | { |
315 | return; |
316 | } |
317 | |
318 | static inline void posix_test_lock(struct file *filp, struct file_lock *fl) |
319 | { |
320 | return; |
321 | } |
322 | |
323 | static inline int posix_lock_file(struct file *filp, struct file_lock *fl, |
324 | struct file_lock *conflock) |
325 | { |
326 | return -ENOLCK; |
327 | } |
328 | |
329 | static inline int locks_delete_block(struct file_lock *waiter) |
330 | { |
331 | return -ENOENT; |
332 | } |
333 | |
334 | static inline int vfs_test_lock(struct file *filp, struct file_lock *fl) |
335 | { |
336 | return 0; |
337 | } |
338 | |
339 | static inline int vfs_lock_file(struct file *filp, unsigned int cmd, |
340 | struct file_lock *fl, struct file_lock *conf) |
341 | { |
342 | return -ENOLCK; |
343 | } |
344 | |
345 | static inline int vfs_cancel_lock(struct file *filp, struct file_lock *fl) |
346 | { |
347 | return 0; |
348 | } |
349 | |
350 | static inline bool vfs_inode_has_locks(struct inode *inode) |
351 | { |
352 | return false; |
353 | } |
354 | |
355 | static inline int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl) |
356 | { |
357 | return -ENOLCK; |
358 | } |
359 | |
360 | static inline int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) |
361 | { |
362 | return 0; |
363 | } |
364 | |
365 | static inline void lease_get_mtime(struct inode *inode, |
366 | struct timespec64 *time) |
367 | { |
368 | return; |
369 | } |
370 | |
371 | static inline int generic_setlease(struct file *filp, int arg, |
372 | struct file_lease **flp, void **priv) |
373 | { |
374 | return -EINVAL; |
375 | } |
376 | |
377 | static inline int kernel_setlease(struct file *filp, int arg, |
378 | struct file_lease **lease, void **priv) |
379 | { |
380 | return -EINVAL; |
381 | } |
382 | |
383 | static inline int vfs_setlease(struct file *filp, int arg, |
384 | struct file_lease **lease, void **priv) |
385 | { |
386 | return -EINVAL; |
387 | } |
388 | |
389 | static inline int lease_modify(struct file_lease *fl, int arg, |
390 | struct list_head *dispose) |
391 | { |
392 | return -EINVAL; |
393 | } |
394 | |
395 | struct files_struct; |
396 | static inline void show_fd_locks(struct seq_file *f, |
397 | struct file *filp, struct files_struct *files) {} |
398 | static inline bool locks_owner_has_blockers(struct file_lock_context *flctx, |
399 | fl_owner_t owner) |
400 | { |
401 | return false; |
402 | } |
403 | |
404 | static inline struct file_lock_context * |
405 | locks_inode_context(const struct inode *inode) |
406 | { |
407 | return NULL; |
408 | } |
409 | |
410 | #endif /* !CONFIG_FILE_LOCKING */ |
411 | |
412 | /* for walking lists of file_locks linked by fl_list */ |
413 | #define for_each_file_lock(_fl, _head) list_for_each_entry(_fl, _head, c.flc_list) |
414 | |
415 | static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl) |
416 | { |
417 | return locks_lock_inode_wait(inode: file_inode(f: filp), fl); |
418 | } |
419 | |
420 | #ifdef CONFIG_FILE_LOCKING |
421 | static inline int break_lease(struct inode *inode, unsigned int mode) |
422 | { |
423 | /* |
424 | * Since this check is lockless, we must ensure that any refcounts |
425 | * taken are done before checking i_flctx->flc_lease. Otherwise, we |
426 | * could end up racing with tasks trying to set a new lease on this |
427 | * file. |
428 | */ |
429 | smp_mb(); |
430 | if (inode->i_flctx && !list_empty_careful(head: &inode->i_flctx->flc_lease)) |
431 | return __break_lease(inode, flags: mode, FL_LEASE); |
432 | return 0; |
433 | } |
434 | |
435 | static inline int break_deleg(struct inode *inode, unsigned int mode) |
436 | { |
437 | /* |
438 | * Since this check is lockless, we must ensure that any refcounts |
439 | * taken are done before checking i_flctx->flc_lease. Otherwise, we |
440 | * could end up racing with tasks trying to set a new lease on this |
441 | * file. |
442 | */ |
443 | smp_mb(); |
444 | if (inode->i_flctx && !list_empty_careful(head: &inode->i_flctx->flc_lease)) |
445 | return __break_lease(inode, flags: mode, FL_DELEG); |
446 | return 0; |
447 | } |
448 | |
449 | static inline int try_break_deleg(struct inode *inode, struct inode **delegated_inode) |
450 | { |
451 | int ret; |
452 | |
453 | ret = break_deleg(inode, O_WRONLY|O_NONBLOCK); |
454 | if (ret == -EWOULDBLOCK && delegated_inode) { |
455 | *delegated_inode = inode; |
456 | ihold(inode); |
457 | } |
458 | return ret; |
459 | } |
460 | |
461 | static inline int break_deleg_wait(struct inode **delegated_inode) |
462 | { |
463 | int ret; |
464 | |
465 | ret = break_deleg(inode: *delegated_inode, O_WRONLY); |
466 | iput(*delegated_inode); |
467 | *delegated_inode = NULL; |
468 | return ret; |
469 | } |
470 | |
471 | static inline int break_layout(struct inode *inode, bool wait) |
472 | { |
473 | smp_mb(); |
474 | if (inode->i_flctx && !list_empty_careful(head: &inode->i_flctx->flc_lease)) |
475 | return __break_lease(inode, |
476 | flags: wait ? O_WRONLY : O_WRONLY | O_NONBLOCK, |
477 | FL_LAYOUT); |
478 | return 0; |
479 | } |
480 | |
481 | #else /* !CONFIG_FILE_LOCKING */ |
482 | static inline int break_lease(struct inode *inode, unsigned int mode) |
483 | { |
484 | return 0; |
485 | } |
486 | |
487 | static inline int break_deleg(struct inode *inode, unsigned int mode) |
488 | { |
489 | return 0; |
490 | } |
491 | |
492 | static inline int try_break_deleg(struct inode *inode, struct inode **delegated_inode) |
493 | { |
494 | return 0; |
495 | } |
496 | |
497 | static inline int break_deleg_wait(struct inode **delegated_inode) |
498 | { |
499 | BUG(); |
500 | return 0; |
501 | } |
502 | |
503 | static inline int break_layout(struct inode *inode, bool wait) |
504 | { |
505 | return 0; |
506 | } |
507 | |
508 | #endif /* CONFIG_FILE_LOCKING */ |
509 | |
510 | #endif /* _LINUX_FILELOCK_H */ |
511 | |