aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/inode.c54
1 files changed, 40 insertions, 14 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 6253ecdac67f..d04c8428bde2 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4538,7 +4538,8 @@ static int ext4_inode_blocks_set(handle_t *handle,
4538 */ 4538 */
4539static int ext4_do_update_inode(handle_t *handle, 4539static int ext4_do_update_inode(handle_t *handle,
4540 struct inode *inode, 4540 struct inode *inode,
4541 struct ext4_iloc *iloc) 4541 struct ext4_iloc *iloc,
4542 int do_sync)
4542{ 4543{
4543 struct ext4_inode *raw_inode = ext4_raw_inode(iloc); 4544 struct ext4_inode *raw_inode = ext4_raw_inode(iloc);
4544 struct ext4_inode_info *ei = EXT4_I(inode); 4545 struct ext4_inode_info *ei = EXT4_I(inode);
@@ -4640,10 +4641,22 @@ static int ext4_do_update_inode(handle_t *handle,
4640 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); 4641 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
4641 } 4642 }
4642 4643
4643 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); 4644 /*
4644 rc = ext4_handle_dirty_metadata(handle, inode, bh); 4645 * If we're not using a journal and we were called from
4645 if (!err) 4646 * ext4_write_inode() to sync the inode (making do_sync true),
4646 err = rc; 4647 * we can just use sync_dirty_buffer() directly to do our dirty
4648 * work. Testing s_journal here is a bit redundant but it's
4649 * worth it to avoid potential future trouble.
4650 */
4651 if (EXT4_SB(inode->i_sb)->s_journal == NULL && do_sync) {
4652 BUFFER_TRACE(bh, "call sync_dirty_buffer");
4653 sync_dirty_buffer(bh);
4654 } else {
4655 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
4656 rc = ext4_handle_dirty_metadata(handle, inode, bh);
4657 if (!err)
4658 err = rc;
4659 }
4647 ei->i_state &= ~EXT4_STATE_NEW; 4660 ei->i_state &= ~EXT4_STATE_NEW;
4648 4661
4649out_brelse: 4662out_brelse:
@@ -4689,19 +4702,32 @@ out_brelse:
4689 */ 4702 */
4690int ext4_write_inode(struct inode *inode, int wait) 4703int ext4_write_inode(struct inode *inode, int wait)
4691{ 4704{
4705 int err;
4706
4692 if (current->flags & PF_MEMALLOC) 4707 if (current->flags & PF_MEMALLOC)
4693 return 0; 4708 return 0;
4694 4709
4695 if (ext4_journal_current_handle()) { 4710 if (EXT4_SB(inode->i_sb)->s_journal) {
4696 jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n"); 4711 if (ext4_journal_current_handle()) {
4697 dump_stack(); 4712 jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
4698 return -EIO; 4713 dump_stack();
4699 } 4714 return -EIO;
4715 }
4700 4716
4701 if (!wait) 4717 if (!wait)
4702 return 0; 4718 return 0;
4719
4720 err = ext4_force_commit(inode->i_sb);
4721 } else {
4722 struct ext4_iloc iloc;
4703 4723
4704 return ext4_force_commit(inode->i_sb); 4724 err = ext4_get_inode_loc(inode, &iloc);
4725 if (err)
4726 return err;
4727 err = ext4_do_update_inode(EXT4_NOJOURNAL_HANDLE,
4728 inode, &iloc, wait);
4729 }
4730 return err;
4705} 4731}
4706 4732
4707/* 4733/*
@@ -4995,7 +5021,7 @@ int ext4_mark_iloc_dirty(handle_t *handle,
4995 get_bh(iloc->bh); 5021 get_bh(iloc->bh);
4996 5022
4997 /* ext4_do_update_inode() does jbd2_journal_dirty_metadata */ 5023 /* ext4_do_update_inode() does jbd2_journal_dirty_metadata */
4998 err = ext4_do_update_inode(handle, inode, iloc); 5024 err = ext4_do_update_inode(handle, inode, iloc, 0);
4999 put_bh(iloc->bh); 5025 put_bh(iloc->bh);
5000 return err; 5026 return err;
5001} 5027}