aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/journal.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs/journal.c')
-rw-r--r--fs/reiserfs/journal.c128
1 files changed, 27 insertions, 101 deletions
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 812e2c05aa29..3eea859e6990 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -43,7 +43,6 @@
43#include <linux/fcntl.h> 43#include <linux/fcntl.h>
44#include <linux/stat.h> 44#include <linux/stat.h>
45#include <linux/string.h> 45#include <linux/string.h>
46#include <linux/smp_lock.h>
47#include <linux/buffer_head.h> 46#include <linux/buffer_head.h>
48#include <linux/workqueue.h> 47#include <linux/workqueue.h>
49#include <linux/writeback.h> 48#include <linux/writeback.h>
@@ -138,13 +137,6 @@ static int reiserfs_clean_and_file_buffer(struct buffer_head *bh)
138 return 0; 137 return 0;
139} 138}
140 139
141static void disable_barrier(struct super_block *s)
142{
143 REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_BARRIER_FLUSH);
144 printk("reiserfs: disabling flush barriers on %s\n",
145 reiserfs_bdevname(s));
146}
147
148static struct reiserfs_bitmap_node *allocate_bitmap_node(struct super_block 140static struct reiserfs_bitmap_node *allocate_bitmap_node(struct super_block
149 *sb) 141 *sb)
150{ 142{
@@ -677,30 +669,6 @@ static void submit_ordered_buffer(struct buffer_head *bh)
677 submit_bh(WRITE, bh); 669 submit_bh(WRITE, bh);
678} 670}
679 671
680static int submit_barrier_buffer(struct buffer_head *bh)
681{
682 get_bh(bh);
683 bh->b_end_io = reiserfs_end_ordered_io;
684 clear_buffer_dirty(bh);
685 if (!buffer_uptodate(bh))
686 BUG();
687 return submit_bh(WRITE_BARRIER, bh);
688}
689
690static void check_barrier_completion(struct super_block *s,
691 struct buffer_head *bh)
692{
693 if (buffer_eopnotsupp(bh)) {
694 clear_buffer_eopnotsupp(bh);
695 disable_barrier(s);
696 set_buffer_uptodate(bh);
697 set_buffer_dirty(bh);
698 reiserfs_write_unlock(s);
699 sync_dirty_buffer(bh);
700 reiserfs_write_lock(s);
701 }
702}
703
704#define CHUNK_SIZE 32 672#define CHUNK_SIZE 32
705struct buffer_chunk { 673struct buffer_chunk {
706 struct buffer_head *bh[CHUNK_SIZE]; 674 struct buffer_head *bh[CHUNK_SIZE];
@@ -1009,7 +977,6 @@ static int flush_commit_list(struct super_block *s,
1009 struct buffer_head *tbh = NULL; 977 struct buffer_head *tbh = NULL;
1010 unsigned int trans_id = jl->j_trans_id; 978 unsigned int trans_id = jl->j_trans_id;
1011 struct reiserfs_journal *journal = SB_JOURNAL(s); 979 struct reiserfs_journal *journal = SB_JOURNAL(s);
1012 int barrier = 0;
1013 int retval = 0; 980 int retval = 0;
1014 int write_len; 981 int write_len;
1015 982
@@ -1094,24 +1061,6 @@ static int flush_commit_list(struct super_block *s,
1094 } 1061 }
1095 atomic_dec(&journal->j_async_throttle); 1062 atomic_dec(&journal->j_async_throttle);
1096 1063
1097 /* We're skipping the commit if there's an error */
1098 if (retval || reiserfs_is_journal_aborted(journal))
1099 barrier = 0;
1100
1101 /* wait on everything written so far before writing the commit
1102 * if we are in barrier mode, send the commit down now
1103 */
1104 barrier = reiserfs_barrier_flush(s);
1105 if (barrier) {
1106 int ret;
1107 lock_buffer(jl->j_commit_bh);
1108 ret = submit_barrier_buffer(jl->j_commit_bh);
1109 if (ret == -EOPNOTSUPP) {
1110 set_buffer_uptodate(jl->j_commit_bh);
1111 disable_barrier(s);
1112 barrier = 0;
1113 }
1114 }
1115 for (i = 0; i < (jl->j_len + 1); i++) { 1064 for (i = 0; i < (jl->j_len + 1); i++) {
1116 bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + 1065 bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) +
1117 (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s); 1066 (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s);
@@ -1143,27 +1092,22 @@ static int flush_commit_list(struct super_block *s,
1143 1092
1144 BUG_ON(atomic_read(&(jl->j_commit_left)) != 1); 1093 BUG_ON(atomic_read(&(jl->j_commit_left)) != 1);
1145 1094
1146 if (!barrier) { 1095 /* If there was a write error in the journal - we can't commit
1147 /* If there was a write error in the journal - we can't commit 1096 * this transaction - it will be invalid and, if successful,
1148 * this transaction - it will be invalid and, if successful, 1097 * will just end up propagating the write error out to
1149 * will just end up propagating the write error out to 1098 * the file system. */
1150 * the file system. */ 1099 if (likely(!retval && !reiserfs_is_journal_aborted (journal))) {
1151 if (likely(!retval && !reiserfs_is_journal_aborted (journal))) { 1100 if (buffer_dirty(jl->j_commit_bh))
1152 if (buffer_dirty(jl->j_commit_bh)) 1101 BUG();
1153 BUG(); 1102 mark_buffer_dirty(jl->j_commit_bh) ;
1154 mark_buffer_dirty(jl->j_commit_bh) ;
1155 reiserfs_write_unlock(s);
1156 sync_dirty_buffer(jl->j_commit_bh) ;
1157 reiserfs_write_lock(s);
1158 }
1159 } else {
1160 reiserfs_write_unlock(s); 1103 reiserfs_write_unlock(s);
1161 wait_on_buffer(jl->j_commit_bh); 1104 if (reiserfs_barrier_flush(s))
1105 __sync_dirty_buffer(jl->j_commit_bh, WRITE_FLUSH_FUA);
1106 else
1107 sync_dirty_buffer(jl->j_commit_bh);
1162 reiserfs_write_lock(s); 1108 reiserfs_write_lock(s);
1163 } 1109 }
1164 1110
1165 check_barrier_completion(s, jl->j_commit_bh);
1166
1167 /* If there was a write error in the journal - we can't commit this 1111 /* If there was a write error in the journal - we can't commit this
1168 * transaction - it will be invalid and, if successful, will just end 1112 * transaction - it will be invalid and, if successful, will just end
1169 * up propagating the write error out to the filesystem. */ 1113 * up propagating the write error out to the filesystem. */
@@ -1319,26 +1263,15 @@ static int _update_journal_header_block(struct super_block *sb,
1319 jh->j_first_unflushed_offset = cpu_to_le32(offset); 1263 jh->j_first_unflushed_offset = cpu_to_le32(offset);
1320 jh->j_mount_id = cpu_to_le32(journal->j_mount_id); 1264 jh->j_mount_id = cpu_to_le32(journal->j_mount_id);
1321 1265
1322 if (reiserfs_barrier_flush(sb)) { 1266 set_buffer_dirty(journal->j_header_bh);
1323 int ret; 1267 reiserfs_write_unlock(sb);
1324 lock_buffer(journal->j_header_bh); 1268
1325 ret = submit_barrier_buffer(journal->j_header_bh); 1269 if (reiserfs_barrier_flush(sb))
1326 if (ret == -EOPNOTSUPP) { 1270 __sync_dirty_buffer(journal->j_header_bh, WRITE_FLUSH_FUA);
1327 set_buffer_uptodate(journal->j_header_bh); 1271 else
1328 disable_barrier(sb);
1329 goto sync;
1330 }
1331 reiserfs_write_unlock(sb);
1332 wait_on_buffer(journal->j_header_bh);
1333 reiserfs_write_lock(sb);
1334 check_barrier_completion(sb, journal->j_header_bh);
1335 } else {
1336 sync:
1337 set_buffer_dirty(journal->j_header_bh);
1338 reiserfs_write_unlock(sb);
1339 sync_dirty_buffer(journal->j_header_bh); 1272 sync_dirty_buffer(journal->j_header_bh);
1340 reiserfs_write_lock(sb); 1273
1341 } 1274 reiserfs_write_lock(sb);
1342 if (!buffer_uptodate(journal->j_header_bh)) { 1275 if (!buffer_uptodate(journal->j_header_bh)) {
1343 reiserfs_warning(sb, "journal-837", 1276 reiserfs_warning(sb, "journal-837",
1344 "IO error during journal replay"); 1277 "IO error during journal replay");
@@ -2618,8 +2551,6 @@ static int release_journal_dev(struct super_block *super,
2618 result = 0; 2551 result = 0;
2619 2552
2620 if (journal->j_dev_bd != NULL) { 2553 if (journal->j_dev_bd != NULL) {
2621 if (journal->j_dev_bd->bd_dev != super->s_dev)
2622 bd_release(journal->j_dev_bd);
2623 result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode); 2554 result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode);
2624 journal->j_dev_bd = NULL; 2555 journal->j_dev_bd = NULL;
2625 } 2556 }
@@ -2637,7 +2568,7 @@ static int journal_init_dev(struct super_block *super,
2637{ 2568{
2638 int result; 2569 int result;
2639 dev_t jdev; 2570 dev_t jdev;
2640 fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE; 2571 fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
2641 char b[BDEVNAME_SIZE]; 2572 char b[BDEVNAME_SIZE];
2642 2573
2643 result = 0; 2574 result = 0;
@@ -2651,7 +2582,10 @@ static int journal_init_dev(struct super_block *super,
2651 2582
2652 /* there is no "jdev" option and journal is on separate device */ 2583 /* there is no "jdev" option and journal is on separate device */
2653 if ((!jdev_name || !jdev_name[0])) { 2584 if ((!jdev_name || !jdev_name[0])) {
2654 journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode); 2585 if (jdev == super->s_dev)
2586 blkdev_mode &= ~FMODE_EXCL;
2587 journal->j_dev_bd = blkdev_get_by_dev(jdev, blkdev_mode,
2588 journal);
2655 journal->j_dev_mode = blkdev_mode; 2589 journal->j_dev_mode = blkdev_mode;
2656 if (IS_ERR(journal->j_dev_bd)) { 2590 if (IS_ERR(journal->j_dev_bd)) {
2657 result = PTR_ERR(journal->j_dev_bd); 2591 result = PTR_ERR(journal->j_dev_bd);
@@ -2660,22 +2594,14 @@ static int journal_init_dev(struct super_block *super,
2660 "cannot init journal device '%s': %i", 2594 "cannot init journal device '%s': %i",
2661 __bdevname(jdev, b), result); 2595 __bdevname(jdev, b), result);
2662 return result; 2596 return result;
2663 } else if (jdev != super->s_dev) { 2597 } else if (jdev != super->s_dev)
2664 result = bd_claim(journal->j_dev_bd, journal);
2665 if (result) {
2666 blkdev_put(journal->j_dev_bd, blkdev_mode);
2667 return result;
2668 }
2669
2670 set_blocksize(journal->j_dev_bd, super->s_blocksize); 2598 set_blocksize(journal->j_dev_bd, super->s_blocksize);
2671 }
2672 2599
2673 return 0; 2600 return 0;
2674 } 2601 }
2675 2602
2676 journal->j_dev_mode = blkdev_mode; 2603 journal->j_dev_mode = blkdev_mode;
2677 journal->j_dev_bd = open_bdev_exclusive(jdev_name, 2604 journal->j_dev_bd = blkdev_get_by_path(jdev_name, blkdev_mode, journal);
2678 blkdev_mode, journal);
2679 if (IS_ERR(journal->j_dev_bd)) { 2605 if (IS_ERR(journal->j_dev_bd)) {
2680 result = PTR_ERR(journal->j_dev_bd); 2606 result = PTR_ERR(journal->j_dev_bd);
2681 journal->j_dev_bd = NULL; 2607 journal->j_dev_bd = NULL;