Skip to content

Commit

Permalink
smb3: cleanup and clarify status of tree connections
Browse files Browse the repository at this point in the history
Currently the way the tid (tree connection) status is tracked
is confusing.  The same enum is used for structs cifs_tcon
and cifs_ses and TCP_Server_info, but each of these three has
different states that they transition among.  The current
code also unnecessarily uses camelCase.

Convert from use of statusEnum to a new tid_status_enum for
tree connections.  The valid states for a tid are:

        TID_NEW = 0,
        TID_GOOD,
        TID_EXITING,
        TID_NEED_RECON,
        TID_NEED_TCON,
        TID_IN_TCON,
        TID_NEED_FILES_INVALIDATE, /* unused, considering removing in future */
        TID_IN_FILES_INVALIDATE

It also removes CifsNeedTcon, CifsInTcon, CifsNeedFilesInvalidate and
CifsInFilesInvalidate from the statusEnum used for session and
TCP_Server_Info since they are not relevant for those.

A follow on patch will fix the places where we use the
tcon->need_reconnect flag to be more consistent with the tid->status.

Also fixes a bug that was:
Reported-by: kernel test robot <lkp@intel.com>
Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
  • Loading branch information
Steve French committed Mar 28, 2022
1 parent be13500 commit fdf59eb
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 33 deletions.
2 changes: 1 addition & 1 deletion fs/cifs/cifs_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
le32_to_cpu(tcon->fsAttrInfo.Attributes),
le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
tcon->tidStatus);
tcon->status);
if (dev_type == FILE_DEVICE_DISK)
seq_puts(m, " type: DISK ");
else if (dev_type == FILE_DEVICE_CD_ROM)
Expand Down
4 changes: 2 additions & 2 deletions fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,14 +699,14 @@ static void cifs_umount_begin(struct super_block *sb)
tcon = cifs_sb_master_tcon(cifs_sb);

