aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode_item.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2009-10-06 16:29:26 -0400
committerAlex Elder <aelder@sgi.com>2009-10-08 13:00:03 -0400
commitf9581b1443abac50c90168301d40a7734b13a5dc (patch)
tree1ffecb2a1be9f0be55d9307fa93910ba24f8ed56 /fs/xfs/xfs_inode_item.c
parent9ef96da6ec5e1b4cf7eb8e30852cd88ec7d5fdc0 (diff)
xfs: implement ->dirty_inode to fix timestamp handling
This is picking up on Felix's repost of Dave's patch to implement a .dirty_inode method. We really need this notification because the VFS keeps writing directly into the inode structure instead of going through methods to update this state. In addition to the long-known atime issue we now also have a caller in VM code that updates c/mtime that way for shared writeable mmaps. And I found another one that no one has noticed in practice in the FIFO code. So implement ->dirty_inode to set i_update_core whenever the inode gets externally dirtied, and switch the c/mtime handling to the same scheme we already use for atime (always picking up the value from the Linux inode). Note that this patch also removes the xfs_synchronize_atime call in xfs_reclaim it was superflous as we already synchronize the time when writing the inode via the log (xfs_inode_item_format) or the normal buffers (xfs_iflush_int). In addition also remove the I_CLEAR check before copying the Linux timestamps - now that we always have the Linux inode available we can always use the timestamps in it. Also switch to just using file_update_time for regular reads/writes - that will get us all optimization done to it for free and make sure we notice early when it breaks. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Felix Blyakher <felixb@sgi.com> Reviewed-by: Alex Elder <aelder@sgi.com> Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_inode_item.c')
-rw-r--r--fs/xfs/xfs_inode_item.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 47d5b663c37e..9794b876d6ff 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -232,6 +232,15 @@ xfs_inode_item_format(
232 nvecs = 1; 232 nvecs = 1;
233 233
234 /* 234 /*
235 * Make sure the linux inode is dirty. We do this before
236 * clearing i_update_core as the VFS will call back into
237 * XFS here and set i_update_core, so we need to dirty the
238 * inode first so that the ordering of i_update_core and
239 * unlogged modifications still works as described below.
240 */
241 xfs_mark_inode_dirty_sync(ip);
242
243 /*
235 * Clear i_update_core if the timestamps (or any other 244 * Clear i_update_core if the timestamps (or any other
236 * non-transactional modification) need flushing/logging 245 * non-transactional modification) need flushing/logging
237 * and we're about to log them with the rest of the core. 246 * and we're about to log them with the rest of the core.
@@ -263,14 +272,9 @@ xfs_inode_item_format(
263 } 272 }
264 273
265 /* 274 /*
266 * Make sure to get the latest atime from the Linux inode. 275 * Make sure to get the latest timestamps from the Linux inode.
267 */ 276 */
268 xfs_synchronize_atime(ip); 277 xfs_synchronize_times(ip);
269
270 /*
271 * make sure the linux inode is dirty
272 */
273 xfs_mark_inode_dirty_sync(ip);
274 278
275 vecp->i_addr = (xfs_caddr_t)&ip->i_d; 279 vecp->i_addr = (xfs_caddr_t)&ip->i_d;
276 vecp->i_len = sizeof(struct xfs_icdinode); 280 vecp->i_len = sizeof(struct xfs_icdinode);