mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-08 19:56:24 -04:00
smb: client: fix missing timestamp updates after utime(2)
Don't reuse open handle when changing timestamps to prevent the server
from disabling automatic timestamp updates 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.utime(fd, None)
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 14:01:21 2025 Fri Oct 3 14:01:21 2025
new : Fri Oct 3 14:01:21 2025 Fri Oct 3 14:01:21 2025
After patch:
$ mount.cifs //srv/share /mnt -o ...
$ python3 run.py
old : Fri Oct 3 17:03:34 2025 Fri Oct 3 17:03:34 2025
new : Fri Oct 3 17:03:36 2025 Fri Oct 3 17:03:36 2025
Fixes: b6f2a0f89d ("cifs: for compound requests, use open handle if possible")
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Cc: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Cc: linux-cifs@vger.kernel.org
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
committed by
Steve French
parent
57ce9f7793
commit
b95cd1bdf5
@@ -1382,31 +1382,33 @@ int
|
||||
smb2_set_file_info(struct inode *inode, const char *full_path,
|
||||
FILE_BASIC_INFO *buf, const unsigned int xid)
|
||||
{
|
||||
struct cifs_open_parms oparms;
|
||||
struct kvec in_iov = { .iov_base = buf, .iov_len = sizeof(*buf), };
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifsFileInfo *cfile = NULL;
|
||||
struct cifs_open_parms oparms;
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifsFileInfo *cfile;
|
||||
struct kvec in_iov = { .iov_base = buf, .iov_len = sizeof(*buf), };
|
||||
int rc;
|
||||
|
||||
if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) &&
|
||||
(buf->LastWriteTime == 0) && (buf->ChangeTime == 0) &&
|
||||
(buf->Attributes == 0))
|
||||
return 0; /* would be a no op, no sense sending this */
|
||||
int rc = 0;
|
||||
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
if (IS_ERR(tlink))
|
||||
return PTR_ERR(tlink);
|
||||
tcon = tlink_tcon(tlink);
|
||||
|
||||
cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
|
||||
if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) &&
|
||||
(buf->LastWriteTime == 0) && (buf->ChangeTime == 0)) {
|
||||
if (buf->Attributes == 0)
|
||||
goto out; /* would be a no op, no sense sending this */
|
||||
cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
|
||||
}
|
||||
|
||||
oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_WRITE_ATTRIBUTES,
|
||||
FILE_OPEN, 0, ACL_NO_MODE);
|
||||
rc = smb2_compound_op(xid, tcon, cifs_sb,
|
||||
full_path, &oparms, &in_iov,
|
||||
&(int){SMB2_OP_SET_INFO}, 1,
|
||||
cfile, NULL, NULL, NULL);
|
||||
out:
|
||||
cifs_put_tlink(tlink);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user