Commit 57ce9f77 authored by Paulo Alcantara's avatar Paulo Alcantara Committed by Steve French
Browse files

smb: client: fix missing timestamp updates after ftruncate(2)



Mask off ATTR_MTIME|ATTR_CTIME bits on ATTR_SIZE (e.g. ftruncate(2))
to prevent the client from sending set info calls and then disabling
automatic timestamp updates on server side as per MS-FSA 2.1.4.17.

---8<---
import os
import time

filename = '/mnt/foo'

def print_stat(prefix):
    st = os.stat(filename)
    print(prefix, ': ', time.ctime(st.st_atime), time.ctime(st.st_ctime))

fd = os.open(filename, os.O_CREAT|os.O_TRUNC|os.O_WRONLY, 0o644)
print_stat('old')
os.ftruncate(fd, 10)
time.sleep(2)
os.write(fd, b'foo')
os.close(fd)
time.sleep(2)
print_stat('new')
---8<---

Before patch:

$ mount.cifs //srv/share /mnt -o ...
$ python3 run.py
old :  Fri Oct  3 13:47:03 2025 Fri Oct  3 13:47:03 2025
new :  Fri Oct  3 13:47:00 2025 Fri Oct  3 13:47:03 2025

After patch:

$ mount.cifs //srv/share /mnt -o ...
$ python3 run.py
old :  Fri Oct  3 13:48:39 2025 Fri Oct  3 13:48:39 2025
new :  Fri Oct  3 13:48:41 2025 Fri Oct  3 13:48:41 2025

Signed-off-by: default avatarPaulo Alcantara (Red Hat) <pc@manguebit.org>
Cc: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: default avatarDavid Howells <dhowells@redhat.com>
Cc: linux-cifs@vger.kernel.org
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 110fee6b
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -3156,12 +3156,11 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
		if (rc != 0)
			goto out;
		/*
		 * The man page of truncate says if the size changed,
		 * then the st_ctime and st_mtime fields for the file
		 * are updated.
		 * Avoid setting timestamps on the server for ftruncate(2) to
		 * prevent it from disabling automatic timestamp updates as per
		 * MS-FSA 2.1.4.17.
		 */
		attrs->ia_ctime = attrs->ia_mtime = current_time(inode);
		attrs->ia_valid |= ATTR_CTIME | ATTR_MTIME;
		attrs->ia_valid &= ~(ATTR_CTIME | ATTR_MTIME);
	}

	/* skip mode change if it's just for clearing setuid/setgid */
@@ -3335,12 +3334,11 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
		if (rc != 0)
			goto cifs_setattr_exit;
		/*
		 * The man page of truncate says if the size changed,
		 * then the st_ctime and st_mtime fields for the file
		 * are updated.
		 * Avoid setting timestamps on the server for ftruncate(2) to
		 * prevent it from disabling automatic timestamp updates as per
		 * MS-FSA 2.1.4.17.
		 */
		attrs->ia_ctime = attrs->ia_mtime = current_time(inode);
		attrs->ia_valid |= ATTR_CTIME | ATTR_MTIME;
		attrs->ia_valid &= ~(ATTR_CTIME | ATTR_MTIME);
	}

	if (attrs->ia_valid & ATTR_UID)