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
19c48ffe
Commit
19c48ffe
authored
Nov 29, 2004
by
Steve French
Committed by
Steve French
Nov 29, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[CIFS] cifs readdir rewrite fix resume key handling
Signed-off-by: Steve French (sfrench@us.ibm.com)
parent
a64a54eb
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
100 additions
and
23 deletions
+100
-23
fs/cifs/cifsglob.h
fs/cifs/cifsglob.h
+4
-2
fs/cifs/cifspdu.h
fs/cifs/cifspdu.h
+1
-1
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+23
-14
fs/cifs/file.c
fs/cifs/file.c
+3
-3
fs/cifs/readdir.c
fs/cifs/readdir.c
+69
-3
No files found.
fs/cifs/cifsglob.h
View file @
19c48ffe
...
...
@@ -244,8 +244,11 @@ struct cifs_search_info {
loff_t
index_of_last_entry
;
__u16
entries_in_buffer
;
__u16
info_level
;
__u32
resume_key
;
char
*
ntwrk_buf_start
;
char
*
srch_entries_start
;
char
*
presume_name
;
unsigned
int
resume_name_len
;
unsigned
endOfSearch
:
1
;
unsigned
emptyDir
:
1
;
unsigned
unicode
:
1
;
...
...
@@ -265,8 +268,7 @@ struct cifsFileInfo {
unsigned
invalidHandle
:
1
;
/* file closed via session abend */
struct
semaphore
fh_sem
;
/* prevents reopen race after dead ses*/
char
*
search_resume_name
;
/* BB removeme BB */
unsigned
int
resume_name_length
;
/* BB removeme BB */
__u32
resume_key
;
/* BB removeme BB */
unsigned
int
resume_name_length
;
/* BB removeme - field renamed and moved BB */
struct
cifs_search_info
srch_inf
;
};
...
...
fs/cifs/cifspdu.h
View file @
19c48ffe
...
...
@@ -1691,7 +1691,7 @@ struct file_attrib_tag {
typedef
struct
{
__le32
NextEntryOffset
;
__
le32
ResumeKey
;
__
u32
ResumeKey
;
/* as with FileIndex - no need to convert */
__le64
EndOfFile
;
__le64
NumOfBytes
;
__le64
LastStatusChange
;
/*SNIA specs DCE time for the 3 time fields */
...
...
fs/cifs/cifssmb.c
View file @
19c48ffe
...
...
@@ -2377,10 +2377,13 @@ int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
T2_FNEXT_RSP_PARMS
*
parms
;
char
*
response_data
;
int
rc
=
0
;
int
bytes_returned
;
int
bytes_returned
,
name_len
;
__u16
params
,
byte_count
;
cFYI
(
1
,
(
"In FindNext"
));
cFYI
(
1
,
(
"In FindNext2"
));
if
(
psrch_inf
->
endOfSearch
==
TRUE
)
return
-
ENOENT
;
rc
=
smb_init
(
SMB_COM_TRANSACTION2
,
15
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
...
...
@@ -2418,16 +2421,19 @@ int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
psrch_inf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
} */
pSMB
->
InformationLevel
=
cpu_to_le16
(
psrch_inf
->
info_level
);
pSMB
->
ResumeKey
=
0
;
/* BB fixme add resume_key BB */
pSMB
->
ResumeKey
=
psrch_inf
->
resume_key
;
pSMB
->
SearchFlags
=
cpu_to_le16
(
CIFS_SEARCH_CLOSE_AT_END
|
CIFS_SEARCH_RETURN_RESUME
);
/* BB fixme check to make sure we do not cross end of smb with long resume name */
/* if(name_len < CIFS_MAX_MSGSIZE) {
memcpy(pSMB->ResumeFileName, resume_file_name, name_len);
byte_count += name_len; */
/* BB fixme - add resume file name processing BB */
/* }
params += name_len; */
name_len
=
psrch_inf
->
resume_name_len
;
params
+=
name_len
;
if
(
name_len
<
PATH_MAX
)
{
memcpy
(
pSMB
->
ResumeFileName
,
psrch_inf
->
presume_name
,
name_len
);
byte_count
+=
name_len
;
}
else
{
rc
=
-
EINVAL
;
goto
FNext2_err_exit
;
}
byte_count
=
params
+
1
/* pad */
;
pSMB
->
TotalParameterCount
=
cpu_to_le16
(
params
);
pSMB
->
ParameterCount
=
pSMB
->
TotalParameterCount
;
...
...
@@ -2438,9 +2444,10 @@ int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
(
struct
smb_hdr
*
)
pSMBr
,
&
bytes_returned
,
0
);
if
(
rc
)
{
if
(
rc
==
-
EBADF
)
if
(
rc
==
-
EBADF
)
{
psrch_inf
->
endOfSearch
=
TRUE
;
rc
=
0
;
/* search probably was closed at end of search above */
else
}
else
cFYI
(
1
,
(
"FindNext returned = %d"
,
rc
));
}
else
{
/* decode response */
rc
=
validate_t2
((
struct
smb_t2_rsp
*
)
pSMBr
);
...
...
@@ -2451,9 +2458,11 @@ int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
psrch_inf
->
unicode
=
TRUE
;
else
psrch_inf
->
unicode
=
FALSE
;
response_data
=
(
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
le16_to_cpu
(
pSMBr
->
t2
.
ParameterOffset
);
parms
=
(
T2_FNEXT_RSP_PARMS
*
)
response_data
;
response_data
=
(
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
le16_to_cpu
(
pSMBr
->
t2
.
DataOffset
);
parms
=
(
T2_FNEXT_RSP_PARMS
*
)
response_data
;
cifs_buf_release
(
psrch_inf
->
ntwrk_buf_start
);
psrch_inf
->
srch_entries_start
=
response_data
;
psrch_inf
->
ntwrk_buf_start
=
(
char
*
)
pSMB
;
...
...
@@ -2477,7 +2486,7 @@ int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
FNext2_err_exit:
if
((
rc
!=
0
)
&&
pSMB
)
cifs_buf_release
(
pSMB
);
...
...
@@ -2543,7 +2552,7 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
pSMB
->
SearchFlags
=
cpu_to_le16
(
CIFS_SEARCH_CLOSE_AT_END
|
CIFS_SEARCH_RETURN_RESUME
);
/* BB add check to make sure we do not cross end of smb */
if
(
name_len
<
CIFS_MAX_MSGSIZE
)
{
if
(
name_len
<
PATH_MAX
)
{
memcpy
(
pSMB
->
ResumeFileName
,
resume_file_name
,
name_len
);
byte_count
+=
name_len
;
}
...
...
fs/cifs/file.c
View file @
19c48ffe
...
...
@@ -1834,7 +1834,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
break
;
}
/* Offset of resume key same for levels 257 and 514 */
cifsFile
->
resume_key
=
lastFindData
->
FileIndex
;
cifsFile
->
srch_inf
.
resume_key
=
lastFindData
->
FileIndex
;
if
(
UnixSearch
==
FALSE
)
{
cifsFile
->
resume_name_length
=
le32_to_cpu
(
lastFindData
->
FileNameLength
);
...
...
@@ -2000,7 +2000,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
&
findNextParms
,
searchHandle
,
cifsFile
->
search_resume_name
,
cifsFile
->
resume_name_length
,
cifsFile
->
resume_key
,
cifsFile
->
srch_inf
.
resume_key
,
&
Unicode
,
&
UnixSearch
);
cFYI
(
1
,(
"Count: %d End: %d "
,
le16_to_cpu
(
findNextParms
.
SearchCount
),
...
...
@@ -2017,7 +2017,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
break
;
}
/* Offset of resume key same for levels 257 and 514 */
cifsFile
->
resume_key
=
lastFindData
->
FileIndex
;
cifsFile
->
srch_inf
.
resume_key
=
lastFindData
->
FileIndex
;
if
(
UnixSearch
==
FALSE
)
{
cifsFile
->
resume_name_length
=
...
...
fs/cifs/readdir.c
View file @
19c48ffe
...
...
@@ -91,7 +91,8 @@ static int initiate_cifs_search(const int xid, struct file * file)
}
cifsFile
=
(
struct
cifsFileInfo
*
)
file
->
private_data
;
cifsFile
->
invalidHandle
=
TRUE
;
cifsFile
->
srch_inf
.
endOfSearch
=
FALSE
;
cifs_sb
=
CIFS_SB
(
file
->
f_dentry
->
d_sb
);
if
(
cifs_sb
==
NULL
)
return
-
EINVAL
;
...
...
@@ -124,6 +125,8 @@ static int initiate_cifs_search(const int xid, struct file * file)
rc
=
CIFSFindFirst2
(
xid
,
pTcon
,
full_path
,
cifs_sb
->
local_nls
,
&
cifsFile
->
netfid
,
&
cifsFile
->
srch_inf
);
if
(
rc
==
0
)
cifsFile
->
invalidHandle
=
FALSE
;
if
(
full_path
)
kfree
(
full_path
);
return
rc
;
...
...
@@ -279,6 +282,8 @@ if(cifsFile->srch_inf.endOfSearch) {
(
rc
==
0
)
&&
(
cifsFile
->
srch_inf
.
endOfSearch
==
FALSE
)){
cFYI
(
1
,(
"calling findnext2"
));
rc
=
CIFSFindNext2
(
xid
,
pTcon
,
cifsFile
->
netfid
,
&
cifsFile
->
srch_inf
);
if
(
rc
)
return
-
ENOENT
;
}
if
(
index_to_find
<
cifsFile
->
srch_inf
.
index_of_last_entry
)
{
/* we found the buffer that contains the entry */
...
...
@@ -314,7 +319,7 @@ if(cifsFile->srch_inf.endOfSearch) {
*
ppCurrentEntry
=
current_entry
;
}
else
{
cFYI
(
1
,(
"index not in buffer - could not findnext into it"
));
return
-
ENOENT
;
/* BB fixme - return 0? */
return
0
;
}
if
(
pos_in_buf
>=
cifsFile
->
srch_inf
.
entries_in_buffer
)
{
...
...
@@ -455,6 +460,61 @@ cifs_filldir2(char * pfindEntry, struct file *file,
return
rc
;
}
int
cifs_save_resume_key
(
const
char
*
current_entry
,
struct
cifsFileInfo
*
cifsFile
)
{
int
rc
=
0
;
unsigned
int
len
=
0
;
__u16
level
;
char
*
filename
;
if
((
cifsFile
==
NULL
)
||
(
current_entry
==
NULL
))
return
-
EINVAL
;
level
=
cifsFile
->
srch_inf
.
info_level
;
if
(
level
==
SMB_FIND_FILE_UNIX
)
{
FILE_UNIX_INFO
*
pFindData
=
(
FILE_UNIX_INFO
*
)
current_entry
;
filename
=
&
pFindData
->
FileName
[
0
];
if
(
cifsFile
->
srch_inf
.
unicode
)
{
len
=
cifs_unicode_bytelen
(
filename
);
}
else
{
/* BB should we make this strnlen of PATH_MAX? */
len
=
strnlen
(
filename
,
PATH_MAX
);
}
cifsFile
->
srch_inf
.
resume_key
=
pFindData
->
ResumeKey
;
}
else
if
(
level
==
SMB_FIND_FILE_DIRECTORY_INFO
)
{
FILE_DIRECTORY_INFO
*
pFindData
=
(
FILE_DIRECTORY_INFO
*
)
current_entry
;
filename
=
&
pFindData
->
FileName
[
0
];
len
=
pFindData
->
FileNameLength
;
cifsFile
->
srch_inf
.
resume_key
=
pFindData
->
FileIndex
;
}
else
if
(
level
==
SMB_FIND_FILE_FULL_DIRECTORY_INFO
)
{
FILE_FULL_DIRECTORY_INFO
*
pFindData
=
(
FILE_FULL_DIRECTORY_INFO
*
)
current_entry
;
filename
=
&
pFindData
->
FileName
[
0
];
len
=
pFindData
->
FileNameLength
;
cifsFile
->
srch_inf
.
resume_key
=
pFindData
->
FileIndex
;
}
else
if
(
level
==
SMB_FIND_FILE_ID_FULL_DIR_INFO
)
{
SEARCH_ID_FULL_DIR_INFO
*
pFindData
=
(
SEARCH_ID_FULL_DIR_INFO
*
)
current_entry
;
filename
=
&
pFindData
->
FileName
[
0
];
len
=
pFindData
->
FileNameLength
;
cifsFile
->
srch_inf
.
resume_key
=
pFindData
->
FileIndex
;
}
else
if
(
level
==
SMB_FIND_FILE_BOTH_DIRECTORY_INFO
)
{
FILE_BOTH_DIRECTORY_INFO
*
pFindData
=
(
FILE_BOTH_DIRECTORY_INFO
*
)
current_entry
;
filename
=
&
pFindData
->
FileName
[
0
];
len
=
pFindData
->
FileNameLength
;
cifsFile
->
srch_inf
.
resume_key
=
pFindData
->
FileIndex
;
}
else
{
cFYI
(
1
,(
"Unknown findfirst level %d"
,
level
));
return
-
EINVAL
;
}
cifsFile
->
srch_inf
.
resume_name_len
=
len
;
cifsFile
->
srch_inf
.
presume_name
=
filename
;
return
rc
;
}
int
cifs_readdir2
(
struct
file
*
file
,
void
*
direntry
,
filldir_t
filldir
)
{
...
...
@@ -577,7 +637,13 @@ cFYI(1,("readdir2 pos: %lld",file->f_pos)); /* BB removeme BB */
rc
=
cifs_filldir2
(
current_entry
,
file
,
filldir
,
direntry
,
tmp_buf
);
file
->
f_pos
++
;
current_entry
=
nxt_dir_entry
(
current_entry
,
end_of_smb
);
if
(
file
->
f_pos
==
cifsFile
->
srch_inf
.
index_of_last_entry
)
{
cFYI
(
1
,(
"last entry in buf at pos %lld %s"
,
file
->
f_pos
,
tmp_buf
));
/* BB removeme BB */
/* BB fixme save resume key BB */
cifs_save_resume_key
(
current_entry
,
cifsFile
);
break
;
}
else
current_entry
=
nxt_dir_entry
(
current_entry
,
end_of_smb
);
}
if
(
tmp_buf
!=
NULL
)
kfree
(
tmp_buf
);
...
...
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