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 10 /* Just increment the non-pointer handle value */ 11 static handle_t *ext4_get_nojournal(void) 12 { 13 handle_t *handle = current->journal_info; 14 unsigned long ref_cnt = (unsigned long)handle; 15 16 BUG_ON(ref_cnt >= EXT4_NOJOURNAL_MAX_REF_COUNT); 17 18 ref_cnt++; 19 handle = (handle_t *)ref_cnt; 20 21 current->journal_info = handle; 22 return handle; 23 } 24 25 26 /* Decrement the non-pointer handle value */ 27 static void ext4_put_nojournal(handle_t *handle) 28 { 29 unsigned long ref_cnt = (unsigned long)handle; 30 31 BUG_ON(ref_cnt == 0); 32 33 ref_cnt--; 34 handle = (handle_t *)ref_cnt; 35 36 current->journal_info = handle; 37 } 38 39 /* 40 * Wrappers for jbd2_journal_start/end. 41 */ 42 static int ext4_journal_check_start(struct super_block *sb) 43 { 44 journal_t *journal; 45 46 might_sleep(); 47 48 if (unlikely(ext4_forced_shutdown(EXT4_SB(sb)))) 49 return -EIO; 50 51 if (sb_rdonly(sb)) 52 return -EROFS; 53 WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE); 54 journal = EXT4_SB(sb)->s_journal; 55 /* 56 * Special case here: if the journal has aborted behind our 57 * backs (eg. EIO in the commit thread), then we still need to 58 * take the FS itself readonly cleanly. 59 */ 60 if (journal && is_journal_aborted(journal)) { 61 ext4_abort(sb, "Detected aborted journal"); 62 return -EROFS; 63 } 64 return 0; 65 } 66 67 handle_t *__ext4_journal_start_sb(struct super_block *sb, unsigned int line, 68 int type, int blocks, int rsv_blocks) 69 { 70 journal_t *journal; 71 int err; 72 73 trace_ext4_journal_start(sb, blocks, rsv_blocks, _RET_IP_); 74 err = ext4_journal_check_start(sb); 75 if (err < 0) 76 return ERR_PTR(err); 77 78 journal = EXT4_SB(sb)->s_journal; 79 if (!journal) 80 return ext4_get_nojournal(); 81 return jbd2__journal_start(journal, blocks, rsv_blocks, GFP_NOFS, 82 type, line); 83 } 84 85 int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) 86 { 87 struct super_block *sb; 88 int err; 89 int rc; 90 91 if (!ext4_handle_valid(handle)) { 92 ext4_put_nojournal(handle); 93 return 0; 94 } 95 96 err = handle->h_err; 97 if (!handle->h_transaction) { 98 rc = jbd2_journal_stop(handle); 99 return err ? err : rc; 100 } 101 102 sb = handle->h_transaction->t_journal->j_private; 103 rc = jbd2_journal_stop(handle); 104 105 if (!err) 106 err = rc; 107 if (err) 108 __ext4_std_error(sb, where, line, err); 109 return err; 110 } 111 112 handle_t *__ext4_journal_start_reserved(handle_t *handle, unsigned int line, 113 int type) 114 { 115 struct super_block *sb; 116 int err; 117 118 if (!ext4_handle_valid(handle)) 119 return ext4_get_nojournal(); 120 121 sb = handle->h_journal->j_private; 122 trace_ext4_journal_start_reserved(sb, handle->h_buffer_credits, 123 _RET_IP_); 124 err = ext4_journal_check_start(sb); 125 if (err < 0) { 126 jbd2_journal_free_reserved(handle); 127 return ERR_PTR(err); 128 } 129 130 err = jbd2_journal_start_reserved(handle, type, line); 131 if (err < 0) 132 return ERR_PTR(err); 133 return handle; 134 } 135 136 static void ext4_journal_abort_handle(const char *caller, unsigned int line, 137 const char *err_fn, 138 struct buffer_head *bh, 139 handle_t *handle, int err) 140 { 141 char nbuf[16]; 142 const char *errstr = ext4_decode_error(NULL, err, nbuf); 143 144 BUG_ON(!ext4_handle_valid(handle)); 145 146 if (bh) 147 BUFFER_TRACE(bh, "abort"); 148 149 if (!handle->h_err) 150 handle->h_err = err; 151 152 if (is_handle_aborted(handle)) 153 return; 154 155 printk(KERN_ERR "EXT4-fs: %s:%d: aborting transaction: %s in %s\n", 156 caller, line, errstr, err_fn); 157 158 jbd2_journal_abort_handle(handle); 159 } 160 161 int __ext4_journal_get_write_access(const char *where, unsigned int line, 162 handle_t *handle, struct buffer_head *bh) 163 { 164 int err = 0; 165 166 might_sleep(); 167 168 if (ext4_handle_valid(handle)) { 169 err = jbd2_journal_get_write_access(handle, bh); 170 if (err) 171 ext4_journal_abort_handle(where, line, __func__, bh, 172 handle, err); 173 } 174 return err; 175 } 176 177 /* 178 * The ext4 forget function must perform a revoke if we are freeing data 179 * which has been journaled. Metadata (eg. indirect blocks) must be 180 * revoked in all cases. 181 * 182 * "bh" may be NULL: a metadata block may have been freed from memory 183 * but there may still be a record of it in the journal, and that record 184 * still needs to be revoked. 185 * 186 * If the handle isn't valid we're not journaling, but we still need to 187 * call into ext4_journal_revoke() to put the buffer head. 188 */ 189 int __ext4_forget(const char *where, unsigned int line, handle_t *handle, 190 int is_metadata, struct inode *inode, 191 struct buffer_head *bh, ext4_fsblk_t blocknr) 192 { 193 int err; 194 195 might_sleep(); 196 197 trace_ext4_forget(inode, is_metadata, blocknr); 198 BUFFER_TRACE(bh, "enter"); 199 200 jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, " 201 "data mode %x\n", 202 bh, is_metadata, inode->i_mode, 203 test_opt(inode->i_sb, DATA_FLAGS)); 204 205 /* In the no journal case, we can just do a bforget and return */ 206 if (!ext4_handle_valid(handle)) { 207 bforget(bh); 208 return 0; 209 } 210 211 /* Never use the revoke function if we are doing full data 212 * journaling: there is no need to, and a V1 superblock won't 213 * support it. Otherwise, only skip the revoke on un-journaled 214 * data blocks. */ 215 216 if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA || 217 (!is_metadata && !ext4_should_journal_data(inode))) { 218 if (bh) { 219 BUFFER_TRACE(bh, "call jbd2_journal_forget"); 220 err = jbd2_journal_forget(handle, bh); 221 if (err) 222 ext4_journal_abort_handle(where, line, __func__, 223 bh, handle, err); 224 return err; 225 } 226 return 0; 227 } 228 229 /* 230 * data!=journal && (is_metadata || should_journal_data(inode)) 231 */ 232 BUFFER_TRACE(bh, "call jbd2_journal_revoke"); 233 err = jbd2_journal_revoke(handle, blocknr, bh); 234 if (err) { 235 ext4_journal_abort_handle(where, line, __func__, 236 bh, handle, err); 237 __ext4_abort(inode->i_sb, where, line, 238 "error %d when attempting revoke", err); 239 } 240 BUFFER_TRACE(bh, "exit"); 241 return err; 242 } 243 244 int __ext4_journal_get_create_access(const char *where, unsigned int line, 245 handle_t *handle, struct buffer_head *bh) 246 { 247 int err = 0; 248 249 if (ext4_handle_valid(handle)) { 250 err = jbd2_journal_get_create_access(handle, bh); 251 if (err) 252 ext4_journal_abort_handle(where, line, __func__, 253 bh, handle, err); 254 } 255 return err; 256 } 257 258 int __ext4_handle_dirty_metadata(const char *where, unsigned int line, 259 handle_t *handle, struct inode *inode, 260 struct buffer_head *bh) 261 { 262 int err = 0; 263 264 might_sleep(); 265 266 set_buffer_meta(bh); 267 set_buffer_prio(bh); 268 if (ext4_handle_valid(handle)) { 269 err = jbd2_journal_dirty_metadata(handle, bh); 270 /* Errors can only happen due to aborted journal or a nasty bug */ 271 if (!is_handle_aborted(handle) && WARN_ON_ONCE(err)) { 272 ext4_journal_abort_handle(where, line, __func__, bh, 273 handle, err); 274 if (inode == NULL) { 275 pr_err("EXT4: jbd2_journal_dirty_metadata " 276 "failed: handle type %u started at " 277 "line %u, credits %u/%u, errcode %d", 278 handle->h_type, 279 handle->h_line_no, 280 handle->h_requested_credits, 281 handle->h_buffer_credits, err); 282 return err; 283 } 284 ext4_error_inode(inode, where, line, 285 bh->b_blocknr, 286 "journal_dirty_metadata failed: " 287 "handle type %u started at line %u, " 288 "credits %u/%u, errcode %d", 289 handle->h_type, 290 handle->h_line_no, 291 handle->h_requested_credits, 292 handle->h_buffer_credits, err); 293 } 294 } else { 295 if (inode) 296 mark_buffer_dirty_inode(bh, inode); 297 else 298 mark_buffer_dirty(bh); 299 if (inode && inode_needs_sync(inode)) { 300 sync_dirty_buffer(bh); 301 if (buffer_req(bh) && !buffer_uptodate(bh)) { 302 struct ext4_super_block *es; 303 304 es = EXT4_SB(inode->i_sb)->s_es; 305 es->s_last_error_block = 306 cpu_to_le64(bh->b_blocknr); 307 ext4_error_inode(inode, where, line, 308 bh->b_blocknr, 309 "IO error syncing itable block"); 310 err = -EIO; 311 } 312 } 313 } 314 return err; 315 } 316 317 int __ext4_handle_dirty_super(const char *where, unsigned int line, 318 handle_t *handle, struct super_block *sb) 319 { 320 struct buffer_head *bh = EXT4_SB(sb)->s_sbh; 321 int err = 0; 322 323 ext4_superblock_csum_set(sb); 324 if (ext4_handle_valid(handle)) { 325 err = jbd2_journal_dirty_metadata(handle, bh); 326 if (err) 327 ext4_journal_abort_handle(where, line, __func__, 328 bh, handle, err); 329 } else 330 mark_buffer_dirty(bh); 331 return err; 332 } 333