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