aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2016-11-23 08:04:55 -0500
committerJan Kara <jack@suse.cz>2016-11-30 02:38:07 -0500
commitc3b004460d77bf3f980d877be539016f2df4df12 (patch)
tree3000d941e7b3ac2fd3ea20d625a384dc4a28a977
parent5f530de63cfc6ca8571cbdf58af63fb166cc6517 (diff)
quota: Remove dqonoff_mutex
The only places that were grabbing dqonoff_mutex are functions turning quotas on and off and these are properly serialized using s_umount semaphore. Remove dqonoff_mutex. Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/quota/dquot.c80
-rw-r--r--fs/super.c1
-rw-r--r--include/linux/quota.h1
3 files changed, 23 insertions, 59 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index d91aecc939c9..550f78f2b7c7 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -119,8 +119,7 @@
119 * spinlock to internal buffers before writing. 119 * spinlock to internal buffers before writing.
120 * 120 *
121 * Lock ordering (including related VFS locks) is the following: 121 * Lock ordering (including related VFS locks) is the following:
122 * dqonoff_mutex > i_mutex > journal_lock > dquot->dq_lock > dqio_mutex 122 * s_umount > i_mutex > journal_lock > dquot->dq_lock > dqio_mutex
123 * dqonoff_mutex > i_mutex comes from dquot_quota_sync, dquot_enable, etc.
124 */ 123 */
125 124
126static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); 125static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock);
@@ -933,7 +932,7 @@ static int dqinit_needed(struct inode *inode, int type)
933 return 0; 932 return 0;
934} 933}
935 934
936/* This routine is guarded by dqonoff_mutex mutex */ 935/* This routine is guarded by s_umount semaphore */
937static void add_dquot_ref(struct super_block *sb, int type) 936static void add_dquot_ref(struct super_block *sb, int type)
938{ 937{
939 struct inode *inode, *old_inode = NULL; 938 struct inode *inode, *old_inode = NULL;
@@ -2108,18 +2107,14 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
2108 DQUOT_USAGE_ENABLED))) 2107 DQUOT_USAGE_ENABLED)))
2109 return -EINVAL; 2108 return -EINVAL;
2110 2109
2111 /* We need to serialize quota_off() for device */
2112 mutex_lock(&dqopt->dqonoff_mutex);
2113
2114 /* 2110 /*
2115 * Skip everything if there's nothing to do. We have to do this because 2111 * Skip everything if there's nothing to do. We have to do this because
2116 * sometimes we are called when fill_super() failed and calling 2112 * sometimes we are called when fill_super() failed and calling
2117 * sync_fs() in such cases does no good. 2113 * sync_fs() in such cases does no good.
2118 */ 2114 */
2119 if (!sb_any_quota_loaded(sb)) { 2115 if (!sb_any_quota_loaded(sb))
2120 mutex_unlock(&dqopt->dqonoff_mutex);
2121 return 0; 2116 return 0;
2122 } 2117
2123 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 2118 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
2124 toputinode[cnt] = NULL; 2119 toputinode[cnt] = NULL;
2125 if (type != -1 && cnt != type) 2120 if (type != -1 && cnt != type)
@@ -2173,7 +2168,6 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
2173 dqopt->info[cnt].dqi_bgrace = 0; 2168 dqopt->info[cnt].dqi_bgrace = 0;
2174 dqopt->ops[cnt] = NULL; 2169 dqopt->ops[cnt] = NULL;
2175 } 2170 }
2176 mutex_unlock(&dqopt->dqonoff_mutex);
2177 2171
2178 /* Skip syncing and setting flags if quota files are hidden */ 2172 /* Skip syncing and setting flags if quota files are hidden */
2179 if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) 2173 if (dqopt->flags & DQUOT_QUOTA_SYS_FILE)
@@ -2191,19 +2185,13 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
2191 * changes done by userspace on the next quotaon() */ 2185 * changes done by userspace on the next quotaon() */
2192 for (cnt = 0; cnt < MAXQUOTAS; cnt++) 2186 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
2193 if (toputinode[cnt]) { 2187 if (toputinode[cnt]) {
2194 mutex_lock(&dqopt->dqonoff_mutex); 2188 WARN_ON_ONCE(sb_has_quota_loaded(sb, cnt));
2195 /* If quota was reenabled in the meantime, we have 2189 inode_lock(toputinode[cnt]);
2196 * nothing to do */ 2190 toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
2197 if (!sb_has_quota_loaded(sb, cnt)) {
2198 inode_lock(toputinode[cnt]);
2199 toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
2200 S_NOATIME | S_NOQUOTA); 2191 S_NOATIME | S_NOQUOTA);
2201 truncate_inode_pages(&toputinode[cnt]->i_data, 2192 truncate_inode_pages(&toputinode[cnt]->i_data, 0);
2202 0); 2193 inode_unlock(toputinode[cnt]);
2203 inode_unlock(toputinode[cnt]); 2194 mark_inode_dirty_sync(toputinode[cnt]);
2204 mark_inode_dirty_sync(toputinode[cnt]);
2205 }
2206 mutex_unlock(&dqopt->dqonoff_mutex);
2207 } 2195 }
2208 if (sb->s_bdev) 2196 if (sb->s_bdev)
2209 invalidate_bdev(sb->s_bdev); 2197 invalidate_bdev(sb->s_bdev);
@@ -2275,6 +2263,10 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
2275 error = -EINVAL; 2263 error = -EINVAL;
2276 goto out_fmt; 2264 goto out_fmt;
2277 } 2265 }
2266 if (sb_has_quota_loaded(sb, type)) {
2267 error = -EBUSY;
2268 goto out_fmt;
2269 }
2278 2270
2279 if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) { 2271 if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
2280 /* As we bypass the pagecache we must now flush all the 2272 /* As we bypass the pagecache we must now flush all the
@@ -2286,11 +2278,6 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
2286 sync_filesystem(sb); 2278 sync_filesystem(sb);
2287 invalidate_bdev(sb->s_bdev); 2279 invalidate_bdev(sb->s_bdev);
2288 } 2280 }
2289 mutex_lock(&dqopt->dqonoff_mutex);
2290 if (sb_has_quota_loaded(sb, type)) {
2291 error = -EBUSY;
2292 goto out_lock;
2293 }
2294 2281
2295 if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) { 2282 if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
2296 /* We don't want quota and atime on quota files (deadlocks 2283 /* We don't want quota and atime on quota files (deadlocks
@@ -2311,7 +2298,7 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
2311 error = -EIO; 2298 error = -EIO;
2312 dqopt->files[type] = igrab(inode); 2299 dqopt->files[type] = igrab(inode);
2313 if (!dqopt->files[type]) 2300 if (!dqopt->files[type])
2314 goto out_lock; 2301 goto out_file_flags;
2315 error = -EINVAL; 2302 error = -EINVAL;
2316 if (!fmt->qf_ops->check_quota_file(sb, type)) 2303 if (!fmt->qf_ops->check_quota_file(sb, type))
2317 goto out_file_init; 2304 goto out_file_init;
@@ -2334,14 +2321,13 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
2334 spin_unlock(&dq_state_lock); 2321 spin_unlock(&dq_state_lock);
2335 2322
2336 add_dquot_ref(sb, type); 2323 add_dquot_ref(sb, type);
2337 mutex_unlock(&dqopt->dqonoff_mutex);
2338 2324
2339 return 0; 2325 return 0;
2340 2326
2341out_file_init: 2327out_file_init:
2342 dqopt->files[type] = NULL; 2328 dqopt->files[type] = NULL;
2343 iput(inode); 2329 iput(inode);
2344out_lock: 2330out_file_flags:
2345 if (oldflags != -1) { 2331 if (oldflags != -1) {
2346 inode_lock(inode); 2332 inode_lock(inode);
2347 /* Set the flags back (in the case of accidental quotaon() 2333 /* Set the flags back (in the case of accidental quotaon()
@@ -2350,7 +2336,6 @@ out_lock:
2350 inode->i_flags |= oldflags; 2336 inode->i_flags |= oldflags;
2351 inode_unlock(inode); 2337 inode_unlock(inode);
2352 } 2338 }
2353 mutex_unlock(&dqopt->dqonoff_mutex);
2354out_fmt: 2339out_fmt:
2355 put_quota_format(fmt); 2340 put_quota_format(fmt);
2356 2341
@@ -2372,12 +2357,9 @@ int dquot_resume(struct super_block *sb, int type)
2372 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 2357 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
2373 if (type != -1 && cnt != type) 2358 if (type != -1 && cnt != type)
2374 continue; 2359 continue;
2375 2360 if (!sb_has_quota_suspended(sb, cnt))
2376 mutex_lock(&dqopt->dqonoff_mutex);
2377 if (!sb_has_quota_suspended(sb, cnt)) {
2378 mutex_unlock(&dqopt->dqonoff_mutex);
2379 continue; 2361 continue;
2380 } 2362
2381 inode = dqopt->files[cnt]; 2363 inode = dqopt->files[cnt];
2382 dqopt->files[cnt] = NULL; 2364 dqopt->files[cnt] = NULL;
2383 spin_lock(&dq_state_lock); 2365 spin_lock(&dq_state_lock);
@@ -2386,7 +2368,6 @@ int dquot_resume(struct super_block *sb, int type)
2386 cnt); 2368 cnt);
2387 dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, cnt); 2369 dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, cnt);
2388 spin_unlock(&dq_state_lock); 2370 spin_unlock(&dq_state_lock);
2389 mutex_unlock(&dqopt->dqonoff_mutex);
2390 2371
2391 flags = dquot_generic_flag(flags, cnt); 2372 flags = dquot_generic_flag(flags, cnt);
2392 ret = vfs_load_quota_inode(inode, cnt, 2373 ret = vfs_load_quota_inode(inode, cnt,
@@ -2422,9 +2403,7 @@ EXPORT_SYMBOL(dquot_quota_on);
2422int dquot_enable(struct inode *inode, int type, int format_id, 2403int dquot_enable(struct inode *inode, int type, int format_id,
2423 unsigned int flags) 2404 unsigned int flags)
2424{ 2405{
2425 int ret = 0;
2426 struct super_block *sb = inode->i_sb; 2406 struct super_block *sb = inode->i_sb;
2427 struct quota_info *dqopt = sb_dqopt(sb);
2428 2407
2429 /* Just unsuspend quotas? */ 2408 /* Just unsuspend quotas? */
2430 BUG_ON(flags & DQUOT_SUSPENDED); 2409 BUG_ON(flags & DQUOT_SUSPENDED);
@@ -2436,31 +2415,18 @@ int dquot_enable(struct inode *inode, int type, int format_id,
2436 return 0; 2415 return 0;
2437 /* Just updating flags needed? */ 2416 /* Just updating flags needed? */
2438 if (sb_has_quota_loaded(sb, type)) { 2417 if (sb_has_quota_loaded(sb, type)) {
2439 mutex_lock(&dqopt->dqonoff_mutex);
2440 /* Now do a reliable test... */
2441 if (!sb_has_quota_loaded(sb, type)) {
2442 mutex_unlock(&dqopt->dqonoff_mutex);
2443 goto load_quota;
2444 }
2445 if (flags & DQUOT_USAGE_ENABLED && 2418 if (flags & DQUOT_USAGE_ENABLED &&
2446 sb_has_quota_usage_enabled(sb, type)) { 2419 sb_has_quota_usage_enabled(sb, type))
2447 ret = -EBUSY; 2420 return -EBUSY;
2448 goto out_lock;
2449 }
2450 if (flags & DQUOT_LIMITS_ENABLED && 2421 if (flags & DQUOT_LIMITS_ENABLED &&
2451 sb_has_quota_limits_enabled(sb, type)) { 2422 sb_has_quota_limits_enabled(sb, type))
2452 ret = -EBUSY; 2423 return -EBUSY;
2453 goto out_lock;
2454 }
2455 spin_lock(&dq_state_lock); 2424 spin_lock(&dq_state_lock);
2456 sb_dqopt(sb)->flags |= dquot_state_flag(flags, type); 2425 sb_dqopt(sb)->flags |= dquot_state_flag(flags, type);
2457 spin_unlock(&dq_state_lock); 2426 spin_unlock(&dq_state_lock);
2458out_lock: 2427 return 0;
2459 mutex_unlock(&dqopt->dqonoff_mutex);
2460 return ret;
2461 } 2428 }
2462 2429
2463load_quota:
2464 return vfs_load_quota_inode(inode, type, format_id, flags); 2430 return vfs_load_quota_inode(inode, type, format_id, flags);
2465} 2431}
2466EXPORT_SYMBOL(dquot_enable); 2432EXPORT_SYMBOL(dquot_enable);
diff --git a/fs/super.c b/fs/super.c
index f7f724230e2b..1709ed029a2c 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -244,7 +244,6 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
244 mutex_init(&s->s_vfs_rename_mutex); 244 mutex_init(&s->s_vfs_rename_mutex);
245 lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); 245 lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key);
246 mutex_init(&s->s_dquot.dqio_mutex); 246 mutex_init(&s->s_dquot.dqio_mutex);
247 mutex_init(&s->s_dquot.dqonoff_mutex);
248 s->s_maxbytes = MAX_NON_LFS; 247 s->s_maxbytes = MAX_NON_LFS;
249 s->s_op = &default_op; 248 s->s_op = &default_op;
250 s->s_time_gran = 1000000000; 249 s->s_time_gran = 1000000000;
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 55107a8ff887..b281d198ee5b 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -520,7 +520,6 @@ static inline void quota_send_warning(struct kqid qid, dev_t dev,
520struct quota_info { 520struct quota_info {
521 unsigned int flags; /* Flags for diskquotas on this device */ 521 unsigned int flags; /* Flags for diskquotas on this device */
522 struct mutex dqio_mutex; /* lock device while I/O in progress */ 522 struct mutex dqio_mutex; /* lock device while I/O in progress */
523 struct mutex dqonoff_mutex; /* Serialize quotaon & quotaoff */
524 struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */ 523 struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */
525 struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ 524 struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */
526 const struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ 525 const struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */