aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/inode.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2009-10-16 13:26:15 -0400
committerJan Kara <jack@suse.cz>2009-11-11 09:22:49 -0500
commitfe8bc91c4c30122b357d197117705cfd4fabaf28 (patch)
tree33e2895847d812204209444db4093af9a2c3623d /fs/ext3/inode.c
parentea0174a7137c8ca9f130ca681f3a99c872da6778 (diff)
ext3: Wait for proper transaction commit on fsync
We cannot rely on buffer dirty bits during fsync because pdflush can come before fsync is called and clear dirty bits without forcing a transaction commit. What we do is that we track which transaction has last changed the inode and which transaction last changed allocation and force it to disk on fsync. Signed-off-by: Jan Kara <jack@suse.cz> Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Diffstat (limited to 'fs/ext3/inode.c')
-rw-r--r--fs/ext3/inode.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 069a163393b4..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) {
@@ -2754,6 +2757,8 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
2754 struct ext3_inode_info *ei; 2757 struct ext3_inode_info *ei;
2755 struct buffer_head *bh; 2758 struct buffer_head *bh;
2756 struct inode *inode; 2759 struct inode *inode;
2760 journal_t *journal = EXT3_SB(sb)->s_journal;
2761 transaction_t *transaction;
2757 long ret; 2762 long ret;
2758 int block; 2763 int block;
2759 2764
@@ -2831,6 +2836,30 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
2831 ei->i_data[block] = raw_inode->i_block[block]; 2836 ei->i_data[block] = raw_inode->i_block[block];
2832 INIT_LIST_HEAD(&ei->i_orphan); 2837 INIT_LIST_HEAD(&ei->i_orphan);
2833 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
2834 if (inode->i_ino >= EXT3_FIRST_INO(inode->i_sb) + 1 && 2863 if (inode->i_ino >= EXT3_FIRST_INO(inode->i_sb) + 1 &&
2835 EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) { 2864 EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) {
2836 /* 2865 /*
@@ -3015,6 +3044,7 @@ again:
3015 err = rc; 3044 err = rc;
3016 ei->i_state &= ~EXT3_STATE_NEW; 3045 ei->i_state &= ~EXT3_STATE_NEW;
3017 3046
3047 atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid);
3018out_brelse: 3048out_brelse:
3019 brelse (bh); 3049 brelse (bh);
3020 ext3_std_error(inode->i_sb, err); 3050 ext3_std_error(inode->i_sb, err);