@ -1535,17 +1535,37 @@ sector_t bmap(struct inode *inode, sector_t block)
}
EXPORT_SYMBOL ( bmap ) ;
/*
* Update times in overlayed inode from underlying real inode
*/
static void update_ovl_inode_times ( struct dentry * dentry , struct inode * inode ,
bool rcu )
{
if ( ! rcu ) {
struct inode * realinode = d_real_inode ( dentry ) ;
if ( unlikely ( inode ! = realinode ) & &
( ! timespec_equal ( & inode - > i_mtime , & realinode - > i_mtime ) | |
! timespec_equal ( & inode - > i_ctime , & realinode - > i_ctime ) ) ) {
inode - > i_mtime = realinode - > i_mtime ;
inode - > i_ctime = realinode - > i_ctime ;
}
}
}
/*
* 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 )
static int relatime_need_update ( const struct path * path , struct inode * inode ,
struct timespec now , bool rcu )
{
if ( ! ( mnt - > mnt_flags & MNT_RELATIME ) )
if ( ! ( path - > mnt - > mnt_flags & MNT_RELATIME ) )
return 1 ;
update_ovl_inode_times ( path - > dentry , inode , rcu ) ;
/*
* Is mtime younger than atime ? If yes , update atime :
*/
@ -1612,7 +1632,8 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
* This function automatically handles read only file systems and media ,
* as well as the " noatime " flag and inode specific " noatime " markers .
*/
bool atime_needs_update ( const struct path * path , struct inode * inode )
bool __atime_needs_update ( const struct path * path , struct inode * inode ,
bool rcu )
{
struct vfsmount * mnt = path - > mnt ;
struct timespec now ;
@ -1638,7 +1659,7 @@ bool atime_needs_update(const struct path *path, struct inode *inode)
now = current_fs_time ( inode - > i_sb ) ;
if ( ! relatime_need_update ( mnt , inode , now ) )
if ( ! relatime_need_update ( path , inode , now , rcu ) )
return false ;
if ( timespec_equal ( & inode - > i_atime , & now ) )
@ -1653,7 +1674,7 @@ void touch_atime(const struct path *path)
struct inode * inode = d_inode ( path - > dentry ) ;
struct timespec now ;
if ( ! atime_needs_update ( path , inode ) )
if ( ! __ atime_needs_update( path , inode , fals e ) )
return ;
if ( ! sb_start_write_trylock ( inode - > i_sb ) )