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

Commit 11ff6f05 authored by Matthew Garrett's avatar Matthew Garrett Committed by Linus Torvalds
Browse files

Allow relatime to update atime once a day



Allow atime to be updated once per day even with relatime. This lets
utilities like tmpreaper (which delete files based on last access time)
continue working, making relatime a plausible default for distributions.

Signed-off-by: default avatarMatthew Garrett <mjg@redhat.com>
Reviewed-by: default avatarMatthew Wilcox <willy@linux.intel.com>
Acked-by: default avatarValerie Aurora Henson <vaurora@redhat.com>
Acked-by: default avatarAlan Cox <alan@redhat.com>
Acked-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8e0ee43b
Loading
Loading
Loading
Loading
+38 −9
Original line number Diff line number Diff line
@@ -1290,6 +1290,40 @@ sector_t bmap(struct inode * inode, sector_t block)
}
EXPORT_SYMBOL(bmap);

/*
 * With relative atime, only update atime if the previous atime is
 * earlier than either the ctime or mtime or if at least a day has
 * passed since the last atime update.
 */
static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
			     struct timespec now)
{

	if (!(mnt->mnt_flags & MNT_RELATIME))
		return 1;
	/*
	 * Is mtime younger than atime? If yes, update atime:
	 */
	if (timespec_compare(&inode->i_mtime, &inode->i_atime) >= 0)
		return 1;
	/*
	 * Is ctime younger than atime? If yes, update atime:
	 */
	if (timespec_compare(&inode->i_ctime, &inode->i_atime) >= 0)
		return 1;

	/*
	 * Is the previous atime value older than a day? If yes,
	 * update atime:
	 */
	if ((long)(now.tv_sec - inode->i_atime.tv_sec) >= 24*60*60)
		return 1;
	/*
	 * Good, we can skip the atime update:
	 */
	return 0;
}

/**
 *	touch_atime	-	update the access time
 *	@mnt: mount the inode is accessed on
@@ -1317,17 +1351,12 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
		goto out;
	if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
		goto out;
	if (mnt->mnt_flags & MNT_RELATIME) {
		/*
		 * With relative atime, only update atime if the previous
		 * atime is earlier than either the ctime or mtime.
		 */
		if (timespec_compare(&inode->i_mtime, &inode->i_atime) < 0 &&
		    timespec_compare(&inode->i_ctime, &inode->i_atime) < 0)
			goto out;
	}

	now = current_fs_time(inode->i_sb);

	if (!relatime_need_update(mnt, inode, now))
		goto out;

	if (timespec_equal(&inode->i_atime, &now))
		goto out;