cifs: flush before set-info if we have writeable handles
Servers can defer destaging any data and updating the mtime until close(). This means that if we do a setinfo to modify the mtime while other handles are open for write the server may overwrite our setinfo timestamps when if flushes the file on close() of the writeable handle. To solve this we add an explicit flush when the mtime is about to be updated. This fixes "cp -p" to preserve mtime when copying a file onto an SMB2 share. CC: Stable <stable@vger.kernel.org> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
89a5bfa350
commit
aa081859b1
@ -2406,6 +2406,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
struct inode *inode = d_inode(direntry);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
|
||||
struct cifsFileInfo *wfile;
|
||||
struct cifs_tcon *tcon;
|
||||
char *full_path = NULL;
|
||||
int rc = -EACCES;
|
||||
__u32 dosattr = 0;
|
||||
@ -2452,6 +2454,20 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
mapping_set_error(inode->i_mapping, rc);
|
||||
rc = 0;
|
||||
|
||||
if (attrs->ia_valid & ATTR_MTIME) {
|
||||
rc = cifs_get_writable_file(cifsInode, false, &wfile);
|
||||
if (!rc) {
|
||||
tcon = tlink_tcon(wfile->tlink);
|
||||
rc = tcon->ses->server->ops->flush(xid, tcon, &wfile->fid);
|
||||
cifsFileInfo_put(wfile);
|
||||
if (rc)
|
||||
return rc;
|
||||
} else if (rc != -EBADF)
|
||||
return rc;
|
||||
else
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (attrs->ia_valid & ATTR_SIZE) {
|
||||
rc = cifs_set_file_size(inode, attrs, xid, full_path);
|
||||
if (rc != 0)
|
||||
|
Loading…
Reference in New Issue
Block a user