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
6b88c695
Commit
6b88c695
authored
Nov 21, 2004
by
Steve French
Committed by
Steve French
Nov 21, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[CIFS] cifs readdir changes part 7
Signed-off-by: Steve French (sfrench@us.ibm.com)
parent
df05c295
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
144 additions
and
16 deletions
+144
-16
fs/cifs/cifsglob.h
fs/cifs/cifsglob.h
+2
-2
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+5
-5
fs/cifs/readdir.c
fs/cifs/readdir.c
+137
-9
No files found.
fs/cifs/cifsglob.h
View file @
6b88c695
...
...
@@ -244,8 +244,8 @@ struct cifs_search_info {
loff_t
index_of_last_entry
;
__u16
entries_in_buffer
;
unsigned
info_level
;
char
*
start_of_network_buffer
;
char
*
s
tart_of_search_entries
;
char
*
ntwrk_buf_start
;
char
*
s
rch_entries_start
;
unsigned
endOfSearch
:
1
;
unsigned
emptyDir
:
1
;
unsigned
unicode
:
1
;
...
...
fs/cifs/cifssmb.c
View file @
6b88c695
...
...
@@ -2138,8 +2138,8 @@ CIFSFindFirst2(const int xid, struct cifsTconInfo *tcon,
else
psrch_inf
->
unicode
=
FALSE
;
psrch_inf
->
start_of_network_buffer
=
(
char
*
)
pSMBr
;
psrch_inf
->
s
tart_of_search_entries
=
psrch_inf
->
ntwrk_buf_start
=
(
char
*
)
pSMBr
;
psrch_inf
->
s
rch_entries_start
=
(
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
le16_to_cpu
(
pSMBr
->
t2
.
DataOffset
);
...
...
@@ -2248,9 +2248,9 @@ int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
response_data
=
(
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
le16_to_cpu
(
pSMBr
->
t2
.
DataOffset
);
parms
=
(
T2_FNEXT_RSP_PARMS
*
)
response_data
;
cifs_buf_release
(
psrch_inf
->
start_of_network_buffer
);
psrch_inf
->
s
tart_of_search_entries
=
response_data
;
psrch_inf
->
start_of_network_buffer
=
(
char
*
)
pSMB
;
cifs_buf_release
(
psrch_inf
->
ntwrk_buf_start
);
psrch_inf
->
s
rch_entries_start
=
response_data
;
psrch_inf
->
ntwrk_buf_start
=
(
char
*
)
pSMB
;
if
(
parms
->
EndofSearch
)
psrch_inf
->
endOfSearch
=
TRUE
;
else
...
...
fs/cifs/readdir.c
View file @
6b88c695
...
...
@@ -70,11 +70,117 @@ static int initiate_cifs_search(const int xid, struct file * file, char * full_p
rc
=
CIFSFindFirst2
(
xid
,
pTcon
,
full_path
,
cifs_sb
->
local_nls
,
&
cifsFile
->
netfid
,
&
cifsFile
->
srch_inf
);
cFYI
(
1
,(
"search initiated with rc %d"
,
rc
));
return
rc
;
}
/* return length of unicode string in bytes */
static
int
cifs_unicode_bytelen
(
char
*
str
)
{
int
len
;
for
(
len
=
0
;
len
<=
2
*
PATH_MAX
;
len
+=
2
)
{
if
((
str
[
len
]
==
0
)
&&
(
str
[
len
+
1
]
==
0
))
{
return
len
;
}
}
cFYI
(
1
,(
"Unicode string longer than PATH_MAX found"
));
return
len
;
}
static
char
*
nxt_dir_entry
(
char
*
old_entry
,
char
*
end_of_smb
)
{
char
*
new_entry
;
FILE_DIRECTORY_INFO
*
pDirInfo
=
(
FILE_DIRECTORY_INFO
*
)
old_entry
;
new_entry
=
old_entry
+
pDirInfo
->
NextEntryOffset
;
/* validate that new_entry is not past end of SMB */
if
(
new_entry
>=
end_of_smb
)
{
cERROR
(
1
,(
"search entry began after end of SMB"
));
return
NULL
;
}
else
return
new_entry
;
}
/* return 0 if no match and 1 for . (current directory) and 2 for .. (parent) */
static
int
cifs_entry_is_dot
(
char
*
current_entry
,
struct
cifsFileInfo
*
cfile
)
{
int
rc
=
0
;
char
*
filename
=
NULL
;
int
len
=
0
;
if
(
cfile
->
srch_inf
.
info_level
==
0x202
)
{
FILE_UNIX_INFO
*
pFindData
=
(
FILE_UNIX_INFO
*
)
current_entry
;
filename
=
&
pFindData
->
FileName
[
0
];
if
(
cfile
->
srch_inf
.
unicode
)
{
len
=
cifs_unicode_bytelen
(
filename
);
}
else
{
/* BB should we make this strnlen of PATH_MAX? */
len
=
strnlen
(
filename
,
5
);
}
}
else
if
(
cfile
->
srch_inf
.
info_level
==
0x101
)
{
FILE_DIRECTORY_INFO
*
pFindData
=
(
FILE_DIRECTORY_INFO
*
)
current_entry
;
filename
=
&
pFindData
->
FileName
[
0
];
len
=
pFindData
->
FileNameLength
;
}
else
if
(
cfile
->
srch_inf
.
info_level
==
0x102
)
{
FILE_FULL_DIRECTORY_INFO
*
pFindData
=
(
FILE_FULL_DIRECTORY_INFO
*
)
current_entry
;
filename
=
&
pFindData
->
FileName
[
0
];
len
=
pFindData
->
FileNameLength
;
}
else
if
(
cfile
->
srch_inf
.
info_level
==
0x105
)
{
SEARCH_ID_FULL_DIR_INFO
*
pFindData
=
(
SEARCH_ID_FULL_DIR_INFO
*
)
current_entry
;
filename
=
&
pFindData
->
FileName
[
0
];
len
=
pFindData
->
FileNameLength
;
}
else
if
(
cfile
->
srch_inf
.
info_level
==
0x104
)
{
FILE_BOTH_DIRECTORY_INFO
*
pFindData
=
(
FILE_BOTH_DIRECTORY_INFO
*
)
current_entry
;
filename
=
&
pFindData
->
FileName
[
0
];
len
=
pFindData
->
FileNameLength
;
}
else
{
cFYI
(
1
,(
"Unknown findfirst level %d"
,
cfile
->
srch_inf
.
info_level
));
}
if
(
filename
)
{
if
(
cfile
->
srch_inf
.
unicode
)
{
if
(
len
==
2
)
{
/* check for . */
if
((
filename
[
0
]
==
'.'
)
&&
(
filename
[
1
]
==
0
))
{
rc
=
1
;
}
}
else
if
(
len
==
4
)
{
/* check for .. */
if
((
filename
[
0
]
==
'.'
)
&&
(
filename
[
1
]
==
0
)
&&
(
filename
[
2
]
==
'.'
)
&&
(
filename
[
3
]
==
0
))
{
rc
=
2
;
}
}
}
else
/* ASCII */
{
if
(
len
==
1
)
{
if
(
filename
[
0
]
==
'.'
)
{
rc
=
1
;
}
}
else
if
(
len
==
2
)
{
if
((
filename
[
0
]
==
'.'
)
&&
(
filename
[
1
]
==
'.'
))
{
rc
=
2
;
}
}
}
}
return
rc
;
}
/* find the corresponding entry in the search */
/* Note that the SMB server returns search entries for . and .. which
complicates logic here if we choose to parse for them and we do not
assume that they are located in the findfirst return buffer.*/
/* We start counting in the buffer with entry 2 and increment for every
entry (do not increment for . or .. entry) */
static
int
find_cifs_entry
(
const
int
xid
,
struct
cifsTconInfo
*
pTcon
,
const
loff_t
index_to_find
,
struct
cifsFileInfo
*
cifsFile
/* BB add missing parm */
)
{
...
...
@@ -102,10 +208,35 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo * pTcon,
/* we found the buffer that contains the entry */
/* scan and find it */
int
i
;
first_entry_in_buffer
=
cifsFile
->
srch_inf
.
index_of_last_entry
-
cifsFile
->
srch_inf
.
entries_in_buffer
;
FILE_DIRECTORY_INFO
*
removeme
;
char
*
current_entry
;
char
*
end_of_smb
=
cifsFile
->
srch_inf
.
ntwrk_buf_start
+
smbCalcSize
((
struct
smb_hdr
*
)
cifsFile
->
srch_inf
.
ntwrk_buf_start
);
cFYI
(
1
,(
"Found buffer that entry is in"
));
/* BB removeme BB */
first_entry_in_buffer
=
cifsFile
->
srch_inf
.
index_of_last_entry
-
cifsFile
->
srch_inf
.
entries_in_buffer
;
position_in_buf
=
index_to_find
-
first_entry_in_buffer
;
for
(
i
=
0
;
i
<
position_in_buf
;
i
++
)
{
/* go to next entry */
current_entry
=
cifsFile
->
srch_inf
.
srch_entries_start
;
for
(
i
=
0
;(
i
<
position_in_buf
)
&&
(
current_entry
!=
NULL
);
i
++
)
{
/* go entry to next entry figuring out which we need to start with */
/* if( . or ..)
skip */
removeme
=
(
FILE_DIRECTORY_INFO
*
)
current_entry
;
/* BB removeme BB */
rc
=
cifs_entry_is_dot
(
current_entry
,
cifsFile
);
if
(
rc
==
1
)
/* is . or .. so skip */
{
cFYI
(
1
,(
"Entry is ."
));
/* BB removeme BB */
continue
;
}
else
if
(
rc
==
2
)
{
cFYI
(
1
,(
"Entry is .."
));
/* BB removeme BB */
continue
;
}
else
{
cFYI
(
1
,(
"entry is %d long"
,
removeme
->
FileNameLength
));
/* BB removeme BB */
}
current_entry
=
nxt_dir_entry
(
current_entry
,
end_of_smb
);
}
for
(
i
=
position_in_buf
;
i
<
cifsFile
->
srch_inf
.
index_of_last_entry
;
i
++
)
{
/* filldir calls */
}
}
...
...
@@ -164,7 +295,7 @@ int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir)
cFYI
(
1
,
(
"Full path: %s start at: %lld "
,
full_path
,
file
->
f_pos
));
switch
((
int
)
file
->
f_pos
)
{
case
0
:
/*
case 0:
if (filldir(direntry, ".", 1, file->f_pos,
file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
cERROR(1, ("Filldir for current dir failed "));
...
...
@@ -172,7 +303,6 @@ int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir)
break;
}
file->f_pos++;
/* fallthrough */
case 1:
if (filldir(direntry, "..", 2, file->f_pos,
file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
...
...
@@ -180,8 +310,7 @@ int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir)
rc = -ENOMEM;
break;
}
file
->
f_pos
++
;
/* fallthrough */
file->f_pos++; */
default:
/* 1) If search is active,
is in current search buffer?
...
...
@@ -215,7 +344,6 @@ int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir)
} */
/* BB account for . and .. in f_pos */
find_cifs_entry
(
xid
,
pTcon
,
file
->
f_pos
,
cifsFile
);
cifs_filldir_with_entries
(
file
->
f_pos
,
cifsFile
);
/* 2) initiate search, */
/* 3) seek into search buffer */
/* 4) if not found && later - FindNext */
...
...
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