Skip to content

Commit

Permalink
[CIFS] Fix cifs reconnection flags
Browse files Browse the repository at this point in the history
In preparation for Jeff's big umount/mount fixes to remove the possibility of
various races in cifs mount and linked list handling of sessions, sockets and
tree connections, this patch cleans up some repetitive code in cifs_mount,
and addresses a problem with ses->status and tcon->tidStatus in which we
were overloading the "need_reconnect" state with other status in that
field.  So the "need_reconnect" flag has been broken out from those
two state fields (need reconnect was not mutually exclusive from some of the
other possible tid and ses states).  In addition, a few exit cases in
cifs_mount were cleaned up, and a problem with a tcon flag (for lease support)
was not being set consistently for the 2nd mount of the same share

CC: Jeff Layton <jlayton@redhat.com>
CC: Shirish Pargaonkar <shirishp@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
  • Loading branch information
Steve French committed Nov 13, 2008
1 parent c527c8a commit 3b79521
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 151 deletions.
2 changes: 1 addition & 1 deletion fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,7 @@ static int cifs_oplock_thread(void *dummyarg)
not bother sending an oplock release if session
to server still is disconnected since oplock
already released by the server in that case */
if (pTcon->tidStatus != CifsNeedReconnect) {
if (!pTcon->need_reconnect) {
rc = CIFSSMBLock(0, pTcon, netfid,
0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE,
Expand Down
5 changes: 5 additions & 0 deletions fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ struct cifs_cred {
*/

struct TCP_Server_Info {
struct list_head tcp_ses_list;
struct list_head smb_ses_list;
/* 15 character server name + 0x20 16th byte indicating type = srv */
char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];
Expand Down Expand Up @@ -195,6 +197,7 @@ struct cifsUidInfo {
*/
struct cifsSesInfo {
struct list_head cifsSessionList;
struct list_head tcon_list;
struct semaphore sesSem;
#if 0
struct cifsUidInfo *uidInfo; /* pointer to user info */
Expand All @@ -216,6 +219,7 @@ struct cifsSesInfo {
char userName[MAX_USERNAME_SIZE + 1];
char *domainName;
char *password;
bool need_reconnect:1; /* connection reset, uid now invalid */
};
/* no more than one of the following three session flags may be set */
#define CIFS_SES_NT4 1
Expand Down Expand Up @@ -288,6 +292,7 @@ struct cifsTconInfo {
bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol
for this mount even if server would support */
bool local_lease:1; /* check leases (only) on local system not remote */
bool need_reconnect:1; /* connection reset, tid now invalid */
/* BB add field for back pointer to sb struct(s)? */
};

Expand Down
40 changes: 22 additions & 18 deletions fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,10 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
/* need to prevent multiple threads trying to
simultaneously reconnect the same SMB session */
down(&tcon->ses->sesSem);
if (tcon->ses->status == CifsNeedReconnect)
if (tcon->ses->need_reconnect)
rc = cifs_setup_session(0, tcon->ses,
nls_codepage);
if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
if (!rc && (tcon->need_reconnect)) {
mark_open_files_invalid(tcon);
rc = CIFSTCon(0, tcon->ses, tcon->treeName,
tcon, nls_codepage);
Expand Down Expand Up @@ -295,7 +295,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
check for tcp and smb session status done differently
for those three - in the calling routine */
if (tcon) {
if (tcon->tidStatus == CifsExiting) {
if (tcon->need_reconnect) {
/* only tree disconnect, open, and write,
(and ulogoff which does not have tcon)
are allowed as we start force umount */
Expand Down Expand Up @@ -337,10 +337,10 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
/* need to prevent multiple threads trying to
simultaneously reconnect the same SMB session */
down(&tcon->ses->sesSem);
if (tcon->ses->status == CifsNeedReconnect)
if (tcon->ses->need_reconnect)
rc = cifs_setup_session(0, tcon->ses,
nls_codepage);
if (!rc && (tcon->tidStatus == CifsNeedReconnect)) {
if (!rc && (tcon->need_reconnect)) {
mark_open_files_invalid(tcon);
rc = CIFSTCon(0, tcon->ses, tcon->treeName,
tcon, nls_codepage);
Expand Down Expand Up @@ -759,7 +759,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)

/* No need to return error on this operation if tid invalidated and
closed on server already e.g. due to tcp session crashing */
if (tcon->tidStatus == CifsNeedReconnect) {
if (tcon->need_reconnect) {
up(&tcon->tconSem);
return 0;
}
Expand Down Expand Up @@ -806,32 +806,36 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
up(&ses->sesSem);
return -EBUSY;
}

if (ses->server == NULL)
return -EIO;

if (ses->need_reconnect)
goto session_already_dead; /* no need to send SMBlogoff if uid
already closed due to reconnect */
rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
if (rc) {
up(&ses->sesSem);
return rc;
}

if (ses->server) {
pSMB->hdr.Mid = GetNextMid(ses->server);
pSMB->hdr.Mid = GetNextMid(ses->server);

if (ses->server->secMode &
if (ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
}

pSMB->hdr.Uid = ses->Suid;

pSMB->AndXCommand = 0xFF;
rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
if (ses->server) {
atomic_dec(&ses->server->socketUseCount);
if (atomic_read(&ses->server->socketUseCount) == 0) {
spin_lock(&GlobalMid_Lock);
ses->server->tcpStatus = CifsExiting;
spin_unlock(&GlobalMid_Lock);
rc = -ESHUTDOWN;
}
session_already_dead:
atomic_dec(&ses->server->socketUseCount);
if (atomic_read(&ses->server->socketUseCount) == 0) {
spin_lock(&GlobalMid_Lock);
ses->server->tcpStatus = CifsExiting;
spin_unlock(&GlobalMid_Lock);
rc = -ESHUTDOWN;
}
up(&ses->sesSem);

Expand Down
Loading

0 comments on commit 3b79521

Please sign in to comment.