@ -26,11 +26,34 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
} ;
}
static void fuse_file_accessed ( struct file * dst_file , struct file * src_file )
{
struct inode * dst_inode ;
struct inode * src_inode ;
if ( dst_file - > f_flags & O_NOATIME )
return ;
dst_inode = file_inode ( dst_file ) ;
src_inode = file_inode ( src_file ) ;
if ( ( ! timespec64_equal ( & dst_inode - > i_mtime , & src_inode - > i_mtime ) | |
! timespec64_equal ( & dst_inode - > i_ctime , & src_inode - > i_ctime ) ) ) {
dst_inode - > i_mtime = src_inode - > i_mtime ;
dst_inode - > i_ctime = src_inode - > i_ctime ;
}
touch_atime ( & dst_file - > f_path ) ;
}
static void fuse_copyattr ( struct file * dst_file , struct file * src_file )
{
struct inode * dst = file_inode ( dst_file ) ;
struct inode * src = file_inode ( src_file ) ;
dst - > i_atime = src - > i_atime ;
dst - > i_mtime = src - > i_mtime ;
dst - > i_ctime = src - > i_ctime ;
i_size_write ( dst , i_size_read ( src ) ) ;
}
@ -96,6 +119,8 @@ ssize_t fuse_passthrough_read_iter(struct kiocb *iocb_fuse,
out :
revert_creds ( old_cred ) ;
fuse_file_accessed ( fuse_filp , passthrough_filp ) ;
return ret ;
}
@ -115,6 +140,8 @@ ssize_t fuse_passthrough_write_iter(struct kiocb *iocb_fuse,
inode_lock ( fuse_inode ) ;
fuse_copyattr ( fuse_filp , passthrough_filp ) ;
old_cred = override_creds ( ff - > passthrough . cred ) ;
if ( is_sync_kiocb ( iocb_fuse ) ) {
file_start_write ( passthrough_filp ) ;
@ -155,9 +182,7 @@ ssize_t fuse_passthrough_mmap(struct file *file, struct vm_area_struct *vma)
int ret ;
const struct cred * old_cred ;
struct fuse_file * ff = file - > private_data ;
struct inode * fuse_inode = file_inode ( file ) ;
struct file * passthrough_filp = ff - > passthrough . filp ;
struct inode * passthrough_inode = file_inode ( passthrough_filp ) ;
if ( ! passthrough_filp - > f_op - > mmap )
return - ENODEV ;
@ -176,17 +201,7 @@ ssize_t fuse_passthrough_mmap(struct file *file, struct vm_area_struct *vma)
else
fput ( file ) ;
if ( file - > f_flags & O_NOATIME )
return ret ;
if ( ( ! timespec64_equal ( & fuse_inode - > i_mtime ,
& passthrough_inode - > i_mtime ) | |
! timespec64_equal ( & fuse_inode - > i_ctime ,
& passthrough_inode - > i_ctime ) ) ) {
fuse_inode - > i_mtime = passthrough_inode - > i_mtime ;
fuse_inode - > i_ctime = passthrough_inode - > i_ctime ;
}
touch_atime ( & file - > f_path ) ;
fuse_file_accessed ( file , passthrough_filp ) ;
return ret ;
}