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 /fs/xfs | |
| 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>
Diffstat (limited to 'fs/xfs')
| -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 |
