diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 09:10:19 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 09:10:19 -0700 | 
| commit | 790eac5640abf7a57fa3a644386df330e18c11b0 (patch) | |
| tree | 08de20bde44f59e51b91ff473a71047c2957e8c9 /Documentation/filesystems | |
| parent | 0b0585c3e192967cb2ef0ac0816eb8a8c8d99840 (diff) | |
| parent | 48bde8d3620f5f3c6ae9ff599eb404055ae51664 (diff) | |
| download | linux-790eac5640abf7a57fa3a644386df330e18c11b0.tar.bz2 | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second set of VFS changes from Al Viro:
 "Assorted f_pos race fixes, making do_splice_direct() safe to call with
  i_mutex on parent, O_TMPFILE support, Jeff's locks.c series,
  ->d_hash/->d_compare calling conventions changes from Linus, misc
  stuff all over the place."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits)
  Document ->tmpfile()
  ext4: ->tmpfile() support
  vfs: export lseek_execute() to modules
  lseek_execute() doesn't need an inode passed to it
  block_dev: switch to fixed_size_llseek()
  cpqphp_sysfs: switch to fixed_size_llseek()
  tile-srom: switch to fixed_size_llseek()
  proc_powerpc: switch to fixed_size_llseek()
  ubi/cdev: switch to fixed_size_llseek()
  pci/proc: switch to fixed_size_llseek()
  isapnp: switch to fixed_size_llseek()
  lpfc: switch to fixed_size_llseek()
  locks: give the blocked_hash its own spinlock
  locks: add a new "lm_owner_key" lock operation
  locks: turn the blocked_list into a hashtable
  locks: convert fl_link to a hlist_node
  locks: avoid taking global lock if possible when waking up blocked waiters
  locks: protect most of the file_lock handling with i_lock
  locks: encapsulate the fl_link list handling
  locks: make "added" in __posix_lock_file a bool
  ...