spin_lock(&cifs_tcp_ses_lock);
if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) {
if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {
/* we have other mounts to same share or we have
already tried to force umount this and woken up
all waiting network requests, nothing to do */
spin_unlock(&cifs_tcp_ses_lock);
return;
} else if (tcon->tc_count == 1)
tcon->tidStatus = CifsExiting;
tcon->status = TID_EXITING;
spin_unlock(&cifs_tcp_ses_lock);

/* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
Expand Down
18 changes: 13 additions & 5 deletions fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,18 @@ enum statusEnum {
CifsInNegotiate,
CifsNeedSessSetup,
CifsInSessSetup,
CifsNeedTcon,
CifsInTcon,
CifsNeedFilesInvalidate,
CifsInFilesInvalidate
};

/* associated with each tree connection to the server */
enum tid_status_enum {
TID_NEW = 0,
TID_GOOD,
TID_EXITING,
TID_NEED_RECON,
TID_NEED_TCON,
TID_IN_TCON,
TID_NEED_FILES_INVALIDATE, /* currently unused */
TID_IN_FILES_INVALIDATE
};

enum securityEnum {
Expand Down Expand Up @@ -1032,7 +1040,7 @@ struct cifs_tcon {
char *password; /* for share-level security */
__u32 tid; /* The 4 byte tree id */
__u16 Flags; /* optional support bits */
enum statusEnum tidStatus;
enum tid_status_enum status;
atomic_t num_smbs_sent;
union {
struct {
Expand Down
11 changes: 5 additions & 6 deletions fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,11 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)

/* only send once per connect */
spin_lock(&cifs_tcp_ses_lock);
if (tcon->ses->status != CifsGood ||
tcon->tidStatus != CifsNeedReconnect) {
if ((tcon->ses->status != CifsGood) || (tcon->status != TID_NEED_RECON)) {
spin_unlock(&cifs_tcp_ses_lock);
return;
}
tcon->tidStatus = CifsInFilesInvalidate;
tcon->status = TID_IN_FILES_INVALIDATE;
spin_unlock(&cifs_tcp_ses_lock);

/* list all files open on tree connection and mark them invalid */
Expand All @@ -100,8 +99,8 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
mutex_unlock(&tcon->crfid.fid_mutex);

spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsInFilesInvalidate)
tcon->tidStatus = CifsNeedTcon;
if (tcon->status == TID_IN_FILES_INVALIDATE)
tcon->status = TID_NEED_TCON;
spin_unlock(&cifs_tcp_ses_lock);

/*
Expand Down Expand Up @@ -136,7 +135,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
* have tcon) are allowed as we start force umount
*/
spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsExiting) {
if (tcon->status == TID_EXITING) {
if (smb_command != SMB_COM_WRITE_ANDX &&
smb_command != SMB_COM_OPEN_ANDX &&
smb_command != SMB_COM_TREE_DISCONNECT) {
Expand Down
32 changes: 16 additions & 16 deletions fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,

list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
tcon->need_reconnect = true;
tcon->tidStatus = CifsNeedReconnect;
tcon->status = TID_NEED_RECON;
}
if (ses->tcon_ipc)
ses->tcon_ipc->need_reconnect = true;
Expand Down Expand Up @@ -2207,7 +2207,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)

static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
{
if (tcon->tidStatus == CifsExiting)
if (tcon->status == TID_EXITING)
return 0;
if (strncmp(tcon->treeName, ctx->UNC, MAX_TREE_SIZE))
return 0;
Expand Down Expand Up @@ -4486,12 +4486,12 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
/* only send once per connect */
spin_lock(&cifs_tcp_ses_lock);
if (tcon->ses->status != CifsGood ||
(tcon->tidStatus != CifsNew &&
tcon->tidStatus != CifsNeedTcon)) {
(tcon->status != TID_NEW &&
tcon->status != TID_NEED_TCON)) {
spin_unlock(&cifs_tcp_ses_lock);
return 0;
}
tcon->tidStatus = CifsInTcon;
tcon->status = TID_IN_TCON;
spin_unlock(&cifs_tcp_ses_lock);

tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
Expand Down Expand Up @@ -4532,13 +4532,13 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru

if (rc) {
spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsInTcon)
tcon->tidStatus = CifsNeedTcon;
if (tcon->status == TID_IN_TCON)
tcon->status = TID_NEED_TCON;
spin_unlock(&cifs_tcp_ses_lock);
} else {
spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsInTcon)
tcon->tidStatus = CifsGood;
if (tcon->status == TID_IN_TCON)
tcon->status = TID_GOOD;
spin_unlock(&cifs_tcp_ses_lock);
tcon->need_reconnect = false;
}
Expand All @@ -4554,24 +4554,24 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
/* only send once per connect */
spin_lock(&cifs_tcp_ses_lock);
if (tcon->ses->status != CifsGood ||
(tcon->tidStatus != CifsNew &&
tcon->tidStatus != CifsNeedTcon)) {
(tcon->status != TID_NEW &&
tcon->status != TID_NEED_TCON)) {
spin_unlock(&cifs_tcp_ses_lock);
return 0;
}
tcon->tidStatus = CifsInTcon;
tcon->status = TID_IN_TCON;
spin_unlock(&cifs_tcp_ses_lock);

rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc);
if (rc) {
spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsInTcon)
tcon->tidStatus = CifsNeedTcon;
if (tcon->status == TID_IN_TCON)
tcon->status = TID_NEED_TCON;
spin_unlock(&cifs_tcp_ses_lock);
} else {
spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsInTcon)
tcon->tidStatus = CifsGood;
if (tcon->status == TID_IN_TCON)
tcon->status = TID_GOOD;
spin_unlock(&cifs_tcp_ses_lock);
tcon->need_reconnect = false;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ tconInfoAlloc(void)
}

atomic_inc(&tconInfoAllocCount);
ret_buf->tidStatus = CifsNew;
ret_buf->status = TID_NEW;
++ret_buf->tc_count;
INIT_LIST_HEAD(&ret_buf->openFileList);
INIT_LIST_HEAD(&ret_buf->tcon_list);
Expand Down
4 changes: 2 additions & 2 deletions fs/cifs/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
return 0;

spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsExiting) {
if (tcon->status == TID_EXITING) {
/*
* only tree disconnect, open, and write,
* (and ulogoff which does not have tcon)
Expand Down Expand Up @@ -3860,7 +3860,7 @@ void smb2_reconnect_server(struct work_struct *work)
goto done;
}

tcon->tidStatus = CifsGood;
tcon->status = TID_GOOD;
tcon->retry = false;
tcon->need_reconnect = false;

Expand Down

0 comments on commit fdf59eb

Please sign in to comment.