aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorFrank Mayhar <fmayhar@google.com>2009-01-07 00:06:22 -0500
committerTheodore Ts'o <tytso@mit.edu>2009-01-07 00:06:22 -0500
commit0390131ba84fd3f726f9e24fc4553828125700bb (patch)
tree4c90afad4e8690e25aec0ce069fd450e92ab5f96 /fs
parentff7ef329b268b603ea4a2303241ef1c3829fd574 (diff)
ext4: Allow ext4 to run without a journal
A few weeks ago I posted a patch for discussion that allowed ext4 to run without a journal. Since that time I've integrated the excellent comments from Andreas and fixed several serious bugs. We're currently running with this patch and generating some performance numbers against both ext2 (with backported reservations code) and ext4 with and without a journal. It just so happens that running without a journal is slightly faster for most everything. We did iozone -T -t 4 s 2g -r 256k -T -I -i0 -i1 -i2 which creates 4 threads, each of which create and do reads and writes on a 2G file, with a buffer size of 256K, using O_DIRECT for all file opens to bypass the page cache. Results: ext2 ext4, default ext4, no journal initial writes 13.0 MB/s 15.4 MB/s 15.7 MB/s rewrites 13.1 MB/s 15.6 MB/s 15.9 MB/s reads 15.2 MB/s 16.9 MB/s 17.2 MB/s re-reads 15.3 MB/s 16.9 MB/s 17.2 MB/s random readers 5.6 MB/s 5.6 MB/s 5.7 MB/s random writers 5.1 MB/s 5.3 MB/s 5.4 MB/s So it seems that, so far, this was a useful exercise. Signed-off-by: Frank Mayhar <fmayhar@google.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/balloc.c4
-rw-r--r--fs/ext4/ext4_jbd2.c83
-rw-r--r--fs/ext4/ext4_jbd2.h83
-rw-r--r--fs/ext4/extents.c12
-rw-r--r--fs/ext4/ialloc.c25
-rw-r--r--fs/ext4/inode.c130
-rw-r--r--fs/ext4/ioctl.c2
-rw-r--r--fs/ext4/mballoc.c17
-rw-r--r--fs/ext4/migrate.c5
-rw-r--r--fs/ext4/namei.c56
-rw-r--r--fs/ext4/resize.c31
-rw-r--r--fs/ext4/super.c207
-rw-r--r--fs/ext4/xattr.c21
13 files changed, 452 insertions, 224 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 35f5f9a27722..31ebeb5e7b07 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -531,11 +531,11 @@ do_more:
531 531
532 /* We dirtied the bitmap block */ 532 /* We dirtied the bitmap block */
533 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); 533 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
534 err = ext4_journal_dirty_metadata(handle, bitmap_bh); 534 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
535 535
536 /* And the group descriptor block */ 536 /* And the group descriptor block */
537 BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); 537 BUFFER_TRACE(gd_bh, "dirtied group descriptor block");
538 ret = ext4_journal_dirty_metadata(handle, gd_bh); 538 ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
539 if (!err) err = ret; 539 if (!err) err = ret;
540 *pdquot_freed_blocks += group_freed; 540 *pdquot_freed_blocks += group_freed;
541 541
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
index c75384b34f2c..ad13a84644e1 100644
--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -7,53 +7,96 @@
7int __ext4_journal_get_undo_access(const char *where, handle_t *handle, 7int __ext4_journal_get_undo_access(const char *where, handle_t *handle,
8 struct buffer_head *bh) 8 struct buffer_head *bh)
9{ 9{
10 int err = jbd2_journal_get_undo_access(handle, bh); 10 int err = 0;
11 if (err) 11
12 ext4_journal_abort_handle(where, __func__, bh, handle, err); 12 if (ext4_handle_valid(handle)) {
13 err = jbd2_journal_get_undo_access(handle, bh);
14 if (err)
15 ext4_journal_abort_handle(where, __func__, bh,
16 handle, err);
17 }
13 return err; 18 return err;
14} 19}
15 20
16int __ext4_journal_get_write_access(const char *where, handle_t *handle, 21int __ext4_journal_get_write_access(const char *where, handle_t *handle,
17 struct buffer_head *bh) 22 struct buffer_head *bh)
18{ 23{
19 int err = jbd2_journal_get_write_access(handle, bh); 24 int err = 0;
20 if (err) 25
21 ext4_journal_abort_handle(where, __func__, bh, handle, err); 26 if (ext4_handle_valid(handle)) {
27 err = jbd2_journal_get_write_access(handle, bh);
28 if (err)
29 ext4_journal_abort_handle(where, __func__, bh,
30 handle, err);
31 }
22 return err; 32 return err;
23} 33}
24 34
25int __ext4_journal_forget(const char *where, handle_t *handle, 35int __ext4_journal_forget(const char *where, handle_t *handle,
26 struct buffer_head *bh) 36 struct buffer_head *bh)
27{ 37{
28 int err = jbd2_journal_forget(handle, bh); 38 int err = 0;
29 if (err) 39
30 ext4_journal_abort_handle(where, __func__, bh, handle, err); 40 if (ext4_handle_valid(handle)) {
41 err = jbd2_journal_forget(handle, bh);
42 if (err)
43 ext4_journal_abort_handle(where, __func__, bh,
44 handle, err);
45 }
31 return err; 46 return err;
32} 47}
33 48
34int __ext4_journal_revoke(const char *where, handle_t *handle, 49int __ext4_journal_revoke(const char *where, handle_t *handle,
35 ext4_fsblk_t blocknr, struct buffer_head *bh) 50 ext4_fsblk_t blocknr, struct buffer_head *bh)
36{ 51{
37 int err = jbd2_journal_revoke(handle, blocknr, bh); 52 int err = 0;
38 if (err) 53
39 ext4_journal_abort_handle(where, __func__, bh, handle, err); 54 if (ext4_handle_valid(handle)) {
55 err = jbd2_journal_revoke(handle, blocknr, bh);
56 if (err)
57 ext4_journal_abort_handle(where, __func__, bh,
58 handle, err);
59 }
40 return err; 60 return err;
41} 61}
42 62
43int __ext4_journal_get_create_access(const char *where, 63int __ext4_journal_get_create_access(const char *where,
44 handle_t *handle, struct buffer_head *bh) 64 handle_t *handle, struct buffer_head *bh)
45{ 65{
46 int err = jbd2_journal_get_create_access(handle, bh); 66 int err = 0;
47 if (err) 67
48 ext4_journal_abort_handle(where, __func__, bh, handle, err); 68 if (ext4_handle_valid(handle)) {
69 err = jbd2_journal_get_create_access(handle, bh);
70 if (err)
71 ext4_journal_abort_handle(where, __func__, bh,
72 handle, err);
73 }
49 return err; 74 return err;
50} 75}
51 76
52int __ext4_journal_dirty_metadata(const char *where, 77int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
53 handle_t *handle, struct buffer_head *bh) 78 struct inode *inode, struct buffer_head *bh)
54{ 79{
55 int err = jbd2_journal_dirty_metadata(handle, bh); 80 int err = 0;
56 if (err) 81
57 ext4_journal_abort_handle(where, __func__, bh, handle, err); 82 if (ext4_handle_valid(handle)) {
83 err = jbd2_journal_dirty_metadata(handle, bh);
84 if (err)
85 ext4_journal_abort_handle(where, __func__, bh,
86 handle, err);
87 } else {
88 mark_buffer_dirty(bh);
89 if (inode && inode_needs_sync(inode)) {
90 sync_dirty_buffer(bh);
91 if (buffer_req(bh) && !buffer_uptodate(bh)) {
92 ext4_error(inode->i_sb, __func__,
93 "IO error syncing inode, "
94 "inode=%lu, block=%llu",
95 inode->i_ino,
96 (unsigned long long) bh->b_blocknr);
97 err = -EIO;
98 }
99 }
100 }
58 return err; 101 return err;
59} 102}
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
index b455c685a98b..663197adae56 100644
--- a/fs/ext4/ext4_jbd2.h
+++ b/fs/ext4/ext4_jbd2.h
@@ -122,12 +122,6 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode);
122 * been done yet. 122 * been done yet.
123 */ 123 */
124 124
125static inline void ext4_journal_release_buffer(handle_t *handle,
126 struct buffer_head *bh)
127{
128 jbd2_journal_release_buffer(handle, bh);
129}
130
131void ext4_journal_abort_handle(const char *caller, const char *err_fn, 125void ext4_journal_abort_handle(const char *caller, const char *err_fn,
132 struct buffer_head *bh, handle_t *handle, int err); 126 struct buffer_head *bh, handle_t *handle, int err);
133 127
@@ -146,8 +140,8 @@ int __ext4_journal_revoke(const char *where, handle_t *handle,
146int __ext4_journal_get_create_access(const char *where, 140int __ext4_journal_get_create_access(const char *where,
147 handle_t *handle, struct buffer_head *bh); 141 handle_t *handle, struct buffer_head *bh);
148 142
149int __ext4_journal_dirty_metadata(const char *where, 143int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
150 handle_t *handle, struct buffer_head *bh); 144 struct inode *inode, struct buffer_head *bh);
151 145
152#define ext4_journal_get_undo_access(handle, bh) \ 146#define ext4_journal_get_undo_access(handle, bh) \
153 __ext4_journal_get_undo_access(__func__, (handle), (bh)) 147 __ext4_journal_get_undo_access(__func__, (handle), (bh))
@@ -157,14 +151,57 @@ int __ext4_journal_dirty_metadata(const char *where,
157 __ext4_journal_revoke(__func__, (handle), (blocknr), (bh)) 151 __ext4_journal_revoke(__func__, (handle), (blocknr), (bh))
158#define ext4_journal_get_create_access(handle, bh) \ 152#define ext4_journal_get_create_access(handle, bh) \
159 __ext4_journal_get_create_access(__func__, (handle), (bh)) 153 __ext4_journal_get_create_access(__func__, (handle), (bh))
160#define ext4_journal_dirty_metadata(handle, bh) \
161 __ext4_journal_dirty_metadata(__func__, (handle), (bh))
162#define ext4_journal_forget(handle, bh) \ 154#define ext4_journal_forget(handle, bh) \
163 __ext4_journal_forget(__func__, (handle), (bh)) 155 __ext4_journal_forget(__func__, (handle), (bh))
156#define ext4_handle_dirty_metadata(handle, inode, bh) \
157 __ext4_handle_dirty_metadata(__func__, (handle), (inode), (bh))
164 158
165handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks); 159handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks);
166int __ext4_journal_stop(const char *where, handle_t *handle); 160int __ext4_journal_stop(const char *where, handle_t *handle);
167 161
162#define EXT4_NOJOURNAL_HANDLE ((handle_t *) 0x1)
163
164static inline int ext4_handle_valid(handle_t *handle)
165{
166 if (handle == EXT4_NOJOURNAL_HANDLE)
167 return 0;
168 return 1;
169}
170
171static inline void ext4_handle_sync(handle_t *handle)
172{
173 if (ext4_handle_valid(handle))
174 handle->h_sync = 1;
175}
176
177static inline void ext4_handle_release_buffer(handle_t *handle,
178 struct buffer_head *bh)
179{
180 if (ext4_handle_valid(handle))
181 jbd2_journal_release_buffer(handle, bh);
182}
183
184static inline int ext4_handle_is_aborted(handle_t *handle)
185{
186 if (ext4_handle_valid(handle))
187 return is_handle_aborted(handle);
188 return 0;
189}
190
191static inline int ext4_handle_has_enough_credits(handle_t *handle, int needed)
192{
193 if (ext4_handle_valid(handle) && handle->h_buffer_credits < needed)
194 return 0;
195 return 1;
196}
197
198static inline void ext4_journal_release_buffer(handle_t *handle,
199 struct buffer_head *bh)
200{
201 if (ext4_handle_valid(handle))
202 jbd2_journal_release_buffer(handle, bh);
203}
204
168static inline handle_t *ext4_journal_start(struct inode *inode, int nblocks) 205static inline handle_t *ext4_journal_start(struct inode *inode, int nblocks)
169{ 206{
170 return ext4_journal_start_sb(inode->i_sb, nblocks); 207 return ext4_journal_start_sb(inode->i_sb, nblocks);
@@ -180,27 +217,37 @@ static inline handle_t *ext4_journal_current_handle(void)
180 217
181static inline int ext4_journal_extend(handle_t *handle, int nblocks) 218static inline int ext4_journal_extend(handle_t *handle, int nblocks)
182{ 219{
183 return jbd2_journal_extend(handle, nblocks); 220 if (ext4_handle_valid(handle))
221 return jbd2_journal_extend(handle, nblocks);
222 return 0;
184} 223}
185 224
186static inline int ext4_journal_restart(handle_t *handle, int nblocks) 225static inline int ext4_journal_restart(handle_t *handle, int nblocks)
187{ 226{
188 return jbd2_journal_restart(handle, nblocks); 227 if (ext4_handle_valid(handle))
228 return jbd2_journal_restart(handle, nblocks);
229 return 0;
189} 230}
190 231
191static inline int ext4_journal_blocks_per_page(struct inode *inode) 232static inline int ext4_journal_blocks_per_page(struct inode *inode)
192{ 233{
193 return jbd2_journal_blocks_per_page(inode); 234 if (EXT4_JOURNAL(inode) != NULL)
235 return jbd2_journal_blocks_per_page(inode);
236 return 0;
194} 237}
195 238
196static inline int ext4_journal_force_commit(journal_t *journal) 239static inline int ext4_journal_force_commit(journal_t *journal)
197{ 240{
198 return jbd2_journal_force_commit(journal); 241 if (journal)
242 return jbd2_journal_force_commit(journal);
243 return 0;
199} 244}
200 245
201static inline int ext4_jbd2_file_inode(handle_t *handle, struct inode *inode) 246static inline int ext4_jbd2_file_inode(handle_t *handle, struct inode *inode)
202{ 247{
203 return jbd2_journal_file_inode(handle, &EXT4_I(inode)->jinode); 248 if (ext4_handle_valid(handle))
249 return jbd2_journal_file_inode(handle, &EXT4_I(inode)->jinode);
250 return 0;
204} 251}
205 252
206/* super.c */ 253/* super.c */
@@ -208,6 +255,8 @@ int ext4_force_commit(struct super_block *sb);
208 255
209static inline int ext4_should_journal_data(struct inode *inode) 256static inline int ext4_should_journal_data(struct inode *inode)
210{ 257{
258 if (EXT4_JOURNAL(inode) == NULL)
259 return 0;
211 if (!S_ISREG(inode->i_mode)) 260 if (!S_ISREG(inode->i_mode))
212 return 1; 261 return 1;
213 if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) 262 if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
@@ -219,6 +268,8 @@ static inline int ext4_should_journal_data(struct inode *inode)
219 268
220static inline int ext4_should_order_data(struct inode *inode) 269static inline int ext4_should_order_data(struct inode *inode)
221{ 270{
271 if (EXT4_JOURNAL(inode) == NULL)
272 return 0;
222 if (!S_ISREG(inode->i_mode)) 273 if (!S_ISREG(inode->i_mode))
223 return 0; 274 return 0;
224 if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) 275 if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL)
@@ -230,6 +281,8 @@ static inline int ext4_should_order_data(struct inode *inode)
230 281
231static inline int ext4_should_writeback_data(struct inode *inode) 282static inline int ext4_should_writeback_data(struct inode *inode)
232{ 283{
284 if (EXT4_JOURNAL(inode) == NULL)
285 return 0;
233 if (!S_ISREG(inode->i_mode)) 286 if (!S_ISREG(inode->i_mode))
234 return 0; 287 return 0;
235 if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) 288 if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 0917be51f102..743e3feb3e50 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -97,6 +97,8 @@ static int ext4_ext_journal_restart(handle_t *handle, int needed)
97{ 97{
98 int err; 98 int err;
99 99
100 if (!ext4_handle_valid(handle))
101 return 0;
100 if (handle->h_buffer_credits > needed) 102 if (handle->h_buffer_credits > needed)
101 return 0; 103 return 0;
102 err = ext4_journal_extend(handle, needed); 104 err = ext4_journal_extend(handle, needed);
@@ -134,7 +136,7 @@ static int ext4_ext_dirty(handle_t *handle, struct inode *inode,
134 int err; 136 int err;
135 if (path->p_bh) { 137 if (path->p_bh) {
136 /* path points to block */ 138 /* path points to block */
137 err = ext4_journal_dirty_metadata(handle, path->p_bh); 139 err = ext4_handle_dirty_metadata(handle, inode, path->p_bh);
138 } else { 140 } else {
139 /* path points to leaf/index in inode body */ 141 /* path points to leaf/index in inode body */
140 err = ext4_mark_inode_dirty(handle, inode); 142 err = ext4_mark_inode_dirty(handle, inode);
@@ -780,7 +782,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
780 set_buffer_uptodate(bh); 782 set_buffer_uptodate(bh);
781 unlock_buffer(bh); 783 unlock_buffer(bh);
782 784
783 err = ext4_journal_dirty_metadata(handle, bh); 785 err = ext4_handle_dirty_metadata(handle, inode, bh);
784 if (err) 786 if (err)
785 goto cleanup; 787 goto cleanup;
786 brelse(bh); 788 brelse(bh);
@@ -859,7 +861,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
859 set_buffer_uptodate(bh); 861 set_buffer_uptodate(bh);
860 unlock_buffer(bh); 862 unlock_buffer(bh);
861 863
862 err = ext4_journal_dirty_metadata(handle, bh); 864 err = ext4_handle_dirty_metadata(handle, inode, bh);
863 if (err) 865 if (err)
864 goto cleanup; 866 goto cleanup;
865 brelse(bh); 867 brelse(bh);
@@ -955,7 +957,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
955 set_buffer_uptodate(bh); 957 set_buffer_uptodate(bh);
956 unlock_buffer(bh); 958 unlock_buffer(bh);
957 959
958 err = ext4_journal_dirty_metadata(handle, bh); 960 err = ext4_handle_dirty_metadata(handle, inode, bh);
959 if (err) 961 if (err)
960 goto out; 962 goto out;
961 963
@@ -2947,7 +2949,7 @@ void ext4_ext_truncate(struct inode *inode)
2947 * transaction synchronous. 2949 * transaction synchronous.
2948 */ 2950 */
2949 if (IS_SYNC(inode)) 2951 if (IS_SYNC(inode))
2950 handle->h_sync = 1; 2952 ext4_handle_sync(handle);
2951 2953
2952out_stop: 2954out_stop:
2953 up_write(&EXT4_I(inode)->i_data_sem); 2955 up_write(&EXT4_I(inode)->i_data_sem);
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 6e6052879aa2..9dd21b75f4bc 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -253,12 +253,12 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
253 spin_unlock(sb_bgl_lock(sbi, flex_group)); 253 spin_unlock(sb_bgl_lock(sbi, flex_group));
254 } 254 }
255 } 255 }
256 BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); 256 BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata");
257 err = ext4_journal_dirty_metadata(handle, bh2); 257 err = ext4_handle_dirty_metadata(handle, NULL, bh2);
258 if (!fatal) fatal = err; 258 if (!fatal) fatal = err;
259 } 259 }
260 BUFFER_TRACE(bitmap_bh, "call ext4_journal_dirty_metadata"); 260 BUFFER_TRACE(bitmap_bh, "call ext4_handle_dirty_metadata");
261 err = ext4_journal_dirty_metadata(handle, bitmap_bh); 261 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
262 if (!fatal) 262 if (!fatal)
263 fatal = err; 263 fatal = err;
264 sb->s_dirt = 1; 264 sb->s_dirt = 1;
@@ -656,15 +656,16 @@ repeat_in_this_group:
656 ino, bitmap_bh->b_data)) { 656 ino, bitmap_bh->b_data)) {
657 /* we won it */ 657 /* we won it */
658 BUFFER_TRACE(bitmap_bh, 658 BUFFER_TRACE(bitmap_bh,
659 "call ext4_journal_dirty_metadata"); 659 "call ext4_handle_dirty_metadata");
660 err = ext4_journal_dirty_metadata(handle, 660 err = ext4_handle_dirty_metadata(handle,
661 inode,
661 bitmap_bh); 662 bitmap_bh);
662 if (err) 663 if (err)
663 goto fail; 664 goto fail;
664 goto got; 665 goto got;
665 } 666 }
666 /* we lost it */ 667 /* we lost it */
667 jbd2_journal_release_buffer(handle, bitmap_bh); 668 ext4_handle_release_buffer(handle, bitmap_bh);
668 669
669 if (++ino < EXT4_INODES_PER_GROUP(sb)) 670 if (++ino < EXT4_INODES_PER_GROUP(sb))
670 goto repeat_in_this_group; 671 goto repeat_in_this_group;
@@ -726,7 +727,8 @@ got:
726 /* Don't need to dirty bitmap block if we didn't change it */ 727 /* Don't need to dirty bitmap block if we didn't change it */
727 if (free) { 728 if (free) {
728 BUFFER_TRACE(block_bh, "dirty block bitmap"); 729 BUFFER_TRACE(block_bh, "dirty block bitmap");
729 err = ext4_journal_dirty_metadata(handle, block_bh); 730 err = ext4_handle_dirty_metadata(handle,
731 NULL, block_bh);
730 } 732 }
731 733
732 brelse(block_bh); 734 brelse(block_bh);
@@ -771,8 +773,8 @@ got:
771 } 773 }
772 gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); 774 gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
773 spin_unlock(sb_bgl_lock(sbi, group)); 775 spin_unlock(sb_bgl_lock(sbi, group));
774 BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); 776 BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata");
775 err = ext4_journal_dirty_metadata(handle, bh2); 777 err = ext4_handle_dirty_metadata(handle, NULL, bh2);
776 if (err) goto fail; 778 if (err) goto fail;
777 779
778 percpu_counter_dec(&sbi->s_freeinodes_counter); 780 percpu_counter_dec(&sbi->s_freeinodes_counter);
@@ -825,7 +827,7 @@ got:
825 827
826 ext4_set_inode_flags(inode); 828 ext4_set_inode_flags(inode);
827 if (IS_DIRSYNC(inode)) 829 if (IS_DIRSYNC(inode))
828 handle->h_sync = 1; 830 ext4_handle_sync(handle);
829 if (insert_inode_locked(inode) < 0) { 831 if (insert_inode_locked(inode) < 0) {
830 err = -EINVAL; 832 err = -EINVAL;
831 goto fail_drop; 833 goto fail_drop;
@@ -1028,4 +1030,3 @@ unsigned long ext4_count_dirs(struct super_block * sb)
1028 } 1030 }
1029 return count; 1031 return count;
1030} 1032}
1031
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c77a7ac753f3..45d0f70a1f04 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -72,12 +72,17 @@ static int ext4_inode_is_fast_symlink(struct inode *inode)
72 * "bh" may be NULL: a metadata block may have been freed from memory 72 * "bh" may be NULL: a metadata block may have been freed from memory
73 * but there may still be a record of it in the journal, and that record 73 * but there may still be a record of it in the journal, and that record
74 * still needs to be revoked. 74 * still needs to be revoked.
75 *
76 * If the handle isn't valid we're not journaling so there's nothing to do.
75 */ 77 */
76int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, 78int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
77 struct buffer_head *bh, ext4_fsblk_t blocknr) 79 struct buffer_head *bh, ext4_fsblk_t blocknr)
78{ 80{
79 int err; 81 int err;
80 82
83 if (!ext4_handle_valid(handle))
84 return 0;
85
81 might_sleep(); 86 might_sleep();
82 87
83 BUFFER_TRACE(bh, "enter"); 88 BUFFER_TRACE(bh, "enter");
@@ -170,7 +175,9 @@ static handle_t *start_transaction(struct inode *inode)
170 */ 175 */
171static int try_to_extend_transaction(handle_t *handle, struct inode *inode) 176static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
172{ 177{
173 if (handle->h_buffer_credits > EXT4_RESERVE_TRANS_BLOCKS) 178 if (!ext4_handle_valid(handle))
179 return 0;
180 if (ext4_handle_has_enough_credits(handle, EXT4_RESERVE_TRANS_BLOCKS+1))
174 return 0; 181 return 0;
175 if (!ext4_journal_extend(handle, blocks_for_truncate(inode))) 182 if (!ext4_journal_extend(handle, blocks_for_truncate(inode)))
176 return 0; 183 return 0;
@@ -184,6 +191,7 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
184 */ 191 */
185static int ext4_journal_test_restart(handle_t *handle, struct inode *inode) 192static int ext4_journal_test_restart(handle_t *handle, struct inode *inode)
186{ 193{
194 BUG_ON(EXT4_JOURNAL(inode) == NULL);
187 jbd_debug(2, "restarting handle %p\n", handle); 195 jbd_debug(2, "restarting handle %p\n", handle);
188 return ext4_journal_restart(handle, blocks_for_truncate(inode)); 196 return ext4_journal_restart(handle, blocks_for_truncate(inode));
189} 197}
@@ -216,7 +224,7 @@ void ext4_delete_inode(struct inode *inode)
216 } 224 }
217 225
218 if (IS_SYNC(inode)) 226 if (IS_SYNC(inode))
219 handle->h_sync = 1; 227 ext4_handle_sync(handle);
220 inode->i_size = 0; 228 inode->i_size = 0;
221 err = ext4_mark_inode_dirty(handle, inode); 229 err = ext4_mark_inode_dirty(handle, inode);
222 if (err) { 230 if (err) {
@@ -233,7 +241,7 @@ void ext4_delete_inode(struct inode *inode)
233 * enough credits left in the handle to remove the inode from 241 * enough credits left in the handle to remove the inode from
234 * the orphan list and set the dtime field. 242 * the orphan list and set the dtime field.
235 */ 243 */
236 if (handle->h_buffer_credits < 3) { 244 if (!ext4_handle_has_enough_credits(handle, 3)) {
237 err = ext4_journal_extend(handle, 3); 245 err = ext4_journal_extend(handle, 3);
238 if (err > 0) 246 if (err > 0)
239 err = ext4_journal_restart(handle, 3); 247 err = ext4_journal_restart(handle, 3);
@@ -717,8 +725,8 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode,
717 set_buffer_uptodate(bh); 725 set_buffer_uptodate(bh);
718 unlock_buffer(bh); 726 unlock_buffer(bh);
719 727
720 BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); 728 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
721 err = ext4_journal_dirty_metadata(handle, bh); 729 err = ext4_handle_dirty_metadata(handle, inode, bh);
722 if (err) 730 if (err)
723 goto failed; 731 goto failed;
724 } 732 }
@@ -800,8 +808,8 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode,
800 * generic_commit_write->__mark_inode_dirty->ext4_dirty_inode. 808 * generic_commit_write->__mark_inode_dirty->ext4_dirty_inode.
801 */ 809 */
802 jbd_debug(5, "splicing indirect only\n"); 810 jbd_debug(5, "splicing indirect only\n");
803 BUFFER_TRACE(where->bh, "call ext4_journal_dirty_metadata"); 811 BUFFER_TRACE(where->bh, "call ext4_handle_dirty_metadata");
804 err = ext4_journal_dirty_metadata(handle, where->bh); 812 err = ext4_handle_dirty_metadata(handle, inode, where->bh);
805 if (err) 813 if (err)
806 goto err_out; 814 goto err_out;
807 } else { 815 } else {
@@ -1229,8 +1237,8 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
1229 set_buffer_uptodate(bh); 1237 set_buffer_uptodate(bh);
1230 } 1238 }
1231 unlock_buffer(bh); 1239 unlock_buffer(bh);
1232 BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); 1240 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
1233 err = ext4_journal_dirty_metadata(handle, bh); 1241 err = ext4_handle_dirty_metadata(handle, inode, bh);
1234 if (!fatal) 1242 if (!fatal)
1235 fatal = err; 1243 fatal = err;
1236 } else { 1244 } else {
@@ -1395,7 +1403,7 @@ static int write_end_fn(handle_t *handle, struct buffer_head *bh)
1395 if (!buffer_mapped(bh) || buffer_freed(bh)) 1403 if (!buffer_mapped(bh) || buffer_freed(bh))
1396 return 0; 1404 return 0;
1397 set_buffer_uptodate(bh); 1405 set_buffer_uptodate(bh);
1398 return ext4_journal_dirty_metadata(handle, bh); 1406 return ext4_handle_dirty_metadata(handle, NULL, bh);
1399} 1407}
1400 1408
1401/* 1409/*
@@ -2762,7 +2770,10 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
2762 filemap_write_and_wait(mapping); 2770 filemap_write_and_wait(mapping);
2763 } 2771 }
2764 2772
2765 if (EXT4_I(inode)->i_state & EXT4_STATE_JDATA) { 2773 BUG_ON(!EXT4_JOURNAL(inode) &&
2774 EXT4_I(inode)->i_state & EXT4_STATE_JDATA);
2775
2776 if (EXT4_JOURNAL(inode) && EXT4_I(inode)->i_state & EXT4_STATE_JDATA) {
2766 /* 2777 /*
2767 * This is a REALLY heavyweight approach, but the use of 2778 * This is a REALLY heavyweight approach, but the use of
2768 * bmap on dirty files is expected to be extremely rare: 2779 * bmap on dirty files is expected to be extremely rare:
@@ -3033,7 +3044,10 @@ static void ext4_invalidatepage(struct page *page, unsigned long offset)
3033 if (offset == 0) 3044 if (offset == 0)
3034 ClearPageChecked(page); 3045 ClearPageChecked(page);
3035 3046
3036 jbd2_journal_invalidatepage(journal, page, offset); 3047 if (journal)
3048 jbd2_journal_invalidatepage(journal, page, offset);
3049 else
3050 block_invalidatepage(page, offset);
3037} 3051}
3038 3052
3039static int ext4_releasepage(struct page *page, gfp_t wait) 3053static int ext4_releasepage(struct page *page, gfp_t wait)
@@ -3043,7 +3057,10 @@ static int ext4_releasepage(struct page *page, gfp_t wait)
3043 WARN_ON(PageChecked(page)); 3057 WARN_ON(PageChecked(page));
3044 if (!page_has_buffers(page)) 3058 if (!page_has_buffers(page))
3045 return 0; 3059 return 0;
3046 return jbd2_journal_try_to_free_buffers(journal, page, wait); 3060 if (journal)
3061 return jbd2_journal_try_to_free_buffers(journal, page, wait);
3062 else
3063 return try_to_free_buffers(page);
3047} 3064}
3048 3065
3049/* 3066/*
@@ -3315,7 +3332,7 @@ int ext4_block_truncate_page(handle_t *handle,
3315 3332
3316 err = 0; 3333 err = 0;
3317 if (ext4_should_journal_data(inode)) { 3334 if (ext4_should_journal_data(inode)) {
3318 err = ext4_journal_dirty_metadata(handle, bh); 3335 err = ext4_handle_dirty_metadata(handle, inode, bh);
3319 } else { 3336 } else {
3320 if (ext4_should_order_data(inode)) 3337 if (ext4_should_order_data(inode))
3321 err = ext4_jbd2_file_inode(handle, inode); 3338 err = ext4_jbd2_file_inode(handle, inode);
@@ -3439,8 +3456,8 @@ static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
3439 __le32 *p; 3456 __le32 *p;
3440 if (try_to_extend_transaction(handle, inode)) { 3457 if (try_to_extend_transaction(handle, inode)) {
3441 if (bh) { 3458 if (bh) {
3442 BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); 3459 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
3443 ext4_journal_dirty_metadata(handle, bh); 3460 ext4_handle_dirty_metadata(handle, inode, bh);
3444 } 3461 }
3445 ext4_mark_inode_dirty(handle, inode); 3462 ext4_mark_inode_dirty(handle, inode);
3446 ext4_journal_test_restart(handle, inode); 3463 ext4_journal_test_restart(handle, inode);
@@ -3540,7 +3557,7 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
3540 count, block_to_free_p, p); 3557 count, block_to_free_p, p);
3541 3558
3542 if (this_bh) { 3559 if (this_bh) {
3543 BUFFER_TRACE(this_bh, "call ext4_journal_dirty_metadata"); 3560 BUFFER_TRACE(this_bh, "call ext4_handle_dirty_metadata");
3544 3561
3545 /* 3562 /*
3546 * The buffer head should have an attached journal head at this 3563 * The buffer head should have an attached journal head at this
@@ -3549,7 +3566,7 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
3549 * the block was cleared. Check for this instead of OOPSing. 3566 * the block was cleared. Check for this instead of OOPSing.
3550 */ 3567 */
3551 if (bh2jh(this_bh)) 3568 if (bh2jh(this_bh))
3552 ext4_journal_dirty_metadata(handle, this_bh); 3569 ext4_handle_dirty_metadata(handle, inode, this_bh);
3553 else 3570 else
3554 ext4_error(inode->i_sb, __func__, 3571 ext4_error(inode->i_sb, __func__,
3555 "circular indirect block detected, " 3572 "circular indirect block detected, "
@@ -3579,7 +3596,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
3579 ext4_fsblk_t nr; 3596 ext4_fsblk_t nr;
3580 __le32 *p; 3597 __le32 *p;
3581 3598
3582 if (is_handle_aborted(handle)) 3599 if (ext4_handle_is_aborted(handle))
3583 return; 3600 return;
3584 3601
3585 if (depth--) { 3602 if (depth--) {
@@ -3649,7 +3666,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
3649 * will merely complain about releasing a free block, 3666 * will merely complain about releasing a free block,
3650 * rather than leaking blocks. 3667 * rather than leaking blocks.
3651 */ 3668 */
3652 if (is_handle_aborted(handle)) 3669 if (ext4_handle_is_aborted(handle))
3653 return; 3670 return;
3654 if (try_to_extend_transaction(handle, inode)) { 3671 if (try_to_extend_transaction(handle, inode)) {
3655 ext4_mark_inode_dirty(handle, inode); 3672 ext4_mark_inode_dirty(handle, inode);
@@ -3668,9 +3685,10 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
3668 parent_bh)){ 3685 parent_bh)){
3669 *p = 0; 3686 *p = 0;
3670 BUFFER_TRACE(parent_bh, 3687 BUFFER_TRACE(parent_bh,
3671 "call ext4_journal_dirty_metadata"); 3688 "call ext4_handle_dirty_metadata");
3672 ext4_journal_dirty_metadata(handle, 3689 ext4_handle_dirty_metadata(handle,
3673 parent_bh); 3690 inode,
3691 parent_bh);
3674 } 3692 }
3675 } 3693 }
3676 } 3694 }
@@ -3858,7 +3876,7 @@ do_indirects:
3858 * synchronous 3876 * synchronous
3859 */ 3877 */
3860 if (IS_SYNC(inode)) 3878 if (IS_SYNC(inode))
3861 handle->h_sync = 1; 3879 ext4_handle_sync(handle);
3862out_stop: 3880out_stop:
3863 /* 3881 /*
3864 * If this was a simple ftruncate(), and the file will remain alive 3882 * If this was a simple ftruncate(), and the file will remain alive
@@ -4357,8 +4375,8 @@ static int ext4_do_update_inode(handle_t *handle,
4357 EXT4_SET_RO_COMPAT_FEATURE(sb, 4375 EXT4_SET_RO_COMPAT_FEATURE(sb,
4358 EXT4_FEATURE_RO_COMPAT_LARGE_FILE); 4376 EXT4_FEATURE_RO_COMPAT_LARGE_FILE);
4359 sb->s_dirt = 1; 4377 sb->s_dirt = 1;
4360 handle->h_sync = 1; 4378 ext4_handle_sync(handle);
4361 err = ext4_journal_dirty_metadata(handle, 4379 err = ext4_handle_dirty_metadata(handle, inode,
4362 EXT4_SB(sb)->s_sbh); 4380 EXT4_SB(sb)->s_sbh);
4363 } 4381 }
4364 } 4382 }
@@ -4385,9 +4403,8 @@ static int ext4_do_update_inode(handle_t *handle,
4385 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); 4403 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
4386 } 4404 }
4387 4405
4388 4406 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
4389 BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); 4407 rc = ext4_handle_dirty_metadata(handle, inode, bh);
4390 rc = ext4_journal_dirty_metadata(handle, bh);
4391 if (!err) 4408 if (!err)
4392 err = rc; 4409 err = rc;
4393 ei->i_state &= ~EXT4_STATE_NEW; 4410 ei->i_state &= ~EXT4_STATE_NEW;
@@ -4450,6 +4467,25 @@ int ext4_write_inode(struct inode *inode, int wait)
4450 return ext4_force_commit(inode->i_sb); 4467 return ext4_force_commit(inode->i_sb);
4451} 4468}
4452 4469
4470int __ext4_write_dirty_metadata(struct inode *inode, struct buffer_head *bh)
4471{
4472 int err = 0;
4473
4474 mark_buffer_dirty(bh);
4475 if (inode && inode_needs_sync(inode)) {
4476 sync_dirty_buffer(bh);
4477 if (buffer_req(bh) && !buffer_uptodate(bh)) {
4478 ext4_error(inode->i_sb, __func__,
4479 "IO error syncing inode, "
4480 "inode=%lu, block=%llu",
4481 inode->i_ino,
4482 (unsigned long long)bh->b_blocknr);
4483 err = -EIO;
4484 }
4485 }
4486 return err;
4487}
4488
4453/* 4489/*
4454 * ext4_setattr() 4490 * ext4_setattr()
4455 * 4491 *
@@ -4754,16 +4790,15 @@ int
4754ext4_reserve_inode_write(handle_t *handle, struct inode *inode, 4790ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
4755 struct ext4_iloc *iloc) 4791 struct ext4_iloc *iloc)
4756{ 4792{
4757 int err = 0; 4793 int err;
4758 if (handle) { 4794
4759 err = ext4_get_inode_loc(inode, iloc); 4795 err = ext4_get_inode_loc(inode, iloc);
4760 if (!err) { 4796 if (!err) {
4761 BUFFER_TRACE(iloc->bh, "get_write_access"); 4797 BUFFER_TRACE(iloc->bh, "get_write_access");
4762 err = ext4_journal_get_write_access(handle, iloc->bh); 4798 err = ext4_journal_get_write_access(handle, iloc->bh);
4763 if (err) { 4799 if (err) {
4764 brelse(iloc->bh); 4800 brelse(iloc->bh);
4765 iloc->bh = NULL; 4801 iloc->bh = NULL;
4766 }
4767 } 4802 }
4768 } 4803 }
4769 ext4_std_error(inode->i_sb, err); 4804 ext4_std_error(inode->i_sb, err);
@@ -4835,7 +4870,8 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
4835 4870
4836 might_sleep(); 4871 might_sleep();
4837 err = ext4_reserve_inode_write(handle, inode, &iloc); 4872 err = ext4_reserve_inode_write(handle, inode, &iloc);
4838 if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && 4873 if (ext4_handle_valid(handle) &&
4874 EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize &&
4839 !(EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND)) { 4875 !(EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND)) {
4840 /* 4876 /*
4841 * We need extra buffer credits since we may write into EA block 4877 * We need extra buffer credits since we may write into EA block
@@ -4887,6 +4923,11 @@ void ext4_dirty_inode(struct inode *inode)
4887 handle_t *current_handle = ext4_journal_current_handle(); 4923 handle_t *current_handle = ext4_journal_current_handle();
4888 handle_t *handle; 4924 handle_t *handle;
4889 4925
4926 if (!ext4_handle_valid(current_handle)) {
4927 ext4_mark_inode_dirty(current_handle, inode);
4928 return;
4929 }
4930
4890 handle = ext4_journal_start(inode, 2); 4931 handle = ext4_journal_start(inode, 2);
4891 if (IS_ERR(handle)) 4932 if (IS_ERR(handle))
4892 goto out; 4933 goto out;
@@ -4924,8 +4965,9 @@ static int ext4_pin_inode(handle_t *handle, struct inode *inode)
4924 BUFFER_TRACE(iloc.bh, "get_write_access"); 4965 BUFFER_TRACE(iloc.bh, "get_write_access");
4925 err = jbd2_journal_get_write_access(handle, iloc.bh); 4966 err = jbd2_journal_get_write_access(handle, iloc.bh);
4926 if (!err) 4967 if (!err)
4927 err = ext4_journal_dirty_metadata(handle, 4968 err = ext4_handle_dirty_metadata(handle,
4928 iloc.bh); 4969 inode,
4970 iloc.bh);
4929 brelse(iloc.bh); 4971 brelse(iloc.bh);
4930 } 4972 }
4931 } 4973 }
@@ -4951,6 +4993,8 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
4951 */ 4993 */
4952 4994
4953 journal = EXT4_JOURNAL(inode); 4995 journal = EXT4_JOURNAL(inode);
4996 if (!journal)
4997 return 0;
4954 if (is_journal_aborted(journal)) 4998 if (is_journal_aborted(journal))
4955 return -EROFS; 4999 return -EROFS;
4956 5000
@@ -4980,7 +5024,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
4980 return PTR_ERR(handle); 5024 return PTR_ERR(handle);
4981 5025
4982 err = ext4_mark_inode_dirty(handle, inode); 5026 err = ext4_mark_inode_dirty(handle, inode);
4983 handle->h_sync = 1; 5027 ext4_handle_sync(handle);
4984 ext4_journal_stop(handle); 5028 ext4_journal_stop(handle);
4985 ext4_std_error(inode->i_sb, err); 5029 ext4_std_error(inode->i_sb, err);
4986 5030
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index dc99b4776d58..42dc83fb247a 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -99,7 +99,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
99 goto flags_out; 99 goto flags_out;
100 } 100 }
101 if (IS_SYNC(inode)) 101 if (IS_SYNC(inode))
102 handle->h_sync = 1; 102 ext4_handle_sync(handle);
103 err = ext4_reserve_inode_write(handle, inode, &iloc); 103 err = ext4_reserve_inode_write(handle, inode, &iloc);
104 if (err) 104 if (err)
105 goto flags_err; 105 goto flags_err;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 7beab7141dd5..edb512b2ec49 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2553,7 +2553,8 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
2553 ext4_mb_init_per_dev_proc(sb); 2553 ext4_mb_init_per_dev_proc(sb);
2554 ext4_mb_history_init(sb); 2554 ext4_mb_history_init(sb);
2555 2555
2556 sbi->s_journal->j_commit_callback = release_blocks_on_commit; 2556 if (sbi->s_journal)
2557 sbi->s_journal->j_commit_callback = release_blocks_on_commit;
2557 2558
2558 printk(KERN_INFO "EXT4-fs: mballoc enabled\n"); 2559 printk(KERN_INFO "EXT4-fs: mballoc enabled\n");
2559 return 0; 2560 return 0;
@@ -2854,7 +2855,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
2854 mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), 2855 mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group),
2855 bitmap_bh->b_data, ac->ac_b_ex.fe_start, 2856 bitmap_bh->b_data, ac->ac_b_ex.fe_start,
2856 ac->ac_b_ex.fe_len); 2857 ac->ac_b_ex.fe_len);
2857 err = ext4_journal_dirty_metadata(handle, bitmap_bh); 2858 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
2858 if (!err) 2859 if (!err)
2859 err = -EAGAIN; 2860 err = -EAGAIN;
2860 goto out_err; 2861 goto out_err;
@@ -2901,10 +2902,10 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
2901 spin_unlock(sb_bgl_lock(sbi, flex_group)); 2902 spin_unlock(sb_bgl_lock(sbi, flex_group));
2902 } 2903 }
2903 2904
2904 err = ext4_journal_dirty_metadata(handle, bitmap_bh); 2905 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
2905 if (err) 2906 if (err)
2906 goto out_err; 2907 goto out_err;
2907 err = ext4_journal_dirty_metadata(handle, gdp_bh); 2908 err = ext4_handle_dirty_metadata(handle, NULL, gdp_bh);
2908 2909
2909out_err: 2910out_err:
2910 sb->s_dirt = 1; 2911 sb->s_dirt = 1;
@@ -4414,7 +4415,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
4414 struct rb_node **n = &db->bb_free_root.rb_node, *node; 4415 struct rb_node **n = &db->bb_free_root.rb_node, *node;
4415 struct rb_node *parent = NULL, *new_node; 4416 struct rb_node *parent = NULL, *new_node;
4416 4417
4417 4418 BUG_ON(!ext4_handle_valid(handle));
4418 BUG_ON(e4b->bd_bitmap_page == NULL); 4419 BUG_ON(e4b->bd_bitmap_page == NULL);
4419 BUG_ON(e4b->bd_buddy_page == NULL); 4420 BUG_ON(e4b->bd_buddy_page == NULL);
4420 4421
@@ -4600,7 +4601,7 @@ do_more:
4600 4601
4601 /* We dirtied the bitmap block */ 4602 /* We dirtied the bitmap block */
4602 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); 4603 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
4603 err = ext4_journal_dirty_metadata(handle, bitmap_bh); 4604 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
4604 4605
4605 if (ac) { 4606 if (ac) {
4606 ac->ac_b_ex.fe_group = block_group; 4607 ac->ac_b_ex.fe_group = block_group;
@@ -4609,7 +4610,7 @@ do_more:
4609 ext4_mb_store_history(ac); 4610 ext4_mb_store_history(ac);
4610 } 4611 }
4611 4612
4612 if (metadata) { 4613 if (metadata && ext4_handle_valid(handle)) {
4613 /* blocks being freed are metadata. these blocks shouldn't 4614 /* blocks being freed are metadata. these blocks shouldn't
4614 * be used until this transaction is committed */ 4615 * be used until this transaction is committed */
4615 ext4_mb_free_metadata(handle, &e4b, block_group, bit, count); 4616 ext4_mb_free_metadata(handle, &e4b, block_group, bit, count);
@@ -4639,7 +4640,7 @@ do_more:
4639 4640
4640 /* And the group descriptor block */ 4641 /* And the group descriptor block */
4641 BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); 4642 BUFFER_TRACE(gd_bh, "dirtied group descriptor block");
4642 ret = ext4_journal_dirty_metadata(handle, gd_bh); 4643 ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
4643 if (!err) 4644 if (!err)
4644 err = ret; 4645 err = ret;
4645 4646
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index f2a9cf498ecd..e7cd488da4bb 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -59,7 +59,8 @@ static int finish_range(handle_t *handle, struct inode *inode,
59 /* 59 /*
60 * Make sure the credit we accumalated is not really high 60 * Make sure the credit we accumalated is not really high
61 */ 61 */
62 if (needed && handle->h_buffer_credits >= EXT4_RESERVE_TRANS_BLOCKS) { 62 if (needed && ext4_handle_has_enough_credits(handle,
63 EXT4_RESERVE_TRANS_BLOCKS)) {
63 retval = ext4_journal_restart(handle, needed); 64 retval = ext4_journal_restart(handle, needed);
64 if (retval) 65 if (retval)
65 goto err_out; 66 goto err_out;
@@ -229,7 +230,7 @@ static int extend_credit_for_blkdel(handle_t *handle, struct inode *inode)
229{ 230{
230 int retval = 0, needed; 231 int retval = 0, needed;
231 232
232 if (handle->h_buffer_credits > EXT4_RESERVE_TRANS_BLOCKS) 233 if (ext4_handle_has_enough_credits(handle, EXT4_RESERVE_TRANS_BLOCKS+1))
233 return 0; 234 return 0;
234 /* 235 /*
235 * We are freeing a blocks. During this we touch 236 * We are freeing a blocks. During this we touch
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 84a68ae623c1..08873e938ab2 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1233,10 +1233,10 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
1233 de = de2; 1233 de = de2;
1234 } 1234 }
1235 dx_insert_block(frame, hash2 + continued, newblock); 1235 dx_insert_block(frame, hash2 + continued, newblock);
1236 err = ext4_journal_dirty_metadata(handle, bh2); 1236 err = ext4_handle_dirty_metadata(handle, dir, bh2);
1237 if (err) 1237 if (err)
1238 goto journal_error; 1238 goto journal_error;
1239 err = ext4_journal_dirty_metadata(handle, frame->bh); 1239 err = ext4_handle_dirty_metadata(handle, dir, frame->bh);
1240 if (err) 1240 if (err)
1241 goto journal_error; 1241 goto journal_error;
1242 brelse(bh2); 1242 brelse(bh2);
@@ -1340,8 +1340,8 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
1340 ext4_update_dx_flag(dir); 1340 ext4_update_dx_flag(dir);
1341 dir->i_version++; 1341 dir->i_version++;
1342 ext4_mark_inode_dirty(handle, dir); 1342 ext4_mark_inode_dirty(handle, dir);
1343 BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); 1343 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
1344 err = ext4_journal_dirty_metadata(handle, bh); 1344 err = ext4_handle_dirty_metadata(handle, dir, bh);
1345 if (err) 1345 if (err)
1346 ext4_std_error(dir->i_sb, err); 1346 ext4_std_error(dir->i_sb, err);
1347 brelse(bh); 1347 brelse(bh);
@@ -1581,7 +1581,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1581 dxtrace(dx_show_index("node", frames[1].entries)); 1581 dxtrace(dx_show_index("node", frames[1].entries));
1582 dxtrace(dx_show_index("node", 1582 dxtrace(dx_show_index("node",
1583 ((struct dx_node *) bh2->b_data)->entries)); 1583 ((struct dx_node *) bh2->b_data)->entries));
1584 err = ext4_journal_dirty_metadata(handle, bh2); 1584 err = ext4_handle_dirty_metadata(handle, inode, bh2);
1585 if (err) 1585 if (err)
1586 goto journal_error; 1586 goto journal_error;
1587 brelse (bh2); 1587 brelse (bh2);
@@ -1607,7 +1607,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1607 if (err) 1607 if (err)
1608 goto journal_error; 1608 goto journal_error;
1609 } 1609 }
1610 ext4_journal_dirty_metadata(handle, frames[0].bh); 1610 ext4_handle_dirty_metadata(handle, inode, frames[0].bh);
1611 } 1611 }
1612 de = do_split(handle, dir, &bh, frame, &hinfo, &err); 1612 de = do_split(handle, dir, &bh, frame, &hinfo, &err);
1613 if (!de) 1613 if (!de)
@@ -1653,8 +1653,8 @@ static int ext4_delete_entry(handle_t *handle,
1653 else 1653 else
1654 de->inode = 0; 1654 de->inode = 0;
1655 dir->i_version++; 1655 dir->i_version++;
1656 BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); 1656 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
1657 ext4_journal_dirty_metadata(handle, bh); 1657 ext4_handle_dirty_metadata(handle, dir, bh);
1658 return 0; 1658 return 0;
1659 } 1659 }
1660 i += ext4_rec_len_from_disk(de->rec_len); 1660 i += ext4_rec_len_from_disk(de->rec_len);
@@ -1732,7 +1732,7 @@ retry:
1732 return PTR_ERR(handle); 1732 return PTR_ERR(handle);
1733 1733
1734 if (IS_DIRSYNC(dir)) 1734 if (IS_DIRSYNC(dir))
1735 handle->h_sync = 1; 1735 ext4_handle_sync(handle);
1736 1736
1737 inode = ext4_new_inode (handle, dir, mode); 1737 inode = ext4_new_inode (handle, dir, mode);
1738 err = PTR_ERR(inode); 1738 err = PTR_ERR(inode);
@@ -1766,7 +1766,7 @@ retry:
1766 return PTR_ERR(handle); 1766 return PTR_ERR(handle);
1767 1767
1768 if (IS_DIRSYNC(dir)) 1768 if (IS_DIRSYNC(dir))
1769 handle->h_sync = 1; 1769 ext4_handle_sync(handle);
1770 1770
1771 inode = ext4_new_inode(handle, dir, mode); 1771 inode = ext4_new_inode(handle, dir, mode);
1772 err = PTR_ERR(inode); 1772 err = PTR_ERR(inode);
@@ -1802,7 +1802,7 @@ retry:
1802 return PTR_ERR(handle); 1802 return PTR_ERR(handle);
1803 1803
1804 if (IS_DIRSYNC(dir)) 1804 if (IS_DIRSYNC(dir))
1805 handle->h_sync = 1; 1805 ext4_handle_sync(handle);
1806 1806
1807 inode = ext4_new_inode(handle, dir, S_IFDIR | mode); 1807 inode = ext4_new_inode(handle, dir, S_IFDIR | mode);
1808 err = PTR_ERR(inode); 1808 err = PTR_ERR(inode);
@@ -1831,8 +1831,8 @@ retry:
1831 strcpy(de->name, ".."); 1831 strcpy(de->name, "..");
1832 ext4_set_de_type(dir->i_sb, de, S_IFDIR); 1832 ext4_set_de_type(dir->i_sb, de, S_IFDIR);
1833 inode->i_nlink = 2; 1833 inode->i_nlink = 2;
1834 BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata"); 1834 BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
1835 ext4_journal_dirty_metadata(handle, dir_block); 1835 ext4_handle_dirty_metadata(handle, dir, dir_block);
1836 brelse(dir_block); 1836 brelse(dir_block);
1837 ext4_mark_inode_dirty(handle, inode); 1837 ext4_mark_inode_dirty(handle, inode);
1838 err = ext4_add_entry(handle, dentry, inode); 1838 err = ext4_add_entry(handle, dentry, inode);
@@ -1944,6 +1944,9 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
1944 struct ext4_iloc iloc; 1944 struct ext4_iloc iloc;
1945 int err = 0, rc; 1945 int err = 0, rc;
1946 1946
1947 if (!ext4_handle_valid(handle))
1948 return 0;
1949
1947 lock_super(sb); 1950 lock_super(sb);
1948 if (!list_empty(&EXT4_I(inode)->i_orphan)) 1951 if (!list_empty(&EXT4_I(inode)->i_orphan))
1949 goto out_unlock; 1952 goto out_unlock;
@@ -1972,7 +1975,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
1972 /* Insert this inode at the head of the on-disk orphan list... */ 1975 /* Insert this inode at the head of the on-disk orphan list... */
1973 NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan); 1976 NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan);
1974 EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino); 1977 EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
1975 err = ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); 1978 err = ext4_handle_dirty_metadata(handle, inode, EXT4_SB(sb)->s_sbh);
1976 rc = ext4_mark_iloc_dirty(handle, inode, &iloc); 1979 rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
1977 if (!err) 1980 if (!err)
1978 err = rc; 1981 err = rc;
@@ -2010,6 +2013,9 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
2010 struct ext4_iloc iloc; 2013 struct ext4_iloc iloc;
2011 int err = 0; 2014 int err = 0;
2012 2015
2016 if (!ext4_handle_valid(handle))
2017 return 0;
2018
2013 lock_super(inode->i_sb); 2019 lock_super(inode->i_sb);
2014 if (list_empty(&ei->i_orphan)) { 2020 if (list_empty(&ei->i_orphan)) {
2015 unlock_super(inode->i_sb); 2021 unlock_super(inode->i_sb);
@@ -2028,7 +2034,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
2028 * transaction handle with which to update the orphan list on 2034 * transaction handle with which to update the orphan list on
2029 * disk, but we still need to remove the inode from the linked 2035 * disk, but we still need to remove the inode from the linked
2030 * list in memory. */ 2036 * list in memory. */
2031 if (!handle) 2037 if (sbi->s_journal && !handle)
2032 goto out; 2038 goto out;
2033 2039
2034 err = ext4_reserve_inode_write(handle, inode, &iloc); 2040 err = ext4_reserve_inode_write(handle, inode, &iloc);
@@ -2042,7 +2048,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
2042 if (err) 2048 if (err)
2043 goto out_brelse; 2049 goto out_brelse;
2044 sbi->s_es->s_last_orphan = cpu_to_le32(ino_next); 2050 sbi->s_es->s_last_orphan = cpu_to_le32(ino_next);
2045 err = ext4_journal_dirty_metadata(handle, sbi->s_sbh); 2051 err = ext4_handle_dirty_metadata(handle, inode, sbi->s_sbh);
2046 } else { 2052 } else {
2047 struct ext4_iloc iloc2; 2053 struct ext4_iloc iloc2;
2048 struct inode *i_prev = 2054 struct inode *i_prev =
@@ -2093,7 +2099,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
2093 goto end_rmdir; 2099 goto end_rmdir;
2094 2100
2095 if (IS_DIRSYNC(dir)) 2101 if (IS_DIRSYNC(dir))
2096 handle->h_sync = 1; 2102 ext4_handle_sync(handle);
2097 2103
2098 inode = dentry->d_inode; 2104 inode = dentry->d_inode;
2099 2105
@@ -2147,7 +2153,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
2147 return PTR_ERR(handle); 2153 return PTR_ERR(handle);
2148 2154
2149 if (IS_DIRSYNC(dir)) 2155 if (IS_DIRSYNC(dir))
2150 handle->h_sync = 1; 2156 ext4_handle_sync(handle);
2151 2157
2152 retval = -ENOENT; 2158 retval = -ENOENT;
2153 bh = ext4_find_entry(dir, &dentry->d_name, &de); 2159 bh = ext4_find_entry(dir, &dentry->d_name, &de);
@@ -2204,7 +2210,7 @@ retry:
2204 return PTR_ERR(handle); 2210 return PTR_ERR(handle);
2205 2211
2206 if (IS_DIRSYNC(dir)) 2212 if (IS_DIRSYNC(dir))
2207 handle->h_sync = 1; 2213 ext4_handle_sync(handle);
2208 2214
2209 inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO); 2215 inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO);
2210 err = PTR_ERR(inode); 2216 err = PTR_ERR(inode);
@@ -2267,7 +2273,7 @@ retry:
2267 return PTR_ERR(handle); 2273 return PTR_ERR(handle);
2268 2274
2269 if (IS_DIRSYNC(dir)) 2275 if (IS_DIRSYNC(dir))
2270 handle->h_sync = 1; 2276 ext4_handle_sync(handle);
2271 2277
2272 inode->i_ctime = ext4_current_time(inode); 2278 inode->i_ctime = ext4_current_time(inode);
2273 ext4_inc_count(handle, inode); 2279 ext4_inc_count(handle, inode);
@@ -2316,7 +2322,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2316 return PTR_ERR(handle); 2322 return PTR_ERR(handle);
2317 2323
2318 if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) 2324 if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
2319 handle->h_sync = 1; 2325 ext4_handle_sync(handle);
2320 2326
2321 old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de); 2327 old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de);
2322 /* 2328 /*
@@ -2370,8 +2376,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2370 new_dir->i_ctime = new_dir->i_mtime = 2376 new_dir->i_ctime = new_dir->i_mtime =
2371 ext4_current_time(new_dir); 2377 ext4_current_time(new_dir);
2372 ext4_mark_inode_dirty(handle, new_dir); 2378 ext4_mark_inode_dirty(handle, new_dir);
2373 BUFFER_TRACE(new_bh, "call ext4_journal_dirty_metadata"); 2379 BUFFER_TRACE(new_bh, "call ext4_handle_dirty_metadata");
2374 ext4_journal_dirty_metadata(handle, new_bh); 2380 ext4_handle_dirty_metadata(handle, new_dir, new_bh);
2375 brelse(new_bh); 2381 brelse(new_bh);
2376 new_bh = NULL; 2382 new_bh = NULL;
2377 } 2383 }
@@ -2421,8 +2427,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2421 BUFFER_TRACE(dir_bh, "get_write_access"); 2427 BUFFER_TRACE(dir_bh, "get_write_access");
2422 ext4_journal_get_write_access(handle, dir_bh); 2428 ext4_journal_get_write_access(handle, dir_bh);
2423 PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); 2429 PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
2424 BUFFER_TRACE(dir_bh, "call ext4_journal_dirty_metadata"); 2430 BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata");
2425 ext4_journal_dirty_metadata(handle, dir_bh); 2431 ext4_handle_dirty_metadata(handle, old_dir, dir_bh);
2426 ext4_dec_count(handle, old_dir); 2432 ext4_dec_count(handle, old_dir);
2427 if (new_inode) { 2433 if (new_inode) {
2428 /* checked empty_dir above, can't have another parent, 2434 /* checked empty_dir above, can't have another parent,
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index d448eb1d9bae..1665aa131d18 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -149,7 +149,7 @@ static int extend_or_restart_transaction(handle_t *handle, int thresh,
149{ 149{
150 int err; 150 int err;
151 151
152 if (handle->h_buffer_credits >= thresh) 152 if (ext4_handle_has_enough_credits(handle, thresh))
153 return 0; 153 return 0;
154 154
155 err = ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA); 155 err = ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA);
@@ -232,7 +232,7 @@ static int setup_new_group_blocks(struct super_block *sb,
232 memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size); 232 memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
233 set_buffer_uptodate(gdb); 233 set_buffer_uptodate(gdb);
234 unlock_buffer(gdb); 234 unlock_buffer(gdb);
235 ext4_journal_dirty_metadata(handle, gdb); 235 ext4_handle_dirty_metadata(handle, NULL, gdb);
236 ext4_set_bit(bit, bh->b_data); 236 ext4_set_bit(bit, bh->b_data);
237 brelse(gdb); 237 brelse(gdb);
238 } 238 }
@@ -251,7 +251,7 @@ static int setup_new_group_blocks(struct super_block *sb,
251 err = PTR_ERR(bh); 251 err = PTR_ERR(bh);
252 goto exit_bh; 252 goto exit_bh;
253 } 253 }
254 ext4_journal_dirty_metadata(handle, gdb); 254 ext4_handle_dirty_metadata(handle, NULL, gdb);
255 ext4_set_bit(bit, bh->b_data); 255 ext4_set_bit(bit, bh->b_data);
256 brelse(gdb); 256 brelse(gdb);
257 } 257 }
@@ -276,7 +276,7 @@ static int setup_new_group_blocks(struct super_block *sb,
276 err = PTR_ERR(it); 276 err = PTR_ERR(it);
277 goto exit_bh; 277 goto exit_bh;
278 } 278 }
279 ext4_journal_dirty_metadata(handle, it); 279 ext4_handle_dirty_metadata(handle, NULL, it);
280 brelse(it); 280 brelse(it);
281 ext4_set_bit(bit, bh->b_data); 281 ext4_set_bit(bit, bh->b_data);
282 } 282 }
@@ -286,7 +286,7 @@ static int setup_new_group_blocks(struct super_block *sb,
286 286
287 mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb), 287 mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb),
288 bh->b_data); 288 bh->b_data);
289 ext4_journal_dirty_metadata(handle, bh); 289 ext4_handle_dirty_metadata(handle, NULL, bh);
290 brelse(bh); 290 brelse(bh);
291 291
292 /* Mark unused entries in inode bitmap used */ 292 /* Mark unused entries in inode bitmap used */
@@ -299,7 +299,7 @@ static int setup_new_group_blocks(struct super_block *sb,
299 299
300 mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb), 300 mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb),
301 bh->b_data); 301 bh->b_data);
302 ext4_journal_dirty_metadata(handle, bh); 302 ext4_handle_dirty_metadata(handle, NULL, bh);
303exit_bh: 303exit_bh:
304 brelse(bh); 304 brelse(bh);
305 305
@@ -486,12 +486,12 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
486 * reserved inode, and will become GDT blocks (primary and backup). 486 * reserved inode, and will become GDT blocks (primary and backup).
487 */ 487 */
488 data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)] = 0; 488 data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)] = 0;
489 ext4_journal_dirty_metadata(handle, dind); 489 ext4_handle_dirty_metadata(handle, NULL, dind);
490 brelse(dind); 490 brelse(dind);
491 inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >> 9; 491 inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >> 9;
492 ext4_mark_iloc_dirty(handle, inode, &iloc); 492 ext4_mark_iloc_dirty(handle, inode, &iloc);
493 memset((*primary)->b_data, 0, sb->s_blocksize); 493 memset((*primary)->b_data, 0, sb->s_blocksize);
494 ext4_journal_dirty_metadata(handle, *primary); 494 ext4_handle_dirty_metadata(handle, NULL, *primary);
495 495
496 o_group_desc = EXT4_SB(sb)->s_group_desc; 496 o_group_desc = EXT4_SB(sb)->s_group_desc;
497 memcpy(n_group_desc, o_group_desc, 497 memcpy(n_group_desc, o_group_desc,
@@ -502,7 +502,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
502 kfree(o_group_desc); 502 kfree(o_group_desc);
503 503
504 le16_add_cpu(&es->s_reserved_gdt_blocks, -1); 504 le16_add_cpu(&es->s_reserved_gdt_blocks, -1);
505 ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); 505 ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
506 506
507 return 0; 507 return 0;
508 508
@@ -618,7 +618,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
618 primary[i]->b_blocknr, gdbackups, 618 primary[i]->b_blocknr, gdbackups,
619 blk + primary[i]->b_blocknr); */ 619 blk + primary[i]->b_blocknr); */
620 data[gdbackups] = cpu_to_le32(blk + primary[i]->b_blocknr); 620 data[gdbackups] = cpu_to_le32(blk + primary[i]->b_blocknr);
621 err2 = ext4_journal_dirty_metadata(handle, primary[i]); 621 err2 = ext4_handle_dirty_metadata(handle, NULL, primary[i]);
622 if (!err) 622 if (!err)
623 err = err2; 623 err = err2;
624 } 624 }
@@ -676,7 +676,8 @@ static void update_backups(struct super_block *sb,
676 struct buffer_head *bh; 676 struct buffer_head *bh;
677 677
678 /* Out of journal space, and can't get more - abort - so sad */ 678 /* Out of journal space, and can't get more - abort - so sad */
679 if (handle->h_buffer_credits == 0 && 679 if (ext4_handle_valid(handle) &&
680 handle->h_buffer_credits == 0 &&
680 ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA) && 681 ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA) &&
681 (err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA))) 682 (err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
682 break; 683 break;
@@ -696,7 +697,7 @@ static void update_backups(struct super_block *sb,
696 memset(bh->b_data + size, 0, rest); 697 memset(bh->b_data + size, 0, rest);
697 set_buffer_uptodate(bh); 698 set_buffer_uptodate(bh);
698 unlock_buffer(bh); 699 unlock_buffer(bh);
699 ext4_journal_dirty_metadata(handle, bh); 700 ext4_handle_dirty_metadata(handle, NULL, bh);
700 brelse(bh); 701 brelse(bh);
701 } 702 }
702 if ((err2 = ext4_journal_stop(handle)) && !err) 703 if ((err2 = ext4_journal_stop(handle)) && !err)
@@ -916,7 +917,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
916 /* Update the global fs size fields */ 917 /* Update the global fs size fields */
917 sbi->s_groups_count++; 918 sbi->s_groups_count++;
918 919
919 ext4_journal_dirty_metadata(handle, primary); 920 ext4_handle_dirty_metadata(handle, NULL, primary);
920 921
921 /* Update the reserved block counts only once the new group is 922 /* Update the reserved block counts only once the new group is
922 * active. */ 923 * active. */
@@ -938,7 +939,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
938 EXT4_INODES_PER_GROUP(sb); 939 EXT4_INODES_PER_GROUP(sb);
939 } 940 }
940 941
941 ext4_journal_dirty_metadata(handle, sbi->s_sbh); 942 ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh);
942 sb->s_dirt = 1; 943 sb->s_dirt = 1;
943 944
944exit_journal: 945exit_journal:
@@ -1072,7 +1073,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
1072 goto exit_put; 1073 goto exit_put;
1073 } 1074 }
1074 ext4_blocks_count_set(es, o_blocks_count + add); 1075 ext4_blocks_count_set(es, o_blocks_count + add);
1075 ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); 1076 ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
1076 sb->s_dirt = 1; 1077 sb->s_dirt = 1;
1077 unlock_super(sb); 1078 unlock_super(sb);
1078 ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, 1079 ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count,
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 8a0ae883f567..9b9076d9c4f7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -136,13 +136,19 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
136 * backs (eg. EIO in the commit thread), then we still need to 136 * backs (eg. EIO in the commit thread), then we still need to
137 * take the FS itself readonly cleanly. */ 137 * take the FS itself readonly cleanly. */
138 journal = EXT4_SB(sb)->s_journal; 138 journal = EXT4_SB(sb)->s_journal;
139 if (is_journal_aborted(journal)) { 139 if (journal) {
140 ext4_abort(sb, __func__, 140 if (is_journal_aborted(journal)) {
141 "Detected aborted journal"); 141 ext4_abort(sb, __func__,
142 return ERR_PTR(-EROFS); 142 "Detected aborted journal");
143 return ERR_PTR(-EROFS);
144 }
145 return jbd2_journal_start(journal, nblocks);
143 } 146 }
144 147 /*
145 return jbd2_journal_start(journal, nblocks); 148 * We're not journaling, return the appropriate indication.
149 */
150 current->journal_info = EXT4_NOJOURNAL_HANDLE;
151 return current->journal_info;
146} 152}
147 153
148/* 154/*
@@ -157,6 +163,14 @@ int __ext4_journal_stop(const char *where, handle_t *handle)
157 int err; 163 int err;
158 int rc; 164 int rc;
159 165
166 if (!ext4_handle_valid(handle)) {
167 /*
168 * Do this here since we don't call jbd2_journal_stop() in
169 * no-journal mode.
170 */
171 current->journal_info = NULL;
172 return 0;
173 }
160 sb = handle->h_transaction->t_journal->j_private; 174 sb = handle->h_transaction->t_journal->j_private;
161 err = handle->h_err; 175 err = handle->h_err;
162 rc = jbd2_journal_stop(handle); 176 rc = jbd2_journal_stop(handle);
@@ -174,6 +188,8 @@ void ext4_journal_abort_handle(const char *caller, const char *err_fn,
174 char nbuf[16]; 188 char nbuf[16];
175 const char *errstr = ext4_decode_error(NULL, err, nbuf); 189 const char *errstr = ext4_decode_error(NULL, err, nbuf);
176 190
191 BUG_ON(!ext4_handle_valid(handle));
192
177 if (bh) 193 if (bh)
178 BUFFER_TRACE(bh, "abort"); 194 BUFFER_TRACE(bh, "abort");
179 195
@@ -448,11 +464,13 @@ static void ext4_put_super(struct super_block *sb)
448 ext4_mb_release(sb); 464 ext4_mb_release(sb);
449 ext4_ext_release(sb); 465 ext4_ext_release(sb);
450 ext4_xattr_put_super(sb); 466 ext4_xattr_put_super(sb);
451 err = jbd2_journal_destroy(sbi->s_journal); 467 if (sbi->s_journal) {
452 sbi->s_journal = NULL; 468 err = jbd2_journal_destroy(sbi->s_journal);
453 if (err < 0) 469 sbi->s_journal = NULL;
454 ext4_abort(sb, __func__, "Couldn't clean up the journal"); 470 if (err < 0)
455 471 ext4_abort(sb, __func__,
472 "Couldn't clean up the journal");
473 }
456 if (!(sb->s_flags & MS_RDONLY)) { 474 if (!(sb->s_flags & MS_RDONLY)) {
457 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 475 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
458 es->s_state = cpu_to_le16(sbi->s_mount_state); 476 es->s_state = cpu_to_le16(sbi->s_mount_state);
@@ -522,6 +540,11 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
522 memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); 540 memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
523 INIT_LIST_HEAD(&ei->i_prealloc_list); 541 INIT_LIST_HEAD(&ei->i_prealloc_list);
524 spin_lock_init(&ei->i_prealloc_lock); 542 spin_lock_init(&ei->i_prealloc_lock);
543 /*
544 * Note: We can be called before EXT4_SB(sb)->s_journal is set,
545 * therefore it can be null here. Don't check it, just initialize
546 * jinode.
547 */
525 jbd2_journal_init_jbd_inode(&ei->jinode, &ei->vfs_inode); 548 jbd2_journal_init_jbd_inode(&ei->jinode, &ei->vfs_inode);
526 ei->i_reserved_data_blocks = 0; 549 ei->i_reserved_data_blocks = 0;
527 ei->i_reserved_meta_blocks = 0; 550 ei->i_reserved_meta_blocks = 0;
@@ -588,7 +611,8 @@ static void ext4_clear_inode(struct inode *inode)
588 } 611 }
589#endif 612#endif
590 ext4_discard_preallocations(inode); 613 ext4_discard_preallocations(inode);
591 jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, 614 if (EXT4_JOURNAL(inode))
615 jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal,
592 &EXT4_I(inode)->jinode); 616 &EXT4_I(inode)->jinode);
593} 617}
594 618
@@ -1406,20 +1430,15 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
1406 printk(KERN_WARNING 1430 printk(KERN_WARNING
1407 "EXT4-fs warning: checktime reached, " 1431 "EXT4-fs warning: checktime reached, "
1408 "running e2fsck is recommended\n"); 1432 "running e2fsck is recommended\n");
1409#if 0 1433 if (!sbi->s_journal)
1410 /* @@@ We _will_ want to clear the valid bit if we find 1434 es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
1411 * inconsistencies, to force a fsck at reboot. But for
1412 * a plain journaled filesystem we can keep it set as
1413 * valid forever! :)
1414 */
1415 es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
1416#endif
1417 if (!(__s16) le16_to_cpu(es->s_max_mnt_count)) 1435 if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
1418 es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT); 1436 es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT);
1419 le16_add_cpu(&es->s_mnt_count, 1); 1437 le16_add_cpu(&es->s_mnt_count, 1);
1420 es->s_mtime = cpu_to_le32(get_seconds()); 1438 es->s_mtime = cpu_to_le32(get_seconds());
1421 ext4_update_dynamic_rev(sb); 1439 ext4_update_dynamic_rev(sb);
1422 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 1440 if (sbi->s_journal)
1441 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
1423 1442
1424 ext4_commit_super(sb, es, 1); 1443 ext4_commit_super(sb, es, 1);
1425 if (test_opt(sb, DEBUG)) 1444 if (test_opt(sb, DEBUG))
@@ -1431,9 +1450,13 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
1431 EXT4_INODES_PER_GROUP(sb), 1450 EXT4_INODES_PER_GROUP(sb),
1432 sbi->s_mount_opt); 1451 sbi->s_mount_opt);
1433 1452
1434 printk(KERN_INFO "EXT4 FS on %s, %s journal on %s\n", 1453 if (EXT4_SB(sb)->s_journal) {
1435 sb->s_id, EXT4_SB(sb)->s_journal->j_inode ? "internal" : 1454 printk(KERN_INFO "EXT4 FS on %s, %s journal on %s\n",
1436 "external", EXT4_SB(sb)->s_journal->j_devname); 1455 sb->s_id, EXT4_SB(sb)->s_journal->j_inode ? "internal" :
1456 "external", EXT4_SB(sb)->s_journal->j_devname);
1457 } else {
1458 printk(KERN_INFO "EXT4 FS on %s, no journal\n", sb->s_id);
1459 }
1437 return res; 1460 return res;
1438} 1461}
1439 1462
@@ -1867,6 +1890,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
1867 unsigned long def_mount_opts; 1890 unsigned long def_mount_opts;
1868 struct inode *root; 1891 struct inode *root;
1869 char *cp; 1892 char *cp;
1893 const char *descr;
1870 int ret = -EINVAL; 1894 int ret = -EINVAL;
1871 int blocksize; 1895 int blocksize;
1872 int db_count; 1896 int db_count;
@@ -2278,21 +2302,23 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2278 EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; 2302 EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
2279 es->s_state |= cpu_to_le16(EXT4_ERROR_FS); 2303 es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
2280 ext4_commit_super(sb, es, 1); 2304 ext4_commit_super(sb, es, 1);
2281 printk(KERN_CRIT
2282 "EXT4-fs (device %s): mount failed\n",
2283 sb->s_id);
2284 goto failed_mount4; 2305 goto failed_mount4;
2285 } 2306 }
2286 } 2307 }
2287 } else if (journal_inum) { 2308 } else if (journal_inum) {
2288 if (ext4_create_journal(sb, es, journal_inum)) 2309 if (ext4_create_journal(sb, es, journal_inum))
2289 goto failed_mount3; 2310 goto failed_mount3;
2311 } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
2312 EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
2313 printk(KERN_ERR "EXT4-fs: required journal recovery "
2314 "suppressed and not mounted read-only\n");
2315 goto failed_mount4;
2290 } else { 2316 } else {
2291 if (!silent) 2317 clear_opt(sbi->s_mount_opt, DATA_FLAGS);
2292 printk(KERN_ERR 2318 set_opt(sbi->s_mount_opt, WRITEBACK_DATA);
2293 "ext4: No journal on filesystem on %s\n", 2319 sbi->s_journal = NULL;
2294 sb->s_id); 2320 needs_recovery = 0;
2295 goto failed_mount3; 2321 goto no_journal;
2296 } 2322 }
2297 2323
2298 if (ext4_blocks_count(es) > 0xffffffffULL && 2324 if (ext4_blocks_count(es) > 0xffffffffULL &&
@@ -2344,6 +2370,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2344 break; 2370 break;
2345 } 2371 }
2346 2372
2373no_journal:
2374
2347 if (test_opt(sb, NOBH)) { 2375 if (test_opt(sb, NOBH)) {
2348 if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { 2376 if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) {
2349 printk(KERN_WARNING "EXT4-fs: Ignoring nobh option - " 2377 printk(KERN_WARNING "EXT4-fs: Ignoring nobh option - "
@@ -2428,13 +2456,22 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2428 EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; 2456 EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
2429 ext4_orphan_cleanup(sb, es); 2457 ext4_orphan_cleanup(sb, es);
2430 EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; 2458 EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
2431 if (needs_recovery) 2459 if (needs_recovery) {
2432 printk(KERN_INFO "EXT4-fs: recovery complete.\n"); 2460 printk(KERN_INFO "EXT4-fs: recovery complete.\n");
2433 ext4_mark_recovery_complete(sb, es); 2461 ext4_mark_recovery_complete(sb, es);
2434 printk(KERN_INFO "EXT4-fs: mounted filesystem with %s data mode.\n", 2462 }
2435 test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ? "journal": 2463 if (EXT4_SB(sb)->s_journal) {
2436 test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": 2464 if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
2437 "writeback"); 2465 descr = " journalled data mode";
2466 else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
2467 descr = " ordered data mode";
2468 else
2469 descr = " writeback data mode";
2470 } else
2471 descr = "out journal";
2472
2473 printk(KERN_INFO "EXT4-fs: mounted filesystem %s with%s\n",
2474 sb->s_id, descr);
2438 2475
2439 lock_kernel(); 2476 lock_kernel();
2440 return 0; 2477 return 0;
@@ -2446,8 +2483,11 @@ cantfind_ext4:
2446 goto failed_mount; 2483 goto failed_mount;
2447 2484
2448failed_mount4: 2485failed_mount4:
2449 jbd2_journal_destroy(sbi->s_journal); 2486 printk(KERN_ERR "EXT4-fs (device %s): mount failed\n", sb->s_id);
2450 sbi->s_journal = NULL; 2487 if (sbi->s_journal) {
2488 jbd2_journal_destroy(sbi->s_journal);
2489 sbi->s_journal = NULL;
2490 }
2451failed_mount3: 2491failed_mount3:
2452 percpu_counter_destroy(&sbi->s_freeblocks_counter); 2492 percpu_counter_destroy(&sbi->s_freeblocks_counter);
2453 percpu_counter_destroy(&sbi->s_freeinodes_counter); 2493 percpu_counter_destroy(&sbi->s_freeinodes_counter);
@@ -2508,6 +2548,8 @@ static journal_t *ext4_get_journal(struct super_block *sb,
2508 struct inode *journal_inode; 2548 struct inode *journal_inode;
2509 journal_t *journal; 2549 journal_t *journal;
2510 2550
2551 BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
2552
2511 /* First, test for the existence of a valid inode on disk. Bad 2553 /* First, test for the existence of a valid inode on disk. Bad
2512 * things happen if we iget() an unused inode, as the subsequent 2554 * things happen if we iget() an unused inode, as the subsequent
2513 * iput() will try to delete it. */ 2555 * iput() will try to delete it. */
@@ -2556,6 +2598,8 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
2556 struct ext4_super_block *es; 2598 struct ext4_super_block *es;
2557 struct block_device *bdev; 2599 struct block_device *bdev;
2558 2600
2601 BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
2602
2559 bdev = ext4_blkdev_get(j_dev); 2603 bdev = ext4_blkdev_get(j_dev);
2560 if (bdev == NULL) 2604 if (bdev == NULL)
2561 return NULL; 2605 return NULL;
@@ -2643,6 +2687,8 @@ static int ext4_load_journal(struct super_block *sb,
2643 int err = 0; 2687 int err = 0;
2644 int really_read_only; 2688 int really_read_only;
2645 2689
2690 BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
2691
2646 if (journal_devnum && 2692 if (journal_devnum &&
2647 journal_devnum != le32_to_cpu(es->s_journal_dev)) { 2693 journal_devnum != le32_to_cpu(es->s_journal_dev)) {
2648 printk(KERN_INFO "EXT4-fs: external journal device major/minor " 2694 printk(KERN_INFO "EXT4-fs: external journal device major/minor "
@@ -2817,6 +2863,10 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
2817{ 2863{
2818 journal_t *journal = EXT4_SB(sb)->s_journal; 2864 journal_t *journal = EXT4_SB(sb)->s_journal;
2819 2865
2866 if (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
2867 BUG_ON(journal != NULL);
2868 return;
2869 }
2820 jbd2_journal_lock_updates(journal); 2870 jbd2_journal_lock_updates(journal);
2821 if (jbd2_journal_flush(journal) < 0) 2871 if (jbd2_journal_flush(journal) < 0)
2822 goto out; 2872 goto out;
@@ -2846,6 +2896,8 @@ static void ext4_clear_journal_err(struct super_block *sb,
2846 int j_errno; 2896 int j_errno;
2847 const char *errstr; 2897 const char *errstr;
2848 2898
2899 BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL));
2900
2849 journal = EXT4_SB(sb)->s_journal; 2901 journal = EXT4_SB(sb)->s_journal;
2850 2902
2851 /* 2903 /*
@@ -2878,14 +2930,17 @@ static void ext4_clear_journal_err(struct super_block *sb,
2878int ext4_force_commit(struct super_block *sb) 2930int ext4_force_commit(struct super_block *sb)
2879{ 2931{
2880 journal_t *journal; 2932 journal_t *journal;
2881 int ret; 2933 int ret = 0;
2882 2934
2883 if (sb->s_flags & MS_RDONLY) 2935 if (sb->s_flags & MS_RDONLY)
2884 return 0; 2936 return 0;
2885 2937
2886 journal = EXT4_SB(sb)->s_journal; 2938 journal = EXT4_SB(sb)->s_journal;
2887 sb->s_dirt = 0; 2939 if (journal) {
2888 ret = ext4_journal_force_commit(journal); 2940 sb->s_dirt = 0;
2941 ret = ext4_journal_force_commit(journal);
2942 }
2943
2889 return ret; 2944 return ret;
2890} 2945}
2891 2946
@@ -2897,9 +2952,13 @@ int ext4_force_commit(struct super_block *sb)
2897 */ 2952 */
2898static void ext4_write_super(struct super_block *sb) 2953static void ext4_write_super(struct super_block *sb)
2899{ 2954{
2900 if (mutex_trylock(&sb->s_lock) != 0) 2955 if (EXT4_SB(sb)->s_journal) {
2901 BUG(); 2956 if (mutex_trylock(&sb->s_lock) != 0)
2902 sb->s_dirt = 0; 2957 BUG();
2958 sb->s_dirt = 0;
2959 } else {
2960 ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
2961 }
2903} 2962}
2904 2963
2905static int ext4_sync_fs(struct super_block *sb, int wait) 2964static int ext4_sync_fs(struct super_block *sb, int wait)
@@ -2908,10 +2967,14 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
2908 2967
2909 trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); 2968 trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait);
2910 sb->s_dirt = 0; 2969 sb->s_dirt = 0;
2911 if (wait) 2970 if (EXT4_SB(sb)->s_journal) {
2912 ret = ext4_force_commit(sb); 2971 if (wait)
2913 else 2972 ret = ext4_force_commit(sb);
2914 jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL); 2973 else
2974 jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL);
2975 } else {
2976 ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait);
2977 }
2915 return ret; 2978 return ret;
2916} 2979}
2917 2980
@@ -2926,15 +2989,17 @@ static void ext4_write_super_lockfs(struct super_block *sb)
2926 if (!(sb->s_flags & MS_RDONLY)) { 2989 if (!(sb->s_flags & MS_RDONLY)) {
2927 journal_t *journal = EXT4_SB(sb)->s_journal; 2990 journal_t *journal = EXT4_SB(sb)->s_journal;
2928 2991
2929 /* Now we set up the journal barrier. */ 2992 if (journal) {
2930 jbd2_journal_lock_updates(journal); 2993 /* Now we set up the journal barrier. */
2994 jbd2_journal_lock_updates(journal);
2931 2995
2932 /* 2996 /*
2933 * We don't want to clear needs_recovery flag when we failed 2997 * We don't want to clear needs_recovery flag when we
2934 * to flush the journal. 2998 * failed to flush the journal.
2935 */ 2999 */
2936 if (jbd2_journal_flush(journal) < 0) 3000 if (jbd2_journal_flush(journal) < 0)
2937 return; 3001 return;
3002 }
2938 3003
2939 /* Journal blocked and flushed, clear needs_recovery flag. */ 3004 /* Journal blocked and flushed, clear needs_recovery flag. */
2940 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 3005 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
@@ -2948,7 +3013,7 @@ static void ext4_write_super_lockfs(struct super_block *sb)
2948 */ 3013 */
2949static void ext4_unlockfs(struct super_block *sb) 3014static void ext4_unlockfs(struct super_block *sb)
2950{ 3015{
2951 if (!(sb->s_flags & MS_RDONLY)) { 3016 if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) {
2952 lock_super(sb); 3017 lock_super(sb);
2953 /* Reser the needs_recovery flag before the fs is unlocked. */ 3018 /* Reser the needs_recovery flag before the fs is unlocked. */
2954 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 3019 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
@@ -2999,7 +3064,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
2999 3064
3000 es = sbi->s_es; 3065 es = sbi->s_es;
3001 3066
3002 ext4_init_journal_params(sb, sbi->s_journal); 3067 if (sbi->s_journal)
3068 ext4_init_journal_params(sb, sbi->s_journal);
3003 3069
3004 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || 3070 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
3005 n_blocks_count > ext4_blocks_count(es)) { 3071 n_blocks_count > ext4_blocks_count(es)) {
@@ -3028,9 +3094,11 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3028 * We have to unlock super so that we can wait for 3094 * We have to unlock super so that we can wait for
3029 * transactions. 3095 * transactions.
3030 */ 3096 */
3031 unlock_super(sb); 3097 if (sbi->s_journal) {
3032 ext4_mark_recovery_complete(sb, es); 3098 unlock_super(sb);
3033 lock_super(sb); 3099 ext4_mark_recovery_complete(sb, es);
3100 lock_super(sb);
3101 }
3034 } else { 3102 } else {
3035 __le32 ret; 3103 __le32 ret;
3036 if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, 3104 if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb,
@@ -3084,7 +3152,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3084 * been changed by e2fsck since we originally mounted 3152 * been changed by e2fsck since we originally mounted
3085 * the partition.) 3153 * the partition.)
3086 */ 3154 */
3087 ext4_clear_journal_err(sb, es); 3155 if (sbi->s_journal)
3156 ext4_clear_journal_err(sb, es);
3088 sbi->s_mount_state = le16_to_cpu(es->s_state); 3157 sbi->s_mount_state = le16_to_cpu(es->s_state);
3089 if ((err = ext4_group_extend(sb, es, n_blocks_count))) 3158 if ((err = ext4_group_extend(sb, es, n_blocks_count)))
3090 goto restore_opts; 3159 goto restore_opts;
@@ -3092,6 +3161,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3092 sb->s_flags &= ~MS_RDONLY; 3161 sb->s_flags &= ~MS_RDONLY;
3093 } 3162 }
3094 } 3163 }
3164 if (sbi->s_journal == NULL)
3165 ext4_commit_super(sb, es, 1);
3166
3095#ifdef CONFIG_QUOTA 3167#ifdef CONFIG_QUOTA
3096 /* Release old quota file names */ 3168 /* Release old quota file names */
3097 for (i = 0; i < MAXQUOTAS; i++) 3169 for (i = 0; i < MAXQUOTAS; i++)
@@ -3368,7 +3440,8 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
3368 * When we journal data on quota file, we have to flush journal to see 3440 * When we journal data on quota file, we have to flush journal to see
3369 * all updates to the file when we bypass pagecache... 3441 * all updates to the file when we bypass pagecache...
3370 */ 3442 */
3371 if (ext4_should_journal_data(path.dentry->d_inode)) { 3443 if (EXT4_SB(sb)->s_journal &&
3444 ext4_should_journal_data(path.dentry->d_inode)) {
3372 /* 3445 /*
3373 * We don't need to lock updates but journal_flush() could 3446 * We don't need to lock updates but journal_flush() could
3374 * otherwise be livelocked... 3447 * otherwise be livelocked...
@@ -3442,7 +3515,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
3442 struct buffer_head *bh; 3515 struct buffer_head *bh;
3443 handle_t *handle = journal_current_handle(); 3516 handle_t *handle = journal_current_handle();
3444 3517
3445 if (!handle) { 3518 if (EXT4_SB(sb)->s_journal && !handle) {
3446 printk(KERN_WARNING "EXT4-fs: Quota write (off=%llu, len=%llu)" 3519 printk(KERN_WARNING "EXT4-fs: Quota write (off=%llu, len=%llu)"
3447 " cancelled because transaction is not started.\n", 3520 " cancelled because transaction is not started.\n",
3448 (unsigned long long)off, (unsigned long long)len); 3521 (unsigned long long)off, (unsigned long long)len);
@@ -3467,7 +3540,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
3467 flush_dcache_page(bh->b_page); 3540 flush_dcache_page(bh->b_page);
3468 unlock_buffer(bh); 3541 unlock_buffer(bh);
3469 if (journal_quota) 3542 if (journal_quota)
3470 err = ext4_journal_dirty_metadata(handle, bh); 3543 err = ext4_handle_dirty_metadata(handle, NULL, bh);
3471 else { 3544 else {
3472 /* Always do at least ordered writes for quotas */ 3545 /* Always do at least ordered writes for quotas */
3473 err = ext4_jbd2_file_inode(handle, inode); 3546 err = ext4_jbd2_file_inode(handle, inode);
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 9b4a368c5728..157ce6589c54 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -457,7 +457,7 @@ static void ext4_xattr_update_super_block(handle_t *handle,
457 if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) { 457 if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) {
458 EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR); 458 EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR);
459 sb->s_dirt = 1; 459 sb->s_dirt = 1;
460 ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); 460 ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
461 } 461 }
462} 462}
463 463
@@ -487,9 +487,9 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
487 ext4_forget(handle, 1, inode, bh, bh->b_blocknr); 487 ext4_forget(handle, 1, inode, bh, bh->b_blocknr);
488 } else { 488 } else {
489 le32_add_cpu(&BHDR(bh)->h_refcount, -1); 489 le32_add_cpu(&BHDR(bh)->h_refcount, -1);
490 error = ext4_journal_dirty_metadata(handle, bh); 490 error = ext4_handle_dirty_metadata(handle, inode, bh);
491 if (IS_SYNC(inode)) 491 if (IS_SYNC(inode))
492 handle->h_sync = 1; 492 ext4_handle_sync(handle);
493 DQUOT_FREE_BLOCK(inode, 1); 493 DQUOT_FREE_BLOCK(inode, 1);
494 ea_bdebug(bh, "refcount now=%d; releasing", 494 ea_bdebug(bh, "refcount now=%d; releasing",
495 le32_to_cpu(BHDR(bh)->h_refcount)); 495 le32_to_cpu(BHDR(bh)->h_refcount));
@@ -724,8 +724,9 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
724 if (error == -EIO) 724 if (error == -EIO)
725 goto bad_block; 725 goto bad_block;
726 if (!error) 726 if (!error)
727 error = ext4_journal_dirty_metadata(handle, 727 error = ext4_handle_dirty_metadata(handle,
728 bs->bh); 728 inode,
729 bs->bh);
729 if (error) 730 if (error)
730 goto cleanup; 731 goto cleanup;
731 goto inserted; 732 goto inserted;
@@ -794,8 +795,9 @@ inserted:
794 ea_bdebug(new_bh, "reusing; refcount now=%d", 795 ea_bdebug(new_bh, "reusing; refcount now=%d",
795 le32_to_cpu(BHDR(new_bh)->h_refcount)); 796 le32_to_cpu(BHDR(new_bh)->h_refcount));
796 unlock_buffer(new_bh); 797 unlock_buffer(new_bh);
797 error = ext4_journal_dirty_metadata(handle, 798 error = ext4_handle_dirty_metadata(handle,
798 new_bh); 799 inode,
800 new_bh);
799 if (error) 801 if (error)
800 goto cleanup_dquot; 802 goto cleanup_dquot;
801 } 803 }
@@ -833,7 +835,8 @@ getblk_failed:
833 set_buffer_uptodate(new_bh); 835 set_buffer_uptodate(new_bh);
834 unlock_buffer(new_bh); 836 unlock_buffer(new_bh);
835 ext4_xattr_cache_insert(new_bh); 837 ext4_xattr_cache_insert(new_bh);
836 error = ext4_journal_dirty_metadata(handle, new_bh); 838 error = ext4_handle_dirty_metadata(handle,
839 inode, new_bh);
837 if (error) 840 if (error)
838 goto cleanup; 841 goto cleanup;
839 } 842 }
@@ -1040,7 +1043,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
1040 */ 1043 */
1041 is.iloc.bh = NULL; 1044 is.iloc.bh = NULL;
1042 if (IS_SYNC(inode)) 1045 if (IS_SYNC(inode))
1043 handle->h_sync = 1; 1046 ext4_handle_sync(handle);
1044 } 1047 }
1045 1048
1046cleanup: 1049cleanup: