diff options
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 4 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 23 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 10 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode.h | 1 |
4 files changed, 25 insertions, 13 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 66abe36c1213..ce369a816ce3 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
| @@ -187,7 +187,7 @@ xfs_setfilesize( | |||
| 187 | isize = xfs_ioend_new_eof(ioend); | 187 | isize = xfs_ioend_new_eof(ioend); |
| 188 | if (isize) { | 188 | if (isize) { |
| 189 | ip->i_d.di_size = isize; | 189 | ip->i_d.di_size = isize; |
| 190 | xfs_mark_inode_dirty_sync(ip); | 190 | xfs_mark_inode_dirty(ip); |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 193 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
| @@ -341,7 +341,7 @@ xfs_submit_ioend_bio( | |||
| 341 | * but don't update the inode size until I/O completion. | 341 | * but don't update the inode size until I/O completion. |
| 342 | */ | 342 | */ |
| 343 | if (xfs_ioend_new_eof(ioend)) | 343 | if (xfs_ioend_new_eof(ioend)) |
| 344 | xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode)); | 344 | xfs_mark_inode_dirty(XFS_I(ioend->io_inode)); |
| 345 | 345 | ||
| 346 | submit_bio(wbc->sync_mode == WB_SYNC_ALL ? | 346 | submit_bio(wbc->sync_mode == WB_SYNC_ALL ? |
| 347 | WRITE_SYNC_PLUG : WRITE, bio); | 347 | WRITE_SYNC_PLUG : WRITE, bio); |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 6c283b7be8ab..43f9554adaac 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
| @@ -97,16 +97,6 @@ xfs_iozero( | |||
| 97 | return (-status); | 97 | return (-status); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | /* | ||
| 101 | * We ignore the datasync flag here because a datasync is effectively | ||
| 102 | * identical to an fsync. That is, datasync implies that we need to write | ||
| 103 | * only the metadata needed to be able to access the data that is written | ||
| 104 | * if we crash after the call completes. Hence if we are writing beyond | ||
| 105 | * EOF we have to log the inode size change as well, which makes it a | ||
| 106 | * full fsync. If we don't write beyond EOF, the inode core will be | ||
| 107 | * clean in memory and so we don't need to log the inode, just like | ||
| 108 | * fsync. | ||
| 109 | */ | ||
| 110 | STATIC int | 100 | STATIC int |
| 111 | xfs_file_fsync( | 101 | xfs_file_fsync( |
| 112 | struct file *file, | 102 | struct file *file, |
| @@ -139,7 +129,18 @@ xfs_file_fsync( | |||
| 139 | */ | 129 | */ |
| 140 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 130 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
| 141 | 131 | ||
| 142 | if (ip->i_update_core) { | 132 | /* |
| 133 | * First check if the VFS inode is marked dirty. All the dirtying | ||
| 134 | * of non-transactional updates no goes through mark_inode_dirty*, | ||
| 135 | * which allows us to distinguish beteeen pure timestamp updates | ||
| 136 | * and i_size updates which need to be caught for fdatasync. | ||
| 137 | * After that also theck for the dirty state in the XFS inode, which | ||
| 138 | * might gets cleared when the inode gets written out via the AIL | ||
| 139 | * or xfs_iflush_cluster. | ||
| 140 | */ | ||
| 141 | if (((dentry->d_inode->i_state & I_DIRTY_DATASYNC) || | ||
| 142 | ((dentry->d_inode->i_state & I_DIRTY_SYNC) && !datasync)) && | ||
| 143 | ip->i_update_core) { | ||
| 143 | /* | 144 | /* |
| 144 | * Kick off a transaction to log the inode core to get the | 145 | * Kick off a transaction to log the inode core to get the |
| 145 | * updates. The sync transaction will also force the log. | 146 | * updates. The sync transaction will also force the log. |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index e8566bbf0f00..61a99608731e 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -91,6 +91,16 @@ xfs_mark_inode_dirty_sync( | |||
| 91 | mark_inode_dirty_sync(inode); | 91 | mark_inode_dirty_sync(inode); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | void | ||
| 95 | xfs_mark_inode_dirty( | ||
| 96 | xfs_inode_t *ip) | ||
| 97 | { | ||
| 98 | struct inode *inode = VFS_I(ip); | ||
| 99 | |||
| 100 | if (!(inode->i_state & (I_WILL_FREE|I_FREEING|I_CLEAR))) | ||
| 101 | mark_inode_dirty(inode); | ||
| 102 | } | ||
| 103 | |||
| 94 | /* | 104 | /* |
| 95 | * Change the requested timestamp in the given inode. | 105 | * Change the requested timestamp in the given inode. |
| 96 | * We don't lock across timestamp updates, and we don't log them but | 106 | * We don't lock across timestamp updates, and we don't log them but |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 6c912b027596..41e8a4e2e3be 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
| @@ -480,6 +480,7 @@ void xfs_lock_inodes(xfs_inode_t **, int, uint); | |||
| 480 | void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); | 480 | void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); |
| 481 | 481 | ||
| 482 | void xfs_synchronize_times(xfs_inode_t *); | 482 | void xfs_synchronize_times(xfs_inode_t *); |
| 483 | void xfs_mark_inode_dirty(xfs_inode_t *); | ||
| 483 | void xfs_mark_inode_dirty_sync(xfs_inode_t *); | 484 | void xfs_mark_inode_dirty_sync(xfs_inode_t *); |
| 484 | 485 | ||
| 485 | #define IHOLD(ip) \ | 486 | #define IHOLD(ip) \ |
