Commit 7f2db912 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] update Documentation/filesystems/Locking

From: Matthew Wilcox <willy@debian.org>

Here's an update to Documentation/filesystems/Locking.
parent 090cd1b4
...@@ -28,8 +28,9 @@ d_iput: no no no yes ...@@ -28,8 +28,9 @@ d_iput: no no no yes
--------------------------- inode_operations --------------------------- --------------------------- inode_operations ---------------------------
prototypes: prototypes:
int (*create) (struct inode *,struct dentry *,int); int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
struct dentry * (*lookup) (struct inode *,struct dentry *); struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameid
ata *);
int (*link) (struct dentry *,struct inode *,struct dentry *); int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *); int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct inode *,struct dentry *,const char *); int (*symlink) (struct inode *,struct dentry *,const char *);
...@@ -38,13 +39,13 @@ prototypes: ...@@ -38,13 +39,13 @@ prototypes:
int (*mknod) (struct inode *,struct dentry *,int,dev_t); int (*mknod) (struct inode *,struct dentry *,int,dev_t);
int (*rename) (struct inode *, struct dentry *, int (*rename) (struct inode *, struct dentry *,
struct inode *, struct dentry *); struct inode *, struct dentry *);
int (*readlink) (struct dentry *, char *,int); int (*readlink) (struct dentry *, char __user *,int);
int (*follow_link) (struct dentry *, struct nameidata *); int (*follow_link) (struct dentry *, struct nameidata *);
void (*truncate) (struct inode *); void (*truncate) (struct inode *);
int (*permission) (struct inode *, int); int (*permission) (struct inode *, int, struct nameidata *);
int (*setattr) (struct dentry *, struct iattr *); int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *); int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *, void *, size_t, int); int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t); ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *); int (*removexattr) (struct dentry *, const char *);
...@@ -85,42 +86,55 @@ of the locking scheme for directory operations. ...@@ -85,42 +86,55 @@ of the locking scheme for directory operations.
--------------------------- super_operations --------------------------- --------------------------- super_operations ---------------------------
prototypes: prototypes:
struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);
void (*read_inode) (struct inode *); void (*read_inode) (struct inode *);
void (*dirty_inode) (struct inode *);
void (*write_inode) (struct inode *, int); void (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *); void (*put_inode) (struct inode *);
void (*drop_inode) (struct inode *); void (*drop_inode) (struct inode *);
void (*delete_inode) (struct inode *); void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *); void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *); void (*write_super) (struct super_block *);
int (*sync_fs) (struct super_block *sb, int wait); int (*sync_fs)(struct super_block *sb, int wait);
int (*statfs) (struct super_block *, struct statfs *); void (*write_super_lockfs) (struct super_block *);
void (*unlockfs) (struct super_block *);
int (*statfs) (struct super_block *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *); int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *); void (*clear_inode) (struct inode *);
void (*umount_begin) (struct super_block *); void (*umount_begin) (struct super_block *);
int (*show_options)(struct seq_file *, struct vfsmount *);
locking rules: locking rules:
All may block. All may block.
BKL s_lock mount_sem BKL s_lock s_umount
read_inode: yes (see below) alloc_inode: no no no
destroy_inode: no
read_inode: no (see below)
dirty_inode: no (must not sleep)
write_inode: no write_inode: no
put_inode: no put_inode: no
drop_inode: no !!!inode_lock!!! drop_inode: no !!!inode_lock!!!
delete_inode: no delete_inode: no
clear_inode: no put_super: yes yes no
put_super: yes yes maybe (see below) write_super: no yes read
write_super: no yes maybe (see below) sync_fs: no no read
sync_fs: no no maybe (see below) write_super_lockfs: ?
unlockfs: ?
statfs: no no no statfs: no no no
remount_fs: yes yes maybe (see below) remount_fs: no yes maybe (see below)
umount_begin: yes no maybe (see below) clear_inode: no
umount_begin: yes no no
show_options: no (vfsmount->sem)
->read_inode() is not a method - it's a callback used in iget(). ->read_inode() is not a method - it's a callback used in iget().
rules for mount_sem are not too nice - it is going to die and be replaced ->remount_fs() will have the s_umount lock if it's already mounted.
by better scheme anyway. When called from get_sb_single, it does NOT have the s_umount lock.
--------------------------- file_system_type --------------------------- --------------------------- file_system_type ---------------------------
prototypes: prototypes:
struct super_block *(*get_sb) (struct file_system_type *, int, const char *, void *); struct super_block *(*get_sb) (struct file_system_type *, int,
const char *, void *);
void (*kill_sb) (struct super_block *); void (*kill_sb) (struct super_block *);
locking rules: locking rules:
may block BKL may block BKL
...@@ -128,7 +142,7 @@ get_sb yes yes ...@@ -128,7 +142,7 @@ get_sb yes yes
kill_sb yes yes kill_sb yes yes
->get_sb() returns error or a locked superblock (exclusive on ->s_umount). ->get_sb() returns error or a locked superblock (exclusive on ->s_umount).
->kill_sb() takes a locked superblock, does all shutdown work on it, ->kill_sb() takes a write-locked superblock, does all shutdown work on it,
unlocks and drops the reference. unlocks and drops the reference.
--------------------------- address_space_operations -------------------------- --------------------------- address_space_operations --------------------------
...@@ -138,12 +152,15 @@ prototypes: ...@@ -138,12 +152,15 @@ prototypes:
int (*sync_page)(struct page *); int (*sync_page)(struct page *);
int (*writepages)(struct address_space *, struct writeback_control *); int (*writepages)(struct address_space *, struct writeback_control *);
int (*set_page_dirty)(struct page *page); int (*set_page_dirty)(struct page *page);
int (*readpages)(struct file *filp, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages);
int (*prepare_write)(struct file *, struct page *, unsigned, unsigned); int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
int (*commit_write)(struct file *, struct page *, unsigned, unsigned); int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
int (*bmap)(struct address_space *, long); sector_t (*bmap)(struct address_space *, sector_t);
int (*invalidatepage) (struct page *, unsigned long); int (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, int); int (*releasepage) (struct page *, int);
int (*direct_IO)(int, struct inode *, struct kiobuf *, unsigned long, int); int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
locking rules: locking rules:
All except set_page_dirty may block All except set_page_dirty may block
...@@ -151,15 +168,16 @@ locking rules: ...@@ -151,15 +168,16 @@ locking rules:
BKL PageLocked(page) BKL PageLocked(page)
writepage: no yes, unlocks (see below) writepage: no yes, unlocks (see below)
readpage: no yes, unlocks readpage: no yes, unlocks
readpages: no
sync_page: no maybe sync_page: no maybe
writepages: no writepages: no
set_page_dirty no no set_page_dirty no no
readpages: no
prepare_write: no yes prepare_write: no yes
commit_write: no yes commit_write: no yes
bmap: yes bmap: yes
invalidatepage: no yes invalidatepage: no yes
releasepage: no yes releasepage: no yes
direct_IO: no
->prepare_write(), ->commit_write(), ->sync_page() and ->readpage() ->prepare_write(), ->commit_write(), ->sync_page() and ->readpage()
may be called from the request handler (/dev/loop). may be called from the request handler (/dev/loop).
...@@ -253,8 +271,8 @@ prototypes: ...@@ -253,8 +271,8 @@ prototypes:
locking rules: locking rules:
BKL may block BKL may block
fl_notify: yes no fl_notify: yes no
fl_insert: yes maybe fl_insert: yes no
fl_remove: yes maybe fl_remove: yes no
Currently only NLM provides instances of this class. None of the Currently only NLM provides instances of this class. None of the
them block. If you have out-of-tree instances - please, show up. Locking them block. If you have out-of-tree instances - please, show up. Locking
in that area will change. in that area will change.
...@@ -274,45 +292,59 @@ prototypes: ...@@ -274,45 +292,59 @@ prototypes:
int (*open) (struct inode *, struct file *); int (*open) (struct inode *, struct file *);
int (*release) (struct inode *, struct file *); int (*release) (struct inode *, struct file *);
int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long); int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
int (*check_media_change) (kdev_t); int (*media_changed) (struct gendisk *);
int (*revalidate) (kdev_t); int (*revalidate_disk) (struct gendisk *);
locking rules: locking rules:
BKL bd_sem BKL bd_sem
open: yes yes open: yes yes
release: yes yes release: yes yes
ioctl: yes no ioctl: yes no
check_media_change: yes no media_changed: no no
revalidate: yes no revalidate_disk: no no
The last two are called only from check_disk_change(). Prototypes are very The last two are called only from check_disk_change().
bad - as soon as we'll get disk_struct they will change (and methods will
become per-disk instead of per-partition).
--------------------------- file_operations ------------------------------- --------------------------- file_operations -------------------------------
prototypes: prototypes:
loff_t (*llseek) (struct file *, loff_t, int); loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *); ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t,
loff_t);
int (*readdir) (struct file *, void *, filldir_t); int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *); unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*ioctl) (struct inode *, struct file *, unsigned int,
unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *); int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *); int (*open) (struct inode *, struct file *);
int (*flush) (struct file *); int (*flush) (struct file *);
int (*release) (struct inode *, struct file *); int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int datasync); int (*fsync) (struct file *, struct dentry *, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int); int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *); int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*readv) (struct file *, const struct iovec *, unsigned long,
ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); loff_t *);
ssize_t (*writev) (struct file *, const struct iovec *, unsigned long,
loff_t *);
ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t,
void __user *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t,
loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long,
unsigned long, unsigned long, unsigned long);
}; };
locking rules: locking rules:
All except ->poll() may block. All except ->poll() may block.
BKL BKL
llseek: yes (see below) llseek: no (see below)
read: no read: no
aio_read: no
write: no write: no
aio_write: no
readdir: no readdir: no
poll: no poll: no
ioctl: yes (see below) ioctl: yes (see below)
...@@ -320,11 +352,15 @@ mmap: no ...@@ -320,11 +352,15 @@ mmap: no
open: maybe (see below) open: maybe (see below)
flush: no flush: no
release: no release: no
fsync: yes (see below) fsync: no (see below)
aio_fsync: no
fasync: yes (see below) fasync: yes (see below)
lock: yes lock: yes
readv: no readv: no
writev: no writev: no
sendfile: no
sendpage: no
get_unmapped_area: no
->llseek() locking has moved from llseek to the individual llseek ->llseek() locking has moved from llseek to the individual llseek
implementations. If your fs is not using generic_file_llseek, you implementations. If your fs is not using generic_file_llseek, you
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment