cifs: properly invalidate cached root handle when closing it
Cached root file was not being completely invalidated sometimes. Reproducing: - With a DFS share with 2 targets, one disabled and one enabled - start some I/O on the mount # while true; do ls /mnt/dfs; done - at the same time, disable the enabled target and enable the disabled one - wait for DFS cache to expire - on reconnect, the previous cached root handle should be invalid, but open_cached_dir_by_dentry() will still try to use it, but throws a use-after-free warning (kref_get()) Make smb2_close_cached_fid() invalidate all fields every time, but only send an SMB2_close() when the entry is still valid. Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de> Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
Родитель
8d014f5fe9
Коммит
9351590f51
|
@ -689,13 +689,19 @@ smb2_close_cached_fid(struct kref *ref)
|
|||
cifs_dbg(FYI, "clear cached root file handle\n");
|
||||
SMB2_close(0, cfid->tcon, cfid->fid->persistent_fid,
|
||||
cfid->fid->volatile_fid);
|
||||
cfid->is_valid = false;
|
||||
cfid->file_all_info_is_valid = false;
|
||||
cfid->has_lease = false;
|
||||
if (cfid->dentry) {
|
||||
dput(cfid->dentry);
|
||||
cfid->dentry = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We only check validity above to send SMB2_close,
|
||||
* but we still need to invalidate these entries
|
||||
* when this function is called
|
||||
*/
|
||||
cfid->is_valid = false;
|
||||
cfid->file_all_info_is_valid = false;
|
||||
cfid->has_lease = false;
|
||||
if (cfid->dentry) {
|
||||
dput(cfid->dentry);
|
||||
cfid->dentry = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче