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.

filelock: rework the __break_lease API to use flags

Currently __break_lease takes both a type and an openmode. With the
addition of directory leases, that makes less sense. Declare a set of
LEASE_BREAK_* flags that can be used to control how lease breaks work
instead of requiring a type and an openmode.

Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: NeilBrown <neil@brown.name>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20251111-dir-deleg-ro-v6-2-52f3feebb2f2@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Jeff Layton and committed by
Christian Brauner
4be9f3cc 6fc5f2b1

+56 -25
+18 -11
fs/locks.c
··· 1529 1529 /** 1530 1530 * __break_lease - revoke all outstanding leases on file 1531 1531 * @inode: the inode of the file to return 1532 - * @mode: O_RDONLY: break only write leases; O_WRONLY or O_RDWR: 1533 - * break all leases 1534 - * @type: FL_LEASE: break leases and delegations; FL_DELEG: break 1535 - * only delegations 1532 + * @flags: LEASE_BREAK_* flags 1536 1533 * 1537 1534 * break_lease (inlined for speed) has checked there already is at least 1538 1535 * some kind of lock (maybe a lease) on this file. Leases are broken on 1539 - * a call to open() or truncate(). This function can sleep unless you 1540 - * specified %O_NONBLOCK to your open(). 1536 + * a call to open() or truncate(). This function can block waiting for the 1537 + * lease break unless you specify LEASE_BREAK_NONBLOCK. 1541 1538 */ 1542 - int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) 1539 + int __break_lease(struct inode *inode, unsigned int flags) 1543 1540 { 1544 - int error = 0; 1545 - struct file_lock_context *ctx; 1546 1541 struct file_lease *new_fl, *fl, *tmp; 1542 + struct file_lock_context *ctx; 1547 1543 unsigned long break_time; 1548 - int want_write = (mode & O_ACCMODE) != O_RDONLY; 1544 + unsigned int type; 1549 1545 LIST_HEAD(dispose); 1546 + bool want_write = !(flags & LEASE_BREAK_OPEN_RDONLY); 1547 + int error = 0; 1548 + 1549 + if (flags & LEASE_BREAK_LEASE) 1550 + type = FL_LEASE; 1551 + else if (flags & LEASE_BREAK_DELEG) 1552 + type = FL_DELEG; 1553 + else if (flags & LEASE_BREAK_LAYOUT) 1554 + type = FL_LAYOUT; 1555 + else 1556 + return -EINVAL; 1550 1557 1551 1558 new_fl = lease_alloc(NULL, type, want_write ? F_WRLCK : F_RDLCK); 1552 1559 if (IS_ERR(new_fl)) ··· 1602 1595 if (list_empty(&ctx->flc_lease)) 1603 1596 goto out; 1604 1597 1605 - if (mode & O_NONBLOCK) { 1598 + if (flags & LEASE_BREAK_NONBLOCK) { 1606 1599 trace_break_lease_noblock(inode, new_fl); 1607 1600 error = -EWOULDBLOCK; 1608 1601 goto out;
+38 -14
include/linux/filelock.h
··· 212 212 void locks_init_lease(struct file_lease *); 213 213 void locks_free_lease(struct file_lease *fl); 214 214 struct file_lease *locks_alloc_lease(void); 215 - int __break_lease(struct inode *inode, unsigned int flags, unsigned int type); 215 + 216 + #define LEASE_BREAK_LEASE BIT(0) // break leases and delegations 217 + #define LEASE_BREAK_DELEG BIT(1) // break delegations only 218 + #define LEASE_BREAK_LAYOUT BIT(2) // break layouts only 219 + #define LEASE_BREAK_NONBLOCK BIT(3) // non-blocking break 220 + #define LEASE_BREAK_OPEN_RDONLY BIT(4) // readonly open event 221 + 222 + int __break_lease(struct inode *inode, unsigned int flags); 216 223 void lease_get_mtime(struct inode *, struct timespec64 *time); 217 224 int generic_setlease(struct file *, int, struct file_lease **, void **priv); 218 225 int kernel_setlease(struct file *, int, struct file_lease **, void **); ··· 374 367 return -ENOLCK; 375 368 } 376 369 377 - static inline int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) 370 + static inline int __break_lease(struct inode *inode, unsigned int flags) 378 371 { 379 372 return 0; 380 373 } ··· 435 428 } 436 429 437 430 #ifdef CONFIG_FILE_LOCKING 431 + static inline unsigned int openmode_to_lease_flags(unsigned int mode) 432 + { 433 + unsigned int flags = 0; 434 + 435 + if ((mode & O_ACCMODE) == O_RDONLY) 436 + flags |= LEASE_BREAK_OPEN_RDONLY; 437 + if (mode & O_NONBLOCK) 438 + flags |= LEASE_BREAK_NONBLOCK; 439 + return flags; 440 + } 441 + 438 442 static inline int break_lease(struct inode *inode, unsigned int mode) 439 443 { 440 444 struct file_lock_context *flctx; ··· 461 443 return 0; 462 444 smp_mb(); 463 445 if (!list_empty_careful(&flctx->flc_lease)) 464 - return __break_lease(inode, mode, FL_LEASE); 446 + return __break_lease(inode, LEASE_BREAK_LEASE | openmode_to_lease_flags(mode)); 465 447 return 0; 466 448 } 467 449 468 - static inline int break_deleg(struct inode *inode, unsigned int mode) 450 + static inline int break_deleg(struct inode *inode, unsigned int flags) 469 451 { 470 452 struct file_lock_context *flctx; 471 453 ··· 479 461 if (!flctx) 480 462 return 0; 481 463 smp_mb(); 482 - if (!list_empty_careful(&flctx->flc_lease)) 483 - return __break_lease(inode, mode, FL_DELEG); 464 + if (!list_empty_careful(&flctx->flc_lease)) { 465 + flags |= LEASE_BREAK_DELEG; 466 + return __break_lease(inode, flags); 467 + } 484 468 return 0; 485 469 } 486 470 ··· 490 470 { 491 471 int ret; 492 472 493 - ret = break_deleg(inode, O_WRONLY|O_NONBLOCK); 473 + ret = break_deleg(inode, LEASE_BREAK_NONBLOCK); 494 474 if (ret == -EWOULDBLOCK && delegated_inode) { 495 475 *delegated_inode = inode; 496 476 ihold(inode); ··· 502 482 { 503 483 int ret; 504 484 505 - ret = break_deleg(*delegated_inode, O_WRONLY); 485 + ret = break_deleg(*delegated_inode, 0); 506 486 iput(*delegated_inode); 507 487 *delegated_inode = NULL; 508 488 return ret; ··· 511 491 static inline int break_layout(struct inode *inode, bool wait) 512 492 { 513 493 smp_mb(); 514 - if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease)) 515 - return __break_lease(inode, 516 - wait ? O_WRONLY : O_WRONLY | O_NONBLOCK, 517 - FL_LAYOUT); 494 + if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease)) { 495 + unsigned int flags = LEASE_BREAK_LAYOUT; 496 + 497 + if (!wait) 498 + flags |= LEASE_BREAK_NONBLOCK; 499 + 500 + return __break_lease(inode, flags); 501 + } 518 502 return 0; 519 503 } 520 504 521 505 #else /* !CONFIG_FILE_LOCKING */ 522 - static inline int break_lease(struct inode *inode, unsigned int mode) 506 + static inline int break_lease(struct inode *inode, bool wait) 523 507 { 524 508 return 0; 525 509 } 526 510 527 - static inline int break_deleg(struct inode *inode, unsigned int mode) 511 + static inline int break_deleg(struct inode *inode, unsigned int flags) 528 512 { 529 513 return 0; 530 514 }