Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
f2ba8b3c
Commit
f2ba8b3c
authored
Jun 07, 2004
by
Steve French
Committed by
Steve French
Jun 07, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix race in updating tcpStatus field
parent
ff3c0388
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
46 additions
and
11 deletions
+46
-11
fs/cifs/AUTHORS
fs/cifs/AUTHORS
+2
-0
fs/cifs/CHANGES
fs/cifs/CHANGES
+2
-0
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+4
-1
fs/cifs/connect.c
fs/cifs/connect.c
+38
-10
No files found.
fs/cifs/AUTHORS
View file @
f2ba8b3c
...
...
@@ -32,3 +32,5 @@ Rene Scharfe, Martin Josefsson, Alexander Wild, Anthony Liguori,
Lars Muller, Urban Widmark, Massimiliano Ferrero, Howard Owen,
Olaf Kirch, Kieron Briggs and others.
And thanks to the IBM LTC and Power test teams and SuSE testers for
finding multiple bugs during excellent stress test runs.
fs/cifs/CHANGES
View file @
f2ba8b3c
...
...
@@ -3,6 +3,8 @@ Version 1.17
Update number of blocks in file so du command is happier (in Linux a fake
blocksize of 512 is required for calculating number of blocks in inode).
Fix prepare write of partial pages to read in data from server if possible.
Fix race on tcpStatus field between unmount and reconnection code, causing
cifsd process sometimes to hang around forever.
Version 1.16
------------
...
...
fs/cifs/cifssmb.c
View file @
f2ba8b3c
...
...
@@ -383,8 +383,11 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
smb_buffer_response
,
&
length
,
0
);
if
(
ses
->
server
)
{
atomic_dec
(
&
ses
->
server
->
socketUseCount
);
if
(
atomic_read
(
&
ses
->
server
->
socketUseCount
)
==
0
)
if
(
atomic_read
(
&
ses
->
server
->
socketUseCount
)
==
0
)
{
spin_lock
(
&
GlobalMid_Lock
);
ses
->
server
->
tcpStatus
=
CifsExiting
;
spin_unlock
(
&
GlobalMid_Lock
);
}
}
if
(
pSMB
)
cifs_buf_release
(
pSMB
);
...
...
fs/cifs/connect.c
View file @
f2ba8b3c
...
...
@@ -95,9 +95,15 @@ cifs_reconnect(struct TCP_Server_Info *server)
struct
cifsTconInfo
*
tcon
;
struct
mid_q_entry
*
mid_entry
;
if
(
server
->
tcpStatus
==
CifsExiting
)
spin_lock
(
&
GlobalMid_Lock
);
if
(
server
->
tcpStatus
==
CifsExiting
)
{
/* the demux thread will exit normally
next time through the loop */
spin_unlock
(
&
GlobalMid_Lock
);
return
rc
;
server
->
tcpStatus
=
CifsNeedReconnect
;
}
else
server
->
tcpStatus
=
CifsNeedReconnect
;
spin_unlock
(
&
GlobalMid_Lock
);
server
->
maxBuf
=
0
;
cFYI
(
1
,
(
"Reconnecting tcp session "
));
...
...
@@ -164,7 +170,10 @@ cifs_reconnect(struct TCP_Server_Info *server)
schedule_timeout
(
3
*
HZ
);
}
else
{
atomic_inc
(
&
tcpSesReconnectCount
);
server
->
tcpStatus
=
CifsGood
;
spin_lock
(
&
GlobalMid_Lock
);
if
(
server
->
tcpStatus
!=
CifsExiting
)
server
->
tcpStatus
=
CifsGood
;
spin_unlock
(
&
GlobalMid_Lock
);
atomic_set
(
&
server
->
inFlight
,
0
);
wake_up
(
&
server
->
response_q
);
}
...
...
@@ -243,12 +252,14 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
/* some servers kill tcp session rather than returning
smb negprot error in which case reconnecting here is
not going to help - return error to mount */
spin_lock
(
&
GlobalMid_Lock
);
server
->
tcpStatus
=
CifsExiting
;
spin_unlock
(
&
GlobalMid_Lock
);
wake_up
(
&
server
->
response_q
);
break
;
}
cFYI
(
1
,(
"Reconnecting after unexpected
rcvmsg error "
));
cFYI
(
1
,(
"Reconnecting after unexpected
peek error %d"
,
length
));
cifs_reconnect
(
server
);
csocket
=
server
->
ssocket
;
wake_up
(
&
server
->
response_q
);
...
...
@@ -280,7 +291,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
/* if nack on negprot (rather than
ret of smb negprot error) reconnecting
not going to help, ret error to mount */
spin_lock
(
&
GlobalMid_Lock
);
server
->
tcpStatus
=
CifsExiting
;
spin_unlock
(
&
GlobalMid_Lock
);
/* wake up thread doing negprot */
wake_up
(
&
server
->
response_q
);
break
;
...
...
@@ -391,7 +404,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
}
}
}
spin_lock
(
&
GlobalMid_Lock
);
server
->
tcpStatus
=
CifsExiting
;
spin_unlock
(
&
GlobalMid_Lock
);
atomic_set
(
&
server
->
inFlight
,
0
);
/* Although there should not be any requests blocked on
this queue it can not hurt to be paranoid and try to wake up requests
...
...
@@ -1226,6 +1241,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
init_waitqueue_head
(
&
srvTcp
->
response_q
);
init_waitqueue_head
(
&
srvTcp
->
request_q
);
INIT_LIST_HEAD
(
&
srvTcp
->
pending_mid_q
);
/* at this point we are the only ones with the pointer
to the struct since the kernel thread not created yet
so no need to spinlock this init of tcpStatus */
srvTcp
->
tcpStatus
=
CifsNew
;
init_MUTEX
(
&
srvTcp
->
tcpSem
);
kernel_thread
((
void
*
)(
void
*
)
cifs_demultiplex_thread
,
srvTcp
,
...
...
@@ -1342,9 +1360,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
/* on error free sesinfo and tcon struct if needed */
if
(
rc
)
{
if
(
atomic_read
(
&
srvTcp
->
socketUseCount
)
==
0
)
srvTcp
->
tcpStatus
=
CifsExiting
;
/* If find_unc succeeded then rc == 0 so we can not end */
if
(
atomic_read
(
&
srvTcp
->
socketUseCount
)
==
0
)
{
spin_lock
(
&
GlobalMid_Lock
);
srvTcp
->
tcpStatus
=
CifsExiting
;
spin_unlock
(
&
GlobalMid_Lock
);
}
/* If find_unc succeeded then rc == 0 so we can not end */
if
(
tcon
)
/* up here accidently freeing someone elses tcon struct */
tconInfoFree
(
tcon
);
if
(
existingCifsSes
==
0
)
{
...
...
@@ -2791,7 +2812,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
char
ntlm_session_key
[
CIFS_SESSION_KEY_SIZE
];
int
ntlmv2_flag
=
FALSE
;
/* what if server changes its buffer size after dropping the session? */
/* what if server changes its buffer size after dropping the session? */
if
(
pSesInfo
->
server
->
maxBuf
==
0
)
/* no need to send on reconnect */
{
rc
=
CIFSSMBNegotiate
(
xid
,
pSesInfo
);
if
(
rc
==
-
EAGAIN
)
/* retry only once on 1st time connection */
{
...
...
@@ -2799,8 +2820,15 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
if
(
rc
==
-
EAGAIN
)
rc
=
-
EHOSTDOWN
;
}
if
(
rc
==
0
)
pSesInfo
->
server
->
tcpStatus
=
CifsGood
;
if
(
rc
==
0
)
{
spin_lock
(
&
GlobalMid_Lock
);
if
(
pSesInfo
->
server
->
tcpStatus
!=
CifsExiting
)
pSesInfo
->
server
->
tcpStatus
=
CifsGood
;
else
rc
=
-
EHOSTDOWN
;
spin_unlock
(
&
GlobalMid_Lock
);
}
}
if
(
!
rc
)
{
pSesInfo
->
capabilities
=
pSesInfo
->
server
->
capabilities
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment