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, unsigned int line, 10 handle_t *handle, 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, line, __func__, bh, 18 handle, err); 19 } 20 return err; 21 } 22 23 int __ext4_journal_get_write_access(const char *where, unsigned int line, 24 handle_t *handle, 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, line, __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, unsigned int line, handle_t *handle, 50 int is_metadata, struct inode *inode, 51 struct buffer_head *bh, 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, line, __func__, 83 bh, 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, line, __func__, 96 bh, handle, err); 97 __ext4_abort(inode->i_sb, where, line, 98 "error %d when attempting revoke", err); 99 } 100 BUFFER_TRACE(bh, "exit"); 101 return err; 102 } 103 104 int __ext4_journal_get_create_access(const char *where, unsigned int line, 105 handle_t *handle, struct buffer_head *bh) 106 { 107 int err = 0; 108 109 if (ext4_handle_valid(handle)) { 110 err = jbd2_journal_get_create_access(handle, bh); 111 if (err) 112 ext4_journal_abort_handle(where, line, __func__, 113 bh, handle, err); 114 } 115 return err; 116 } 117 118 int __ext4_handle_dirty_metadata(const char *where, unsigned int line, 119 handle_t *handle, struct inode *inode, 120 struct buffer_head *bh) 121 { 122 int err = 0; 123 124 if (ext4_handle_valid(handle)) { 125 err = jbd2_journal_dirty_metadata(handle, bh); 126 if (err) 127 ext4_journal_abort_handle(where, line, __func__, 128 bh, handle, err); 129 } else { 130 if (inode) 131 mark_buffer_dirty_inode(bh, inode); 132 else 133 mark_buffer_dirty(bh); 134 if (inode && inode_needs_sync(inode)) { 135 sync_dirty_buffer(bh); 136 if (buffer_req(bh) && !buffer_uptodate(bh)) { 137 struct ext4_super_block *es; 138 139 es = EXT4_SB(inode->i_sb)->s_es; 140 es->s_last_error_block = 141 cpu_to_le64(bh->b_blocknr); 142 ext4_error_inode(inode, where, line, 143 bh->b_blocknr, 144 "IO error syncing itable block"); 145 err = -EIO; 146 } 147 } 148 } 149 return err; 150 } 151 152 int __ext4_handle_dirty_super(const char *where, unsigned int line, 153 handle_t *handle, struct super_block *sb) 154 { 155 struct buffer_head *bh = EXT4_SB(sb)->s_sbh; 156 int err = 0; 157 158 if (ext4_handle_valid(handle)) { 159 err = jbd2_journal_dirty_metadata(handle, bh); 160 if (err) 161 ext4_journal_abort_handle(where, line, __func__, 162 bh, handle, err); 163 } else 164 sb->s_dirt = 1; 165 return err; 166 } 167