diff options
| -rw-r--r-- | Documentation/filesystems/Locking | 214 |
1 files changed, 102 insertions, 112 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index b6426f15b4ae..7686e7684495 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
| @@ -18,7 +18,6 @@ prototypes: | |||
| 18 | char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); | 18 | char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); |
| 19 | 19 | ||
| 20 | locking rules: | 20 | locking rules: |
| 21 | none have BKL | ||
| 22 | dcache_lock rename_lock ->d_lock may block | 21 | dcache_lock rename_lock ->d_lock may block |
| 23 | d_revalidate: no no no yes | 22 | d_revalidate: no no no yes |
| 24 | d_hash no no no yes | 23 | d_hash no no no yes |
| @@ -42,18 +41,23 @@ ata *); | |||
| 42 | int (*rename) (struct inode *, struct dentry *, | 41 | int (*rename) (struct inode *, struct dentry *, |
| 43 | struct inode *, struct dentry *); | 42 | struct inode *, struct dentry *); |
| 44 | int (*readlink) (struct dentry *, char __user *,int); | 43 | int (*readlink) (struct dentry *, char __user *,int); |
| 45 | int (*follow_link) (struct dentry *, struct nameidata *); | 44 | void * (*follow_link) (struct dentry *, struct nameidata *); |
| 45 | void (*put_link) (struct dentry *, struct nameidata *, void *); | ||
| 46 | void (*truncate) (struct inode *); | 46 | void (*truncate) (struct inode *); |
| 47 | int (*permission) (struct inode *, int, struct nameidata *); | 47 | int (*permission) (struct inode *, int, struct nameidata *); |
| 48 | int (*check_acl)(struct inode *, int); | ||
| 48 | int (*setattr) (struct dentry *, struct iattr *); | 49 | int (*setattr) (struct dentry *, struct iattr *); |
| 49 | int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *); | 50 | int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *); |
| 50 | int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); | 51 | int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); |
| 51 | ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); | 52 | ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); |
| 52 | ssize_t (*listxattr) (struct dentry *, char *, size_t); | 53 | ssize_t (*listxattr) (struct dentry *, char *, size_t); |
| 53 | int (*removexattr) (struct dentry *, const char *); | 54 | int (*removexattr) (struct dentry *, const char *); |
| 55 | void (*truncate_range)(struct inode *, loff_t, loff_t); | ||
| 56 | long (*fallocate)(struct inode *inode, int mode, loff_t offset, loff_t len); | ||
| 57 | int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); | ||
| 54 | 58 | ||
| 55 | locking rules: | 59 | locking rules: |
| 56 | all may block, none have BKL | 60 | all may block |
| 57 | i_mutex(inode) | 61 | i_mutex(inode) |
| 58 | lookup: yes | 62 | lookup: yes |
| 59 | create: yes | 63 | create: yes |
| @@ -66,19 +70,24 @@ rmdir: yes (both) (see below) | |||
| 66 | rename: yes (all) (see below) | 70 | rename: yes (all) (see below) |
| 67 | readlink: no | 71 | readlink: no |
| 68 | follow_link: no | 72 | follow_link: no |
| 73 | put_link: no | ||
| 69 | truncate: yes (see below) | 74 | truncate: yes (see below) |
| 70 | setattr: yes | 75 | setattr: yes |
| 71 | permission: no | 76 | permission: no |
| 77 | check_acl: no | ||
| 72 | getattr: no | 78 | getattr: no |
| 73 | setxattr: yes | 79 | setxattr: yes |
| 74 | getxattr: no | 80 | getxattr: no |
| 75 | listxattr: no | 81 | listxattr: no |
| 76 | removexattr: yes | 82 | removexattr: yes |
| 83 | truncate_range: yes | ||
| 84 | fallocate: no | ||
| 85 | fiemap: no | ||
| 77 | Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on | 86 | Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on |
| 78 | victim. | 87 | victim. |
| 79 | cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. | 88 | cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. |
| 80 | ->truncate() is never called directly - it's a callback, not a | 89 | ->truncate() is never called directly - it's a callback, not a |
| 81 | method. It's called by vmtruncate() - library function normally used by | 90 | method. It's called by vmtruncate() - deprecated library function used by |
| 82 | ->setattr(). Locking information above applies to that call (i.e. is | 91 | ->setattr(). Locking information above applies to that call (i.e. is |
| 83 | inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been | 92 | inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been |
| 84 | passed). | 93 | passed). |
| @@ -91,7 +100,7 @@ prototypes: | |||
| 91 | struct inode *(*alloc_inode)(struct super_block *sb); | 100 | struct inode *(*alloc_inode)(struct super_block *sb); |
| 92 | void (*destroy_inode)(struct inode *); | 101 | void (*destroy_inode)(struct inode *); |
| 93 | void (*dirty_inode) (struct inode *); | 102 | void (*dirty_inode) (struct inode *); |
| 94 | int (*write_inode) (struct inode *, int); | 103 | int (*write_inode) (struct inode *, struct writeback_control *wbc); |
| 95 | int (*drop_inode) (struct inode *); | 104 | int (*drop_inode) (struct inode *); |
| 96 | void (*evict_inode) (struct inode *); | 105 | void (*evict_inode) (struct inode *); |
| 97 | void (*put_super) (struct super_block *); | 106 | void (*put_super) (struct super_block *); |
| @@ -105,10 +114,11 @@ prototypes: | |||
| 105 | int (*show_options)(struct seq_file *, struct vfsmount *); | 114 | int (*show_options)(struct seq_file *, struct vfsmount *); |
| 106 | ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); | 115 | ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); |
| 107 | ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); | 116 | ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); |
| 117 | int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t); | ||
| 118 | int (*trim_fs) (struct super_block *, struct fstrim_range *); | ||
| 108 | 119 | ||
| 109 | locking rules: | 120 | locking rules: |
| 110 | All may block [not true, see below] | 121 | All may block [not true, see below] |
| 111 | None have BKL | ||
| 112 | s_umount | 122 | s_umount |
| 113 | alloc_inode: | 123 | alloc_inode: |
| 114 | destroy_inode: | 124 | destroy_inode: |
| @@ -127,6 +137,8 @@ umount_begin: no | |||
| 127 | show_options: no (namespace_sem) | 137 | show_options: no (namespace_sem) |
| 128 | quota_read: no (see below) | 138 | quota_read: no (see below) |
| 129 | quota_write: no (see below) | 139 | quota_write: no (see below) |
| 140 | bdev_try_to_free_page: no (see below) | ||
| 141 | trim_fs: no | ||
| 130 | 142 | ||
| 131 | ->statfs() has s_umount (shared) when called by ustat(2) (native or | 143 | ->statfs() has s_umount (shared) when called by ustat(2) (native or |
| 132 | compat), but that's an accident of bad API; s_umount is used to pin | 144 | compat), but that's an accident of bad API; s_umount is used to pin |
| @@ -139,19 +151,25 @@ be the only ones operating on the quota file by the quota code (via | |||
| 139 | dqio_sem) (unless an admin really wants to screw up something and | 151 | dqio_sem) (unless an admin really wants to screw up something and |
| 140 | writes to quota files with quotas on). For other details about locking | 152 | writes to quota files with quotas on). For other details about locking |
| 141 | see also dquot_operations section. | 153 | see also dquot_operations section. |
| 154 | ->bdev_try_to_free_page is called from the ->releasepage handler of | ||
| 155 | the block device inode. See there for more details. | ||
| 142 | 156 | ||
| 143 | --------------------------- file_system_type --------------------------- | 157 | --------------------------- file_system_type --------------------------- |
| 144 | prototypes: | 158 | prototypes: |
| 145 | int (*get_sb) (struct file_system_type *, int, | 159 | int (*get_sb) (struct file_system_type *, int, |
| 146 | const char *, void *, struct vfsmount *); | 160 | const char *, void *, struct vfsmount *); |
| 161 | struct dentry *(*mount) (struct file_system_type *, int, | ||
| 162 | const char *, void *); | ||
| 147 | void (*kill_sb) (struct super_block *); | 163 | void (*kill_sb) (struct super_block *); |
| 148 | locking rules: | 164 | locking rules: |
| 149 | may block BKL | 165 | may block |
| 150 | get_sb yes no | 166 | get_sb yes |
| 151 | kill_sb yes no | 167 | mount yes |
| 168 | kill_sb yes | ||
| 152 | 169 | ||
| 153 | ->get_sb() returns error or 0 with locked superblock attached to the vfsmount | 170 | ->get_sb() returns error or 0 with locked superblock attached to the vfsmount |
| 154 | (exclusive on ->s_umount). | 171 | (exclusive on ->s_umount). |
| 172 | ->mount() returns ERR_PTR or the root dentry. | ||
| 155 | ->kill_sb() takes a write-locked superblock, does all shutdown work on it, | 173 | ->kill_sb() takes a write-locked superblock, does all shutdown work on it, |
| 156 | unlocks and drops the reference. | 174 | unlocks and drops the reference. |
| 157 | 175 | ||
| @@ -176,27 +194,35 @@ prototypes: | |||
| 176 | void (*freepage)(struct page *); | 194 | void (*freepage)(struct page *); |
| 177 | int (*direct_IO)(int, struct kiocb *, const struct iovec *iov, | 195 | int (*direct_IO)(int, struct kiocb *, const struct iovec *iov, |
| 178 | loff_t offset, unsigned long nr_segs); | 196 | loff_t offset, unsigned long nr_segs); |
| 179 | int (*launder_page) (struct page *); | 197 | int (*get_xip_mem)(struct address_space *, pgoff_t, int, void **, |
| 198 | unsigned long *); | ||
| 199 | int (*migratepage)(struct address_space *, struct page *, struct page *); | ||
| 200 | int (*launder_page)(struct page *); | ||
| 201 | int (*is_partially_uptodate)(struct page *, read_descriptor_t *, unsigned long); | ||
| 202 | int (*error_remove_page)(struct address_space *, struct page *); | ||
| 180 | 203 | ||
| 181 | locking rules: | 204 | locking rules: |
| 182 | All except set_page_dirty and freepage may block | 205 | All except set_page_dirty and freepage may block |
| 183 | 206 | ||
| 184 | BKL PageLocked(page) i_mutex | 207 | PageLocked(page) i_mutex |
| 185 | writepage: no yes, unlocks (see below) | 208 | writepage: yes, unlocks (see below) |
| 186 | readpage: no yes, unlocks | 209 | readpage: yes, unlocks |
| 187 | sync_page: no maybe | 210 | sync_page: maybe |
| 188 | writepages: no | 211 | writepages: |
| 189 | set_page_dirty no no | 212 | set_page_dirty no |
| 190 | readpages: no | 213 | readpages: |
| 191 | write_begin: no locks the page yes | 214 | write_begin: locks the page yes |
| 192 | write_end: no yes, unlocks yes | 215 | write_end: yes, unlocks yes |
| 193 | perform_write: no n/a yes | 216 | bmap: |
| 194 | bmap: no | 217 | invalidatepage: yes |
| 195 | invalidatepage: no yes | 218 | releasepage: yes |
| 196 | releasepage: no yes | 219 | freepage: yes |
| 197 | freepage: no yes | 220 | direct_IO: |
| 198 | direct_IO: no | 221 | get_xip_mem: maybe |
| 199 | launder_page: no yes | 222 | migratepage: yes (both) |
| 223 | launder_page: yes | ||
| 224 | is_partially_uptodate: yes | ||
| 225 | error_remove_page: yes | ||
| 200 | 226 | ||
| 201 | ->write_begin(), ->write_end(), ->sync_page() and ->readpage() | 227 | ->write_begin(), ->write_end(), ->sync_page() and ->readpage() |
| 202 | may be called from the request handler (/dev/loop). | 228 | may be called from the request handler (/dev/loop). |
| @@ -276,9 +302,8 @@ under spinlock (it cannot block) and is sometimes called with the page | |||
| 276 | not locked. | 302 | not locked. |
| 277 | 303 | ||
| 278 | ->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some | 304 | ->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some |
| 279 | filesystems and by the swapper. The latter will eventually go away. All | 305 | filesystems and by the swapper. The latter will eventually go away. Please, |
| 280 | instances do not actually need the BKL. Please, keep it that way and don't | 306 | keep it that way and don't breed new callers. |
| 281 | breed new callers. | ||
| 282 | 307 | ||
| 283 | ->invalidatepage() is called when the filesystem must attempt to drop | 308 | ->invalidatepage() is called when the filesystem must attempt to drop |
| 284 | some or all of the buffers from the page when it is being truncated. It | 309 | some or all of the buffers from the page when it is being truncated. It |
| @@ -299,47 +324,37 @@ cleaned, or an error value if not. Note that in order to prevent the page | |||
| 299 | getting mapped back in and redirtied, it needs to be kept locked | 324 | getting mapped back in and redirtied, it needs to be kept locked |
| 300 | across the entire operation. | 325 | across the entire operation. |
| 301 | 326 | ||
| 302 | Note: currently almost all instances of address_space methods are | ||
| 303 | using BKL for internal serialization and that's one of the worst sources | ||
| 304 | of contention. Normally they are calling library functions (in fs/buffer.c) | ||
| 305 | and pass foo_get_block() as a callback (on local block-based filesystems, | ||
| 306 | indeed). BKL is not needed for library stuff and is usually taken by | ||
| 307 | foo_get_block(). It's an overkill, since block bitmaps can be protected by | ||
| 308 | internal fs locking and real critical areas are much smaller than the areas | ||
| 309 | filesystems protect now. | ||
| 310 | |||
| 311 | ----------------------- file_lock_operations ------------------------------ | 327 | ----------------------- file_lock_operations ------------------------------ |
| 312 | prototypes: | 328 | prototypes: |
| 313 | void (*fl_insert)(struct file_lock *); /* lock insertion callback */ | ||
| 314 | void (*fl_remove)(struct file_lock *); /* lock removal callback */ | ||
| 315 | void (*fl_copy_lock)(struct file_lock *, struct file_lock *); | 329 | void (*fl_copy_lock)(struct file_lock *, struct file_lock *); |
| 316 | void (*fl_release_private)(struct file_lock *); | 330 | void (*fl_release_private)(struct file_lock *); |
| 317 | 331 | ||
| 318 | 332 | ||
| 319 | locking rules: | 333 | locking rules: |
| 320 | BKL may block | 334 | file_lock_lock may block |
| 321 | fl_insert: yes no | 335 | fl_copy_lock: yes no |
| 322 | fl_remove: yes no | 336 | fl_release_private: maybe no |
| 323 | fl_copy_lock: yes no | ||
| 324 | fl_release_private: yes yes | ||
| 325 | 337 | ||
| 326 | ----------------------- lock_manager_operations --------------------------- | 338 | ----------------------- lock_manager_operations --------------------------- |
| 327 | prototypes: | 339 | prototypes: |
| 328 | int (*fl_compare_owner)(struct file_lock *, struct file_lock *); | 340 | int (*fl_compare_owner)(struct file_lock *, struct file_lock *); |
| 329 | void (*fl_notify)(struct file_lock *); /* unblock callback */ | 341 | void (*fl_notify)(struct file_lock *); /* unblock callback */ |
| 342 | int (*fl_grant)(struct file_lock *, struct file_lock *, int); | ||
| 330 | void (*fl_release_private)(struct file_lock *); | 343 | void (*fl_release_private)(struct file_lock *); |
| 331 | void (*fl_break)(struct file_lock *); /* break_lease callback */ | 344 | void (*fl_break)(struct file_lock *); /* break_lease callback */ |
| 345 | int (*fl_mylease)(struct file_lock *, struct file_lock *); | ||
| 346 | int (*fl_change)(struct file_lock **, int); | ||
| 332 | 347 | ||
| 333 | locking rules: | 348 | locking rules: |
| 334 | BKL may block | 349 | file_lock_lock may block |
| 335 | fl_compare_owner: yes no | 350 | fl_compare_owner: yes no |
| 336 | fl_notify: yes no | 351 | fl_notify: yes no |
| 337 | fl_release_private: yes yes | 352 | fl_grant: no no |
| 338 | fl_break: yes no | 353 | fl_release_private: maybe no |
| 339 | 354 | fl_break: yes no | |
| 340 | Currently only NFSD and NLM provide instances of this class. None of the | 355 | fl_mylease: yes no |
| 341 | them block. If you have out-of-tree instances - please, show up. Locking | 356 | fl_change yes no |
| 342 | in that area will change. | 357 | |
| 343 | --------------------------- buffer_head ----------------------------------- | 358 | --------------------------- buffer_head ----------------------------------- |
| 344 | prototypes: | 359 | prototypes: |
| 345 | void (*b_end_io)(struct buffer_head *bh, int uptodate); | 360 | void (*b_end_io)(struct buffer_head *bh, int uptodate); |
| @@ -364,17 +379,17 @@ prototypes: | |||
| 364 | void (*swap_slot_free_notify) (struct block_device *, unsigned long); | 379 | void (*swap_slot_free_notify) (struct block_device *, unsigned long); |
| 365 | 380 | ||
| 366 | locking rules: | 381 | locking rules: |
| 367 | BKL bd_mutex | 382 | bd_mutex |
| 368 | open: no yes | 383 | open: yes |
| 369 | release: no yes | 384 | release: yes |
| 370 | ioctl: no no | 385 | ioctl: no |
| 371 | compat_ioctl: no no | 386 | compat_ioctl: no |
| 372 | direct_access: no no | 387 | direct_access: no |
| 373 | media_changed: no no | 388 | media_changed: no |
| 374 | unlock_native_capacity: no no | 389 | unlock_native_capacity: no |
| 375 | revalidate_disk: no no | 390 | revalidate_disk: no |
| 376 | getgeo: no no | 391 | getgeo: no |
| 377 | swap_slot_free_notify: no no (see below) | 392 | swap_slot_free_notify: no (see below) |
| 378 | 393 | ||
| 379 | media_changed, unlock_native_capacity and revalidate_disk are called only from | 394 | media_changed, unlock_native_capacity and revalidate_disk are called only from |
| 380 | check_disk_change(). | 395 | check_disk_change(). |
| @@ -413,34 +428,21 @@ prototypes: | |||
| 413 | unsigned long (*get_unmapped_area)(struct file *, unsigned long, | 428 | unsigned long (*get_unmapped_area)(struct file *, unsigned long, |
| 414 | unsigned long, unsigned long, unsigned long); | 429 | unsigned long, unsigned long, unsigned long); |
| 415 | int (*check_flags)(int); | 430 | int (*check_flags)(int); |
| 431 | int (*flock) (struct file *, int, struct file_lock *); | ||
| 432 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, | ||
| 433 | size_t, unsigned int); | ||
| 434 | ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, | ||
| 435 | size_t, unsigned int); | ||
| 436 | int (*setlease)(struct file *, long, struct file_lock **); | ||
| 416 | }; | 437 | }; |
| 417 | 438 | ||
| 418 | locking rules: | 439 | locking rules: |
| 419 | All may block. | 440 | All may block except for ->setlease. |
| 420 | BKL | 441 | No VFS locks held on entry except for ->fsync and ->setlease. |
| 421 | llseek: no (see below) | 442 | |
| 422 | read: no | 443 | ->fsync() has i_mutex on inode. |
| 423 | aio_read: no | 444 | |
| 424 | write: no | 445 | ->setlease has the file_list_lock held and must not sleep. |
| 425 | aio_write: no | ||
| 426 | readdir: no | ||
| 427 | poll: no | ||
| 428 | unlocked_ioctl: no | ||
| 429 | compat_ioctl: no | ||
| 430 | mmap: no | ||
| 431 | open: no | ||
| 432 | flush: no | ||
| 433 | release: no | ||
| 434 | fsync: no (see below) | ||
| 435 | aio_fsync: no | ||
| 436 | fasync: no | ||
| 437 | lock: yes | ||
| 438 | readv: no | ||
| 439 | writev: no | ||
| 440 | sendfile: no | ||
| 441 | sendpage: no | ||
| 442 | get_unmapped_area: no | ||
| 443 | check_flags: no | ||
| 444 | 446 | ||
| 445 | ->llseek() locking has moved from llseek to the individual llseek | 447 | ->llseek() locking has moved from llseek to the individual llseek |
| 446 | implementations. If your fs is not using generic_file_llseek, you | 448 | implementations. If your fs is not using generic_file_llseek, you |
| @@ -450,17 +452,10 @@ mutex or just to use i_size_read() instead. | |||
| 450 | Note: this does not protect the file->f_pos against concurrent modifications | 452 | Note: this does not protect the file->f_pos against concurrent modifications |
| 451 | since this is something the userspace has to take care about. | 453 | since this is something the userspace has to take care about. |
| 452 | 454 | ||
| 453 | Note: ext2_release() was *the* source of contention on fs-intensive | 455 | ->fasync() is responsible for maintaining the FASYNC bit in filp->f_flags. |
| 454 | loads and dropping BKL on ->release() helps to get rid of that (we still | 456 | Most instances call fasync_helper(), which does that maintenance, so it's |
| 455 | grab BKL for cases when we close a file that had been opened r/w, but that | 457 | not normally something one needs to worry about. Return values > 0 will be |
| 456 | can and should be done using the internal locking with smaller critical areas). | 458 | mapped to zero in the VFS layer. |
| 457 | Current worst offender is ext2_get_block()... | ||
| 458 | |||
| 459 | ->fasync() is called without BKL protection, and is responsible for | ||
| 460 | maintaining the FASYNC bit in filp->f_flags. Most instances call | ||
| 461 | fasync_helper(), which does that maintenance, so it's not normally | ||
| 462 | something one needs to worry about. Return values > 0 will be mapped to | ||
| 463 | zero in the VFS layer. | ||
| 464 | 459 | ||
| 465 | ->readdir() and ->ioctl() on directories must be changed. Ideally we would | 460 | ->readdir() and ->ioctl() on directories must be changed. Ideally we would |
| 466 | move ->readdir() to inode_operations and use a separate method for directory | 461 | move ->readdir() to inode_operations and use a separate method for directory |
| @@ -471,8 +466,6 @@ components. And there are other reasons why the current interface is a mess... | |||
| 471 | ->read on directories probably must go away - we should just enforce -EISDIR | 466 | ->read on directories probably must go away - we should just enforce -EISDIR |
| 472 | in sys_read() and friends. | 467 | in sys_read() and friends. |
| 473 | 468 | ||
| 474 | ->fsync() has i_mutex on inode. | ||
| 475 | |||
| 476 | --------------------------- dquot_operations ------------------------------- | 469 | --------------------------- dquot_operations ------------------------------- |
| 477 | prototypes: | 470 | prototypes: |
| 478 | int (*write_dquot) (struct dquot *); | 471 | int (*write_dquot) (struct dquot *); |
| @@ -507,12 +500,12 @@ prototypes: | |||
| 507 | int (*access)(struct vm_area_struct *, unsigned long, void*, int, int); | 500 | int (*access)(struct vm_area_struct *, unsigned long, void*, int, int); |
| 508 | 501 | ||
| 509 | locking rules: | 502 | locking rules: |
| 510 | BKL mmap_sem PageLocked(page) | 503 | mmap_sem PageLocked(page) |
| 511 | open: no yes | 504 | open: yes |
| 512 | close: no yes | 505 | close: yes |
| 513 | fault: no yes can return with page locked | 506 | fault: yes can return with page locked |
| 514 | page_mkwrite: no yes can return with page locked | 507 | page_mkwrite: yes can return with page locked |
| 515 | access: no yes | 508 | access: yes |
| 516 | 509 | ||
| 517 | ->fault() is called when a previously not present pte is about | 510 | ->fault() is called when a previously not present pte is about |
| 518 | to be faulted in. The filesystem must find and return the page associated | 511 | to be faulted in. The filesystem must find and return the page associated |
| @@ -539,6 +532,3 @@ VM_IO | VM_PFNMAP VMAs. | |||
| 539 | 532 | ||
| 540 | (if you break something or notice that it is broken and do not fix it yourself | 533 | (if you break something or notice that it is broken and do not fix it yourself |
| 541 | - at least put it here) | 534 | - at least put it here) |
| 542 | |||
| 543 | ipc/shm.c::shm_delete() - may need BKL. | ||
| 544 | ->read() and ->write() in many drivers are (probably) missing BKL. | ||
