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
nexedi
linux
Commits
1915ad84
Commit
1915ad84
authored
Nov 11, 2003
by
Steve French
Committed by
Steve French
Nov 11, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
have to reconnect open files safely, one at a time, as needed
parent
c0426ae3
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
122 additions
and
57 deletions
+122
-57
fs/cifs/cifsglob.h
fs/cifs/cifsglob.h
+1
-0
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+79
-42
fs/cifs/connect.c
fs/cifs/connect.c
+3
-2
fs/cifs/file.c
fs/cifs/file.c
+15
-3
fs/cifs/inode.c
fs/cifs/inode.c
+24
-7
fs/cifs/transport.c
fs/cifs/transport.c
+0
-3
No files found.
fs/cifs/cifsglob.h
View file @
1915ad84
...
...
@@ -211,6 +211,7 @@ struct cifsFileInfo {
struct
inode
*
pInode
;
/* needed for oplock break */
int
endOfSearch
:
1
;
/* we have reached end of search */
int
closePend
:
1
;
/* file is marked to close */
int
reopenPend
:
1
;
/* reopen of file in progress */
int
emptyDir
:
1
;
int
invalidHandle
:
1
;
/* file closed via session abend */
char
*
search_resume_name
;
...
...
fs/cifs/cifssmb.c
View file @
1915ad84
...
...
@@ -21,7 +21,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
/* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
/* These are mostly routines that operate on a pathname, or on a tree id */
/* (mounted volume), but there are eight handle based routines which must be */
/* treated slightly different for reconnection purposes since we never want */
/* to reuse a stale file handle and the caller knows the file handle */
#include <linux/fs.h>
#include <linux/kernel.h>
...
...
@@ -49,21 +53,45 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
{
int
rc
=
0
;
if
(
tcon
&&
(
tcon
->
tidStatus
==
CifsNeedReconnect
))
{
if
(
tcon
->
ses
)
{
/* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
check for tcp and smb session status done differently
for those three - in the calling routine */
if
(
tcon
)
{
if
((
tcon
->
ses
)
&&
(
tcon
->
ses
->
server
)){
if
(
tcon
->
ses
->
server
->
tcpStatus
==
CifsNeedReconnect
)
{
/* Give Demultiplex thread up to 10 seconds to
reconnect, should be greater than cifs socket
timeout which is 7 seconds */
wait_event_interruptible_timeout
(
tcon
->
ses
->
server
->
response_q
,
(
tcon
->
ses
->
server
->
tcpStatus
==
CifsGood
),
10
*
HZ
);
if
(
tcon
->
ses
->
server
->
tcpStatus
==
CifsNeedReconnect
)
return
-
EHOSTDOWN
;
}
/* need to prevent multiple threads trying to
simultaneously reconnect the same SMB session */
down
(
&
tcon
->
ses
->
sesSem
);
struct
nls_table
*
nls_codepage
=
load_nls_default
();
if
(
tcon
->
ses
->
status
==
CifsNeedReconnect
)
rc
=
setup_session
(
0
,
tcon
->
ses
,
nls_codepage
);
if
(
!
rc
)
{
if
(
!
rc
&&
(
tcon
->
tidStatus
==
CifsNeedReconnect
)
)
{
rc
=
CIFSTCon
(
0
,
tcon
->
ses
,
tcon
->
treeName
,
tcon
,
nls_codepage
);
up
(
&
tcon
->
ses
->
sesSem
);
cFYI
(
1
,
(
"reconnect tcon rc = %d"
,
rc
));
if
(
!
rc
)
reopen_files
(
tcon
,
nls_codepage
);
/* Remove call to reopen files here -
it is safer (and faster) to reopen
files as needed in read and write */
/* if(!rc)
reopen_files(tcon,nls_codepage);*/
}
else
{
up
(
&
tcon
->
ses
->
sesSem
);
}
unload_nls
(
nls_codepage
);
}
else
rc
=
-
EIO
;
}
else
{
return
-
EIO
;
}
}
if
(
rc
)
return
rc
;
...
...
@@ -209,7 +237,6 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
* (and inside session disconnect we should check if tcp socket needs
* to be freed and kernel thread woken up).
*/
tdisRetry:
if
(
tcon
)
down
(
&
tcon
->
tconSem
);
else
...
...
@@ -221,12 +248,19 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
return
-
EBUSY
;
}
/* 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
)
{
up
(
&
tcon
->
tconSem
);
return
0
;
}
/* BB remove (from server) list of shares - but with smp safety BB */
/* BB is ses active - do we need to check here - but how? BB */
if
((
tcon
->
ses
==
0
)
||
(
tcon
->
ses
->
server
==
0
))
{
up
(
&
tcon
->
tconSem
);
return
-
EIO
;
}
if
((
tcon
->
ses
==
0
)
||
(
tcon
->
ses
->
server
==
0
))
{
up
(
&
tcon
->
tconSem
);
return
-
EIO
;
}
rc
=
smb_init
(
SMB_COM_TREE_DISCONNECT
,
0
,
tcon
,
(
void
**
)
&
smb_buffer
,
(
void
**
)
&
smb_buffer_response
);
...
...
@@ -242,8 +276,12 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
if
(
smb_buffer
)
buf_release
(
smb_buffer
);
up
(
&
tcon
->
tconSem
);
/* No need to return error on this operation if tid invalidated and
closed on server already e.g. due to tcp session crashing */
if
(
rc
==
-
EAGAIN
)
goto
tdisRetry
;
rc
=
0
;
return
rc
;
}
...
...
@@ -256,9 +294,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
int
length
;
cFYI
(
1
,
(
"In SMBLogoff for session disconnect"
));
LogoffRetry:
if
(
ses
)
down
(
&
ses
->
sesSem
);
/* check this sem more places */
down
(
&
ses
->
sesSem
);
else
return
-
EIO
;
...
...
@@ -292,8 +329,12 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
if
(
pSMB
)
buf_release
(
pSMB
);
up
(
&
ses
->
sesSem
);
/* if session dead then we do not need to do ulogoff,
since server closed smb session, no sense reporting
error */
if
(
rc
==
-
EAGAIN
)
goto
LogoffRetry
;
rc
=
0
;
return
rc
;
}
...
...
@@ -537,7 +578,6 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
char
*
pReadData
=
NULL
;
int
bytes_returned
;
readRetry:
*
nbytes
=
0
;
rc
=
smb_init
(
SMB_COM_READ_ANDX
,
12
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
...
...
@@ -588,9 +628,9 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
else
*
buf
=
(
char
*
)
pSMB
;
}
if
(
rc
==
-
EAGAIN
)
goto
readRetry
;
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return
rc
;
}
...
...
@@ -605,7 +645,6 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
WRITE_RSP
*
pSMBr
=
NULL
;
int
bytes_returned
;
writeRetry:
rc
=
smb_init
(
SMB_COM_WRITE_ANDX
,
14
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
if
(
rc
)
...
...
@@ -646,8 +685,8 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
if
(
pSMB
)
buf_release
(
pSMB
);
if
(
rc
==
-
EAGAIN
)
goto
writeRetry
;
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return
rc
;
}
...
...
@@ -666,7 +705,6 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
__u64
temp
;
cFYI
(
1
,
(
"In CIFSSMBLock"
));
lockRetry:
rc
=
smb_init
(
SMB_COM_LOCKING_ANDX
,
8
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
if
(
rc
)
...
...
@@ -701,8 +739,9 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
}
if
(
pSMB
)
buf_release
(
pSMB
);
if
(
rc
==
-
EAGAIN
)
goto
lockRetry
;
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return
rc
;
}
...
...
@@ -732,9 +771,9 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
if
(
pSMB
)
buf_release
(
pSMB
);
/*
file will be closed on server if session is dead
*/
/*
Since session is dead, file will be closed on server already
*/
if
(
rc
==
-
EAGAIN
)
rc
=
-
EHOSTDOWN
;
/* should we fake success? */
rc
=
0
;
return
rc
;
}
...
...
@@ -822,7 +861,6 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
int
len_of_str
;
cFYI
(
1
,
(
"Rename to File by handle"
));
renameOpenFileRetry:
rc
=
smb_init
(
SMB_COM_TRANSACTION2
,
15
,
pTcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
if
(
rc
)
...
...
@@ -880,8 +918,8 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
if
(
pSMB
)
buf_release
(
pSMB
);
if
(
rc
==
-
EAGAIN
)
goto
renameOpenFileRetry
;
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return
rc
;
}
...
...
@@ -1249,7 +1287,6 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
struct
smb_com_transaction_ioctl_rsp
*
pSMBr
;
cFYI
(
1
,
(
"In Windows reparse style QueryLink for path %s"
,
searchName
));
queryReparseLinkInfoRetry:
rc
=
smb_init
(
SMB_COM_NT_TRANSACT
,
23
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
if
(
rc
)
...
...
@@ -1314,8 +1351,9 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
}
if
(
pSMB
)
buf_release
(
pSMB
);
if
(
rc
==
-
EAGAIN
)
goto
queryReparseLinkInfoRetry
;
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return
rc
;
}
...
...
@@ -1686,7 +1724,6 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
cFYI
(
1
,
(
"In FindNext"
));
findNextRetry:
if
(
resume_file_name
==
NULL
)
{
return
-
EIO
;
}
...
...
@@ -1771,8 +1808,8 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
if
(
pSMB
)
buf_release
(
pSMB
);
if
(
rc
==
-
EAGAIN
)
goto
findNextRetry
;
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return
rc
;
}
...
...
@@ -1784,8 +1821,8 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
FINDCLOSE_REQ
*
pSMB
=
NULL
;
CLOSE_RSP
*
pSMBr
=
NULL
;
int
bytes_returned
;
cFYI
(
1
,
(
"In CIFSSMBFindClose"
));
findCloseRetry:
rc
=
smb_init
(
SMB_COM_FIND_CLOSE2
,
1
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
if
(
rc
)
...
...
@@ -1801,8 +1838,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
if
(
pSMB
)
buf_release
(
pSMB
);
/* Since session is dead, search handle closed on server already */
if
(
rc
==
-
EAGAIN
)
goto
findCloseRetry
;
rc
=
0
;
return
rc
;
}
...
...
@@ -2363,7 +2401,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
__u32
tmp
;
cFYI
(
1
,
(
"SetFileSize (via SetFileInfo)"
));
SetFileSizeRetry:
rc
=
smb_init
(
SMB_COM_TRANSACTION2
,
15
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
if
(
rc
)
...
...
@@ -2434,8 +2471,8 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
if
(
pSMB
)
buf_release
(
pSMB
);
if
(
rc
==
-
EAGAIN
)
goto
SetFileSizeRetry
;
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return
rc
;
}
...
...
fs/cifs/connect.c
View file @
1915ad84
...
...
@@ -821,7 +821,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket)
/* Eventually check for other socket options to change from
the default. sock_setsockopt not used because it expects
user space buffer */
(
*
csocket
)
->
sk
->
sk_rcvtimeo
=
8
*
HZ
;
(
*
csocket
)
->
sk
->
sk_rcvtimeo
=
7
*
HZ
;
return
rc
;
}
...
...
@@ -1002,8 +1002,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
strncpy
(
pSesInfo
->
domainName
,
volume_info
.
domainname
,
MAX_USERNAME_SIZE
);
pSesInfo
->
linux_uid
=
volume_info
.
linux_uid
;
down
(
&
pSesInfo
->
sesSem
);
rc
=
setup_session
(
xid
,
pSesInfo
,
cifs_sb
->
local_nls
);
up
(
&
pSesInfo
->
sesSem
);
if
(
!
rc
)
atomic_inc
(
&
srvTcp
->
socketUseCount
);
}
...
...
fs/cifs/file.c
View file @
1915ad84
...
...
@@ -740,10 +740,22 @@ cifs_commit_write(struct file *file, struct page *page, unsigned offset,
if
(
file
->
private_data
==
NULL
)
{
rc
=
-
EBADF
;
}
else
{
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
open_file
=
(
struct
cifsFileInfo
*
)
file
->
private_data
;
rc
=
CIFSSMBSetFileSize
(
xid
,
cifs_sb
->
tcon
,
position
,
open_file
->
netfid
,
open_file
->
pid
,
FALSE
);
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
rc
=
-
EAGAIN
;
while
(
rc
==
-
EAGAIN
)
{
if
((
open_file
->
invalidHandle
==
TRUE
)
&&
(
open_file
->
closePend
==
FALSE
))
{
open_file
->
reopenPend
=
TRUE
;
rc
=
cifs_reopen_file
(
file
->
f_dentry
->
d_inode
,
file
);
open_file
->
reopenPend
=
FALSE
;
}
if
(
rc
!=
0
)
break
;
rc
=
CIFSSMBSetFileSize
(
xid
,
cifs_sb
->
tcon
,
position
,
open_file
->
netfid
,
open_file
->
pid
,
FALSE
);
}
cFYI
(
1
,(
" SetEOF (commit write) rc = %d"
,
rc
));
}
}
...
...
fs/cifs/inode.c
View file @
1915ad84
...
...
@@ -665,7 +665,12 @@ cifs_truncate_file(struct inode *inode)
if
(
rc
==
0
)
{
FreeXid
(
xid
);
return
;
}
}
/* Do not need reopen and retry on EAGAIN since we will
retry by pathname below */
if
(
rc
==
-
EAGAIN
)
rc
=
-
EHOSTDOWN
;
break
;
/* now that we found one valid file handle no
sense continuing to loop trying others */
}
...
...
@@ -767,19 +772,31 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
if
((
open_file
->
pfile
)
&&
((
open_file
->
pfile
->
f_flags
&
O_RDWR
)
||
(
open_file
->
pfile
->
f_flags
&
O_WRONLY
)))
{
read_unlock
(
&
GlobalSMBSeslock
);
found
=
TRUE
;
rc
=
CIFSSMBSetFileSize
(
xid
,
pTcon
,
attrs
->
ia_size
,
open_file
->
netfid
,
open_file
->
pid
,
FALSE
);
cFYI
(
1
,(
"SetFileSize by handle (setattrs) rc = %d"
,
rc
));
break
;
/* now that we found one valid file handle no
if
(
open_file
->
invalidHandle
==
FALSE
)
{
/* we found a valid, writeable network file
handle to use to try to set the file size */
__u16
nfid
=
open_file
->
netfid
;
__u32
npid
=
open_file
->
pid
;
read_unlock
(
&
GlobalSMBSeslock
);
found
=
TRUE
;
rc
=
CIFSSMBSetFileSize
(
xid
,
pTcon
,
attrs
->
ia_size
,
nfid
,
npid
,
FALSE
);
cFYI
(
1
,(
"SetFileSize by handle (setattrs) rc = %d"
,
rc
));
/* Do not need reopen and retry on EAGAIN since we will
retry by pathname below */
break
;
/* now that we found one valid file handle no
sense continuing to loop trying others */
}
}
}
if
(
found
==
FALSE
)
read_unlock
(
&
GlobalSMBSeslock
);
if
(
rc
!=
0
)
{
/* Set file size by pathname rather than by handle either
because no valid, writeable file handle for it was found or
because there was an error setting it by handle */
rc
=
CIFSSMBSetEOF
(
xid
,
pTcon
,
full_path
,
attrs
->
ia_size
,
FALSE
,
cifs_sb
->
local_nls
);
cFYI
(
1
,(
" SetEOF by path (setattrs) rc = %d"
,
rc
));
...
...
fs/cifs/transport.c
View file @
1915ad84
...
...
@@ -184,9 +184,6 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
return
-
ENOENT
;
}
else
if
(
ses
->
server
->
tcpStatus
==
CifsNeedReconnect
)
{
cFYI
(
1
,(
"tcp session dead - return to caller to retry"
));
/* Give Demultiplex thread up to 10 seconds to reconnect */
wait_event_interruptible_timeout
(
ses
->
server
->
response_q
,
(
ses
->
server
->
tcpStatus
==
CifsGood
),
10
*
HZ
);
return
-
EAGAIN
;
}
else
if
(
ses
->
status
!=
CifsGood
)
{
/* check if SMB session is bad because we are setting it up */
...
...
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