int __ext4_handle_dirty_metadata(const char *where, unsigned int line, handle_t *handle, struct inode *inode, struct buffer_head *bh) { int err = 0; if (ext4_handle_valid(handle)) { err = jbd2_journal_dirty_metadata(handle, bh); if (err) { /* Errors can only happen if there is a bug */ handle->h_err = err; __ext4_journal_stop(where, line, handle); } } else { if (inode) mark_buffer_dirty_inode(bh, inode); else mark_buffer_dirty(bh); if (inode && inode_needs_sync(inode)) { sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { struct ext4_super_block *es; es = EXT4_SB(inode->i_sb)->s_es; es->s_last_error_block = cpu_to_le64(bh->b_blocknr); ext4_error_inode(inode, where, line, bh->b_blocknr, "IO error syncing itable block"); err = -EIO; } } } return err; }
int __ext4_handle_dirty_metadata(const char *where, unsigned int line, handle_t *handle, struct inode *inode, struct buffer_head *bh) { int err = 0; might_sleep(); set_buffer_meta(bh); set_buffer_prio(bh); if (ext4_handle_valid(handle)) { err = jbd2_journal_dirty_metadata(handle, bh); /* Errors can only happen if there is a bug */ if (WARN_ON_ONCE(err)) { ext4_journal_abort_handle(where, line, __func__, bh, handle, err); if (inode == NULL) { pr_err("EXT4: jbd2_journal_dirty_metadata " "failed: handle type %u started at " "line %u, credits %u/%u, errcode %d", handle->h_type, handle->h_line_no, handle->h_requested_credits, handle->h_buffer_credits, err); return err; } ext4_error_inode(inode, where, line, bh->b_blocknr, "journal_dirty_metadata failed: " "handle type %u started at line %u, " "credits %u/%u, errcode %d", handle->h_type, handle->h_line_no, handle->h_requested_credits, handle->h_buffer_credits, err); } } else { if (inode) mark_buffer_dirty_inode(bh, inode); else mark_buffer_dirty(bh); if (inode && inode_needs_sync(inode)) { sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { struct ext4_super_block *es; es = EXT4_SB(inode->i_sb)->s_es; es->s_last_error_block = cpu_to_le64(bh->b_blocknr); ext4_error_inode(inode, where, line, bh->b_blocknr, "IO error syncing itable block"); err = -EIO; } } } return err; }
int __ext4bf_handle_dirty_metadata(const char *where, unsigned int line, handle_t *handle, struct inode *inode, struct buffer_head *bh) { int err = 0; if (ext4bf_handle_valid(handle)) { #ifdef DCHECKSUM /* ext4bf: handle cases where it is a data block. */ if (bh && bh->b_blocktype == B_BLOCKTYPE_DATA) { #endif #ifdef PARTJ if (!buffer_new(bh)) err = jbdbf_journal_dirty_metadata(handle, bh); else #endif #ifdef DCHECKSUM jbdbf_journal_dirty_data(handle, bh); } else #endif err = jbdbf_journal_dirty_metadata(handle, bh); if (err) { /* Errors can only happen if there is a bug */ handle->h_err = err; __ext4bf_journal_stop(where, line, handle); } } else { if (inode) mark_buffer_dirty_inode(bh, inode); else mark_buffer_dirty(bh); if (inode && inode_needs_sync(inode)) { sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { struct ext4bf_super_block *es; es = EXT4_SB(inode->i_sb)->s_es; es->s_last_error_block = cpu_to_le64(bh->b_blocknr); ext4bf_error_inode(inode, where, line, bh->b_blocknr, "IO error syncing itable block"); err = -EIO; } } } return err; }
/* * Called at the last iput() if i_nlink is zero. */ void ext2_delete_inode (struct inode * inode) { if (is_bad_inode(inode)) goto no_delete; EXT2_I(inode)->i_dtime = get_seconds(); mark_inode_dirty(inode); ext2_update_inode(inode, inode_needs_sync(inode)); inode->i_size = 0; if (inode->i_blocks) ext2_truncate (inode); ext2_free_inode (inode); return; no_delete: clear_inode(inode); /* We must guarantee clearing of inode... */ }
/* * Called at the last iput() if i_nlink is zero. */ void ext2_evict_inode(struct inode * inode) { struct ext2_block_alloc_info *rsv; int want_delete = 0; if (!inode->i_nlink && !is_bad_inode(inode)) { want_delete = 1; dquot_initialize(inode); } else { dquot_drop(inode); } truncate_inode_pages_final(&inode->i_data); if (want_delete) { sb_start_intwrite(inode->i_sb); /* set dtime */ EXT2_I(inode)->i_dtime = get_seconds(); mark_inode_dirty(inode); __ext2_write_inode(inode, inode_needs_sync(inode)); /* truncate to 0 */ inode->i_size = 0; if (inode->i_blocks) ext2_truncate_blocks(inode, 0); ext2_xattr_delete_inode(inode); } invalidate_inode_buffers(inode); clear_inode(inode); ext2_discard_reservation(inode); rsv = EXT2_I(inode)->i_block_alloc_info; EXT2_I(inode)->i_block_alloc_info = NULL; if (unlikely(rsv)) kfree(rsv); if (want_delete) { ext2_free_inode(inode); sb_end_intwrite(inode->i_sb); } }