diff options
-rw-r--r-- | fs/ext4/balloc.c | 4 | ||||
-rw-r--r-- | fs/ext4/ext4_jbd2.c | 83 | ||||
-rw-r--r-- | fs/ext4/ext4_jbd2.h | 83 | ||||
-rw-r--r-- | fs/ext4/extents.c | 12 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 25 | ||||
-rw-r--r-- | fs/ext4/inode.c | 130 | ||||
-rw-r--r-- | fs/ext4/ioctl.c | 2 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 17 | ||||
-rw-r--r-- | fs/ext4/migrate.c | 5 | ||||
-rw-r--r-- | fs/ext4/namei.c | 56 | ||||
-rw-r--r-- | fs/ext4/resize.c | 31 | ||||
-rw-r--r-- | fs/ext4/super.c | 207 | ||||
-rw-r--r-- | fs/ext4/xattr.c | 21 |
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 @@ | |||
7 | int __ext4_journal_get_undo_access(const char *where, handle_t *handle, | 7 | int __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 | ||
16 | int __ext4_journal_get_write_access(const char *where, handle_t *handle, | 21 | int __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 | ||
25 | int __ext4_journal_forget(const char *where, handle_t *handle, | 35 | int __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 | ||
34 | int __ext4_journal_revoke(const char *where, handle_t *handle, | 49 | int __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 | ||
43 | int __ext4_journal_get_create_access(const char *where, | 63 | int __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 | ||
52 | int __ext4_journal_dirty_metadata(const char *where, | 77 | int __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 | ||
125 | static inline void ext4_journal_release_buffer(handle_t *handle, | ||
126 | struct buffer_head *bh) | ||
127 | { | ||
128 | jbd2_journal_release_buffer(handle, bh); | ||
129 | } | ||
130 | |||
131 | void ext4_journal_abort_handle(const char *caller, const char *err_fn, | 125 | void 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, | |||
146 | int __ext4_journal_get_create_access(const char *where, | 140 | int __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 | ||
149 | int __ext4_journal_dirty_metadata(const char *where, | 143 | int __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 | ||
165 | handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks); | 159 | handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks); |
166 | int __ext4_journal_stop(const char *where, handle_t *handle); | 160 | int __ext4_journal_stop(const char *where, handle_t *handle); |
167 | 161 | ||
162 | #define EXT4_NOJOURNAL_HANDLE ((handle_t *) 0x1) | ||
163 | |||
164 | static inline int ext4_handle_valid(handle_t *handle) | ||
165 | { | ||
166 | if (handle == EXT4_NOJOURNAL_HANDLE) | ||
167 | return 0; | ||
168 | return 1; | ||
169 | } | ||
170 | |||
171 | static inline void ext4_handle_sync(handle_t *handle) | ||
172 | { | ||
173 | if (ext4_handle_valid(handle)) | ||
174 | handle->h_sync = 1; | ||
175 | } | ||
176 | |||
177 | static 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 | |||
184 | static 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 | |||
191 | static 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 | |||
198 | static 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 | |||
168 | static inline handle_t *ext4_journal_start(struct inode *inode, int nblocks) | 205 | static 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 | ||
181 | static inline int ext4_journal_extend(handle_t *handle, int nblocks) | 218 | static 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 | ||
186 | static inline int ext4_journal_restart(handle_t *handle, int nblocks) | 225 | static 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 | ||
191 | static inline int ext4_journal_blocks_per_page(struct inode *inode) | 232 | static 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 | ||
196 | static inline int ext4_journal_force_commit(journal_t *journal) | 239 | static 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 | ||
201 | static inline int ext4_jbd2_file_inode(handle_t *handle, struct inode *inode) | 246 | static 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 | ||
209 | static inline int ext4_should_journal_data(struct inode *inode) | 256 | static 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 | ||
220 | static inline int ext4_should_order_data(struct inode *inode) | 269 | static 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 | ||
231 | static inline int ext4_should_writeback_data(struct inode *inode) | 282 | static 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 | ||
2952 | out_stop: | 2954 | out_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 | */ |
76 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, | 78 | int 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 | */ |
171 | static int try_to_extend_transaction(handle_t *handle, struct inode *inode) | 176 | static 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 | */ |
185 | static int ext4_journal_test_restart(handle_t *handle, struct inode *inode) | 192 | static 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 | ||
3039 | static int ext4_releasepage(struct page *page, gfp_t wait) | 3053 | static 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); |
3862 | out_stop: | 3880 | out_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 | ||
4470 | int __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 | |||
4754 | ext4_reserve_inode_write(handle_t *handle, struct inode *inode, | 4790 | ext4_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 | ||
2909 | out_err: | 2910 | out_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); |
303 | exit_bh: | 303 | exit_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 | ||
944 | exit_journal: | 945 | exit_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 | ||
2373 | no_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 | ||
2448 | failed_mount4: | 2485 | failed_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 | } | ||
2451 | failed_mount3: | 2491 | failed_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, | |||
2878 | int ext4_force_commit(struct super_block *sb) | 2930 | int 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 | */ |
2898 | static void ext4_write_super(struct super_block *sb) | 2953 | static 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 | ||
2905 | static int ext4_sync_fs(struct super_block *sb, int wait) | 2964 | static 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 | */ |
2949 | static void ext4_unlockfs(struct super_block *sb) | 3014 | static 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 | ||
1046 | cleanup: | 1049 | cleanup: |