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 struct super_block *sb; 170 171 sb = handle->h_transaction->t_journal->j_private; 172 if (unlikely(ext4_forced_shutdown(EXT4_SB(sb)))) { 173 jbd2_journal_abort_handle(handle); 174 return -EIO; 175 } 176 err = jbd2_journal_get_write_access(handle, bh); 177 if (err) 178 ext4_journal_abort_handle(where, line, __func__, bh, 179 handle, err); 180 } 181 return err; 182 } 183 184 /* 185 * The ext4 forget function must perform a revoke if we are freeing data 186 * which has been journaled. Metadata (eg. indirect blocks) must be 187 * revoked in all cases. 188 * 189 * "bh" may be NULL: a metadata block may have been freed from memory 190 * but there may still be a record of it in the journal, and that record 191 * still needs to be revoked. 192 * 193 * If the handle isn't valid we're not journaling, but we still need to 194 * call into ext4_journal_revoke() to put the buffer head. 195 */ 196 int __ext4_forget(const char *where, unsigned int line, handle_t *handle, 197 int is_metadata, struct inode *inode, 198 struct buffer_head *bh, ext4_fsblk_t blocknr) 199 { 200 int err; 201 202 might_sleep(); 203 204 trace_ext4_forget(inode, is_metadata, blocknr); 205 BUFFER_TRACE(bh, "enter"); 206 207 jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, " 208 "data mode %x\n", 209 bh, is_metadata, inode->i_mode, 210 test_opt(inode->i_sb, DATA_FLAGS)); 211 212 /* In the no journal case, we can just do a bforget and return */ 213 if (!ext4_handle_valid(handle)) { 214 bforget(bh); 215 return 0; 216 } 217 218 /* Never use the revoke function if we are doing full data 219 * journaling: there is no need to, and a V1 superblock won't 220 * support it. Otherwise, only skip the revoke on un-journaled 221 * data blocks. */ 222 223 if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA || 224 (!is_metadata && !ext4_should_journal_data(inode))) { 225 if (bh) { 226 BUFFER_TRACE(bh, "call jbd2_journal_forget"); 227 err = jbd2_journal_forget(handle, bh); 228 if (err) 229 ext4_journal_abort_handle(where, line, __func__, 230 bh, handle, err); 231 return err; 232 } 233 return 0; 234 } 235 236 /* 237 * data!=journal && (is_metadata || should_journal_data(inode)) 238 */ 239 BUFFER_TRACE(bh, "call jbd2_journal_revoke"); 240 err = jbd2_journal_revoke(handle, blocknr, bh); 241 if (err) { 242 ext4_journal_abort_handle(where, line, __func__, 243 bh, handle, err); 244 __ext4_abort(inode->i_sb, where, line, 245 "error %d when attempting revoke", err); 246 } 247 BUFFER_TRACE(bh, "exit"); 248 return err; 249 } 250 251 int __ext4_journal_get_create_access(const char *where, unsigned int line, 252 handle_t *handle, struct buffer_head *bh) 253 { 254 int err = 0; 255 256 if (ext4_handle_valid(handle)) { 257 err = jbd2_journal_get_create_access(handle, bh); 258 if (err) 259 ext4_journal_abort_handle(where, line, __func__, 260 bh, handle, err); 261 } 262 return err; 263 } 264 265 int __ext4_handle_dirty_metadata(const char *where, unsigned int line, 266 handle_t *handle, struct inode *inode, 267 struct buffer_head *bh) 268 { 269 int err = 0; 270 271 might_sleep(); 272 273 set_buffer_meta(bh); 274 set_buffer_prio(bh); 275 if (ext4_handle_valid(handle)) { 276 err = jbd2_journal_dirty_metadata(handle, bh); 277 /* Errors can only happen due to aborted journal or a nasty bug */ 278 if (!is_handle_aborted(handle) && WARN_ON_ONCE(err)) { 279 ext4_journal_abort_handle(where, line, __func__, bh, 280 handle, err); 281 if (inode == NULL) { 282 pr_err("EXT4: jbd2_journal_dirty_metadata " 283 "failed: handle type %u started at " 284 "line %u, credits %u/%u, errcode %d", 285 handle->h_type, 286 handle->h_line_no, 287 handle->h_requested_credits, 288 handle->h_buffer_credits, err); 289 return err; 290 } 291 ext4_error_inode(inode, where, line, 292 bh->b_blocknr, 293 "journal_dirty_metadata failed: " 294 "handle type %u started at line %u, " 295 "credits %u/%u, errcode %d", 296 handle->h_type, 297 handle->h_line_no, 298 handle->h_requested_credits, 299 handle->h_buffer_credits, err); 300 } 301 } else { 302 if (inode) 303 mark_buffer_dirty_inode(bh, inode); 304 else 305 mark_buffer_dirty(bh); 306 if (inode && inode_needs_sync(inode)) { 307 sync_dirty_buffer(bh); 308 if (buffer_req(bh) && !buffer_uptodate(bh)) { 309 struct ext4_super_block *es; 310 311 es = EXT4_SB(inode->i_sb)->s_es; 312 es->s_last_error_block = 313 cpu_to_le64(bh->b_blocknr); 314 ext4_error_inode(inode, where, line, 315 bh->b_blocknr, 316 "IO error syncing itable block"); 317 err = -EIO; 318 } 319 } 320 } 321 return err; 322 } 323 324 int __ext4_handle_dirty_super(const char *where, unsigned int line, 325 handle_t *handle, struct super_block *sb) 326 { 327 struct buffer_head *bh = EXT4_SB(sb)->s_sbh; 328 int err = 0; 329 330 ext4_superblock_csum_set(sb); 331 if (ext4_handle_valid(handle)) { 332 err = jbd2_journal_dirty_metadata(handle, bh); 333 if (err) 334 ext4_journal_abort_handle(where, line, __func__, 335 bh, handle, err); 336 } else 337 mark_buffer_dirty(bh); 338 return err; 339 } 340