aboutsummaryrefslogtreecommitdiffstats
path: root/fs/quota
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-04-25 15:15:53 -0400
committerJan Kara <jack@suse.cz>2012-05-15 17:34:39 -0400
commita80b12c3d08dbbf15e6a551e481c32a2df4911f3 (patch)
tree364989f0fc990496820296b5fc6b655e29416c14 /fs/quota
parentf9ef178412cab442719c9ffdc659933f5f2fa87e (diff)
quota: Get rid of nested I_MUTEX_QUOTA locking subclass
So far i_mutex was ranking above dqonoff_mutex and i_mutex on quota files was special and ranking below dqonoff_mutex (and several other locks). However there's no real need for i_mutex on quota files to be special. IO on quota files is serialized by dqio_mutex anyway so we don't need to take i_mutex when writing to quota files. Other places where we take i_mutex on quota file can accomodate standard i_mutex lock ranking, we only need to change the lock ranking to be dqonoff_mutex > i_mutex which is a matter of changing documentation because there's no place which would enforce ordering in the other direction. Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/quota')
-rw-r--r--fs/quota/dquot.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 6e429fdda17d..10cbe841cb7e 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -116,15 +116,15 @@
116 * spinlock to internal buffers before writing. 116 * spinlock to internal buffers before writing.
117 * 117 *
118 * Lock ordering (including related VFS locks) is the following: 118 * Lock ordering (including related VFS locks) is the following:
119 * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > 119 * dqonoff_mutex > i_mutex > journal_lock > dqptr_sem > dquot->dq_lock >
120 * dqio_mutex 120 * dqio_mutex
121 * dqonoff_mutex > i_mutex comes from dquot_quota_sync, dquot_enable, etc.
121 * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem > 122 * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem >
122 * dqptr_sem. But filesystem has to count with the fact that functions such as 123 * dqptr_sem. But filesystem has to count with the fact that functions such as
123 * dquot_alloc_space() acquire dqptr_sem and they usually have to be called 124 * dquot_alloc_space() acquire dqptr_sem and they usually have to be called
124 * from inside a transaction to keep filesystem consistency after a crash. Also 125 * from inside a transaction to keep filesystem consistency after a crash. Also
125 * filesystems usually want to do some IO on dquot from ->mark_dirty which is 126 * filesystems usually want to do some IO on dquot from ->mark_dirty which is
126 * called with dqptr_sem held. 127 * called with dqptr_sem held.
127 * i_mutex on quota files is special (it's below dqio_mutex)
128 */ 128 */
129 129
130static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); 130static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock);
@@ -658,8 +658,7 @@ int dquot_quota_sync(struct super_block *sb, int type, int wait)
658 continue; 658 continue;
659 if (!sb_has_quota_active(sb, cnt)) 659 if (!sb_has_quota_active(sb, cnt))
660 continue; 660 continue;
661 mutex_lock_nested(&dqopt->files[cnt]->i_mutex, 661 mutex_lock(&dqopt->files[cnt]->i_mutex);
662 I_MUTEX_QUOTA);
663 truncate_inode_pages(&dqopt->files[cnt]->i_data, 0); 662 truncate_inode_pages(&dqopt->files[cnt]->i_data, 0);
664 mutex_unlock(&dqopt->files[cnt]->i_mutex); 663 mutex_unlock(&dqopt->files[cnt]->i_mutex);
665 } 664 }
@@ -2037,8 +2036,7 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
2037 /* If quota was reenabled in the meantime, we have 2036 /* If quota was reenabled in the meantime, we have
2038 * nothing to do */ 2037 * nothing to do */
2039 if (!sb_has_quota_loaded(sb, cnt)) { 2038 if (!sb_has_quota_loaded(sb, cnt)) {
2040 mutex_lock_nested(&toputinode[cnt]->i_mutex, 2039 mutex_lock(&toputinode[cnt]->i_mutex);
2041 I_MUTEX_QUOTA);
2042 toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | 2040 toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
2043 S_NOATIME | S_NOQUOTA); 2041 S_NOATIME | S_NOQUOTA);
2044 truncate_inode_pages(&toputinode[cnt]->i_data, 2042 truncate_inode_pages(&toputinode[cnt]->i_data,
@@ -2133,7 +2131,7 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
2133 /* We don't want quota and atime on quota files (deadlocks 2131 /* We don't want quota and atime on quota files (deadlocks
2134 * possible) Also nobody should write to the file - we use 2132 * possible) Also nobody should write to the file - we use
2135 * special IO operations which ignore the immutable bit. */ 2133 * special IO operations which ignore the immutable bit. */
2136 mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); 2134 mutex_lock(&inode->i_mutex);
2137 oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | 2135 oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE |
2138 S_NOQUOTA); 2136 S_NOQUOTA);
2139 inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; 2137 inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
@@ -2180,7 +2178,7 @@ out_file_init:
2180 iput(inode); 2178 iput(inode);
2181out_lock: 2179out_lock:
2182 if (oldflags != -1) { 2180 if (oldflags != -1) {
2183 mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); 2181 mutex_lock(&inode->i_mutex);
2184 /* Set the flags back (in the case of accidental quotaon() 2182 /* Set the flags back (in the case of accidental quotaon()
2185 * on a wrong file we don't want to mess up the flags) */ 2183 * on a wrong file we don't want to mess up the flags) */
2186 inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE); 2184 inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE);