Skip to content

Commit

Permalink
Allow relatime to update atime once a day
Browse files Browse the repository at this point in the history
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: Matthew Garrett <mjg@redhat.com>
Reviewed-by: Matthew Wilcox <willy@linux.intel.com>
Acked-by: Valerie Aurora Henson <vaurora@redhat.com>
Acked-by: Alan Cox <alan@redhat.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Matthew Garrett authored and Linus Torvalds committed Mar 26, 2009
1 parent 8e0ee43 commit 11ff6f0
Showing 1 changed file with 38 additions and 9 deletions.
47 changes: 38 additions & 9 deletions fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit 11ff6f0

Please sign in to comment.