Diffstat (limited to 'Documentation/filesystems')
| -rw-r--r-- | Documentation/filesystems/Locking | 35 | ||||
| -rw-r--r-- | Documentation/filesystems/vfs.txt | 24 | 
2 files changed, 37 insertions, 22 deletions
| diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 9858f337529c..fe7afe225381 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -11,10 +11,8 @@ be able to use diff(1).  prototypes:  	int (*d_revalidate)(struct dentry *, unsigned int);  	int (*d_weak_revalidate)(struct dentry *, unsigned int); -	int (*d_hash)(const struct dentry *, const struct inode *, -			struct qstr *); -	int (*d_compare)(const struct dentry *, const struct inode *, -			const struct dentry *, const struct inode *, +	int (*d_hash)(const struct dentry *, struct qstr *); +	int (*d_compare)(const struct dentry *, const struct dentry *,  			unsigned int, const char *, const struct qstr *);  	int (*d_delete)(struct dentry *);  	void (*d_release)(struct dentry *); @@ -66,6 +64,7 @@ prototypes:  	int (*atomic_open)(struct inode *, struct dentry *,  				struct file *, unsigned open_flag,  				umode_t create_mode, int *opened); +	int (*tmpfile) (struct inode *, struct dentry *, umode_t);  locking rules:  	all may block @@ -93,6 +92,7 @@ removexattr:	yes  fiemap:		no  update_time:	no  atomic_open:	yes +tmpfile:	no  	Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on  victim. @@ -344,25 +344,38 @@ prototypes:  locking rules: -			file_lock_lock	may block +			inode->i_lock	may block  fl_copy_lock:		yes		no  fl_release_private:	maybe		no  ----------------------- lock_manager_operations ---------------------------  prototypes:  	int (*lm_compare_owner)(struct file_lock *, struct file_lock *); +	unsigned long (*lm_owner_key)(struct file_lock *);  	void (*lm_notify)(struct file_lock *);  /* unblock callback */  	int (*lm_grant)(struct file_lock *, struct file_lock *, int);  	void (*lm_break)(struct file_lock *); /* break_lease callback */  	int (*lm_change)(struct file_lock **, int);  locking rules: -			file_lock_lock	may block -lm_compare_owner:	yes		no -lm_notify:		yes		no -lm_grant:		no		no -lm_break:		yes		no -lm_change		yes		no + +			inode->i_lock	blocked_lock_lock	may block +lm_compare_owner:	yes[1]		maybe			no +lm_owner_key		yes[1]		yes			no +lm_notify:		yes		yes			no +lm_grant:		no		no			no +lm_break:		yes		no			no +lm_change		yes		no			no + +[1]:	->lm_compare_owner and ->lm_owner_key are generally called with +*an* inode->i_lock held. It may not be the i_lock of the inode +associated with either file_lock argument! This is the case with deadlock +detection, since the code has to chase down the owners of locks that may +be entirely unrelated to the one on which the lock is being acquired. +For deadlock detection however, the blocked_lock_lock is also held. The +fact that these locks are held ensures that the file_locks do not +disappear out from under you while doing the comparison or generating an +owner key.  --------------------------- buffer_head -----------------------------------  prototypes: diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index e6bd1ffd821e..1f0ba30ae47e 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -360,6 +360,8 @@ struct inode_operations {  	int (*removexattr) (struct dentry *, const char *);  	void (*update_time)(struct inode *, struct timespec *, int);  	int (*atomic_open)(struct inode *, struct dentry *, +	int (*tmpfile) (struct inode *, struct dentry *, umode_t); +} ____cacheline_aligned;  				struct file *, unsigned open_flag,  				umode_t create_mode, int *opened);  }; @@ -472,6 +474,9 @@ otherwise noted.    	component is negative or needs lookup.  Cached positive dentries are    	still handled by f_op->open(). +  tmpfile: called in the end of O_TMPFILE open().  Optional, equivalent to +	atomically creating, opening and unlinking a file in given directory. +  The Address Space Object  ======================== @@ -901,10 +906,8 @@ defined:  struct dentry_operations {  	int (*d_revalidate)(struct dentry *, unsigned int);  	int (*d_weak_revalidate)(struct dentry *, unsigned int); -	int (*d_hash)(const struct dentry *, const struct inode *, -			struct qstr *); -	int (*d_compare)(const struct dentry *, const struct inode *, -			const struct dentry *, const struct inode *, +	int (*d_hash)(const struct dentry *, struct qstr *); +	int (*d_compare)(const struct dentry *, const struct dentry *,  			unsigned int, const char *, const struct qstr *);  	int (*d_delete)(const struct dentry *);  	void (*d_release)(struct dentry *); @@ -949,25 +952,24 @@ struct dentry_operations {    d_hash: called when the VFS adds a dentry to the hash table. The first  	dentry passed to d_hash is the parent directory that the name is -	to be hashed into. The inode is the dentry's inode. +	to be hashed into.  	Same locking and synchronisation rules as d_compare regarding  	what is safe to dereference etc.    d_compare: called to compare a dentry name with a given name. The first  	dentry is the parent of the dentry to be compared, the second is -	the parent's inode, then the dentry and inode (may be NULL) of the -	child dentry. len and name string are properties of the dentry to be -	compared. qstr is the name to compare it with. +	the child dentry. len and name string are properties of the dentry +	to be compared. qstr is the name to compare it with.  	Must be constant and idempotent, and should not take locks if -	possible, and should not or store into the dentry or inodes. -	Should not dereference pointers outside the dentry or inodes without +	possible, and should not or store into the dentry. +	Should not dereference pointers outside the dentry without  	lots of care (eg.  d_parent, d_inode, d_name should not be used).  	However, our vfsmount is pinned, and RCU held, so the dentries and  	inodes won't disappear, neither will our sb or filesystem module. -	->i_sb and ->d_sb may be used. +	->d_sb may be used.  	It is a tricky calling convention because it needs to be called under  	"rcu-walk", ie. without any locks or references on things. |