Commit 42fe2b1f7fe788ed5304a7bfa0a0b0db81bc03a8

Authored by Christoph Hellwig
Committed by Nathan Scott
1 parent dd954c69d1

[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>

Showing 8 changed files with 49 additions and 54 deletions Side-by-side Diff

fs/xfs/linux-2.6/xfs_iops.c
... ... @@ -58,6 +58,24 @@
58 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 79 * Change the requested timestamp in the given inode.
62 80 * We don't lock across timestamp updates, and we don't log them but
63 81 * we do record the fact that there is dirty information in core.
... ... @@ -76,23 +94,6 @@
76 94 struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
77 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 97 nanotime(&tv);
97 98 if (flags & XFS_ICHGTIME_MOD) {
98 99 inode->i_mtime = tv;
... ... @@ -129,8 +130,6 @@
129 130 * Variant on the above which avoids querying the system clock
130 131 * in situations where we know the Linux inode timestamps have
131 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 134 void
136 135 xfs_ichgtime_fast(
137 136  
138 137  
... ... @@ -141,31 +140,22 @@
141 140 timespec_t *tvp;
142 141  
143 142 /*
  143 + * Atime updates for read() & friends are handled lazily now, and
  144 + * explicit updates must go through xfs_ichgtime()
  145 + */
  146 + ASSERT((flags & XFS_ICHGTIME_ACC) == 0);
  147 +
  148 + /*
144 149 * We're not supposed to change timestamps in readonly-mounted
145 150 * filesystems. Throw it away if anyone asks us.
146 151 */
147 152 if (unlikely(IS_RDONLY(inode)))
148 153 return;
149 154  
150   - /*
151   - * Don't update access timestamps on reads if mounted "noatime".
152   - * Throw it away if anyone asks us.
153   - */
154   - if (unlikely(
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;
159   -
160 155 if (flags & XFS_ICHGTIME_MOD) {
161 156 tvp = &inode->i_mtime;
162 157 ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec;
163 158 ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec;
164   - }
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 159 }
170 160 if (flags & XFS_ICHGTIME_CHG) {
171 161 tvp = &inode->i_ctime;
fs/xfs/linux-2.6/xfs_lrw.c
... ... @@ -281,9 +281,6 @@
281 281  
282 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 284 unlock_isem:
288 285 if (unlikely(ioflags & IO_ISDIRECT))
289 286 mutex_unlock(&inode->i_mutex);
... ... @@ -345,9 +342,6 @@
345 342  
346 343 if (ret > 0)
347 344 XFS_STATS_ADD(xs_read_bytes, ret);
348   -
349   - if (likely(!(ioflags & IO_INVIS)))
350   - xfs_ichgtime_fast(ip, LINVFS_GET_IP(vp), XFS_ICHGTIME_ACC);
351 345  
352 346 return ret;
353 347 }
fs/xfs/linux-2.6/xfs_vnode.c
... ... @@ -106,7 +106,6 @@
106 106 inode->i_blocks = vap->va_nblocks;
107 107 inode->i_mtime = vap->va_mtime;
108 108 inode->i_ctime = vap->va_ctime;
109   - inode->i_atime = vap->va_atime;
110 109 inode->i_blksize = vap->va_blocksize;
111 110 if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
112 111 inode->i_flags |= S_IMMUTABLE;
... ... @@ -3364,6 +3364,11 @@
3364 3364 ip->i_update_core = 0;
3365 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 3372 if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC,
3368 3373 mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
3369 3374 xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
... ... @@ -436,6 +436,8 @@
436 436 xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
437 437 void xfs_lock_inodes(xfs_inode_t **, int, int, uint);
438 438  
  439 +void xfs_synchronize_atime(xfs_inode_t *);
  440 +
439 441 #define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))
440 442  
441 443 #ifdef DEBUG
fs/xfs/xfs_inode_item.c
... ... @@ -271,6 +271,11 @@
271 271 if (ip->i_update_size)
272 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 279 vecp->i_addr = (xfs_caddr_t)&ip->i_d;
275 280 vecp->i_len = sizeof(xfs_dinode_core_t);
276 281 XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE);
... ... @@ -56,6 +56,7 @@
56 56 {
57 57 xfs_dinode_core_t *dic; /* dinode core info pointer */
58 58 xfs_inode_t *ip; /* incore inode pointer */
  59 + vnode_t *vp;
59 60 int error;
60 61  
61 62 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
... ... @@ -72,6 +73,7 @@
72 73 goto out_iput;
73 74 }
74 75  
  76 + vp = XFS_ITOV(ip);
75 77 dic = &ip->i_d;
76 78  
77 79 /* xfs_iget returns the following without needing
... ... @@ -84,8 +86,9 @@
84 86 buf->bs_uid = dic->di_uid;
85 87 buf->bs_gid = dic->di_gid;
86 88 buf->bs_size = dic->di_size;
87   - buf->bs_atime.tv_sec = dic->di_atime.t_sec;
88   - buf->bs_atime.tv_nsec = dic->di_atime.t_nsec;
  89 + /* atime is only kept uptodate in the Linux inode */
  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 92 buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
90 93 buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec;
91 94 buf->bs_ctime.tv_sec = dic->di_ctime.t_sec;
fs/xfs/xfs_vnodeops.c
... ... @@ -182,8 +182,8 @@
182 182 break;
183 183 }
184 184  
185   - vap->va_atime.tv_sec = ip->i_d.di_atime.t_sec;
186   - vap->va_atime.tv_nsec = ip->i_d.di_atime.t_nsec;
  185 + /* atime is only kept uptodate in the Linux inode */
  186 + vap->va_atime = vp->v_inode.i_atime;
187 187 vap->va_mtime.tv_sec = ip->i_d.di_mtime.t_sec;
188 188 vap->va_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
189 189 vap->va_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
... ... @@ -982,10 +982,6 @@
982 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 986 * See if the symlink is stored inline.
991 987 */
... ... @@ -3226,7 +3222,6 @@
3226 3222 xfs_trans_t *tp = NULL;
3227 3223 int error = 0;
3228 3224 uint lock_mode;
3229   - xfs_off_t start_offset;
3230 3225  
3231 3226 vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
3232 3227 (inst_t *)__return_address);
3233 3228  
... ... @@ -3237,11 +3232,7 @@
3237 3232 }
3238 3233  
3239 3234 lock_mode = xfs_ilock_map_shared(dp);
3240   - start_offset = uiop->uio_offset;
3241 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 3236 xfs_iunlock_map_shared(dp, lock_mode);
3246 3237 return error;
3247 3238 }
... ... @@ -3818,6 +3809,12 @@
3818 3809 vn_iowait(vp);
3819 3810  
3820 3811 ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
  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);
3821 3818  
3822 3819 /* If we have nothing to flush with this inode then complete the
3823 3820 * teardown now, otherwise break the link between the xfs inode