1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Interface between ext4 and JBD
4 */
5
6#include "ext4_jbd2.h"
7
8#include <trace/events/ext4.h>
9
10int ext4_inode_journal_mode(struct inode *inode)
11{
12 if (EXT4_JOURNAL(inode) == NULL)
13 return EXT4_INODE_WRITEBACK_DATA_MODE; /* writeback */
14 /* We do not support data journalling with delayed allocation */
15 if (!S_ISREG(inode->i_mode) ||
16 ext4_test_inode_flag(inode, bit: EXT4_INODE_EA_INODE) ||
17 test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
18 (ext4_test_inode_flag(inode, bit: EXT4_INODE_JOURNAL_DATA) &&
19 !test_opt(inode->i_sb, DELALLOC) &&
20 !mapping_large_folio_support(mapping: inode->i_mapping))) {
21 /* We do not support data journalling for encrypted data */
22 if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode))
23 return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */
24 return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */
25 }
26 if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
27 return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */
28 if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
29 return EXT4_INODE_WRITEBACK_DATA_MODE; /* writeback */
30 BUG();
31}
32
33/* Just increment the non-pointer handle value */
34static handle_t *ext4_get_nojournal(void)
35{
36 handle_t *handle = current->journal_info;
37 unsigned long ref_cnt = (unsigned long)handle;
38
39 BUG_ON(ref_cnt >= EXT4_NOJOURNAL_MAX_REF_COUNT);
40
41 ref_cnt++;
42 handle = (handle_t *)ref_cnt;
43
44 current->journal_info = handle;
45 return handle;
46}
47
48
49/* Decrement the non-pointer handle value */
50static void ext4_put_nojournal(handle_t *handle)
51{
52 unsigned long ref_cnt = (unsigned long)handle;
53
54 BUG_ON(ref_cnt == 0);
55
56 ref_cnt--;
57 handle = (handle_t *)ref_cnt;
58
59 current->journal_info = handle;
60}
61
62/*
63 * Wrappers for jbd2_journal_start/end.
64 */
65static int ext4_journal_check_start(struct super_block *sb)
66{
67 int ret;
68 journal_t *journal;
69
70 might_sleep();
71
72 ret = ext4_emergency_state(sb);
73 if (unlikely(ret))
74 return ret;
75
76 if (WARN_ON_ONCE(sb_rdonly(sb)))
77 return -EROFS;
78
79 WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE);
80 journal = EXT4_SB(sb)->s_journal;
81 /*
82 * Special case here: if the journal has aborted behind our
83 * backs (eg. EIO in the commit thread), then we still need to
84 * take the FS itself readonly cleanly.
85 */
86 if (journal && is_journal_aborted(journal)) {
87 ext4_abort(sb, -journal->j_errno, "Detected aborted journal");
88 return -EROFS;
89 }
90 return 0;
91}
92
93handle_t *__ext4_journal_start_sb(struct inode *inode,
94 struct super_block *sb, unsigned int line,
95 int type, int blocks, int rsv_blocks,
96 int revoke_creds)
97{
98 journal_t *journal;
99 int err;
100 if (inode)
101 trace_ext4_journal_start_inode(inode, blocks, rsv_blocks,
102 revoke_creds, type,
103 _RET_IP_);
104 else
105 trace_ext4_journal_start_sb(sb, blocks, rsv_blocks,
106 revoke_creds, type,
107 _RET_IP_);
108 err = ext4_journal_check_start(sb);
109 if (err < 0)
110 return ERR_PTR(error: err);
111
112 journal = EXT4_SB(sb)->s_journal;
113 if (!journal || (EXT4_SB(sb)->s_mount_state & EXT4_FC_REPLAY))
114 return ext4_get_nojournal();
115 return jbd2__journal_start(journal, blocks, rsv_blocks, revoke_records: revoke_creds,
116 GFP_NOFS, type, line_no: line);
117}
118
119int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle)
120{
121 struct super_block *sb;
122 int err;
123 int rc;
124
125 if (!ext4_handle_valid(handle)) {
126 ext4_put_nojournal(handle);
127 return 0;
128 }
129
130 err = handle->h_err;
131 if (!handle->h_transaction) {
132 rc = jbd2_journal_stop(handle);
133 return err ? err : rc;
134 }
135
136 sb = handle->h_transaction->t_journal->j_private;
137 rc = jbd2_journal_stop(handle);
138
139 if (!err)
140 err = rc;
141 if (err)
142 __ext4_std_error(sb, where, line, err);
143 return err;
144}
145
146handle_t *__ext4_journal_start_reserved(handle_t *handle, unsigned int line,
147 int type)
148{
149 struct super_block *sb;
150 int err;
151
152 if (!ext4_handle_valid(handle))
153 return ext4_get_nojournal();
154
155 sb = handle->h_journal->j_private;
156 trace_ext4_journal_start_reserved(sb,
157 blocks: jbd2_handle_buffer_credits(handle), _RET_IP_);
158 err = ext4_journal_check_start(sb);
159 if (err < 0) {
160 jbd2_journal_free_reserved(handle);
161 return ERR_PTR(error: err);
162 }
163
164 err = jbd2_journal_start_reserved(handle, type, line_no: line);
165 if (err < 0)
166 return ERR_PTR(error: err);
167 return handle;
168}
169
170int __ext4_journal_ensure_credits(handle_t *handle, int check_cred,
171 int extend_cred, int revoke_cred)
172{
173 if (!ext4_handle_valid(handle))
174 return 0;
175 if (is_handle_aborted(handle))
176 return -EROFS;
177 if (jbd2_handle_buffer_credits(handle) >= check_cred &&
178 handle->h_revoke_credits >= revoke_cred)
179 return 0;
180 extend_cred = max(0, extend_cred - jbd2_handle_buffer_credits(handle));
181 revoke_cred = max(0, revoke_cred - handle->h_revoke_credits);
182 return ext4_journal_extend(handle, nblocks: extend_cred, revoke: revoke_cred);
183}
184
185static void ext4_journal_abort_handle(const char *caller, unsigned int line,
186 const char *err_fn,
187 struct buffer_head *bh,
188 handle_t *handle, int err)
189{
190 char nbuf[16];
191 const char *errstr = ext4_decode_error(NULL, errno: err, nbuf);
192
193 BUG_ON(!ext4_handle_valid(handle));
194
195 if (bh)
196 BUFFER_TRACE(bh, "abort");
197
198 if (!handle->h_err)
199 handle->h_err = err;
200
201 if (is_handle_aborted(handle))
202 return;
203
204 printk(KERN_ERR "EXT4-fs: %s:%d: aborting transaction: %s in %s\n",
205 caller, line, errstr, err_fn);
206
207 jbd2_journal_abort_handle(handle);
208}
209
210static void ext4_check_bdev_write_error(struct super_block *sb)
211{
212 struct address_space *mapping = sb->s_bdev->bd_mapping;
213 struct ext4_sb_info *sbi = EXT4_SB(sb);
214 int err;
215
216 /*
217 * If the block device has write error flag, it may have failed to
218 * async write out metadata buffers in the background. In this case,
219 * we could read old data from disk and write it out again, which
220 * may lead to on-disk filesystem inconsistency.
221 */
222 if (errseq_check(eseq: &mapping->wb_err, READ_ONCE(sbi->s_bdev_wb_err))) {
223 spin_lock(lock: &sbi->s_bdev_wb_lock);
224 err = errseq_check_and_advance(eseq: &mapping->wb_err, since: &sbi->s_bdev_wb_err);
225 spin_unlock(lock: &sbi->s_bdev_wb_lock);
226 if (err)
227 ext4_error_err(sb, -err,
228 "Error while async write back metadata");
229 }
230}
231
232int __ext4_journal_get_write_access(const char *where, unsigned int line,
233 handle_t *handle, struct super_block *sb,
234 struct buffer_head *bh,
235 enum ext4_journal_trigger_type trigger_type)
236{
237 int err;
238
239 might_sleep();
240
241 if (ext4_handle_valid(handle)) {
242 err = jbd2_journal_get_write_access(handle, bh);
243 if (err) {
244 ext4_journal_abort_handle(caller: where, line, err_fn: __func__, bh,
245 handle, err);
246 return err;
247 }
248 } else
249 ext4_check_bdev_write_error(sb);
250 if (trigger_type == EXT4_JTR_NONE ||
251 !ext4_has_feature_metadata_csum(sb))
252 return 0;
253 BUG_ON(trigger_type >= EXT4_JOURNAL_TRIGGER_COUNT);
254 jbd2_journal_set_triggers(bh,
255 type: &EXT4_SB(sb)->s_journal_triggers[trigger_type].tr_triggers);
256 return 0;
257}
258
259/*
260 * The ext4 forget function must perform a revoke if we are freeing data
261 * which has been journaled. Metadata (eg. indirect blocks) must be
262 * revoked in all cases.
263 *
264 * "bh" may be NULL: a metadata block may have been freed from memory
265 * but there may still be a record of it in the journal, and that record
266 * still needs to be revoked.
267 */
268int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
269 int is_metadata, struct inode *inode,
270 struct buffer_head *bh, ext4_fsblk_t blocknr)
271{
272 int err;
273
274 might_sleep();
275
276 trace_ext4_forget(inode, is_metadata, block: blocknr);
277 BUFFER_TRACE(bh, "enter");
278
279 ext4_debug("forgetting bh %p: is_metadata=%d, mode %o, data mode %x\n",
280 bh, is_metadata, inode->i_mode,
281 test_opt(inode->i_sb, DATA_FLAGS));
282
283 /* In the no journal case, we can just do a bforget and return */
284 if (!ext4_handle_valid(handle)) {
285 bforget(bh);
286 return 0;
287 }
288
289 /* Never use the revoke function if we are doing full data
290 * journaling: there is no need to, and a V1 superblock won't
291 * support it. Otherwise, only skip the revoke on un-journaled
292 * data blocks. */
293
294 if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
295 (!is_metadata && !ext4_should_journal_data(inode))) {
296 if (bh) {
297 BUFFER_TRACE(bh, "call jbd2_journal_forget");
298 err = jbd2_journal_forget(handle, bh);
299 if (err)
300 ext4_journal_abort_handle(caller: where, line, err_fn: __func__,
301 bh, handle, err);
302 return err;
303 }
304 return 0;
305 }
306
307 /*
308 * data!=journal && (is_metadata || should_journal_data(inode))
309 */
310 BUFFER_TRACE(bh, "call jbd2_journal_revoke");
311 err = jbd2_journal_revoke(handle, blocknr, bh);
312 if (err) {
313 ext4_journal_abort_handle(caller: where, line, err_fn: __func__,
314 bh, handle, err);
315 __ext4_error(inode->i_sb, where, line, true, -err, 0,
316 "error %d when attempting revoke", err);
317 }
318 BUFFER_TRACE(bh, "exit");
319 return err;
320}
321
322int __ext4_journal_get_create_access(const char *where, unsigned int line,
323 handle_t *handle, struct super_block *sb,
324 struct buffer_head *bh,
325 enum ext4_journal_trigger_type trigger_type)
326{
327 int err;
328
329 if (!ext4_handle_valid(handle))
330 return 0;
331
332 err = jbd2_journal_get_create_access(handle, bh);
333 if (err) {
334 ext4_journal_abort_handle(caller: where, line, err_fn: __func__, bh, handle,
335 err);
336 return err;
337 }
338 if (trigger_type == EXT4_JTR_NONE ||
339 !ext4_has_feature_metadata_csum(sb))
340 return 0;
341 BUG_ON(trigger_type >= EXT4_JOURNAL_TRIGGER_COUNT);
342 jbd2_journal_set_triggers(bh,
343 type: &EXT4_SB(sb)->s_journal_triggers[trigger_type].tr_triggers);
344 return 0;
345}
346
347int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
348 handle_t *handle, struct inode *inode,
349 struct buffer_head *bh)
350{
351 int err = 0;
352
353 might_sleep();
354
355 set_buffer_meta(bh);
356 set_buffer_prio(bh);
357 set_buffer_uptodate(bh);
358 if (ext4_handle_valid(handle)) {
359 err = jbd2_journal_dirty_metadata(handle, bh);
360 /* Errors can only happen due to aborted journal or a nasty bug */
361 if (!is_handle_aborted(handle) && WARN_ON_ONCE(err)) {
362 ext4_journal_abort_handle(caller: where, line, err_fn: __func__, bh,
363 handle, err);
364 if (inode == NULL) {
365 pr_err("EXT4: jbd2_journal_dirty_metadata "
366 "failed: handle type %u started at "
367 "line %u, credits %u/%u, errcode %d",
368 handle->h_type,
369 handle->h_line_no,
370 handle->h_requested_credits,
371 jbd2_handle_buffer_credits(handle), err);
372 return err;
373 }
374 ext4_error_inode(inode, where, line,
375 bh->b_blocknr,
376 "journal_dirty_metadata failed: "
377 "handle type %u started at line %u, "
378 "credits %u/%u, errcode %d",
379 handle->h_type,
380 handle->h_line_no,
381 handle->h_requested_credits,
382 jbd2_handle_buffer_credits(handle),
383 err);
384 }
385 } else {
386 if (inode)
387 mark_buffer_dirty_inode(bh, inode);
388 else
389 mark_buffer_dirty(bh);
390 if (inode && inode_needs_sync(inode)) {
391 sync_dirty_buffer(bh);
392 if (buffer_req(bh) && !buffer_uptodate(bh)) {
393 ext4_error_inode_err(inode, where, line,
394 bh->b_blocknr, EIO,
395 "IO error syncing itable block");
396 err = -EIO;
397 }
398 }
399 }
400 return err;
401}
402