aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-11-13 08:55:52 -0500
committerJan Kara <jack@suse.cz>2012-11-19 15:34:32 -0500
commit3bb3e1fc47aca554e7e2cc4deeddc24750987ac2 (patch)
tree2460e3e16353e865b9e322981760d2b220bcf69c /fs/reiserfs
parent77b67063bb6bce6d475e910d3b886a606d0d91f7 (diff)
reiserfs: Fix lock ordering during remount
When remounting reiserfs dquot_suspend() or dquot_resume() can be called. These functions take dqonoff_mutex which ranks above write lock so we have to drop it before calling into quota code. CC: stable@vger.kernel.org # >= 3.0 Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/reiserfs')
-rw-r--r--fs/reiserfs/super.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 1078ae179993..5372980ec458 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1335,7 +1335,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1335 kfree(qf_names[i]); 1335 kfree(qf_names[i]);
1336#endif 1336#endif
1337 err = -EINVAL; 1337 err = -EINVAL;
1338 goto out_err; 1338 goto out_unlock;
1339 } 1339 }
1340#ifdef CONFIG_QUOTA 1340#ifdef CONFIG_QUOTA
1341 handle_quota_files(s, qf_names, &qfmt); 1341 handle_quota_files(s, qf_names, &qfmt);
@@ -1379,7 +1379,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1379 if (blocks) { 1379 if (blocks) {
1380 err = reiserfs_resize(s, blocks); 1380 err = reiserfs_resize(s, blocks);
1381 if (err != 0) 1381 if (err != 0)
1382 goto out_err; 1382 goto out_unlock;
1383 } 1383 }
1384 1384
1385 if (*mount_flags & MS_RDONLY) { 1385 if (*mount_flags & MS_RDONLY) {
@@ -1389,9 +1389,15 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1389 /* it is read-only already */ 1389 /* it is read-only already */
1390 goto out_ok; 1390 goto out_ok;
1391 1391
1392 /*
1393 * Drop write lock. Quota will retake it when needed and lock
1394 * ordering requires calling dquot_suspend() without it.
1395 */
1396 reiserfs_write_unlock(s);
1392 err = dquot_suspend(s, -1); 1397 err = dquot_suspend(s, -1);
1393 if (err < 0) 1398 if (err < 0)
1394 goto out_err; 1399 goto out_err;
1400 reiserfs_write_lock(s);
1395 1401
1396 /* try to remount file system with read-only permissions */ 1402 /* try to remount file system with read-only permissions */
1397 if (sb_umount_state(rs) == REISERFS_VALID_FS 1403 if (sb_umount_state(rs) == REISERFS_VALID_FS
@@ -1401,7 +1407,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1401 1407
1402 err = journal_begin(&th, s, 10); 1408 err = journal_begin(&th, s, 10);
1403 if (err) 1409 if (err)
1404 goto out_err; 1410 goto out_unlock;
1405 1411
1406 /* Mounting a rw partition read-only. */ 1412 /* Mounting a rw partition read-only. */
1407 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); 1413 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
@@ -1416,7 +1422,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1416 1422
1417 if (reiserfs_is_journal_aborted(journal)) { 1423 if (reiserfs_is_journal_aborted(journal)) {
1418 err = journal->j_errno; 1424 err = journal->j_errno;
1419 goto out_err; 1425 goto out_unlock;
1420 } 1426 }
1421 1427
1422 handle_data_mode(s, mount_options); 1428 handle_data_mode(s, mount_options);
@@ -1425,7 +1431,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1425 s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */ 1431 s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */
1426 err = journal_begin(&th, s, 10); 1432 err = journal_begin(&th, s, 10);
1427 if (err) 1433 if (err)
1428 goto out_err; 1434 goto out_unlock;
1429 1435
1430 /* Mount a partition which is read-only, read-write */ 1436 /* Mount a partition which is read-only, read-write */
1431 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); 1437 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
@@ -1442,10 +1448,16 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1442 SB_JOURNAL(s)->j_must_wait = 1; 1448 SB_JOURNAL(s)->j_must_wait = 1;
1443 err = journal_end(&th, s, 10); 1449 err = journal_end(&th, s, 10);
1444 if (err) 1450 if (err)
1445 goto out_err; 1451 goto out_unlock;
1446 1452
1447 if (!(*mount_flags & MS_RDONLY)) { 1453 if (!(*mount_flags & MS_RDONLY)) {
1454 /*
1455 * Drop write lock. Quota will retake it when needed and lock
1456 * ordering requires calling dquot_resume() without it.
1457 */
1458 reiserfs_write_unlock(s);
1448 dquot_resume(s, -1); 1459 dquot_resume(s, -1);
1460 reiserfs_write_lock(s);
1449 finish_unfinished(s); 1461 finish_unfinished(s);
1450 reiserfs_xattr_init(s, *mount_flags); 1462 reiserfs_xattr_init(s, *mount_flags);
1451 } 1463 }
@@ -1455,9 +1467,10 @@ out_ok:
1455 reiserfs_write_unlock(s); 1467 reiserfs_write_unlock(s);
1456 return 0; 1468 return 0;
1457 1469
1470out_unlock:
1471 reiserfs_write_unlock(s);
1458out_err: 1472out_err:
1459 kfree(new_opts); 1473 kfree(new_opts);
1460 reiserfs_write_unlock(s);
1461 return err; 1474 return err;
1462} 1475}
1463 1476