diff options
author | Christoph Hellwig <hch@sgi.com> | 2006-01-10 23:35:17 -0500 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2006-01-10 23:35:17 -0500 |
commit | 42fe2b1f7fe788ed5304a7bfa0a0b0db81bc03a8 (patch) | |
tree | bbf454c788e4370faf569fdf51893529b3f71ab3 | |
parent | dd954c69d189cd91571b42d3f926e70351395dc3 (diff) |
[XFS] fix, speedup and simplify atime handling let the VFS handle atime
updates and only sync back to the xfs inode when nessecary
SGI-PV: 946679
SGI-Modid: xfs-linux-melb:xfs-kern:203362a
Signed-off-by: Christoph Hellwig <hch@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
-rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 58 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 6 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vnode.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode_item.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_itable.c | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 19 |
8 files changed, 49 insertions, 54 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 97fb1470cf28..8fd274fc26d5 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -58,6 +58,24 @@ | |||
58 | (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME)) | 58 | (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME)) |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Bring the atime in the XFS inode uptodate. | ||
62 | * Used before logging the inode to disk or when the Linux inode goes away. | ||
63 | */ | ||
64 | void | ||
65 | xfs_synchronize_atime( | ||
66 | xfs_inode_t *ip) | ||
67 | { | ||
68 | vnode_t *vp; | ||
69 | |||
70 | vp = XFS_ITOV_NULL(ip); | ||
71 | if (vp) { | ||
72 | struct inode *inode = &vp->v_inode; | ||
73 | ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec; | ||
74 | ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | /* | ||
61 | * Change the requested timestamp in the given inode. | 79 | * Change the requested timestamp in the given inode. |
62 | * We don't lock across timestamp updates, and we don't log them but | 80 | * We don't lock across timestamp updates, and we don't log them but |
63 | * we do record the fact that there is dirty information in core. | 81 | * we do record the fact that there is dirty information in core. |
@@ -76,23 +94,6 @@ xfs_ichgtime( | |||
76 | struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip)); | 94 | struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip)); |
77 | timespec_t tv; | 95 | timespec_t tv; |
78 | 96 | ||
79 | /* | ||
80 | * We're not supposed to change timestamps in readonly-mounted | ||
81 | * filesystems. Throw it away if anyone asks us. | ||
82 | */ | ||
83 | if (unlikely(IS_RDONLY(inode))) | ||
84 | return; | ||
85 | |||
86 | /* | ||
87 | * Don't update access timestamps on reads if mounted "noatime". | ||
88 | * Throw it away if anyone asks us. | ||
89 | */ | ||
90 | if (unlikely( | ||
91 | (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) && | ||
92 | (flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) == | ||
93 | XFS_ICHGTIME_ACC)) | ||
94 | return; | ||
95 | |||
96 | nanotime(&tv); | 97 | nanotime(&tv); |
97 | if (flags & XFS_ICHGTIME_MOD) { | 98 | if (flags & XFS_ICHGTIME_MOD) { |
98 | inode->i_mtime = tv; | 99 | inode->i_mtime = tv; |
@@ -129,8 +130,6 @@ xfs_ichgtime( | |||
129 | * Variant on the above which avoids querying the system clock | 130 | * Variant on the above which avoids querying the system clock |
130 | * in situations where we know the Linux inode timestamps have | 131 | * in situations where we know the Linux inode timestamps have |
131 | * just been updated (and so we can update our inode cheaply). | 132 | * just been updated (and so we can update our inode cheaply). |
132 | * We also skip the readonly and noatime checks here, they are | ||
133 | * also catered for already. | ||
134 | */ | 133 | */ |
135 | void | 134 | void |
136 | xfs_ichgtime_fast( | 135 | xfs_ichgtime_fast( |
@@ -141,20 +140,16 @@ xfs_ichgtime_fast( | |||
141 | timespec_t *tvp; | 140 | timespec_t *tvp; |
142 | 141 | ||
143 | /* | 142 | /* |
144 | * We're not supposed to change timestamps in readonly-mounted | 143 | * Atime updates for read() & friends are handled lazily now, and |
145 | * filesystems. Throw it away if anyone asks us. | 144 | * explicit updates must go through xfs_ichgtime() |
146 | */ | 145 | */ |
147 | if (unlikely(IS_RDONLY(inode))) | 146 | ASSERT((flags & XFS_ICHGTIME_ACC) == 0); |
148 | return; | ||
149 | 147 | ||
150 | /* | 148 | /* |
151 | * Don't update access timestamps on reads if mounted "noatime". | 149 | * We're not supposed to change timestamps in readonly-mounted |
152 | * Throw it away if anyone asks us. | 150 | * filesystems. Throw it away if anyone asks us. |
153 | */ | 151 | */ |
154 | if (unlikely( | 152 | if (unlikely(IS_RDONLY(inode))) |
155 | (ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) && | ||
156 | ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) == | ||
157 | XFS_ICHGTIME_ACC))) | ||
158 | return; | 153 | return; |
159 | 154 | ||
160 | if (flags & XFS_ICHGTIME_MOD) { | 155 | if (flags & XFS_ICHGTIME_MOD) { |
@@ -162,11 +157,6 @@ xfs_ichgtime_fast( | |||
162 | ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec; | 157 | ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec; |
163 | ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec; | 158 | ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec; |
164 | } | 159 | } |
165 | if (flags & XFS_ICHGTIME_ACC) { | ||
166 | tvp = &inode->i_atime; | ||
167 | ip->i_d.di_atime.t_sec = (__int32_t)tvp->tv_sec; | ||
168 | ip->i_d.di_atime.t_nsec = (__int32_t)tvp->tv_nsec; | ||
169 | } | ||
170 | if (flags & XFS_ICHGTIME_CHG) { | 160 | if (flags & XFS_ICHGTIME_CHG) { |
171 | tvp = &inode->i_ctime; | 161 | tvp = &inode->i_ctime; |
172 | ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec; | 162 | ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec; |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index c73d3c18882c..563cb9e975d2 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -281,9 +281,6 @@ xfs_read( | |||
281 | 281 | ||
282 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 282 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
283 | 283 | ||
284 | if (likely(!(ioflags & IO_INVIS))) | ||
285 | xfs_ichgtime_fast(ip, inode, XFS_ICHGTIME_ACC); | ||
286 | |||
287 | unlock_isem: | 284 | unlock_isem: |
288 | if (unlikely(ioflags & IO_ISDIRECT)) | 285 | if (unlikely(ioflags & IO_ISDIRECT)) |
289 | mutex_unlock(&inode->i_mutex); | 286 | mutex_unlock(&inode->i_mutex); |
@@ -346,9 +343,6 @@ xfs_sendfile( | |||
346 | if (ret > 0) | 343 | if (ret > 0) |
347 | XFS_STATS_ADD(xs_read_bytes, ret); | 344 | XFS_STATS_ADD(xs_read_bytes, ret); |
348 | 345 | ||
349 | if (likely(!(ioflags & IO_INVIS))) | ||
350 | xfs_ichgtime_fast(ip, LINVFS_GET_IP(vp), XFS_ICHGTIME_ACC); | ||
351 | |||
352 | return ret; | 346 | return ret; |
353 | } | 347 | } |
354 | 348 | ||
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c index e9bbcb4d6243..260dd8415dd7 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.c +++ b/fs/xfs/linux-2.6/xfs_vnode.c | |||
@@ -106,7 +106,6 @@ vn_revalidate_core( | |||
106 | inode->i_blocks = vap->va_nblocks; | 106 | inode->i_blocks = vap->va_nblocks; |
107 | inode->i_mtime = vap->va_mtime; | 107 | inode->i_mtime = vap->va_mtime; |
108 | inode->i_ctime = vap->va_ctime; | 108 | inode->i_ctime = vap->va_ctime; |
109 | inode->i_atime = vap->va_atime; | ||
110 | inode->i_blksize = vap->va_blocksize; | 109 | inode->i_blksize = vap->va_blocksize; |
111 | if (vap->va_xflags & XFS_XFLAG_IMMUTABLE) | 110 | if (vap->va_xflags & XFS_XFLAG_IMMUTABLE) |
112 | inode->i_flags |= S_IMMUTABLE; | 111 | inode->i_flags |= S_IMMUTABLE; |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 0063437f291a..6b7ac8bdcac2 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -3364,6 +3364,11 @@ xfs_iflush_int( | |||
3364 | ip->i_update_core = 0; | 3364 | ip->i_update_core = 0; |
3365 | SYNCHRONIZE(); | 3365 | SYNCHRONIZE(); |
3366 | 3366 | ||
3367 | /* | ||
3368 | * Make sure to get the latest atime from the Linux inode. | ||
3369 | */ | ||
3370 | xfs_synchronize_atime(ip); | ||
3371 | |||
3367 | if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC, | 3372 | if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC, |
3368 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { | 3373 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { |
3369 | xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, | 3374 | xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 124d30e6143b..c4c1d9bce82e 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -436,6 +436,8 @@ void xfs_ichgtime(xfs_inode_t *, int); | |||
436 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); | 436 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); |
437 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); | 437 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); |
438 | 438 | ||
439 | void xfs_synchronize_atime(xfs_inode_t *); | ||
440 | |||
439 | #define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount)) | 441 | #define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount)) |
440 | 442 | ||
441 | #ifdef DEBUG | 443 | #ifdef DEBUG |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 7f3363c621e1..9369010f3f16 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -271,6 +271,11 @@ xfs_inode_item_format( | |||
271 | if (ip->i_update_size) | 271 | if (ip->i_update_size) |
272 | ip->i_update_size = 0; | 272 | ip->i_update_size = 0; |
273 | 273 | ||
274 | /* | ||
275 | * Make sure to get the latest atime from the Linux inode. | ||
276 | */ | ||
277 | xfs_synchronize_atime(ip); | ||
278 | |||
274 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; | 279 | vecp->i_addr = (xfs_caddr_t)&ip->i_d; |
275 | vecp->i_len = sizeof(xfs_dinode_core_t); | 280 | vecp->i_len = sizeof(xfs_dinode_core_t); |
276 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE); | 281 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE); |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index f63646ead816..41f50e7d1c32 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -56,6 +56,7 @@ xfs_bulkstat_one_iget( | |||
56 | { | 56 | { |
57 | xfs_dinode_core_t *dic; /* dinode core info pointer */ | 57 | xfs_dinode_core_t *dic; /* dinode core info pointer */ |
58 | xfs_inode_t *ip; /* incore inode pointer */ | 58 | xfs_inode_t *ip; /* incore inode pointer */ |
59 | vnode_t *vp; | ||
59 | int error; | 60 | int error; |
60 | 61 | ||
61 | error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno); | 62 | error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno); |
@@ -72,6 +73,7 @@ xfs_bulkstat_one_iget( | |||
72 | goto out_iput; | 73 | goto out_iput; |
73 | } | 74 | } |
74 | 75 | ||
76 | vp = XFS_ITOV(ip); | ||
75 | dic = &ip->i_d; | 77 | dic = &ip->i_d; |
76 | 78 | ||
77 | /* xfs_iget returns the following without needing | 79 | /* xfs_iget returns the following without needing |
@@ -84,8 +86,9 @@ xfs_bulkstat_one_iget( | |||
84 | buf->bs_uid = dic->di_uid; | 86 | buf->bs_uid = dic->di_uid; |
85 | buf->bs_gid = dic->di_gid; | 87 | buf->bs_gid = dic->di_gid; |
86 | buf->bs_size = dic->di_size; | 88 | buf->bs_size = dic->di_size; |
87 | buf->bs_atime.tv_sec = dic->di_atime.t_sec; | 89 | /* atime is only kept uptodate in the Linux inode */ |
88 | buf->bs_atime.tv_nsec = dic->di_atime.t_nsec; | 90 | buf->bs_atime.tv_sec = vp->v_inode.i_atime.tv_sec; |
91 | buf->bs_atime.tv_nsec = vp->v_inode.i_atime.tv_nsec; | ||
89 | buf->bs_mtime.tv_sec = dic->di_mtime.t_sec; | 92 | buf->bs_mtime.tv_sec = dic->di_mtime.t_sec; |
90 | buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec; | 93 | buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec; |
91 | buf->bs_ctime.tv_sec = dic->di_ctime.t_sec; | 94 | buf->bs_ctime.tv_sec = dic->di_ctime.t_sec; |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 15734c54952e..688fc2cb4b8d 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -182,8 +182,8 @@ xfs_getattr( | |||
182 | break; | 182 | break; |
183 | } | 183 | } |
184 | 184 | ||
185 | vap->va_atime.tv_sec = ip->i_d.di_atime.t_sec; | 185 | /* atime is only kept uptodate in the Linux inode */ |
186 | vap->va_atime.tv_nsec = ip->i_d.di_atime.t_nsec; | 186 | vap->va_atime = vp->v_inode.i_atime; |
187 | vap->va_mtime.tv_sec = ip->i_d.di_mtime.t_sec; | 187 | vap->va_mtime.tv_sec = ip->i_d.di_mtime.t_sec; |
188 | vap->va_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; | 188 | vap->va_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; |
189 | vap->va_ctime.tv_sec = ip->i_d.di_ctime.t_sec; | 189 | vap->va_ctime.tv_sec = ip->i_d.di_ctime.t_sec; |
@@ -982,10 +982,6 @@ xfs_readlink( | |||
982 | goto error_return; | 982 | goto error_return; |
983 | } | 983 | } |
984 | 984 | ||
985 | if (!(ioflags & IO_INVIS)) { | ||
986 | xfs_ichgtime(ip, XFS_ICHGTIME_ACC); | ||
987 | } | ||
988 | |||
989 | /* | 985 | /* |
990 | * See if the symlink is stored inline. | 986 | * See if the symlink is stored inline. |
991 | */ | 987 | */ |
@@ -3226,7 +3222,6 @@ xfs_readdir( | |||
3226 | xfs_trans_t *tp = NULL; | 3222 | xfs_trans_t *tp = NULL; |
3227 | int error = 0; | 3223 | int error = 0; |
3228 | uint lock_mode; | 3224 | uint lock_mode; |
3229 | xfs_off_t start_offset; | ||
3230 | 3225 | ||
3231 | vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__, | 3226 | vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__, |
3232 | (inst_t *)__return_address); | 3227 | (inst_t *)__return_address); |
@@ -3237,11 +3232,7 @@ xfs_readdir( | |||
3237 | } | 3232 | } |
3238 | 3233 | ||
3239 | lock_mode = xfs_ilock_map_shared(dp); | 3234 | lock_mode = xfs_ilock_map_shared(dp); |
3240 | start_offset = uiop->uio_offset; | ||
3241 | error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp); | 3235 | error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp); |
3242 | if (start_offset != uiop->uio_offset) { | ||
3243 | xfs_ichgtime(dp, XFS_ICHGTIME_ACC); | ||
3244 | } | ||
3245 | xfs_iunlock_map_shared(dp, lock_mode); | 3236 | xfs_iunlock_map_shared(dp, lock_mode); |
3246 | return error; | 3237 | return error; |
3247 | } | 3238 | } |
@@ -3819,6 +3810,12 @@ xfs_reclaim( | |||
3819 | 3810 | ||
3820 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); | 3811 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); |
3821 | 3812 | ||
3813 | /* | ||
3814 | * Make sure the atime in the XFS inode is correct before freeing the | ||
3815 | * Linux inode. | ||
3816 | */ | ||
3817 | xfs_synchronize_atime(ip); | ||
3818 | |||
3822 | /* If we have nothing to flush with this inode then complete the | 3819 | /* If we have nothing to flush with this inode then complete the |
3823 | * teardown now, otherwise break the link between the xfs inode | 3820 | * teardown now, otherwise break the link between the xfs inode |
3824 | * and the linux inode and clean up the xfs inode later. This | 3821 | * and the linux inode and clean up the xfs inode later. This |