Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42fe2b1f authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Nathan Scott
Browse files

[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: default avatarChristoph Hellwig <hch@sgi.com>
Signed-off-by: default avatarNathan Scott <nathans@sgi.com>
parent dd954c69
Loading
Loading
Loading
Loading
+24 −34
Original line number Diff line number Diff line
@@ -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
@@ -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;
@@ -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(
@@ -141,20 +140,16 @@ 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) {
@@ -162,11 +157,6 @@ xfs_ichgtime_fast(
		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;
+0 −6
Original line number Diff line number Diff line
@@ -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);
@@ -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;
}

+0 −1
Original line number Diff line number Diff line
@@ -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;
+5 −0
Original line number Diff line number Diff line
@@ -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,
+2 −0
Original line number Diff line number Diff line
@@ -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
Loading