cifs: do not return atime less than mtime
authorSteve French <stfrench@microsoft.com>
Sat, 22 Sep 2018 17:07:06 +0000 (12:07 -0500)
committerSteve French <stfrench@microsoft.com>
Wed, 24 Oct 2018 02:16:05 +0000 (21:16 -0500)
In network file system it is fairly easy for server and client
atime vs. mtime to get confused (and atime updated less frequently)
which we noticed broke some apps which expect atime >= mtime

Also ignore relatime mount option (rather than error on it) since
relatime is basically what some network server fs are doing
(relatime).

Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/inode.c

index 1605bf2506918ba21584495c742381270a3b4f78..d82f0cc7175508e9881873a2ee9c8a53c1a72944 100644 (file)
@@ -250,6 +250,7 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_ignore, "dev" },
        { Opt_ignore, "mand" },
        { Opt_ignore, "nomand" },
+       { Opt_ignore, "relatime" },
        { Opt_ignore, "_netdev" },
 
        { Opt_err, NULL }
index 8d41ca7bfcf1fe8f0eb0e3e8c6272547e09cc16c..fa723e7a08d7550c9730ee177f7c525dff33fec4 100644 (file)
@@ -3889,8 +3889,12 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
        else
                cifs_dbg(FYI, "Bytes read %d\n", rc);
 
-       file_inode(file)->i_atime =
-               current_time(file_inode(file));
+       /* we do not want atime to be less than mtime, it broke some apps */
+       file_inode(file)->i_atime = current_time(file_inode(file));
+       if (timespec64_compare(&(file_inode(file)->i_atime), &(file_inode(file)->i_mtime)))
+               file_inode(file)->i_atime = file_inode(file)->i_mtime;
+       else
+               file_inode(file)->i_atime = current_time(file_inode(file));
 
        if (PAGE_SIZE > rc)
                memset(read_data + rc, 0, PAGE_SIZE - rc);
index 6e8765f445086d2208a567825b5fb6022e564900..0945d40030eb9e5e37069afe8884a5bcab387b18 100644 (file)
@@ -162,7 +162,11 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
        cifs_revalidate_cache(inode, fattr);
 
        spin_lock(&inode->i_lock);
-       inode->i_atime = fattr->cf_atime;
+       /* we do not want atime to be less than mtime, it broke some apps */
+       if (timespec64_compare(&fattr->cf_atime, &fattr->cf_mtime))
+               inode->i_atime = fattr->cf_mtime;
+       else
+               inode->i_atime = fattr->cf_atime;
        inode->i_mtime = fattr->cf_mtime;
        inode->i_ctime = fattr->cf_ctime;
        inode->i_rdev = fattr->cf_rdev;