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