1 /* 2 * Interface between ext4 and JBD 3 */ 4 5 #include "ext4_jbd2.h" 6 7 #include <trace/events/ext4.h> 8 9 int __ext4_journal_get_undo_access(const char *where, handle_t *handle, 10 struct buffer_head *bh) 11 { 12 int err = 0; 13 14 if (ext4_handle_valid(handle)) { 15 err = jbd2_journal_get_undo_access(handle, bh); 16 if (err) 17 ext4_journal_abort_handle(where, __func__, bh, 18 handle, err); 19 } 20 return err; 21 } 22 23 int __ext4_journal_get_write_access(const char *where, handle_t *handle, 24 struct buffer_head *bh) 25 { 26 int err = 0; 27 28 if (ext4_handle_valid(handle)) { 29 err = jbd2_journal_get_write_access(handle, bh); 30 if (err) 31 ext4_journal_abort_handle(where, __func__, bh, 32 handle, err); 33 } 34 return err; 35 } 36 37 /* 38 * The ext4 forget function must perform a revoke if we are freeing data 39 * which has been journaled. Metadata (eg. indirect blocks) must be 40 * revoked in all cases. 41 * 42 * "bh" may be NULL: a metadata block may have been freed from memory 43 * but there may still be a record of it in the journal, and that record 44 * still needs to be revoked. 45 * 46 * If the handle isn't valid we're not journaling, but we still need to 47 * call into ext4_journal_revoke() to put the buffer head. 48 */ 49 int __ext4_forget(const char *where, handle_t *handle, int is_metadata, 50 struct inode *inode, struct buffer_head *bh, 51 ext4_fsblk_t blocknr) 52 { 53 int err; 54 55 might_sleep(); 56 57 trace_ext4_forget(inode, is_metadata, blocknr); 58 BUFFER_TRACE(bh, "enter"); 59 60 jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, " 61 "data mode %x\n", 62 bh, is_metadata, inode->i_mode, 63 test_opt(inode->i_sb, DATA_FLAGS)); 64 65 /* In the no journal case, we can just do a bforget and return */ 66 if (!ext4_handle_valid(handle)) { 67 bforget(bh); 68 return 0; 69 } 70 71 /* Never use the revoke function if we are doing full data 72 * journaling: there is no need to, and a V1 superblock won't 73 * support it. Otherwise, only skip the revoke on un-journaled 74 * data blocks. */ 75 76 if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA || 77 (!is_metadata && !ext4_should_journal_data(inode))) { 78 if (bh) { 79 BUFFER_TRACE(bh, "call jbd2_journal_forget"); 80 err = jbd2_journal_forget(handle, bh); 81 if (err) 82 ext4_journal_abort_handle(where, __func__, bh, 83 handle, err); 84 return err; 85 } 86 return 0; 87 } 88 89 /* 90 * data!=journal && (is_metadata || should_journal_data(inode)) 91 */ 92 BUFFER_TRACE(bh, "call jbd2_journal_revoke"); 93 err = jbd2_journal_revoke(handle, blocknr, bh); 94 if (err) { 95 ext4_journal_abort_handle(where, __func__, bh, handle, err); 96 ext4_abort(inode->i_sb, __func__, 97 "error %d when attempting revoke", err); 98 } 99 BUFFER_TRACE(bh, "exit"); 100 return err; 101 } 102 103 int __ext4_journal_get_create_access(const char *where, 104 handle_t *handle, struct buffer_head *bh) 105 { 106 int err = 0; 107 108 if (ext4_handle_valid(handle)) { 109 err = jbd2_journal_get_create_access(handle, bh); 110 if (err) 111 ext4_journal_abort_handle(where, __func__, bh, 112 handle, err); 113 } 114 return err; 115 } 116 117 int __ext4_handle_dirty_metadata(const char *where, handle_t *handle, 118 struct inode *inode, struct buffer_head *bh) 119 { 120 int err = 0; 121 122 if (ext4_handle_valid(handle)) { 123 err = jbd2_journal_dirty_metadata(handle, bh); 124 if (err) 125 ext4_journal_abort_handle(where, __func__, bh, 126 handle, err); 127 } else { 128 if (inode && bh) 129 mark_buffer_dirty_inode(bh, inode); 130 else 131 mark_buffer_dirty(bh); 132 if (inode && inode_needs_sync(inode)) { 133 sync_dirty_buffer(bh); 134 if (buffer_req(bh) && !buffer_uptodate(bh)) { 135 ext4_error(inode->i_sb, __func__, 136 "IO error syncing inode, " 137 "inode=%lu, block=%llu", 138 inode->i_ino, 139 (unsigned long long) bh->b_blocknr); 140 err = -EIO; 141 } 142 } 143 } 144 return err; 145 } 146