Commit fdf59eb5 authored by Steve French's avatar Steve French
Browse files

smb3: cleanup and clarify status of tree connections



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: default avatarkernel test robot <lkp@intel.com>
Reviewed-by: default avatarShyam Prasad N <sprasad@microsoft.com>
Reviewed-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent be135000
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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)
+2 −2
Original line number Diff line number Diff line
@@ -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 */
+13 −5
Original line number Diff line number Diff line
@@ -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 {
@@ -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 {
+5 −6
Original line number Diff line number Diff line
@@ -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 */
@@ -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);

	/*
@@ -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) {
+16 −16
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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);
@@ -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;
	}
@@ -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;
	}
Loading