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

fs: provide rcu-walk aware permission i_ops

Signed-off-by: Nick Piggin <npiggin@kernel.dk>

+287 -146
+3 -3
Documentation/filesystems/Locking
··· 47 47 void * (*follow_link) (struct dentry *, struct nameidata *); 48 48 void (*put_link) (struct dentry *, struct nameidata *, void *); 49 49 void (*truncate) (struct inode *); 50 - int (*permission) (struct inode *, int, struct nameidata *); 51 - int (*check_acl)(struct inode *, int); 50 + int (*permission) (struct inode *, int, unsigned int); 51 + int (*check_acl)(struct inode *, int, unsigned int); 52 52 int (*setattr) (struct dentry *, struct iattr *); 53 53 int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *); 54 54 int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); ··· 76 76 put_link: no 77 77 truncate: yes (see below) 78 78 setattr: yes 79 - permission: no 79 + permission: no (may not block if called in rcu-walk mode) 80 80 check_acl: no 81 81 getattr: no 82 82 setxattr: yes
+41 -3
Documentation/filesystems/path-lookup.txt
··· 316 316 317 317 The cases where rcu-walk cannot continue are: 318 318 * NULL dentry (ie. any uncached path element) 319 - * parent with d_inode->i_op->permission or ACLs 320 319 * Following links 321 320 322 - In future patches, permission checks become rcu-walk aware. It may be possible 323 - eventually to make following links rcu-walk aware. 321 + It may be possible eventually to make following links rcu-walk aware. 324 322 325 323 Uncached path elements will always require dropping to ref-walk mode, at the 326 324 very least because i_mutex needs to be grabbed, and objects allocated. ··· 334 336 scalability of path resolution. 335 337 336 338 339 + Interesting statistics 340 + ====================== 341 + 342 + The following table gives rcu lookup statistics for a few simple workloads 343 + (2s12c24t Westmere, debian non-graphical system). Ungraceful are attempts to 344 + drop rcu that fail due to d_seq failure and requiring the entire path lookup 345 + again. Other cases are successful rcu-drops that are required before the final 346 + element, nodentry for missing dentry, revalidate for filesystem revalidate 347 + routine requiring rcu drop, permission for permission check requiring drop, 348 + and link for symlink traversal requiring drop. 349 + 350 + rcu-lookups restart nodentry link revalidate permission 351 + bootup 47121 0 4624 1010 10283 7852 352 + dbench 25386793 0 6778659(26.7%) 55 549 1156 353 + kbuild 2696672 10 64442(2.3%) 108764(4.0%) 1 1590 354 + git diff 39605 0 28 2 0 106 355 + vfstest 24185492 4945 708725(2.9%) 1076136(4.4%) 0 2651 356 + 357 + What this shows is that failed rcu-walk lookups, ie. ones that are restarted 358 + entirely with ref-walk, are quite rare. Even the "vfstest" case which 359 + specifically has concurrent renames/mkdir/rmdir/ creat/unlink/etc to excercise 360 + such races is not showing a huge amount of restarts. 361 + 362 + Dropping from rcu-walk to ref-walk mean that we have encountered a dentry where 363 + the reference count needs to be taken for some reason. This is either because 364 + we have reached the target of the path walk, or because we have encountered a 365 + condition that can't be resolved in rcu-walk mode. Ideally, we drop rcu-walk 366 + only when we have reached the target dentry, so the other statistics show where 367 + this does not happen. 368 + 369 + Note that a graceful drop from rcu-walk mode due to something such as the 370 + dentry not existing (which can be common) is not necessarily a failure of 371 + rcu-walk scheme, because some elements of the path may have been walked in 372 + rcu-walk mode. The further we get from common path elements (such as cwd or 373 + root), the less contended the dentry is likely to be. The closer we are to 374 + common path elements, the more likely they will exist in dentry cache. 375 + 376 + 337 377 Papers and other documentation on dcache locking 338 378 ================================================ 339 379 340 380 1. Scaling dcache with RCU (http://linuxjournal.com/article.php?sid=7124). 341 381 342 382 2. http://lse.sourceforge.net/locking/dcache/dcache.html 383 + 384 +
+5
Documentation/filesystems/porting
··· 380 380 may now be called in rcu-walk mode (nd->flags & LOOKUP_RCU). -ECHILD should be 381 381 returned if the filesystem cannot handle rcu-walk. See 382 382 Documentation/filesystems/vfs.txt for more details. 383 + 384 + permission and check_acl are inode permission checks that are called 385 + on many or all directory inodes on the way down a path walk (to check for 386 + exec permission). These must now be rcu-walk aware (flags & IPERM_RCU). See 387 + Documentation/filesystems/vfs.txt for more details.
+9 -1
Documentation/filesystems/vfs.txt
··· 325 325 void * (*follow_link) (struct dentry *, struct nameidata *); 326 326 void (*put_link) (struct dentry *, struct nameidata *, void *); 327 327 void (*truncate) (struct inode *); 328 - int (*permission) (struct inode *, int, struct nameidata *); 328 + int (*permission) (struct inode *, int, unsigned int); 329 + int (*check_acl)(struct inode *, int, unsigned int); 329 330 int (*setattr) (struct dentry *, struct iattr *); 330 331 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); 331 332 int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); ··· 414 413 415 414 permission: called by the VFS to check for access rights on a POSIX-like 416 415 filesystem. 416 + 417 + May be called in rcu-walk mode (flags & IPERM_RCU). If in rcu-walk 418 + mode, the filesystem must check the permission without blocking or 419 + storing to the inode. 420 + 421 + If a situation is encountered that rcu-walk cannot handle, return 422 + -ECHILD and it will be called again in ref-walk mode. 417 423 418 424 setattr: called by the VFS to set attributes for a file. This method 419 425 is called by chmod(2) and related system calls.
+4 -1
drivers/staging/smbfs/file.c
··· 407 407 * privileges, so we need our own check for this. 408 408 */ 409 409 static int 410 - smb_file_permission(struct inode *inode, int mask) 410 + smb_file_permission(struct inode *inode, int mask, unsigned int flags) 411 411 { 412 412 int mode = inode->i_mode; 413 413 int error = 0; 414 + 415 + if (flags & IPERM_FLAG_RCU) 416 + return -ECHILD; 414 417 415 418 VERBOSE("mode=%x, mask=%x\n", mode, mask); 416 419
+4 -1
fs/9p/acl.c
··· 91 91 return acl; 92 92 } 93 93 94 - int v9fs_check_acl(struct inode *inode, int mask) 94 + int v9fs_check_acl(struct inode *inode, int mask, unsigned int flags) 95 95 { 96 96 struct posix_acl *acl; 97 97 struct v9fs_session_info *v9ses; 98 + 99 + if (flags & IPERM_FLAG_RCU) 100 + return -ECHILD; 98 101 99 102 v9ses = v9fs_inode2v9ses(inode); 100 103 if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) {
+1 -1
fs/9p/acl.h
··· 16 16 17 17 #ifdef CONFIG_9P_FS_POSIX_ACL 18 18 extern int v9fs_get_acl(struct inode *, struct p9_fid *); 19 - extern int v9fs_check_acl(struct inode *inode, int mask); 19 + extern int v9fs_check_acl(struct inode *inode, int mask, unsigned int flags); 20 20 extern int v9fs_acl_chmod(struct dentry *); 21 21 extern int v9fs_set_create_acl(struct dentry *, 22 22 struct posix_acl *, struct posix_acl *);
+1 -1
fs/afs/internal.h
··· 624 624 extern void afs_cache_permit(struct afs_vnode *, struct key *, long); 625 625 extern void afs_zap_permits(struct rcu_head *); 626 626 extern struct key *afs_request_key(struct afs_cell *); 627 - extern int afs_permission(struct inode *, int); 627 + extern int afs_permission(struct inode *, int, unsigned int); 628 628 629 629 /* 630 630 * server.c
+5 -2
fs/afs/security.c
··· 285 285 * - AFS ACLs are attached to directories only, and a file is controlled by its 286 286 * parent directory's ACL 287 287 */ 288 - int afs_permission(struct inode *inode, int mask) 288 + int afs_permission(struct inode *inode, int mask, unsigned int flags) 289 289 { 290 290 struct afs_vnode *vnode = AFS_FS_I(inode); 291 291 afs_access_t uninitialized_var(access); 292 292 struct key *key; 293 293 int ret; 294 + 295 + if (flags & IPERM_FLAG_RCU) 296 + return -ECHILD; 294 297 295 298 _enter("{{%x:%u},%lx},%x,", 296 299 vnode->fid.vid, vnode->fid.vnode, vnode->flags, mask); ··· 350 347 } 351 348 352 349 key_put(key); 353 - ret = generic_permission(inode, mask, NULL); 350 + ret = generic_permission(inode, mask, flags, NULL); 354 351 _leave(" = %d", ret); 355 352 return ret; 356 353
+4 -1
fs/bad_inode.c
··· 229 229 return -EIO; 230 230 } 231 231 232 - static int bad_inode_permission(struct inode *inode, int mask) 232 + static int bad_inode_permission(struct inode *inode, int mask, unsigned int flags) 233 233 { 234 + if (flags & IPERM_FLAG_RCU) 235 + return -ECHILD; 236 + 234 237 return -EIO; 235 238 } 236 239
+4 -2
fs/btrfs/acl.c
··· 185 185 return ret; 186 186 } 187 187 188 - int btrfs_check_acl(struct inode *inode, int mask) 188 + int btrfs_check_acl(struct inode *inode, int mask, unsigned int flags) 189 189 { 190 190 struct posix_acl *acl; 191 191 int error = -EAGAIN; 192 192 193 - acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS); 193 + if (flags & IPERM_FLAG_RCU) 194 + return -ECHILD; 194 195 196 + acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS); 195 197 if (IS_ERR(acl)) 196 198 return PTR_ERR(acl); 197 199 if (acl) {
+1 -1
fs/btrfs/ctree.h
··· 2544 2544 2545 2545 /* acl.c */ 2546 2546 #ifdef CONFIG_BTRFS_FS_POSIX_ACL 2547 - int btrfs_check_acl(struct inode *inode, int mask); 2547 + int btrfs_check_acl(struct inode *inode, int mask, unsigned int flags); 2548 2548 #else 2549 2549 #define btrfs_check_acl NULL 2550 2550 #endif
+5 -2
fs/btrfs/inode.c
··· 7211 7211 return __set_page_dirty_nobuffers(page); 7212 7212 } 7213 7213 7214 - static int btrfs_permission(struct inode *inode, int mask) 7214 + static int btrfs_permission(struct inode *inode, int mask, unsigned int flags) 7215 7215 { 7216 + if (flags & IPERM_FLAG_RCU) 7217 + return -ECHILD; 7218 + 7216 7219 if ((BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) && (mask & MAY_WRITE)) 7217 7220 return -EACCES; 7218 - return generic_permission(inode, mask, btrfs_check_acl); 7221 + return generic_permission(inode, mask, flags, btrfs_check_acl); 7219 7222 } 7220 7223 7221 7224 static const struct inode_operations btrfs_dir_inode_operations = {
+8 -3
fs/ceph/inode.c
··· 1781 1781 * Check inode permissions. We verify we have a valid value for 1782 1782 * the AUTH cap, then call the generic handler. 1783 1783 */ 1784 - int ceph_permission(struct inode *inode, int mask) 1784 + int ceph_permission(struct inode *inode, int mask, unsigned int flags) 1785 1785 { 1786 - int err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED); 1786 + int err; 1787 + 1788 + if (flags & IPERM_FLAG_RCU) 1789 + return -ECHILD; 1790 + 1791 + err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED); 1787 1792 1788 1793 if (!err) 1789 - err = generic_permission(inode, mask, NULL); 1794 + err = generic_permission(inode, mask, flags, NULL); 1790 1795 return err; 1791 1796 } 1792 1797
+1 -1
fs/ceph/super.h
··· 665 665 extern void ceph_queue_writeback(struct inode *inode); 666 666 667 667 extern int ceph_do_getattr(struct inode *inode, int mask); 668 - extern int ceph_permission(struct inode *inode, int mask); 668 + extern int ceph_permission(struct inode *inode, int mask, unsigned int flags); 669 669 extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); 670 670 extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, 671 671 struct kstat *stat);
+5 -2
fs/cifs/cifsfs.c
··· 283 283 return 0; 284 284 } 285 285 286 - static int cifs_permission(struct inode *inode, int mask) 286 + static int cifs_permission(struct inode *inode, int mask, unsigned int flags) 287 287 { 288 288 struct cifs_sb_info *cifs_sb; 289 + 290 + if (flags & IPERM_FLAG_RCU) 291 + return -ECHILD; 289 292 290 293 cifs_sb = CIFS_SB(inode->i_sb); 291 294 ··· 301 298 on the client (above and beyond ACL on servers) for 302 299 servers which do not support setting and viewing mode bits, 303 300 so allowing client to check permissions is useful */ 304 - return generic_permission(inode, mask, NULL); 301 + return generic_permission(inode, mask, flags, NULL); 305 302 } 306 303 307 304 static struct kmem_cache *cifs_inode_cachep;
+4 -1
fs/coda/dir.c
··· 135 135 } 136 136 137 137 138 - int coda_permission(struct inode *inode, int mask) 138 + int coda_permission(struct inode *inode, int mask, unsigned int flags) 139 139 { 140 140 int error; 141 + 142 + if (flags & IPERM_FLAG_RCU) 143 + return -ECHILD; 141 144 142 145 mask &= MAY_READ | MAY_WRITE | MAY_EXEC; 143 146
+4 -2
fs/coda/pioctl.c
··· 24 24 #include <linux/coda_psdev.h> 25 25 26 26 /* pioctl ops */ 27 - static int coda_ioctl_permission(struct inode *inode, int mask); 27 + static int coda_ioctl_permission(struct inode *inode, int mask, unsigned int flags); 28 28 static long coda_pioctl(struct file *filp, unsigned int cmd, 29 29 unsigned long user_data); 30 30 ··· 41 41 }; 42 42 43 43 /* the coda pioctl inode ops */ 44 - static int coda_ioctl_permission(struct inode *inode, int mask) 44 + static int coda_ioctl_permission(struct inode *inode, int mask, unsigned int flags) 45 45 { 46 + if (flags & IPERM_FLAG_RCU) 47 + return -ECHILD; 46 48 return (mask & MAY_EXEC) ? -EACCES : 0; 47 49 } 48 50
+3 -1
fs/ecryptfs/inode.c
··· 980 980 } 981 981 982 982 static int 983 - ecryptfs_permission(struct inode *inode, int mask) 983 + ecryptfs_permission(struct inode *inode, int mask, unsigned int flags) 984 984 { 985 + if (flags & IPERM_FLAG_RCU) 986 + return -ECHILD; 985 987 return inode_permission(ecryptfs_inode_to_lower(inode), mask); 986 988 } 987 989
+6 -2
fs/ext2/acl.c
··· 232 232 } 233 233 234 234 int 235 - ext2_check_acl(struct inode *inode, int mask) 235 + ext2_check_acl(struct inode *inode, int mask, unsigned int flags) 236 236 { 237 - struct posix_acl *acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); 237 + struct posix_acl *acl; 238 238 239 + if (flags & IPERM_FLAG_RCU) 240 + return -ECHILD; 241 + 242 + acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); 239 243 if (IS_ERR(acl)) 240 244 return PTR_ERR(acl); 241 245 if (acl) {
+1 -1
fs/ext2/acl.h
··· 54 54 #ifdef CONFIG_EXT2_FS_POSIX_ACL 55 55 56 56 /* acl.c */ 57 - extern int ext2_check_acl (struct inode *, int); 57 + extern int ext2_check_acl (struct inode *, int, unsigned int); 58 58 extern int ext2_acl_chmod (struct inode *); 59 59 extern int ext2_init_acl (struct inode *, struct inode *); 60 60
+6 -2
fs/ext3/acl.c
··· 240 240 } 241 241 242 242 int 243 - ext3_check_acl(struct inode *inode, int mask) 243 + ext3_check_acl(struct inode *inode, int mask, unsigned int flags) 244 244 { 245 - struct posix_acl *acl = ext3_get_acl(inode, ACL_TYPE_ACCESS); 245 + struct posix_acl *acl; 246 246 247 + if (flags & IPERM_FLAG_RCU) 248 + return -ECHILD; 249 + 250 + acl = ext3_get_acl(inode, ACL_TYPE_ACCESS); 247 251 if (IS_ERR(acl)) 248 252 return PTR_ERR(acl); 249 253 if (acl) {
+1 -1
fs/ext3/acl.h
··· 54 54 #ifdef CONFIG_EXT3_FS_POSIX_ACL 55 55 56 56 /* acl.c */ 57 - extern int ext3_check_acl (struct inode *, int); 57 + extern int ext3_check_acl (struct inode *, int, unsigned int); 58 58 extern int ext3_acl_chmod (struct inode *); 59 59 extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); 60 60
+6 -2
fs/ext4/acl.c
··· 238 238 } 239 239 240 240 int 241 - ext4_check_acl(struct inode *inode, int mask) 241 + ext4_check_acl(struct inode *inode, int mask, unsigned int flags) 242 242 { 243 - struct posix_acl *acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); 243 + struct posix_acl *acl; 244 244 245 + if (flags & IPERM_FLAG_RCU) 246 + return -ECHILD; 247 + 248 + acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); 245 249 if (IS_ERR(acl)) 246 250 return PTR_ERR(acl); 247 251 if (acl) {
+1 -1
fs/ext4/acl.h
··· 54 54 #ifdef CONFIG_EXT4_FS_POSIX_ACL 55 55 56 56 /* acl.c */ 57 - extern int ext4_check_acl(struct inode *, int); 57 + extern int ext4_check_acl(struct inode *, int, unsigned int); 58 58 extern int ext4_acl_chmod(struct inode *); 59 59 extern int ext4_init_acl(handle_t *, struct inode *, struct inode *); 60 60
+7 -3
fs/fuse/dir.c
··· 985 985 * access request is sent. Execute permission is still checked 986 986 * locally based on file mode. 987 987 */ 988 - static int fuse_permission(struct inode *inode, int mask) 988 + static int fuse_permission(struct inode *inode, int mask, unsigned int flags) 989 989 { 990 990 struct fuse_conn *fc = get_fuse_conn(inode); 991 991 bool refreshed = false; 992 992 int err = 0; 993 + 994 + if (flags & IPERM_FLAG_RCU) 995 + return -ECHILD; 993 996 994 997 if (!fuse_allow_task(fc, current)) 995 998 return -EACCES; ··· 1008 1005 } 1009 1006 1010 1007 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { 1011 - err = generic_permission(inode, mask, NULL); 1008 + err = generic_permission(inode, mask, flags, NULL); 1012 1009 1013 1010 /* If permission is denied, try to refresh file 1014 1011 attributes. This is also needed, because the root ··· 1016 1013 if (err == -EACCES && !refreshed) { 1017 1014 err = fuse_do_getattr(inode, NULL, NULL); 1018 1015 if (!err) 1019 - err = generic_permission(inode, mask, NULL); 1016 + err = generic_permission(inode, mask, 1017 + flags, NULL); 1020 1018 } 1021 1019 1022 1020 /* Note: the opposite of the above test does not
+6 -2
fs/generic_acl.c
··· 190 190 } 191 191 192 192 int 193 - generic_check_acl(struct inode *inode, int mask) 193 + generic_check_acl(struct inode *inode, int mask, unsigned int flags) 194 194 { 195 - struct posix_acl *acl = get_cached_acl(inode, ACL_TYPE_ACCESS); 195 + struct posix_acl *acl; 196 196 197 + if (flags & IPERM_FLAG_RCU) 198 + return -ECHILD; 199 + 200 + acl = get_cached_acl(inode, ACL_TYPE_ACCESS); 197 201 if (acl) { 198 202 int error = posix_acl_permission(inode, acl, mask); 199 203 posix_acl_release(acl);
+4 -1
fs/gfs2/acl.c
··· 75 75 * Returns: errno 76 76 */ 77 77 78 - int gfs2_check_acl(struct inode *inode, int mask) 78 + int gfs2_check_acl(struct inode *inode, int mask, unsigned int flags) 79 79 { 80 80 struct posix_acl *acl; 81 81 int error; 82 + 83 + if (flags & IPERM_FLAG_RCU) 84 + return -ECHILD; 82 85 83 86 acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS); 84 87 if (IS_ERR(acl))
+1 -1
fs/gfs2/acl.h
··· 16 16 #define GFS2_POSIX_ACL_DEFAULT "posix_acl_default" 17 17 #define GFS2_ACL_MAX_ENTRIES 25 18 18 19 - extern int gfs2_check_acl(struct inode *inode, int mask); 19 + extern int gfs2_check_acl(struct inode *inode, int mask, unsigned int); 20 20 extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode); 21 21 extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); 22 22 extern const struct xattr_handler gfs2_xattr_system_handler;
+1 -1
fs/gfs2/file.c
··· 241 241 !capable(CAP_LINUX_IMMUTABLE)) 242 242 goto out; 243 243 if (!IS_IMMUTABLE(inode)) { 244 - error = gfs2_permission(inode, MAY_WRITE); 244 + error = gfs2_permission(inode, MAY_WRITE, 0); 245 245 if (error) 246 246 goto out; 247 247 }
+2 -2
fs/gfs2/inode.c
··· 509 509 } 510 510 511 511 if (!is_root) { 512 - error = gfs2_permission(dir, MAY_EXEC); 512 + error = gfs2_permission(dir, MAY_EXEC, 0); 513 513 if (error) 514 514 goto out; 515 515 } ··· 539 539 { 540 540 int error; 541 541 542 - error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); 542 + error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC, 0); 543 543 if (error) 544 544 return error; 545 545
+1 -1
fs/gfs2/inode.h
··· 113 113 extern struct inode *gfs2_createi(struct gfs2_holder *ghs, 114 114 const struct qstr *name, 115 115 unsigned int mode, dev_t dev); 116 - extern int gfs2_permission(struct inode *inode, int mask); 116 + extern int gfs2_permission(struct inode *inode, int mask, unsigned int flags); 117 117 extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); 118 118 extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); 119 119 extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf);
+11 -7
fs/gfs2/ops_inode.c
··· 166 166 if (error) 167 167 goto out_child; 168 168 169 - error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC); 169 + error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC, 0); 170 170 if (error) 171 171 goto out_gunlock; 172 172 ··· 289 289 if (IS_APPEND(&dip->i_inode)) 290 290 return -EPERM; 291 291 292 - error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); 292 + error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC, 0); 293 293 if (error) 294 294 return error; 295 295 ··· 822 822 } 823 823 } 824 824 } else { 825 - error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC); 825 + error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC, 0); 826 826 if (error) 827 827 goto out_gunlock; 828 828 ··· 857 857 /* Check out the dir to be renamed */ 858 858 859 859 if (dir_rename) { 860 - error = gfs2_permission(odentry->d_inode, MAY_WRITE); 860 + error = gfs2_permission(odentry->d_inode, MAY_WRITE, 0); 861 861 if (error) 862 862 goto out_gunlock; 863 863 } ··· 1041 1041 * Returns: errno 1042 1042 */ 1043 1043 1044 - int gfs2_permission(struct inode *inode, int mask) 1044 + int gfs2_permission(struct inode *inode, int mask, unsigned int flags) 1045 1045 { 1046 - struct gfs2_inode *ip = GFS2_I(inode); 1046 + struct gfs2_inode *ip; 1047 1047 struct gfs2_holder i_gh; 1048 1048 int error; 1049 1049 int unlock = 0; 1050 1050 1051 + if (flags & IPERM_FLAG_RCU) 1052 + return -ECHILD; 1053 + 1054 + ip = GFS2_I(inode); 1051 1055 if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { 1052 1056 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); 1053 1057 if (error) ··· 1062 1058 if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) 1063 1059 error = -EACCES; 1064 1060 else 1065 - error = generic_permission(inode, mask, gfs2_check_acl); 1061 + error = generic_permission(inode, mask, flags, gfs2_check_acl); 1066 1062 if (unlock) 1067 1063 gfs2_glock_dq_uninit(&i_gh); 1068 1064
+5 -2
fs/hostfs/hostfs_kern.c
··· 749 749 return err; 750 750 } 751 751 752 - int hostfs_permission(struct inode *ino, int desired) 752 + int hostfs_permission(struct inode *ino, int desired, unsigned int flags) 753 753 { 754 754 char *name; 755 755 int r = 0, w = 0, x = 0, err; 756 + 757 + if (flags & IPERM_FLAG_RCU) 758 + return -ECHILD; 756 759 757 760 if (desired & MAY_READ) r = 1; 758 761 if (desired & MAY_WRITE) w = 1; ··· 771 768 err = access_file(name, r, w, x); 772 769 __putname(name); 773 770 if (!err) 774 - err = generic_permission(ino, desired, NULL); 771 + err = generic_permission(ino, desired, flags, NULL); 775 772 return err; 776 773 } 777 774
+1 -1
fs/hpfs/namei.c
··· 419 419 unlock_kernel(); 420 420 return -ENOSPC; 421 421 } 422 - if (generic_permission(inode, MAY_WRITE, NULL) || 422 + if (generic_permission(inode, MAY_WRITE, 0, NULL) || 423 423 !S_ISREG(inode->i_mode) || 424 424 get_write_access(inode)) { 425 425 d_rehash(dentry);
+4 -1
fs/jffs2/acl.c
··· 259 259 return rc; 260 260 } 261 261 262 - int jffs2_check_acl(struct inode *inode, int mask) 262 + int jffs2_check_acl(struct inode *inode, int mask, unsigned int flags) 263 263 { 264 264 struct posix_acl *acl; 265 265 int rc; 266 + 267 + if (flags & IPERM_FLAG_RCU) 268 + return -ECHILD; 266 269 267 270 acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS); 268 271 if (IS_ERR(acl))
+1 -1
fs/jffs2/acl.h
··· 26 26 27 27 #ifdef CONFIG_JFFS2_FS_POSIX_ACL 28 28 29 - extern int jffs2_check_acl(struct inode *, int); 29 + extern int jffs2_check_acl(struct inode *, int, unsigned int); 30 30 extern int jffs2_acl_chmod(struct inode *); 31 31 extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); 32 32 extern int jffs2_init_acl_post(struct inode *);
+6 -2
fs/jfs/acl.c
··· 114 114 return rc; 115 115 } 116 116 117 - int jfs_check_acl(struct inode *inode, int mask) 117 + int jfs_check_acl(struct inode *inode, int mask, unsigned int flags) 118 118 { 119 - struct posix_acl *acl = jfs_get_acl(inode, ACL_TYPE_ACCESS); 119 + struct posix_acl *acl; 120 120 121 + if (flags & IPERM_FLAG_RCU) 122 + return -ECHILD; 123 + 124 + acl = jfs_get_acl(inode, ACL_TYPE_ACCESS); 121 125 if (IS_ERR(acl)) 122 126 return PTR_ERR(acl); 123 127 if (acl) {
+1 -1
fs/jfs/jfs_acl.h
··· 20 20 21 21 #ifdef CONFIG_JFS_POSIX_ACL 22 22 23 - int jfs_check_acl(struct inode *, int); 23 + int jfs_check_acl(struct inode *, int, unsigned int flags); 24 24 int jfs_init_acl(tid_t, struct inode *, struct inode *); 25 25 int jfs_acl_chmod(struct inode *inode); 26 26
+4 -2
fs/logfs/dir.c
··· 555 555 return __logfs_create(dir, dentry, inode, target, destlen); 556 556 } 557 557 558 - static int logfs_permission(struct inode *inode, int mask) 558 + static int logfs_permission(struct inode *inode, int mask, unsigned int flags) 559 559 { 560 - return generic_permission(inode, mask, NULL); 560 + if (flags & IPERM_FLAG_RCU) 561 + return -ECHILD; 562 + return generic_permission(inode, mask, flags, NULL); 561 563 } 562 564 563 565 static int logfs_link(struct dentry *old_dentry, struct inode *dir,
+29 -46
fs/namei.c
··· 169 169 /* 170 170 * This does basic POSIX ACL permission checking 171 171 */ 172 - static inline int __acl_permission_check(struct inode *inode, int mask, 173 - int (*check_acl)(struct inode *inode, int mask), int rcu) 172 + static int acl_permission_check(struct inode *inode, int mask, unsigned int flags, 173 + int (*check_acl)(struct inode *inode, int mask, unsigned int flags)) 174 174 { 175 175 umode_t mode = inode->i_mode; 176 176 ··· 180 180 mode >>= 6; 181 181 else { 182 182 if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) { 183 - if (rcu) { 184 - return -ECHILD; 185 - } else { 186 - int error = check_acl(inode, mask); 187 - if (error != -EAGAIN) 188 - return error; 189 - } 183 + int error = check_acl(inode, mask, flags); 184 + if (error != -EAGAIN) 185 + return error; 190 186 } 191 187 192 188 if (in_group_p(inode->i_gid)) ··· 197 201 return -EACCES; 198 202 } 199 203 200 - static inline int acl_permission_check(struct inode *inode, int mask, 201 - int (*check_acl)(struct inode *inode, int mask)) 202 - { 203 - return __acl_permission_check(inode, mask, check_acl, 0); 204 - } 205 - 206 204 /** 207 - * generic_permission - check for access rights on a Posix-like filesystem 205 + * generic_permission - check for access rights on a Posix-like filesystem 208 206 * @inode: inode to check access rights for 209 207 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) 210 208 * @check_acl: optional callback to check for Posix ACLs 209 + * @flags IPERM_FLAG_ flags. 211 210 * 212 211 * Used to check for read/write/execute permissions on a file. 213 212 * We use "fsuid" for this, letting us set arbitrary permissions 214 213 * for filesystem access without changing the "normal" uids which 215 - * are used for other things.. 214 + * are used for other things. 215 + * 216 + * generic_permission is rcu-walk aware. It returns -ECHILD in case an rcu-walk 217 + * request cannot be satisfied (eg. requires blocking or too much complexity). 218 + * It would then be called again in ref-walk mode. 216 219 */ 217 - int generic_permission(struct inode *inode, int mask, 218 - int (*check_acl)(struct inode *inode, int mask)) 220 + int generic_permission(struct inode *inode, int mask, unsigned int flags, 221 + int (*check_acl)(struct inode *inode, int mask, unsigned int flags)) 219 222 { 220 223 int ret; 221 224 222 225 /* 223 226 * Do the basic POSIX ACL permission checks. 224 227 */ 225 - ret = acl_permission_check(inode, mask, check_acl); 228 + ret = acl_permission_check(inode, mask, flags, check_acl); 226 229 if (ret != -EACCES) 227 230 return ret; 228 231 ··· 276 281 } 277 282 278 283 if (inode->i_op->permission) 279 - retval = inode->i_op->permission(inode, mask); 284 + retval = inode->i_op->permission(inode, mask, 0); 280 285 else 281 - retval = generic_permission(inode, mask, inode->i_op->check_acl); 286 + retval = generic_permission(inode, mask, 0, 287 + inode->i_op->check_acl); 282 288 283 289 if (retval) 284 290 return retval; ··· 664 668 * short-cut DAC fails, then call ->permission() to do more 665 669 * complete permission check. 666 670 */ 667 - static inline int __exec_permission(struct inode *inode, int rcu) 671 + static inline int exec_permission(struct inode *inode, unsigned int flags) 668 672 { 669 673 int ret; 670 674 671 675 if (inode->i_op->permission) { 672 - if (rcu) 673 - return -ECHILD; 674 - ret = inode->i_op->permission(inode, MAY_EXEC); 675 - if (!ret) 676 - goto ok; 677 - return ret; 676 + ret = inode->i_op->permission(inode, MAY_EXEC, flags); 677 + } else { 678 + ret = acl_permission_check(inode, MAY_EXEC, flags, 679 + inode->i_op->check_acl); 678 680 } 679 - ret = __acl_permission_check(inode, MAY_EXEC, inode->i_op->check_acl, rcu); 680 - if (!ret) 681 + if (likely(!ret)) 681 682 goto ok; 682 - if (rcu && ret == -ECHILD) 683 + if (ret == -ECHILD) 683 684 return ret; 684 685 685 686 if (capable(CAP_DAC_OVERRIDE) || capable(CAP_DAC_READ_SEARCH)) ··· 684 691 685 692 return ret; 686 693 ok: 687 - return security_inode_exec_permission(inode, rcu); 688 - } 689 - 690 - static int exec_permission(struct inode *inode) 691 - { 692 - return __exec_permission(inode, 0); 693 - } 694 - 695 - static int exec_permission_rcu(struct inode *inode) 696 - { 697 - return __exec_permission(inode, 1); 694 + return security_inode_exec_permission(inode, flags); 698 695 } 699 696 700 697 static __always_inline void set_root(struct nameidata *nd) ··· 1148 1165 1149 1166 nd->flags |= LOOKUP_CONTINUE; 1150 1167 if (nd->flags & LOOKUP_RCU) { 1151 - err = exec_permission_rcu(nd->inode); 1168 + err = exec_permission(nd->inode, IPERM_FLAG_RCU); 1152 1169 if (err == -ECHILD) { 1153 1170 if (nameidata_drop_rcu(nd)) 1154 1171 return -ECHILD; ··· 1156 1173 } 1157 1174 } else { 1158 1175 exec_again: 1159 - err = exec_permission(nd->inode); 1176 + err = exec_permission(nd->inode, 0); 1160 1177 } 1161 1178 if (err) 1162 1179 break; ··· 1603 1620 struct dentry *dentry; 1604 1621 int err; 1605 1622 1606 - err = exec_permission(inode); 1623 + err = exec_permission(inode, 0); 1607 1624 if (err) 1608 1625 return ERR_PTR(err); 1609 1626
+5 -2
fs/nfs/dir.c
··· 2189 2189 return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); 2190 2190 } 2191 2191 2192 - int nfs_permission(struct inode *inode, int mask) 2192 + int nfs_permission(struct inode *inode, int mask, unsigned int flags) 2193 2193 { 2194 2194 struct rpc_cred *cred; 2195 2195 int res = 0; 2196 + 2197 + if (flags & IPERM_FLAG_RCU) 2198 + return -ECHILD; 2196 2199 2197 2200 nfs_inc_stats(inode, NFSIOS_VFSACCESS); 2198 2201 ··· 2244 2241 out_notsup: 2245 2242 res = nfs_revalidate_inode(NFS_SERVER(inode), inode); 2246 2243 if (res == 0) 2247 - res = generic_permission(inode, mask, NULL); 2244 + res = generic_permission(inode, mask, flags, NULL); 2248 2245 goto out; 2249 2246 } 2250 2247
+7 -3
fs/nilfs2/inode.c
··· 785 785 return err; 786 786 } 787 787 788 - int nilfs_permission(struct inode *inode, int mask) 788 + int nilfs_permission(struct inode *inode, int mask, unsigned int flags) 789 789 { 790 - struct nilfs_root *root = NILFS_I(inode)->i_root; 790 + struct nilfs_root *root; 791 791 792 + if (flags & IPERM_FLAG_RCU) 793 + return -ECHILD; 794 + 795 + root = NILFS_I(inode)->i_root; 792 796 if ((mask & MAY_WRITE) && root && 793 797 root->cno != NILFS_CPTREE_CURRENT_CNO) 794 798 return -EROFS; /* snapshot is not writable */ 795 799 796 - return generic_permission(inode, mask, NULL); 800 + return generic_permission(inode, mask, flags, NULL); 797 801 } 798 802 799 803 int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode,
+1 -1
fs/nilfs2/nilfs.h
··· 256 256 extern void nilfs_truncate(struct inode *); 257 257 extern void nilfs_evict_inode(struct inode *); 258 258 extern int nilfs_setattr(struct dentry *, struct iattr *); 259 - int nilfs_permission(struct inode *inode, int mask); 259 + int nilfs_permission(struct inode *inode, int mask, unsigned int flags); 260 260 extern int nilfs_load_inode_block(struct nilfs_sb_info *, struct inode *, 261 261 struct buffer_head **); 262 262 extern int nilfs_inode_dirty(struct inode *);
+6 -2
fs/ocfs2/acl.c
··· 291 291 return ret; 292 292 } 293 293 294 - int ocfs2_check_acl(struct inode *inode, int mask) 294 + int ocfs2_check_acl(struct inode *inode, int mask, unsigned int flags) 295 295 { 296 - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 296 + struct ocfs2_super *osb; 297 297 struct buffer_head *di_bh = NULL; 298 298 struct posix_acl *acl; 299 299 int ret = -EAGAIN; 300 300 301 + if (flags & IPERM_FLAG_RCU) 302 + return -ECHILD; 303 + 304 + osb = OCFS2_SB(inode->i_sb); 301 305 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) 302 306 return ret; 303 307
+1 -1
fs/ocfs2/acl.h
··· 26 26 __le32 e_id; 27 27 }; 28 28 29 - extern int ocfs2_check_acl(struct inode *, int); 29 + extern int ocfs2_check_acl(struct inode *, int, unsigned int); 30 30 extern int ocfs2_acl_chmod(struct inode *); 31 31 extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, 32 32 struct buffer_head *, struct buffer_head *,
+5 -2
fs/ocfs2/file.c
··· 1307 1307 return err; 1308 1308 } 1309 1309 1310 - int ocfs2_permission(struct inode *inode, int mask) 1310 + int ocfs2_permission(struct inode *inode, int mask, unsigned int flags) 1311 1311 { 1312 1312 int ret; 1313 + 1314 + if (flags & IPERM_FLAG_RCU) 1315 + return -ECHILD; 1313 1316 1314 1317 mlog_entry_void(); 1315 1318 ··· 1323 1320 goto out; 1324 1321 } 1325 1322 1326 - ret = generic_permission(inode, mask, ocfs2_check_acl); 1323 + ret = generic_permission(inode, mask, flags, ocfs2_check_acl); 1327 1324 1328 1325 ocfs2_inode_unlock(inode, 0); 1329 1326 out:
+1 -1
fs/ocfs2/file.h
··· 61 61 int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); 62 62 int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, 63 63 struct kstat *stat); 64 - int ocfs2_permission(struct inode *inode, int mask); 64 + int ocfs2_permission(struct inode *inode, int mask, unsigned int flags); 65 65 66 66 int ocfs2_should_update_atime(struct inode *inode, 67 67 struct vfsmount *vfsmnt);
+4 -2
fs/proc/base.c
··· 2114 2114 * /proc/pid/fd needs a special permission handler so that a process can still 2115 2115 * access /proc/self/fd after it has executed a setuid(). 2116 2116 */ 2117 - static int proc_fd_permission(struct inode *inode, int mask) 2117 + static int proc_fd_permission(struct inode *inode, int mask, unsigned int flags) 2118 2118 { 2119 2119 int rv; 2120 2120 2121 - rv = generic_permission(inode, mask, NULL); 2121 + if (flags & IPERM_FLAG_RCU) 2122 + return -ECHILD; 2123 + rv = generic_permission(inode, mask, flags, NULL); 2122 2124 if (rv == 0) 2123 2125 return 0; 2124 2126 if (task_pid(current) == proc_pid(inode))
+4 -1
fs/proc/proc_sysctl.c
··· 295 295 return ret; 296 296 } 297 297 298 - static int proc_sys_permission(struct inode *inode, int mask) 298 + static int proc_sys_permission(struct inode *inode, int mask,unsigned int flags) 299 299 { 300 300 /* 301 301 * sysctl entries that are not writeable, ··· 304 304 struct ctl_table_header *head; 305 305 struct ctl_table *table; 306 306 int error; 307 + 308 + if (flags & IPERM_FLAG_RCU) 309 + return -ECHILD; 307 310 308 311 /* Executable files are not allowed under /proc/sys/ */ 309 312 if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))
+10 -4
fs/reiserfs/xattr.c
··· 870 870 return err; 871 871 } 872 872 873 - static int reiserfs_check_acl(struct inode *inode, int mask) 873 + static int reiserfs_check_acl(struct inode *inode, int mask, unsigned int flags) 874 874 { 875 875 struct posix_acl *acl; 876 876 int error = -EAGAIN; /* do regular unix permission checks by default */ 877 + 878 + if (flags & IPERM_FLAG_RCU) 879 + return -ECHILD; 877 880 878 881 acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); 879 882 ··· 954 951 return 0; 955 952 } 956 953 957 - int reiserfs_permission(struct inode *inode, int mask) 954 + int reiserfs_permission(struct inode *inode, int mask, unsigned int flags) 958 955 { 956 + if (flags & IPERM_FLAG_RCU) 957 + return -ECHILD; 959 958 /* 960 959 * We don't do permission checks on the internal objects. 961 960 * Permissions are determined by the "owning" object. ··· 970 965 * Stat data v1 doesn't support ACLs. 971 966 */ 972 967 if (get_inode_sd_version(inode) != STAT_DATA_V1) 973 - return generic_permission(inode, mask, reiserfs_check_acl); 968 + return generic_permission(inode, mask, flags, 969 + reiserfs_check_acl); 974 970 #endif 975 - return generic_permission(inode, mask, NULL); 971 + return generic_permission(inode, mask, flags, NULL); 976 972 } 977 973 978 974 static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd)
+8 -3
fs/sysfs/inode.c
··· 348 348 return -ENOENT; 349 349 } 350 350 351 - int sysfs_permission(struct inode *inode, int mask) 351 + int sysfs_permission(struct inode *inode, int mask, unsigned int flags) 352 352 { 353 - struct sysfs_dirent *sd = inode->i_private; 353 + struct sysfs_dirent *sd; 354 + 355 + if (flags & IPERM_FLAG_RCU) 356 + return -ECHILD; 357 + 358 + sd = inode->i_private; 354 359 355 360 mutex_lock(&sysfs_mutex); 356 361 sysfs_refresh_inode(sd, inode); 357 362 mutex_unlock(&sysfs_mutex); 358 363 359 - return generic_permission(inode, mask, NULL); 364 + return generic_permission(inode, mask, flags, NULL); 360 365 }
+1 -1
fs/sysfs/sysfs.h
··· 200 200 struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd); 201 201 void sysfs_evict_inode(struct inode *inode); 202 202 int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); 203 - int sysfs_permission(struct inode *inode, int mask); 203 + int sysfs_permission(struct inode *inode, int mask, unsigned int flags); 204 204 int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); 205 205 int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); 206 206 int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+6 -2
fs/xfs/linux-2.6/xfs_acl.c
··· 219 219 } 220 220 221 221 int 222 - xfs_check_acl(struct inode *inode, int mask) 222 + xfs_check_acl(struct inode *inode, int mask, unsigned int flags) 223 223 { 224 - struct xfs_inode *ip = XFS_I(inode); 224 + struct xfs_inode *ip; 225 225 struct posix_acl *acl; 226 226 int error = -EAGAIN; 227 227 228 + if (flags & IPERM_FLAG_RCU) 229 + return -ECHILD; 230 + 231 + ip = XFS_I(inode); 228 232 trace_xfs_check_acl(ip); 229 233 230 234 /*
+1 -1
fs/xfs/xfs_acl.h
··· 42 42 #define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1) 43 43 44 44 #ifdef CONFIG_XFS_POSIX_ACL 45 - extern int xfs_check_acl(struct inode *inode, int mask); 45 + extern int xfs_check_acl(struct inode *inode, int mask, unsigned int flags); 46 46 extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); 47 47 extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); 48 48 extern int xfs_acl_chmod(struct inode *inode);
+1 -1
include/linux/coda_linux.h
··· 37 37 /* operations shared over more than one file */ 38 38 int coda_open(struct inode *i, struct file *f); 39 39 int coda_release(struct inode *i, struct file *f); 40 - int coda_permission(struct inode *inode, int mask); 40 + int coda_permission(struct inode *inode, int mask, unsigned int flags); 41 41 int coda_revalidate_inode(struct dentry *); 42 42 int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *); 43 43 int coda_setattr(struct dentry *, struct iattr *);
+6 -4
include/linux/fs.h
··· 1550 1550 int (*setlease)(struct file *, long, struct file_lock **); 1551 1551 }; 1552 1552 1553 + #define IPERM_FLAG_RCU 0x0001 1554 + 1553 1555 struct inode_operations { 1554 1556 struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); 1555 1557 void * (*follow_link) (struct dentry *, struct nameidata *); 1556 - int (*permission) (struct inode *, int); 1557 - int (*check_acl)(struct inode *, int); 1558 + int (*permission) (struct inode *, int, unsigned int); 1559 + int (*check_acl)(struct inode *, int, unsigned int); 1558 1560 1559 1561 int (*readlink) (struct dentry *, char __user *,int); 1560 1562 void (*put_link) (struct dentry *, struct nameidata *, void *); ··· 2167 2165 #endif 2168 2166 extern int notify_change(struct dentry *, struct iattr *); 2169 2167 extern int inode_permission(struct inode *, int); 2170 - extern int generic_permission(struct inode *, int, 2171 - int (*check_acl)(struct inode *, int)); 2168 + extern int generic_permission(struct inode *, int, unsigned int, 2169 + int (*check_acl)(struct inode *, int, unsigned int)); 2172 2170 2173 2171 static inline bool execute_ok(struct inode *inode) 2174 2172 {
+1 -1
include/linux/generic_acl.h
··· 10 10 11 11 int generic_acl_init(struct inode *, struct inode *); 12 12 int generic_acl_chmod(struct inode *); 13 - int generic_check_acl(struct inode *inode, int mask); 13 + int generic_check_acl(struct inode *inode, int mask, unsigned int flags); 14 14 15 15 #endif /* LINUX_GENERIC_ACL_H */
+1 -1
include/linux/nfs_fs.h
··· 351 351 extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); 352 352 extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr); 353 353 extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); 354 - extern int nfs_permission(struct inode *, int); 354 + extern int nfs_permission(struct inode *, int, unsigned int); 355 355 extern int nfs_open(struct inode *, struct file *); 356 356 extern int nfs_release(struct inode *, struct file *); 357 357 extern int nfs_attribute_timeout(struct inode *inode);
+1 -1
include/linux/reiserfs_xattr.h
··· 41 41 int reiserfs_lookup_privroot(struct super_block *sb); 42 42 int reiserfs_delete_xattrs(struct inode *inode); 43 43 int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); 44 - int reiserfs_permission(struct inode *inode, int mask); 44 + int reiserfs_permission(struct inode *inode, int mask, unsigned int flags); 45 45 46 46 #ifdef CONFIG_REISERFS_FS_XATTR 47 47 #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir)