diff options
Diffstat (limited to 'fs/ext3/inode.c')
-rw-r--r-- | fs/ext3/inode.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index acf1b1423327..354ed3b47b30 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -699,8 +699,9 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode, | |||
699 | int err = 0; | 699 | int err = 0; |
700 | struct ext3_block_alloc_info *block_i; | 700 | struct ext3_block_alloc_info *block_i; |
701 | ext3_fsblk_t current_block; | 701 | ext3_fsblk_t current_block; |
702 | struct ext3_inode_info *ei = EXT3_I(inode); | ||
702 | 703 | ||
703 | block_i = EXT3_I(inode)->i_block_alloc_info; | 704 | block_i = ei->i_block_alloc_info; |
704 | /* | 705 | /* |
705 | * If we're splicing into a [td]indirect block (as opposed to the | 706 | * If we're splicing into a [td]indirect block (as opposed to the |
706 | * inode) then we need to get write access to the [td]indirect block | 707 | * inode) then we need to get write access to the [td]indirect block |
@@ -741,6 +742,8 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode, | |||
741 | 742 | ||
742 | inode->i_ctime = CURRENT_TIME_SEC; | 743 | inode->i_ctime = CURRENT_TIME_SEC; |
743 | ext3_mark_inode_dirty(handle, inode); | 744 | ext3_mark_inode_dirty(handle, inode); |
745 | /* ext3_mark_inode_dirty already updated i_sync_tid */ | ||
746 | atomic_set(&ei->i_datasync_tid, handle->h_transaction->t_tid); | ||
744 | 747 | ||
745 | /* had we spliced it onto indirect block? */ | 748 | /* had we spliced it onto indirect block? */ |
746 | if (where->bh) { | 749 | if (where->bh) { |
@@ -1735,6 +1738,7 @@ static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, | |||
1735 | ssize_t ret; | 1738 | ssize_t ret; |
1736 | int orphan = 0; | 1739 | int orphan = 0; |
1737 | size_t count = iov_length(iov, nr_segs); | 1740 | size_t count = iov_length(iov, nr_segs); |
1741 | int retries = 0; | ||
1738 | 1742 | ||
1739 | if (rw == WRITE) { | 1743 | if (rw == WRITE) { |
1740 | loff_t final_size = offset + count; | 1744 | loff_t final_size = offset + count; |
@@ -1757,9 +1761,12 @@ static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, | |||
1757 | } | 1761 | } |
1758 | } | 1762 | } |
1759 | 1763 | ||
1764 | retry: | ||
1760 | ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 1765 | ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, |
1761 | offset, nr_segs, | 1766 | offset, nr_segs, |
1762 | ext3_get_block, NULL); | 1767 | ext3_get_block, NULL); |
1768 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) | ||
1769 | goto retry; | ||
1763 | 1770 | ||
1764 | if (orphan) { | 1771 | if (orphan) { |
1765 | int err; | 1772 | int err; |
@@ -2750,6 +2757,8 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino) | |||
2750 | struct ext3_inode_info *ei; | 2757 | struct ext3_inode_info *ei; |
2751 | struct buffer_head *bh; | 2758 | struct buffer_head *bh; |
2752 | struct inode *inode; | 2759 | struct inode *inode; |
2760 | journal_t *journal = EXT3_SB(sb)->s_journal; | ||
2761 | transaction_t *transaction; | ||
2753 | long ret; | 2762 | long ret; |
2754 | int block; | 2763 | int block; |
2755 | 2764 | ||
@@ -2827,6 +2836,30 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino) | |||
2827 | ei->i_data[block] = raw_inode->i_block[block]; | 2836 | ei->i_data[block] = raw_inode->i_block[block]; |
2828 | INIT_LIST_HEAD(&ei->i_orphan); | 2837 | INIT_LIST_HEAD(&ei->i_orphan); |
2829 | 2838 | ||
2839 | /* | ||
2840 | * Set transaction id's of transactions that have to be committed | ||
2841 | * to finish f[data]sync. We set them to currently running transaction | ||
2842 | * as we cannot be sure that the inode or some of its metadata isn't | ||
2843 | * part of the transaction - the inode could have been reclaimed and | ||
2844 | * now it is reread from disk. | ||
2845 | */ | ||
2846 | if (journal) { | ||
2847 | tid_t tid; | ||
2848 | |||
2849 | spin_lock(&journal->j_state_lock); | ||
2850 | if (journal->j_running_transaction) | ||
2851 | transaction = journal->j_running_transaction; | ||
2852 | else | ||
2853 | transaction = journal->j_committing_transaction; | ||
2854 | if (transaction) | ||
2855 | tid = transaction->t_tid; | ||
2856 | else | ||
2857 | tid = journal->j_commit_sequence; | ||
2858 | spin_unlock(&journal->j_state_lock); | ||
2859 | atomic_set(&ei->i_sync_tid, tid); | ||
2860 | atomic_set(&ei->i_datasync_tid, tid); | ||
2861 | } | ||
2862 | |||
2830 | if (inode->i_ino >= EXT3_FIRST_INO(inode->i_sb) + 1 && | 2863 | if (inode->i_ino >= EXT3_FIRST_INO(inode->i_sb) + 1 && |
2831 | EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) { | 2864 | EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) { |
2832 | /* | 2865 | /* |
@@ -3011,6 +3044,7 @@ again: | |||
3011 | err = rc; | 3044 | err = rc; |
3012 | ei->i_state &= ~EXT3_STATE_NEW; | 3045 | ei->i_state &= ~EXT3_STATE_NEW; |
3013 | 3046 | ||
3047 | atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid); | ||
3014 | out_brelse: | 3048 | out_brelse: |
3015 | brelse (bh); | 3049 | brelse (bh); |
3016 | ext3_std_error(inode->i_sb, err); | 3050 | ext3_std_error(inode->i_sb, err); |