Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 703ccb63ae9f7444d6ff876d024e17f628103c69 595 lines 15 kB view raw
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 29struct file_lock; 30struct file_lease; 31 32struct file_lock_operations { 33 void (*fl_copy_lock)(struct file_lock *, struct file_lock *); 34 void (*fl_release_private)(struct file_lock *); 35}; 36 37struct 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 47struct 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 int (*lm_open_conflict)(struct file *, int); 53}; 54 55struct lock_manager { 56 struct list_head list; 57 /* 58 * NFSv4 and up also want opens blocked during the grace period; 59 * NLM doesn't care: 60 */ 61 bool block_opens; 62}; 63 64struct net; 65void locks_start_grace(struct net *, struct lock_manager *); 66void locks_end_grace(struct lock_manager *); 67bool locks_in_grace(struct net *); 68bool opens_in_grace(struct net *); 69 70/* 71 * struct file_lock has a union that some filesystems use to track 72 * their own private info. The NFS side of things is defined here: 73 */ 74#include <linux/nfs_fs_i.h> 75 76/* 77 * struct file_lock represents a generic "file lock". It's used to represent 78 * POSIX byte range locks, BSD (flock) locks, and leases. It's important to 79 * note that the same struct is used to represent both a request for a lock and 80 * the lock itself, but the same object is never used for both. 81 * 82 * FIXME: should we create a separate "struct lock_request" to help distinguish 83 * these two uses? 84 * 85 * The varous i_flctx lists are ordered by: 86 * 87 * 1) lock owner 88 * 2) lock range start 89 * 3) lock range end 90 * 91 * Obviously, the last two criteria only matter for POSIX locks. 92 */ 93 94struct file_lock_core { 95 struct file_lock_core *flc_blocker; /* The lock that is blocking us */ 96 struct list_head flc_list; /* link into file_lock_context */ 97 struct hlist_node flc_link; /* node in global lists */ 98 struct list_head flc_blocked_requests; /* list of requests with 99 * ->fl_blocker pointing here 100 */ 101 struct list_head flc_blocked_member; /* node in 102 * ->fl_blocker->fl_blocked_requests 103 */ 104 fl_owner_t flc_owner; 105 unsigned int flc_flags; 106 unsigned char flc_type; 107 pid_t flc_pid; 108 int flc_link_cpu; /* what cpu's list is this on? */ 109 wait_queue_head_t flc_wait; 110 struct file *flc_file; 111}; 112 113struct file_lock { 114 struct file_lock_core c; 115 loff_t fl_start; 116 loff_t fl_end; 117 118 const struct file_lock_operations *fl_ops; /* Callbacks for filesystems */ 119 const struct lock_manager_operations *fl_lmops; /* Callbacks for lockmanagers */ 120 union { 121 struct nfs_lock_info nfs_fl; 122 struct nfs4_lock_info nfs4_fl; 123 struct { 124 struct list_head link; /* link in AFS vnode's pending_locks list */ 125 int state; /* state of grant or error if -ve */ 126 unsigned int debug_id; 127 } afs; 128 struct { 129 struct inode *inode; 130 } ceph; 131 } fl_u; 132} __randomize_layout; 133 134struct file_lease { 135 struct file_lock_core c; 136 struct fasync_struct * fl_fasync; /* for lease break notifications */ 137 /* for lease breaks: */ 138 unsigned long fl_break_time; 139 unsigned long fl_downgrade_time; 140 const struct lease_manager_operations *fl_lmops; /* Callbacks for lease managers */ 141} __randomize_layout; 142 143struct file_lock_context { 144 spinlock_t flc_lock; 145 struct list_head flc_flock; 146 struct list_head flc_posix; 147 struct list_head flc_lease; 148}; 149 150#ifdef CONFIG_FILE_LOCKING 151int fcntl_getlk(struct file *, unsigned int, struct flock *); 152int fcntl_setlk(unsigned int, struct file *, unsigned int, 153 struct flock *); 154 155#if BITS_PER_LONG == 32 156int fcntl_getlk64(struct file *, unsigned int, struct flock64 *); 157int fcntl_setlk64(unsigned int, struct file *, unsigned int, 158 struct flock64 *); 159#endif 160 161int fcntl_setlease(unsigned int fd, struct file *filp, int arg); 162int fcntl_getlease(struct file *filp); 163int fcntl_setdeleg(unsigned int fd, struct file *filp, struct delegation *deleg); 164int fcntl_getdeleg(struct file *filp, struct delegation *deleg); 165 166static inline bool lock_is_unlock(struct file_lock *fl) 167{ 168 return fl->c.flc_type == F_UNLCK; 169} 170 171static inline bool lock_is_read(struct file_lock *fl) 172{ 173 return fl->c.flc_type == F_RDLCK; 174} 175 176static inline bool lock_is_write(struct file_lock *fl) 177{ 178 return fl->c.flc_type == F_WRLCK; 179} 180 181static inline void locks_wake_up_waiter(struct file_lock_core *flc) 182{ 183 wake_up(&flc->flc_wait); 184} 185 186static inline void locks_wake_up(struct file_lock *fl) 187{ 188 locks_wake_up_waiter(&fl->c); 189} 190 191static inline bool locks_can_async_lock(const struct file_operations *fops) 192{ 193 return !fops->lock || fops->fop_flags & FOP_ASYNC_LOCK; 194} 195 196/* fs/locks.c */ 197void locks_free_lock_context(struct inode *inode); 198void locks_free_lock(struct file_lock *fl); 199void locks_init_lock(struct file_lock *); 200struct file_lock *locks_alloc_lock(void); 201void locks_copy_lock(struct file_lock *, struct file_lock *); 202void locks_copy_conflock(struct file_lock *, struct file_lock *); 203void locks_remove_posix(struct file *, fl_owner_t); 204void locks_remove_file(struct file *); 205void locks_release_private(struct file_lock *); 206void posix_test_lock(struct file *, struct file_lock *); 207int posix_lock_file(struct file *, struct file_lock *, struct file_lock *); 208int locks_delete_block(struct file_lock *); 209int vfs_test_lock(struct file *, struct file_lock *); 210int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *); 211int vfs_cancel_lock(struct file *filp, struct file_lock *fl); 212bool vfs_inode_has_locks(struct inode *inode); 213int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl); 214 215void locks_init_lease(struct file_lease *); 216void locks_free_lease(struct file_lease *fl); 217struct file_lease *locks_alloc_lease(void); 218 219#define LEASE_BREAK_LEASE BIT(0) // break leases and delegations 220#define LEASE_BREAK_DELEG BIT(1) // break delegations only 221#define LEASE_BREAK_LAYOUT BIT(2) // break layouts only 222#define LEASE_BREAK_NONBLOCK BIT(3) // non-blocking break 223#define LEASE_BREAK_OPEN_RDONLY BIT(4) // readonly open event 224 225int __break_lease(struct inode *inode, unsigned int flags); 226void lease_get_mtime(struct inode *, struct timespec64 *time); 227int generic_setlease(struct file *, int, struct file_lease **, void **priv); 228int kernel_setlease(struct file *, int, struct file_lease **, void **); 229int vfs_setlease(struct file *, int, struct file_lease **, void **); 230int lease_modify(struct file_lease *, int, struct list_head *); 231 232struct notifier_block; 233int lease_register_notifier(struct notifier_block *); 234void lease_unregister_notifier(struct notifier_block *); 235 236struct files_struct; 237void show_fd_locks(struct seq_file *f, 238 struct file *filp, struct files_struct *files); 239bool locks_owner_has_blockers(struct file_lock_context *flctx, 240 fl_owner_t owner); 241 242static inline struct file_lock_context * 243locks_inode_context(const struct inode *inode) 244{ 245 /* 246 * Paired with smp_store_release in locks_get_lock_context(). 247 * 248 * Ensures ->i_flctx will be visible if we spotted the flag. 249 */ 250 if (likely(!(smp_load_acquire(&inode->i_opflags) & IOP_FLCTX))) 251 return NULL; 252 return READ_ONCE(inode->i_flctx); 253} 254 255#else /* !CONFIG_FILE_LOCKING */ 256static inline int fcntl_getlk(struct file *file, unsigned int cmd, 257 struct flock __user *user) 258{ 259 return -EINVAL; 260} 261 262static inline int fcntl_setlk(unsigned int fd, struct file *file, 263 unsigned int cmd, struct flock __user *user) 264{ 265 return -EACCES; 266} 267 268#if BITS_PER_LONG == 32 269static inline int fcntl_getlk64(struct file *file, unsigned int cmd, 270 struct flock64 *user) 271{ 272 return -EINVAL; 273} 274 275static inline int fcntl_setlk64(unsigned int fd, struct file *file, 276 unsigned int cmd, struct flock64 *user) 277{ 278 return -EACCES; 279} 280#endif 281static inline int fcntl_setlease(unsigned int fd, struct file *filp, int arg) 282{ 283 return -EINVAL; 284} 285 286static inline int fcntl_getlease(struct file *filp) 287{ 288 return F_UNLCK; 289} 290 291static inline int fcntl_setdeleg(unsigned int fd, struct file *filp, struct delegation *deleg) 292{ 293 return -EINVAL; 294} 295 296static inline int fcntl_getdeleg(struct file *filp, struct delegation *deleg) 297{ 298 return -EINVAL; 299} 300 301static inline bool lock_is_unlock(struct file_lock *fl) 302{ 303 return false; 304} 305 306static inline bool lock_is_read(struct file_lock *fl) 307{ 308 return false; 309} 310 311static inline bool lock_is_write(struct file_lock *fl) 312{ 313 return false; 314} 315 316static inline void locks_wake_up(struct file_lock *fl) 317{ 318} 319 320static inline void 321locks_free_lock_context(struct inode *inode) 322{ 323} 324 325static inline void locks_init_lock(struct file_lock *fl) 326{ 327 return; 328} 329 330static inline void locks_init_lease(struct file_lease *fl) 331{ 332 return; 333} 334 335static inline void locks_copy_conflock(struct file_lock *new, struct file_lock *fl) 336{ 337 return; 338} 339 340static inline void locks_copy_lock(struct file_lock *new, struct file_lock *fl) 341{ 342 return; 343} 344 345static inline void locks_remove_posix(struct file *filp, fl_owner_t owner) 346{ 347 return; 348} 349 350static inline void locks_remove_file(struct file *filp) 351{ 352 return; 353} 354 355static inline void posix_test_lock(struct file *filp, struct file_lock *fl) 356{ 357 return; 358} 359 360static inline int posix_lock_file(struct file *filp, struct file_lock *fl, 361 struct file_lock *conflock) 362{ 363 return -ENOLCK; 364} 365 366static inline int locks_delete_block(struct file_lock *waiter) 367{ 368 return -ENOENT; 369} 370 371static inline int vfs_test_lock(struct file *filp, struct file_lock *fl) 372{ 373 return 0; 374} 375 376static inline int vfs_lock_file(struct file *filp, unsigned int cmd, 377 struct file_lock *fl, struct file_lock *conf) 378{ 379 return -ENOLCK; 380} 381 382static inline int vfs_cancel_lock(struct file *filp, struct file_lock *fl) 383{ 384 return 0; 385} 386 387static inline bool vfs_inode_has_locks(struct inode *inode) 388{ 389 return false; 390} 391 392static inline int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl) 393{ 394 return -ENOLCK; 395} 396 397static inline int __break_lease(struct inode *inode, unsigned int flags) 398{ 399 return 0; 400} 401 402static inline void lease_get_mtime(struct inode *inode, 403 struct timespec64 *time) 404{ 405 return; 406} 407 408static inline int generic_setlease(struct file *filp, int arg, 409 struct file_lease **flp, void **priv) 410{ 411 return -EINVAL; 412} 413 414static inline int kernel_setlease(struct file *filp, int arg, 415 struct file_lease **lease, void **priv) 416{ 417 return -EINVAL; 418} 419 420static inline int vfs_setlease(struct file *filp, int arg, 421 struct file_lease **lease, void **priv) 422{ 423 return -EINVAL; 424} 425 426static inline int lease_modify(struct file_lease *fl, int arg, 427 struct list_head *dispose) 428{ 429 return -EINVAL; 430} 431 432struct files_struct; 433static inline void show_fd_locks(struct seq_file *f, 434 struct file *filp, struct files_struct *files) {} 435static inline bool locks_owner_has_blockers(struct file_lock_context *flctx, 436 fl_owner_t owner) 437{ 438 return false; 439} 440 441static inline struct file_lock_context * 442locks_inode_context(const struct inode *inode) 443{ 444 return NULL; 445} 446 447#endif /* !CONFIG_FILE_LOCKING */ 448 449/* for walking lists of file_locks linked by fl_list */ 450#define for_each_file_lock(_fl, _head) list_for_each_entry(_fl, _head, c.flc_list) 451 452static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl) 453{ 454 return locks_lock_inode_wait(file_inode(filp), fl); 455} 456 457#ifdef CONFIG_FILE_LOCKING 458static inline unsigned int openmode_to_lease_flags(unsigned int mode) 459{ 460 unsigned int flags = 0; 461 462 if ((mode & O_ACCMODE) == O_RDONLY) 463 flags |= LEASE_BREAK_OPEN_RDONLY; 464 if (mode & O_NONBLOCK) 465 flags |= LEASE_BREAK_NONBLOCK; 466 return flags; 467} 468 469static inline int break_lease(struct inode *inode, unsigned int mode) 470{ 471 struct file_lock_context *flctx; 472 473 /* 474 * Since this check is lockless, we must ensure that any refcounts 475 * taken are done before checking i_flctx->flc_lease. Otherwise, we 476 * could end up racing with tasks trying to set a new lease on this 477 * file. 478 */ 479 flctx = locks_inode_context(inode); 480 if (!flctx) 481 return 0; 482 smp_mb(); 483 if (!list_empty_careful(&flctx->flc_lease)) 484 return __break_lease(inode, LEASE_BREAK_LEASE | openmode_to_lease_flags(mode)); 485 return 0; 486} 487 488static inline int break_deleg(struct inode *inode, unsigned int flags) 489{ 490 struct file_lock_context *flctx; 491 492 /* 493 * Since this check is lockless, we must ensure that any refcounts 494 * taken are done before checking i_flctx->flc_lease. Otherwise, we 495 * could end up racing with tasks trying to set a new lease on this 496 * file. 497 */ 498 flctx = locks_inode_context(inode); 499 if (!flctx) 500 return 0; 501 smp_mb(); 502 if (!list_empty_careful(&flctx->flc_lease)) { 503 flags |= LEASE_BREAK_DELEG; 504 return __break_lease(inode, flags); 505 } 506 return 0; 507} 508 509struct delegated_inode { 510 struct inode *di_inode; 511}; 512 513static inline bool is_delegated(struct delegated_inode *di) 514{ 515 return di->di_inode; 516} 517 518static inline int try_break_deleg(struct inode *inode, 519 struct delegated_inode *di) 520{ 521 int ret; 522 523 ret = break_deleg(inode, LEASE_BREAK_NONBLOCK); 524 if (ret == -EWOULDBLOCK && di) { 525 di->di_inode = inode; 526 ihold(inode); 527 } 528 return ret; 529} 530 531static inline int break_deleg_wait(struct delegated_inode *di) 532{ 533 int ret; 534 535 ret = break_deleg(di->di_inode, 0); 536 iput(di->di_inode); 537 di->di_inode = NULL; 538 return ret; 539} 540 541static inline int break_layout(struct inode *inode, bool wait) 542{ 543 struct file_lock_context *flctx; 544 545 smp_mb(); 546 flctx = locks_inode_context(inode); 547 if (flctx && !list_empty_careful(&flctx->flc_lease)) { 548 unsigned int flags = LEASE_BREAK_LAYOUT; 549 550 if (!wait) 551 flags |= LEASE_BREAK_NONBLOCK; 552 553 return __break_lease(inode, flags); 554 } 555 return 0; 556} 557 558#else /* !CONFIG_FILE_LOCKING */ 559struct delegated_inode { }; 560 561static inline bool is_delegated(struct delegated_inode *di) 562{ 563 return false; 564} 565 566static inline int break_lease(struct inode *inode, bool wait) 567{ 568 return 0; 569} 570 571static inline int break_deleg(struct inode *inode, unsigned int flags) 572{ 573 return 0; 574} 575 576static inline int try_break_deleg(struct inode *inode, 577 struct delegated_inode *delegated_inode) 578{ 579 return 0; 580} 581 582static inline int break_deleg_wait(struct delegated_inode *delegated_inode) 583{ 584 BUG(); 585 return 0; 586} 587 588static inline int break_layout(struct inode *inode, bool wait) 589{ 590 return 0; 591} 592 593#endif /* CONFIG_FILE_LOCKING */ 594 595#endif /* _LINUX_FILELOCK_H */