summaryrefslogtreecommitdiffstats
path: root/fs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/inode.c')
-rw-r--r--fs/inode.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 7e3ef3af3db9..4a1fc1631e00 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1536,16 +1536,36 @@ sector_t bmap(struct inode *inode, sector_t block)
1536EXPORT_SYMBOL(bmap); 1536EXPORT_SYMBOL(bmap);
1537 1537
1538/* 1538/*
1539 * Update times in overlayed inode from underlying real inode
1540 */
1541static void update_ovl_inode_times(struct dentry *dentry, struct inode *inode,
1542 bool rcu)
1543{
1544 if (!rcu) {
1545 struct inode *realinode = d_real_inode(dentry);
1546
1547 if (unlikely(inode != realinode) &&
1548 (!timespec_equal(&inode->i_mtime, &realinode->i_mtime) ||
1549 !timespec_equal(&inode->i_ctime, &realinode->i_ctime))) {
1550 inode->i_mtime = realinode->i_mtime;
1551 inode->i_ctime = realinode->i_ctime;
1552 }
1553 }
1554}
1555
1556/*
1539 * With relative atime, only update atime if the previous atime is 1557 * With relative atime, only update atime if the previous atime is
1540 * earlier than either the ctime or mtime or if at least a day has 1558 * earlier than either the ctime or mtime or if at least a day has
1541 * passed since the last atime update. 1559 * passed since the last atime update.
1542 */ 1560 */
1543static int relatime_need_update(struct vfsmount *mnt, struct inode *inode, 1561static int relatime_need_update(const struct path *path, struct inode *inode,
1544 struct timespec now) 1562 struct timespec now, bool rcu)
1545{ 1563{
1546 1564
1547 if (!(mnt->mnt_flags & MNT_RELATIME)) 1565 if (!(path->mnt->mnt_flags & MNT_RELATIME))
1548 return 1; 1566 return 1;
1567
1568 update_ovl_inode_times(path->dentry, inode, rcu);
1549 /* 1569 /*
1550 * Is mtime younger than atime? If yes, update atime: 1570 * Is mtime younger than atime? If yes, update atime:
1551 */ 1571 */
@@ -1612,7 +1632,8 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
1612 * This function automatically handles read only file systems and media, 1632 * This function automatically handles read only file systems and media,
1613 * as well as the "noatime" flag and inode specific "noatime" markers. 1633 * as well as the "noatime" flag and inode specific "noatime" markers.
1614 */ 1634 */
1615bool atime_needs_update(const struct path *path, struct inode *inode) 1635bool __atime_needs_update(const struct path *path, struct inode *inode,
1636 bool rcu)
1616{ 1637{
1617 struct vfsmount *mnt = path->mnt; 1638 struct vfsmount *mnt = path->mnt;
1618 struct timespec now; 1639 struct timespec now;
@@ -1638,7 +1659,7 @@ bool atime_needs_update(const struct path *path, struct inode *inode)
1638 1659
1639 now = current_fs_time(inode->i_sb); 1660 now = current_fs_time(inode->i_sb);
1640 1661
1641 if (!relatime_need_update(mnt, inode, now)) 1662 if (!relatime_need_update(path, inode, now, rcu))
1642 return false; 1663 return false;
1643 1664
1644 if (timespec_equal(&inode->i_atime, &now)) 1665 if (timespec_equal(&inode->i_atime, &now))
@@ -1653,7 +1674,7 @@ void touch_atime(const struct path *path)
1653 struct inode *inode = d_inode(path->dentry); 1674 struct inode *inode = d_inode(path->dentry);
1654 struct timespec now; 1675 struct timespec now;
1655 1676
1656 if (!atime_needs_update(path, inode)) 1677 if (!__atime_needs_update(path, inode, false))
1657 return; 1678 return;
1658 1679
1659 if (!sb_start_write_trylock(inode->i_sb)) 1680 if (!sb_start_write_trylock(inode->i_sb))