From a87bb308b7d126b522d4390dbf37f63e743133ac Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Mon, 20 Feb 2023 08:47:55 +0000 Subject: [PATCH] cifs: fix tcon status change after tree connect After cifs_tree_connect, tcon status should not be set to TID_GOOD. There could still be files that need reopen. The status should instead be changed to TID_NEED_FILES_INVALIDATE. That way, after reopen of files, the status can be changed to TID_GOOD. Signed-off-by: Shyam Prasad N --- fs/cifs/cifsglob.h | 2 +- fs/cifs/connect.c | 14 ++++++++++---- fs/cifs/dfs.c | 16 +++++++++++----- fs/cifs/file.c | 10 +++++----- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index cfdd5bf701a1..274ee0c921c8 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -140,7 +140,7 @@ enum tid_status_enum { TID_NEED_RECON, TID_NEED_TCON, TID_IN_TCON, - TID_NEED_FILES_INVALIDATE, /* currently unused */ + TID_NEED_FILES_INVALIDATE, TID_IN_FILES_INVALIDATE }; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 89831e5da2ee..780f2b42793c 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -4111,9 +4111,15 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru /* only send once per connect */ spin_lock(&tcon->tc_lock); - if (tcon->ses->ses_status != SES_GOOD || - (tcon->status != TID_NEW && - tcon->status != TID_NEED_TCON)) { + if (tcon->status != TID_GOOD && + tcon->status != TID_NEW && + tcon->status != TID_NEED_RECON) { + spin_unlock(&tcon->tc_lock); + return -EHOSTDOWN; + } + + if (tcon->status == TID_NEED_FILES_INVALIDATE || + tcon->status == TID_GOOD) { spin_unlock(&tcon->tc_lock); return 0; } @@ -4124,7 +4130,7 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru if (rc) { spin_lock(&tcon->tc_lock); if (tcon->status == TID_IN_TCON) - tcon->status = TID_NEED_TCON; + tcon->status = TID_NEED_RECON; spin_unlock(&tcon->tc_lock); } else { spin_lock(&tcon->tc_lock); diff --git a/fs/cifs/dfs.c b/fs/cifs/dfs.c index b64d20374b9c..d37af02902c5 100644 --- a/fs/cifs/dfs.c +++ b/fs/cifs/dfs.c @@ -479,9 +479,15 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru /* only send once per connect */ spin_lock(&tcon->tc_lock); - if (tcon->ses->ses_status != SES_GOOD || - (tcon->status != TID_NEW && - tcon->status != TID_NEED_TCON)) { + if (tcon->status != TID_GOOD && + tcon->status != TID_NEW && + tcon->status != TID_NEED_RECON) { + spin_unlock(&tcon->tc_lock); + return -EHOSTDOWN; + } + + if (tcon->status == TID_NEED_FILES_INVALIDATE || + tcon->status == TID_GOOD) { spin_unlock(&tcon->tc_lock); return 0; } @@ -529,12 +535,12 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru if (rc) { spin_lock(&tcon->tc_lock); if (tcon->status == TID_IN_TCON) - tcon->status = TID_NEED_TCON; + tcon->status = TID_NEED_RECON; spin_unlock(&tcon->tc_lock); } else { spin_lock(&tcon->tc_lock); if (tcon->status == TID_IN_TCON) - tcon->status = TID_GOOD; + tcon->status = TID_NEED_FILES_INVALIDATE; spin_unlock(&tcon->tc_lock); tcon->need_reconnect = false; } diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 22dfc1f8b4f1..4a63e56a5e98 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -48,13 +48,13 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon) struct list_head *tmp1; /* only send once per connect */ - spin_lock(&tcon->ses->ses_lock); - if ((tcon->ses->ses_status != SES_GOOD) || (tcon->status != TID_NEED_RECON)) { - spin_unlock(&tcon->ses->ses_lock); + spin_lock(&tcon->tc_lock); + if (tcon->status != TID_NEED_FILES_INVALIDATE) { + spin_unlock(&tcon->tc_lock); return; } tcon->status = TID_IN_FILES_INVALIDATE; - spin_unlock(&tcon->ses->ses_lock); + spin_unlock(&tcon->tc_lock); /* list all files open on tree connection and mark them invalid */ spin_lock(&tcon->open_file_lock); @@ -68,7 +68,7 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon) invalidate_all_cached_dirs(tcon); spin_lock(&tcon->tc_lock); if (tcon->status == TID_IN_FILES_INVALIDATE) - tcon->status = TID_NEED_TCON; + tcon->status = TID_GOOD; spin_unlock(&tcon->tc_lock); /*