diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-06 12:06:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-06 12:06:02 -0400 |
commit | ec0ad730802173ec17e942f4b652a1819b1025b2 (patch) | |
tree | 25020c312014f1028447f981b0014f90c36b158a /fs/reiserfs/super.c | |
parent | eb97a784f02991cc3736d787511e788f32f0627f (diff) | |
parent | 97a2847d064e2fdd2e3cd4ff14cad2f377f0677a (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull ext3, reiserfs, udf & isofs fixes from Jan Kara:
"The contains a bunch of ext3 cleanups and minor improvements, major
reiserfs locking changes which should hopefully fix deadlocks
introduced by BKL removal, and udf/isofs changes to refuse mounting fs
rw instead of mounting it ro automatically which makes eject button
work as expected for all media (see the changelog for why userspace
should be ok with this change)"
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
jbd: use a single printk for jbd_debug()
reiserfs: locking, release lock around quota operations
reiserfs: locking, handle nested locks properly
reiserfs: locking, push write lock out of xattr code
jbd: relocate assert after state lock in journal_commit_transaction()
udf: Refuse RW mount of the filesystem instead of making it RO
udf: Standardize return values in mount sequence
isofs: Refuse RW mount of the filesystem instead of making it RO
ext3: allow specifying external journal by pathname mount option
jbd: remove unneeded semicolon
Diffstat (limited to 'fs/reiserfs/super.c')
-rw-r--r-- | fs/reiserfs/super.c | 75 |
1 files changed, 39 insertions, 36 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index e2e202a07b31..3ead145dadc4 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -243,6 +243,7 @@ static int finish_unfinished(struct super_block *s) | |||
243 | done = 0; | 243 | done = 0; |
244 | REISERFS_SB(s)->s_is_unlinked_ok = 1; | 244 | REISERFS_SB(s)->s_is_unlinked_ok = 1; |
245 | while (!retval) { | 245 | while (!retval) { |
246 | int depth; | ||
246 | retval = search_item(s, &max_cpu_key, &path); | 247 | retval = search_item(s, &max_cpu_key, &path); |
247 | if (retval != ITEM_NOT_FOUND) { | 248 | if (retval != ITEM_NOT_FOUND) { |
248 | reiserfs_error(s, "vs-2140", | 249 | reiserfs_error(s, "vs-2140", |
@@ -298,9 +299,9 @@ static int finish_unfinished(struct super_block *s) | |||
298 | retval = remove_save_link_only(s, &save_link_key, 0); | 299 | retval = remove_save_link_only(s, &save_link_key, 0); |
299 | continue; | 300 | continue; |
300 | } | 301 | } |
301 | reiserfs_write_unlock(s); | 302 | depth = reiserfs_write_unlock_nested(inode->i_sb); |
302 | dquot_initialize(inode); | 303 | dquot_initialize(inode); |
303 | reiserfs_write_lock(s); | 304 | reiserfs_write_lock_nested(inode->i_sb, depth); |
304 | 305 | ||
305 | if (truncate && S_ISDIR(inode->i_mode)) { | 306 | if (truncate && S_ISDIR(inode->i_mode)) { |
306 | /* We got a truncate request for a dir which is impossible. | 307 | /* We got a truncate request for a dir which is impossible. |
@@ -356,10 +357,12 @@ static int finish_unfinished(struct super_block *s) | |||
356 | 357 | ||
357 | #ifdef CONFIG_QUOTA | 358 | #ifdef CONFIG_QUOTA |
358 | /* Turn quotas off */ | 359 | /* Turn quotas off */ |
360 | reiserfs_write_unlock(s); | ||
359 | for (i = 0; i < MAXQUOTAS; i++) { | 361 | for (i = 0; i < MAXQUOTAS; i++) { |
360 | if (sb_dqopt(s)->files[i] && quota_enabled[i]) | 362 | if (sb_dqopt(s)->files[i] && quota_enabled[i]) |
361 | dquot_quota_off(s, i); | 363 | dquot_quota_off(s, i); |
362 | } | 364 | } |
365 | reiserfs_write_lock(s); | ||
363 | if (ms_active_set) | 366 | if (ms_active_set) |
364 | /* Restore the flag back */ | 367 | /* Restore the flag back */ |
365 | s->s_flags &= ~MS_ACTIVE; | 368 | s->s_flags &= ~MS_ACTIVE; |
@@ -623,7 +626,6 @@ static void reiserfs_dirty_inode(struct inode *inode, int flags) | |||
623 | struct reiserfs_transaction_handle th; | 626 | struct reiserfs_transaction_handle th; |
624 | 627 | ||
625 | int err = 0; | 628 | int err = 0; |
626 | int lock_depth; | ||
627 | 629 | ||
628 | if (inode->i_sb->s_flags & MS_RDONLY) { | 630 | if (inode->i_sb->s_flags & MS_RDONLY) { |
629 | reiserfs_warning(inode->i_sb, "clm-6006", | 631 | reiserfs_warning(inode->i_sb, "clm-6006", |
@@ -631,7 +633,7 @@ static void reiserfs_dirty_inode(struct inode *inode, int flags) | |||
631 | inode->i_ino); | 633 | inode->i_ino); |
632 | return; | 634 | return; |
633 | } | 635 | } |
634 | lock_depth = reiserfs_write_lock_once(inode->i_sb); | 636 | reiserfs_write_lock(inode->i_sb); |
635 | 637 | ||
636 | /* this is really only used for atime updates, so they don't have | 638 | /* this is really only used for atime updates, so they don't have |
637 | ** to be included in O_SYNC or fsync | 639 | ** to be included in O_SYNC or fsync |
@@ -644,7 +646,7 @@ static void reiserfs_dirty_inode(struct inode *inode, int flags) | |||
644 | journal_end(&th, inode->i_sb, 1); | 646 | journal_end(&th, inode->i_sb, 1); |
645 | 647 | ||
646 | out: | 648 | out: |
647 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | 649 | reiserfs_write_unlock(inode->i_sb); |
648 | } | 650 | } |
649 | 651 | ||
650 | static int reiserfs_show_options(struct seq_file *seq, struct dentry *root) | 652 | static int reiserfs_show_options(struct seq_file *seq, struct dentry *root) |
@@ -1334,7 +1336,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1334 | kfree(qf_names[i]); | 1336 | kfree(qf_names[i]); |
1335 | #endif | 1337 | #endif |
1336 | err = -EINVAL; | 1338 | err = -EINVAL; |
1337 | goto out_unlock; | 1339 | goto out_err_unlock; |
1338 | } | 1340 | } |
1339 | #ifdef CONFIG_QUOTA | 1341 | #ifdef CONFIG_QUOTA |
1340 | handle_quota_files(s, qf_names, &qfmt); | 1342 | handle_quota_files(s, qf_names, &qfmt); |
@@ -1378,35 +1380,32 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1378 | if (blocks) { | 1380 | if (blocks) { |
1379 | err = reiserfs_resize(s, blocks); | 1381 | err = reiserfs_resize(s, blocks); |
1380 | if (err != 0) | 1382 | if (err != 0) |
1381 | goto out_unlock; | 1383 | goto out_err_unlock; |
1382 | } | 1384 | } |
1383 | 1385 | ||
1384 | if (*mount_flags & MS_RDONLY) { | 1386 | if (*mount_flags & MS_RDONLY) { |
1387 | reiserfs_write_unlock(s); | ||
1385 | reiserfs_xattr_init(s, *mount_flags); | 1388 | reiserfs_xattr_init(s, *mount_flags); |
1386 | /* remount read-only */ | 1389 | /* remount read-only */ |
1387 | if (s->s_flags & MS_RDONLY) | 1390 | if (s->s_flags & MS_RDONLY) |
1388 | /* it is read-only already */ | 1391 | /* it is read-only already */ |
1389 | goto out_ok; | 1392 | goto out_ok_unlocked; |
1390 | 1393 | ||
1391 | /* | ||
1392 | * Drop write lock. Quota will retake it when needed and lock | ||
1393 | * ordering requires calling dquot_suspend() without it. | ||
1394 | */ | ||
1395 | reiserfs_write_unlock(s); | ||
1396 | err = dquot_suspend(s, -1); | 1394 | err = dquot_suspend(s, -1); |
1397 | if (err < 0) | 1395 | if (err < 0) |
1398 | goto out_err; | 1396 | goto out_err; |
1399 | reiserfs_write_lock(s); | ||
1400 | 1397 | ||
1401 | /* try to remount file system with read-only permissions */ | 1398 | /* try to remount file system with read-only permissions */ |
1402 | if (sb_umount_state(rs) == REISERFS_VALID_FS | 1399 | if (sb_umount_state(rs) == REISERFS_VALID_FS |
1403 | || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) { | 1400 | || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) { |
1404 | goto out_ok; | 1401 | goto out_ok_unlocked; |
1405 | } | 1402 | } |
1406 | 1403 | ||
1404 | reiserfs_write_lock(s); | ||
1405 | |||
1407 | err = journal_begin(&th, s, 10); | 1406 | err = journal_begin(&th, s, 10); |
1408 | if (err) | 1407 | if (err) |
1409 | goto out_unlock; | 1408 | goto out_err_unlock; |
1410 | 1409 | ||
1411 | /* Mounting a rw partition read-only. */ | 1410 | /* Mounting a rw partition read-only. */ |
1412 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); | 1411 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); |
@@ -1415,13 +1414,14 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1415 | } else { | 1414 | } else { |
1416 | /* remount read-write */ | 1415 | /* remount read-write */ |
1417 | if (!(s->s_flags & MS_RDONLY)) { | 1416 | if (!(s->s_flags & MS_RDONLY)) { |
1417 | reiserfs_write_unlock(s); | ||
1418 | reiserfs_xattr_init(s, *mount_flags); | 1418 | reiserfs_xattr_init(s, *mount_flags); |
1419 | goto out_ok; /* We are read-write already */ | 1419 | goto out_ok_unlocked; /* We are read-write already */ |
1420 | } | 1420 | } |
1421 | 1421 | ||
1422 | if (reiserfs_is_journal_aborted(journal)) { | 1422 | if (reiserfs_is_journal_aborted(journal)) { |
1423 | err = journal->j_errno; | 1423 | err = journal->j_errno; |
1424 | goto out_unlock; | 1424 | goto out_err_unlock; |
1425 | } | 1425 | } |
1426 | 1426 | ||
1427 | handle_data_mode(s, mount_options); | 1427 | handle_data_mode(s, mount_options); |
@@ -1430,7 +1430,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1430 | s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */ | 1430 | s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */ |
1431 | err = journal_begin(&th, s, 10); | 1431 | err = journal_begin(&th, s, 10); |
1432 | if (err) | 1432 | if (err) |
1433 | goto out_unlock; | 1433 | goto out_err_unlock; |
1434 | 1434 | ||
1435 | /* Mount a partition which is read-only, read-write */ | 1435 | /* Mount a partition which is read-only, read-write */ |
1436 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); | 1436 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); |
@@ -1447,26 +1447,22 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1447 | SB_JOURNAL(s)->j_must_wait = 1; | 1447 | SB_JOURNAL(s)->j_must_wait = 1; |
1448 | err = journal_end(&th, s, 10); | 1448 | err = journal_end(&th, s, 10); |
1449 | if (err) | 1449 | if (err) |
1450 | goto out_unlock; | 1450 | goto out_err_unlock; |
1451 | 1451 | ||
1452 | reiserfs_write_unlock(s); | ||
1452 | if (!(*mount_flags & MS_RDONLY)) { | 1453 | if (!(*mount_flags & MS_RDONLY)) { |
1453 | /* | ||
1454 | * Drop write lock. Quota will retake it when needed and lock | ||
1455 | * ordering requires calling dquot_resume() without it. | ||
1456 | */ | ||
1457 | reiserfs_write_unlock(s); | ||
1458 | dquot_resume(s, -1); | 1454 | dquot_resume(s, -1); |
1459 | reiserfs_write_lock(s); | 1455 | reiserfs_write_lock(s); |
1460 | finish_unfinished(s); | 1456 | finish_unfinished(s); |
1457 | reiserfs_write_unlock(s); | ||
1461 | reiserfs_xattr_init(s, *mount_flags); | 1458 | reiserfs_xattr_init(s, *mount_flags); |
1462 | } | 1459 | } |
1463 | 1460 | ||
1464 | out_ok: | 1461 | out_ok_unlocked: |
1465 | replace_mount_options(s, new_opts); | 1462 | replace_mount_options(s, new_opts); |
1466 | reiserfs_write_unlock(s); | ||
1467 | return 0; | 1463 | return 0; |
1468 | 1464 | ||
1469 | out_unlock: | 1465 | out_err_unlock: |
1470 | reiserfs_write_unlock(s); | 1466 | reiserfs_write_unlock(s); |
1471 | out_err: | 1467 | out_err: |
1472 | kfree(new_opts); | 1468 | kfree(new_opts); |
@@ -2013,12 +2009,14 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
2013 | goto error; | 2009 | goto error; |
2014 | } | 2010 | } |
2015 | 2011 | ||
2012 | reiserfs_write_unlock(s); | ||
2016 | if ((errval = reiserfs_lookup_privroot(s)) || | 2013 | if ((errval = reiserfs_lookup_privroot(s)) || |
2017 | (errval = reiserfs_xattr_init(s, s->s_flags))) { | 2014 | (errval = reiserfs_xattr_init(s, s->s_flags))) { |
2018 | dput(s->s_root); | 2015 | dput(s->s_root); |
2019 | s->s_root = NULL; | 2016 | s->s_root = NULL; |
2020 | goto error; | 2017 | goto error_unlocked; |
2021 | } | 2018 | } |
2019 | reiserfs_write_lock(s); | ||
2022 | 2020 | ||
2023 | /* look for files which were to be removed in previous session */ | 2021 | /* look for files which were to be removed in previous session */ |
2024 | finish_unfinished(s); | 2022 | finish_unfinished(s); |
@@ -2027,12 +2025,14 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
2027 | reiserfs_info(s, "using 3.5.x disk format\n"); | 2025 | reiserfs_info(s, "using 3.5.x disk format\n"); |
2028 | } | 2026 | } |
2029 | 2027 | ||
2028 | reiserfs_write_unlock(s); | ||
2030 | if ((errval = reiserfs_lookup_privroot(s)) || | 2029 | if ((errval = reiserfs_lookup_privroot(s)) || |
2031 | (errval = reiserfs_xattr_init(s, s->s_flags))) { | 2030 | (errval = reiserfs_xattr_init(s, s->s_flags))) { |
2032 | dput(s->s_root); | 2031 | dput(s->s_root); |
2033 | s->s_root = NULL; | 2032 | s->s_root = NULL; |
2034 | goto error; | 2033 | goto error_unlocked; |
2035 | } | 2034 | } |
2035 | reiserfs_write_lock(s); | ||
2036 | } | 2036 | } |
2037 | // mark hash in super block: it could be unset. overwrite should be ok | 2037 | // mark hash in super block: it could be unset. overwrite should be ok |
2038 | set_sb_hash_function_code(rs, function2code(sbi->s_hash_function)); | 2038 | set_sb_hash_function_code(rs, function2code(sbi->s_hash_function)); |
@@ -2100,6 +2100,7 @@ static int reiserfs_write_dquot(struct dquot *dquot) | |||
2100 | { | 2100 | { |
2101 | struct reiserfs_transaction_handle th; | 2101 | struct reiserfs_transaction_handle th; |
2102 | int ret, err; | 2102 | int ret, err; |
2103 | int depth; | ||
2103 | 2104 | ||
2104 | reiserfs_write_lock(dquot->dq_sb); | 2105 | reiserfs_write_lock(dquot->dq_sb); |
2105 | ret = | 2106 | ret = |
@@ -2107,9 +2108,9 @@ static int reiserfs_write_dquot(struct dquot *dquot) | |||
2107 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); | 2108 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); |
2108 | if (ret) | 2109 | if (ret) |
2109 | goto out; | 2110 | goto out; |
2110 | reiserfs_write_unlock(dquot->dq_sb); | 2111 | depth = reiserfs_write_unlock_nested(dquot->dq_sb); |
2111 | ret = dquot_commit(dquot); | 2112 | ret = dquot_commit(dquot); |
2112 | reiserfs_write_lock(dquot->dq_sb); | 2113 | reiserfs_write_lock_nested(dquot->dq_sb, depth); |
2113 | err = | 2114 | err = |
2114 | journal_end(&th, dquot->dq_sb, | 2115 | journal_end(&th, dquot->dq_sb, |
2115 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); | 2116 | REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); |
@@ -2124,6 +2125,7 @@ static int reiserfs_acquire_dquot(struct dquot *dquot) | |||
2124 | { | 2125 | { |
2125 | struct reiserfs_transaction_handle th; | 2126 | struct reiserfs_transaction_handle th; |
2126 | int ret, err; | 2127 | int ret, err; |
2128 | int depth; | ||
2127 | 2129 | ||
2128 | reiserfs_write_lock(dquot->dq_sb); | 2130 | reiserfs_write_lock(dquot->dq_sb); |
2129 | ret = | 2131 | ret = |
@@ -2131,9 +2133,9 @@ static int reiserfs_acquire_dquot(struct dquot *dquot) | |||
2131 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); | 2133 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); |
2132 | if (ret) | 2134 | if (ret) |
2133 | goto out; | 2135 | goto out; |
2134 | reiserfs_write_unlock(dquot->dq_sb); | 2136 | depth = reiserfs_write_unlock_nested(dquot->dq_sb); |
2135 | ret = dquot_acquire(dquot); | 2137 | ret = dquot_acquire(dquot); |
2136 | reiserfs_write_lock(dquot->dq_sb); | 2138 | reiserfs_write_lock_nested(dquot->dq_sb, depth); |
2137 | err = | 2139 | err = |
2138 | journal_end(&th, dquot->dq_sb, | 2140 | journal_end(&th, dquot->dq_sb, |
2139 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); | 2141 | REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); |
@@ -2186,15 +2188,16 @@ static int reiserfs_write_info(struct super_block *sb, int type) | |||
2186 | { | 2188 | { |
2187 | struct reiserfs_transaction_handle th; | 2189 | struct reiserfs_transaction_handle th; |
2188 | int ret, err; | 2190 | int ret, err; |
2191 | int depth; | ||
2189 | 2192 | ||
2190 | /* Data block + inode block */ | 2193 | /* Data block + inode block */ |
2191 | reiserfs_write_lock(sb); | 2194 | reiserfs_write_lock(sb); |
2192 | ret = journal_begin(&th, sb, 2); | 2195 | ret = journal_begin(&th, sb, 2); |
2193 | if (ret) | 2196 | if (ret) |
2194 | goto out; | 2197 | goto out; |
2195 | reiserfs_write_unlock(sb); | 2198 | depth = reiserfs_write_unlock_nested(sb); |
2196 | ret = dquot_commit_info(sb, type); | 2199 | ret = dquot_commit_info(sb, type); |
2197 | reiserfs_write_lock(sb); | 2200 | reiserfs_write_lock_nested(sb, depth); |
2198 | err = journal_end(&th, sb, 2); | 2201 | err = journal_end(&th, sb, 2); |
2199 | if (!ret && err) | 2202 | if (!ret && err) |
2200 | ret = err; | 2203 | ret = err; |