Skip to content

Commit

Permalink
[XFS] fix, speedup and simplify atime handling let the VFS handle atime
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Nathan Scott committed Jan 11, 2006
1 parent dd954c6 commit 42fe2b1
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 54 deletions.
58 changes: 24 additions & 34 deletions fs/xfs/linux-2.6/xfs_iops.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,24 @@
#define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) || \
(S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME))

/*
* Bring the atime in the XFS inode uptodate.
* Used before logging the inode to disk or when the Linux inode goes away.
*/
void
xfs_synchronize_atime(
xfs_inode_t *ip)
{
vnode_t *vp;

vp = XFS_ITOV_NULL(ip);
if (vp) {
struct inode *inode = &vp->v_inode;
ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
}
}

/*
* Change the requested timestamp in the given inode.
* We don't lock across timestamp updates, and we don't log them but
Expand All @@ -76,23 +94,6 @@ xfs_ichgtime(
struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
timespec_t tv;

/*
* We're not supposed to change timestamps in readonly-mounted
* filesystems. Throw it away if anyone asks us.
*/
if (unlikely(IS_RDONLY(inode)))
return;

/*
* Don't update access timestamps on reads if mounted "noatime".
* Throw it away if anyone asks us.
*/
if (unlikely(
(ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
(flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
XFS_ICHGTIME_ACC))
return;

nanotime(&tv);
if (flags & XFS_ICHGTIME_MOD) {
inode->i_mtime = tv;
Expand Down Expand Up @@ -129,8 +130,6 @@ xfs_ichgtime(
* Variant on the above which avoids querying the system clock
* in situations where we know the Linux inode timestamps have
* just been updated (and so we can update our inode cheaply).
* We also skip the readonly and noatime checks here, they are
* also catered for already.
*/
void
xfs_ichgtime_fast(
Expand All @@ -141,32 +140,23 @@ xfs_ichgtime_fast(
timespec_t *tvp;

/*
* We're not supposed to change timestamps in readonly-mounted
* filesystems. Throw it away if anyone asks us.
* Atime updates for read() & friends are handled lazily now, and
* explicit updates must go through xfs_ichgtime()
*/
if (unlikely(IS_RDONLY(inode)))
return;
ASSERT((flags & XFS_ICHGTIME_ACC) == 0);

/*
* Don't update access timestamps on reads if mounted "noatime".
* Throw it away if anyone asks us.
* We're not supposed to change timestamps in readonly-mounted
* filesystems. Throw it away if anyone asks us.
*/
if (unlikely(
(ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) &&
((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) ==
XFS_ICHGTIME_ACC)))
if (unlikely(IS_RDONLY(inode)))
return;

if (flags & XFS_ICHGTIME_MOD) {
tvp = &inode->i_mtime;
ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec;
ip->i_d.di_mtime.t_nsec = (__int32_t)tvp->tv_nsec;
}
if (flags & XFS_ICHGTIME_ACC) {
tvp = &inode->i_atime;
ip->i_d.di_atime.t_sec = (__int32_t)tvp->tv_sec;
ip->i_d.di_atime.t_nsec = (__int32_t)tvp->tv_nsec;
}
if (flags & XFS_ICHGTIME_CHG) {
tvp = &inode->i_ctime;
ip->i_d.di_ctime.t_sec = (__int32_t)tvp->tv_sec;
Expand Down
6 changes: 0 additions & 6 deletions fs/xfs/linux-2.6/xfs_lrw.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,6 @@ xfs_read(

xfs_iunlock(ip, XFS_IOLOCK_SHARED);

if (likely(!(ioflags & IO_INVIS)))
xfs_ichgtime_fast(ip, inode, XFS_ICHGTIME_ACC);

unlock_isem:
if (unlikely(ioflags & IO_ISDIRECT))
mutex_unlock(&inode->i_mutex);
Expand Down Expand Up @@ -346,9 +343,6 @@ xfs_sendfile(
if (ret > 0)
XFS_STATS_ADD(xs_read_bytes, ret);

if (likely(!(ioflags & IO_INVIS)))
xfs_ichgtime_fast(ip, LINVFS_GET_IP(vp), XFS_ICHGTIME_ACC);

return ret;
}

Expand Down
1 change: 0 additions & 1 deletion fs/xfs/linux-2.6/xfs_vnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ vn_revalidate_core(
inode->i_blocks = vap->va_nblocks;
inode->i_mtime = vap->va_mtime;
inode->i_ctime = vap->va_ctime;
inode->i_atime = vap->va_atime;
inode->i_blksize = vap->va_blocksize;
if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE;
Expand Down
5 changes: 5 additions & 0 deletions fs/xfs/xfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3364,6 +3364,11 @@ xfs_iflush_int(
ip->i_update_core = 0;
SYNCHRONIZE();

/*
* Make sure to get the latest atime from the Linux inode.
*/
xfs_synchronize_atime(ip);

if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC,
mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
Expand Down
2 changes: 2 additions & 0 deletions fs/xfs/xfs_inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ void xfs_ichgtime(xfs_inode_t *, int);
xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
void xfs_lock_inodes(xfs_inode_t **, int, int, uint);

void xfs_synchronize_atime(xfs_inode_t *);

#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))

#ifdef DEBUG
Expand Down
5 changes: 5 additions & 0 deletions fs/xfs/xfs_inode_item.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ xfs_inode_item_format(
if (ip->i_update_size)
ip->i_update_size = 0;

/*
* Make sure to get the latest atime from the Linux inode.
*/
xfs_synchronize_atime(ip);

vecp->i_addr = (xfs_caddr_t)&ip->i_d;
vecp->i_len = sizeof(xfs_dinode_core_t);
XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE);
Expand Down
7 changes: 5 additions & 2 deletions fs/xfs/xfs_itable.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ xfs_bulkstat_one_iget(
{
xfs_dinode_core_t *dic; /* dinode core info pointer */
xfs_inode_t *ip; /* incore inode pointer */
vnode_t *vp;
int error;

error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
Expand All @@ -72,6 +73,7 @@ xfs_bulkstat_one_iget(
goto out_iput;
}

vp = XFS_ITOV(ip);
dic = &ip->i_d;

/* xfs_iget returns the following without needing
Expand All @@ -84,8 +86,9 @@ xfs_bulkstat_one_iget(
buf->bs_uid = dic->di_uid;
buf->bs_gid = dic->di_gid;
buf->bs_size = dic->di_size;
buf->bs_atime.tv_sec = dic->di_atime.t_sec;
buf->bs_atime.tv_nsec = dic->di_atime.t_nsec;
/* atime is only kept uptodate in the Linux inode */
buf->bs_atime.tv_sec = vp->v_inode.i_atime.tv_sec;
buf->bs_atime.tv_nsec = vp->v_inode.i_atime.tv_nsec;
buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec;
buf->bs_ctime.tv_sec = dic->di_ctime.t_sec;
Expand Down
19 changes: 8 additions & 11 deletions fs/xfs/xfs_vnodeops.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ xfs_getattr(
break;
}

vap->va_atime.tv_sec = ip->i_d.di_atime.t_sec;
vap->va_atime.tv_nsec = ip->i_d.di_atime.t_nsec;
/* atime is only kept uptodate in the Linux inode */
vap->va_atime = vp->v_inode.i_atime;
vap->va_mtime.tv_sec = ip->i_d.di_mtime.t_sec;
vap->va_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
vap->va_ctime.tv_sec = ip->i_d.di_ctime.t_sec;
Expand Down Expand Up @@ -982,10 +982,6 @@ xfs_readlink(
goto error_return;
}

if (!(ioflags & IO_INVIS)) {
xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
}

/*
* See if the symlink is stored inline.
*/
Expand Down Expand Up @@ -3226,7 +3222,6 @@ xfs_readdir(
xfs_trans_t *tp = NULL;
int error = 0;
uint lock_mode;
xfs_off_t start_offset;

vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
(inst_t *)__return_address);
Expand All @@ -3237,11 +3232,7 @@ xfs_readdir(
}

lock_mode = xfs_ilock_map_shared(dp);
start_offset = uiop->uio_offset;
error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp);
if (start_offset != uiop->uio_offset) {
xfs_ichgtime(dp, XFS_ICHGTIME_ACC);
}
xfs_iunlock_map_shared(dp, lock_mode);
return error;
}
Expand Down Expand Up @@ -3819,6 +3810,12 @@ xfs_reclaim(

ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);

/*
* Make sure the atime in the XFS inode is correct before freeing the
* Linux inode.
*/
xfs_synchronize_atime(ip);

/* If we have nothing to flush with this inode then complete the
* teardown now, otherwise break the link between the xfs inode
* and the linux inode and clean up the xfs inode later. This
Expand Down

0 comments on commit 42fe2b1

Please sign in to comment.