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: add struct delegated_inode

The current API requires a pointer to an inode pointer. It's easy for
callers to get this wrong. Add a new delegated_inode structure and use
that to pass back any inode that needs to be waited on.

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-3-52f3feebb2f2@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Jeff Layton and committed by
Christian Brauner
6976ed2d 4be9f3cc

+60 -41
+1 -1
fs/attr.c
··· 415 415 * performed on the raw inode simply pass @nop_mnt_idmap. 416 416 */ 417 417 int notify_change(struct mnt_idmap *idmap, struct dentry *dentry, 418 - struct iattr *attr, struct inode **delegated_inode) 418 + struct iattr *attr, struct delegated_inode *delegated_inode) 419 419 { 420 420 struct inode *inode = dentry->d_inode; 421 421 umode_t mode = inode->i_mode;
+9 -9
fs/namei.c
··· 4648 4648 * raw inode simply pass @nop_mnt_idmap. 4649 4649 */ 4650 4650 int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir, 4651 - struct dentry *dentry, struct inode **delegated_inode) 4651 + struct dentry *dentry, struct delegated_inode *delegated_inode) 4652 4652 { 4653 4653 struct inode *target = dentry->d_inode; 4654 4654 int error = may_delete(idmap, dir, dentry, 0); ··· 4706 4706 struct qstr last; 4707 4707 int type; 4708 4708 struct inode *inode = NULL; 4709 - struct inode *delegated_inode = NULL; 4709 + struct delegated_inode delegated_inode = { }; 4710 4710 unsigned int lookup_flags = 0; 4711 4711 retry: 4712 4712 error = filename_parentat(dfd, name, lookup_flags, &path, &last, &type); ··· 4743 4743 if (inode) 4744 4744 iput(inode); /* truncate the inode here */ 4745 4745 inode = NULL; 4746 - if (delegated_inode) { 4746 + if (is_delegated(&delegated_inode)) { 4747 4747 error = break_deleg_wait(&delegated_inode); 4748 4748 if (!error) 4749 4749 goto retry_deleg; ··· 4892 4892 */ 4893 4893 int vfs_link(struct dentry *old_dentry, struct mnt_idmap *idmap, 4894 4894 struct inode *dir, struct dentry *new_dentry, 4895 - struct inode **delegated_inode) 4895 + struct delegated_inode *delegated_inode) 4896 4896 { 4897 4897 struct inode *inode = old_dentry->d_inode; 4898 4898 unsigned max_links = dir->i_sb->s_max_links; ··· 4968 4968 struct mnt_idmap *idmap; 4969 4969 struct dentry *new_dentry; 4970 4970 struct path old_path, new_path; 4971 - struct inode *delegated_inode = NULL; 4971 + struct delegated_inode delegated_inode = { }; 4972 4972 int how = 0; 4973 4973 int error; 4974 4974 ··· 5012 5012 new_dentry, &delegated_inode); 5013 5013 out_dput: 5014 5014 end_creating_path(&new_path, new_dentry); 5015 - if (delegated_inode) { 5015 + if (is_delegated(&delegated_inode)) { 5016 5016 error = break_deleg_wait(&delegated_inode); 5017 5017 if (!error) { 5018 5018 path_put(&old_path); ··· 5098 5098 struct inode *new_dir = d_inode(rd->new_parent); 5099 5099 struct dentry *old_dentry = rd->old_dentry; 5100 5100 struct dentry *new_dentry = rd->new_dentry; 5101 - struct inode **delegated_inode = rd->delegated_inode; 5101 + struct delegated_inode *delegated_inode = rd->delegated_inode; 5102 5102 unsigned int flags = rd->flags; 5103 5103 bool is_dir = d_is_dir(old_dentry); 5104 5104 struct inode *source = old_dentry->d_inode; ··· 5261 5261 struct path old_path, new_path; 5262 5262 struct qstr old_last, new_last; 5263 5263 int old_type, new_type; 5264 - struct inode *delegated_inode = NULL; 5264 + struct delegated_inode delegated_inode = { }; 5265 5265 unsigned int lookup_flags = 0, target_flags = 5266 5266 LOOKUP_RENAME_TARGET | LOOKUP_CREATE; 5267 5267 bool should_retry = false; ··· 5369 5369 exit3: 5370 5370 unlock_rename(new_path.dentry, old_path.dentry); 5371 5371 exit_lock_rename: 5372 - if (delegated_inode) { 5372 + if (is_delegated(&delegated_inode)) { 5373 5373 error = break_deleg_wait(&delegated_inode); 5374 5374 if (!error) 5375 5375 goto retry_deleg;
+4 -4
fs/open.c
··· 631 631 int chmod_common(const struct path *path, umode_t mode) 632 632 { 633 633 struct inode *inode = path->dentry->d_inode; 634 - struct inode *delegated_inode = NULL; 634 + struct delegated_inode delegated_inode = { }; 635 635 struct iattr newattrs; 636 636 int error; 637 637 ··· 651 651 &newattrs, &delegated_inode); 652 652 out_unlock: 653 653 inode_unlock(inode); 654 - if (delegated_inode) { 654 + if (is_delegated(&delegated_inode)) { 655 655 error = break_deleg_wait(&delegated_inode); 656 656 if (!error) 657 657 goto retry_deleg; ··· 756 756 struct mnt_idmap *idmap; 757 757 struct user_namespace *fs_userns; 758 758 struct inode *inode = path->dentry->d_inode; 759 - struct inode *delegated_inode = NULL; 759 + struct delegated_inode delegated_inode = { }; 760 760 int error; 761 761 struct iattr newattrs; 762 762 kuid_t uid; ··· 791 791 error = notify_change(idmap, path->dentry, &newattrs, 792 792 &delegated_inode); 793 793 inode_unlock(inode); 794 - if (delegated_inode) { 794 + if (is_delegated(&delegated_inode)) { 795 795 error = break_deleg_wait(&delegated_inode); 796 796 if (!error) 797 797 goto retry_deleg;
+4 -4
fs/posix_acl.c
··· 1091 1091 int acl_type; 1092 1092 int error; 1093 1093 struct inode *inode = d_inode(dentry); 1094 - struct inode *delegated_inode = NULL; 1094 + struct delegated_inode delegated_inode = { }; 1095 1095 1096 1096 acl_type = posix_acl_type(acl_name); 1097 1097 if (acl_type < 0) ··· 1141 1141 out_inode_unlock: 1142 1142 inode_unlock(inode); 1143 1143 1144 - if (delegated_inode) { 1144 + if (is_delegated(&delegated_inode)) { 1145 1145 error = break_deleg_wait(&delegated_inode); 1146 1146 if (!error) 1147 1147 goto retry_deleg; ··· 1212 1212 int acl_type; 1213 1213 int error; 1214 1214 struct inode *inode = d_inode(dentry); 1215 - struct inode *delegated_inode = NULL; 1215 + struct delegated_inode delegated_inode = { }; 1216 1216 1217 1217 acl_type = posix_acl_type(acl_name); 1218 1218 if (acl_type < 0) ··· 1249 1249 out_inode_unlock: 1250 1250 inode_unlock(inode); 1251 1251 1252 - if (delegated_inode) { 1252 + if (is_delegated(&delegated_inode)) { 1253 1253 error = break_deleg_wait(&delegated_inode); 1254 1254 if (!error) 1255 1255 goto retry_deleg;
+2 -2
fs/utimes.c
··· 22 22 int error; 23 23 struct iattr newattrs; 24 24 struct inode *inode = path->dentry->d_inode; 25 - struct inode *delegated_inode = NULL; 25 + struct delegated_inode delegated_inode = { }; 26 26 27 27 if (times) { 28 28 if (!nsec_valid(times[0].tv_nsec) || ··· 66 66 error = notify_change(mnt_idmap(path->mnt), path->dentry, &newattrs, 67 67 &delegated_inode); 68 68 inode_unlock(inode); 69 - if (delegated_inode) { 69 + if (is_delegated(&delegated_inode)) { 70 70 error = break_deleg_wait(&delegated_inode); 71 71 if (!error) 72 72 goto retry_deleg;
+6 -6
fs/xattr.c
··· 274 274 int 275 275 __vfs_setxattr_locked(struct mnt_idmap *idmap, struct dentry *dentry, 276 276 const char *name, const void *value, size_t size, 277 - int flags, struct inode **delegated_inode) 277 + int flags, struct delegated_inode *delegated_inode) 278 278 { 279 279 struct inode *inode = dentry->d_inode; 280 280 int error; ··· 305 305 const char *name, const void *value, size_t size, int flags) 306 306 { 307 307 struct inode *inode = dentry->d_inode; 308 - struct inode *delegated_inode = NULL; 308 + struct delegated_inode delegated_inode = { }; 309 309 const void *orig_value = value; 310 310 int error; 311 311 ··· 322 322 flags, &delegated_inode); 323 323 inode_unlock(inode); 324 324 325 - if (delegated_inode) { 325 + if (is_delegated(&delegated_inode)) { 326 326 error = break_deleg_wait(&delegated_inode); 327 327 if (!error) 328 328 goto retry_deleg; ··· 533 533 int 534 534 __vfs_removexattr_locked(struct mnt_idmap *idmap, 535 535 struct dentry *dentry, const char *name, 536 - struct inode **delegated_inode) 536 + struct delegated_inode *delegated_inode) 537 537 { 538 538 struct inode *inode = dentry->d_inode; 539 539 int error; ··· 567 567 const char *name) 568 568 { 569 569 struct inode *inode = dentry->d_inode; 570 - struct inode *delegated_inode = NULL; 570 + struct delegated_inode delegated_inode = { }; 571 571 int error; 572 572 573 573 retry_deleg: ··· 576 576 name, &delegated_inode); 577 577 inode_unlock(inode); 578 578 579 - if (delegated_inode) { 579 + if (is_delegated(&delegated_inode)) { 580 580 error = break_deleg_wait(&delegated_inode); 581 581 if (!error) 582 582 goto retry_deleg;
+27 -9
include/linux/filelock.h
··· 486 486 return 0; 487 487 } 488 488 489 - static inline int try_break_deleg(struct inode *inode, struct inode **delegated_inode) 489 + struct delegated_inode { 490 + struct inode *di_inode; 491 + }; 492 + 493 + static inline bool is_delegated(struct delegated_inode *di) 494 + { 495 + return di->di_inode; 496 + } 497 + 498 + static inline int try_break_deleg(struct inode *inode, 499 + struct delegated_inode *di) 490 500 { 491 501 int ret; 492 502 493 503 ret = break_deleg(inode, LEASE_BREAK_NONBLOCK); 494 - if (ret == -EWOULDBLOCK && delegated_inode) { 495 - *delegated_inode = inode; 504 + if (ret == -EWOULDBLOCK && di) { 505 + di->di_inode = inode; 496 506 ihold(inode); 497 507 } 498 508 return ret; 499 509 } 500 510 501 - static inline int break_deleg_wait(struct inode **delegated_inode) 511 + static inline int break_deleg_wait(struct delegated_inode *di) 502 512 { 503 513 int ret; 504 514 505 - ret = break_deleg(*delegated_inode, 0); 506 - iput(*delegated_inode); 507 - *delegated_inode = NULL; 515 + ret = break_deleg(di->di_inode, 0); 516 + iput(di->di_inode); 517 + di->di_inode = NULL; 508 518 return ret; 509 519 } 510 520 ··· 533 523 } 534 524 535 525 #else /* !CONFIG_FILE_LOCKING */ 526 + struct delegated_inode { }; 527 + 528 + static inline bool is_delegated(struct delegated_inode *di) 529 + { 530 + return false; 531 + } 532 + 536 533 static inline int break_lease(struct inode *inode, bool wait) 537 534 { 538 535 return 0; ··· 550 533 return 0; 551 534 } 552 535 553 - static inline int try_break_deleg(struct inode *inode, struct inode **delegated_inode) 536 + static inline int try_break_deleg(struct inode *inode, 537 + struct delegated_inode *delegated_inode) 554 538 { 555 539 return 0; 556 540 } 557 541 558 - static inline int break_deleg_wait(struct inode **delegated_inode) 542 + static inline int break_deleg_wait(struct delegated_inode *delegated_inode) 559 543 { 560 544 BUG(); 561 545 return 0;
+5 -4
include/linux/fs.h
··· 80 80 struct fs_parameter_spec; 81 81 struct file_kattr; 82 82 struct iomap_ops; 83 + struct delegated_inode; 83 84 84 85 extern void __init inode_init(void); 85 86 extern void __init inode_init_early(void); ··· 2120 2119 int vfs_symlink(struct mnt_idmap *, struct inode *, 2121 2120 struct dentry *, const char *); 2122 2121 int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *, 2123 - struct dentry *, struct inode **); 2122 + struct dentry *, struct delegated_inode *); 2124 2123 int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *); 2125 2124 int vfs_unlink(struct mnt_idmap *, struct inode *, struct dentry *, 2126 - struct inode **); 2125 + struct delegated_inode *); 2127 2126 2128 2127 /** 2129 2128 * struct renamedata - contains all information required for renaming ··· 2141 2140 struct dentry *old_dentry; 2142 2141 struct dentry *new_parent; 2143 2142 struct dentry *new_dentry; 2144 - struct inode **delegated_inode; 2143 + struct delegated_inode *delegated_inode; 2145 2144 unsigned int flags; 2146 2145 } __randomize_layout; 2147 2146 ··· 3072 3071 #endif 3073 3072 3074 3073 int notify_change(struct mnt_idmap *, struct dentry *, 3075 - struct iattr *, struct inode **); 3074 + struct iattr *, struct delegated_inode *); 3076 3075 int inode_permission(struct mnt_idmap *, struct inode *, int); 3077 3076 int generic_permission(struct mnt_idmap *, struct inode *, int); 3078 3077 static inline int file_permission(struct file *file, int mask)
+2 -2
include/linux/xattr.h
··· 85 85 const char *, const void *, size_t, int); 86 86 int __vfs_setxattr_locked(struct mnt_idmap *, struct dentry *, 87 87 const char *, const void *, size_t, int, 88 - struct inode **); 88 + struct delegated_inode *); 89 89 int vfs_setxattr(struct mnt_idmap *, struct dentry *, const char *, 90 90 const void *, size_t, int); 91 91 int __vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *); 92 92 int __vfs_removexattr_locked(struct mnt_idmap *, struct dentry *, 93 - const char *, struct inode **); 93 + const char *, struct delegated_inode *); 94 94 int vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *); 95 95 96 96 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);