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
be4ccdcc
Commit
be4ccdcc
authored
May 22, 2013
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[readdir] convert cifs
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
9b5d5a17
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
82 additions
and
100 deletions
+82
-100
fs/cifs/cifsfs.c
fs/cifs/cifsfs.c
+1
-1
fs/cifs/cifsfs.h
fs/cifs/cifsfs.h
+1
-1
fs/cifs/readdir.c
fs/cifs/readdir.c
+80
-98
No files found.
fs/cifs/cifsfs.c
View file @
be4ccdcc
...
...
@@ -968,7 +968,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
};
const
struct
file_operations
cifs_dir_ops
=
{
.
readdir
=
cifs_readdir
,
.
iterate
=
cifs_readdir
,
.
release
=
cifs_closedir
,
.
read
=
generic_read_dir
,
.
unlocked_ioctl
=
cifs_ioctl
,
...
...
fs/cifs/cifsfs.h
View file @
be4ccdcc
...
...
@@ -101,7 +101,7 @@ extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
extern
int
cifs_file_strict_mmap
(
struct
file
*
,
struct
vm_area_struct
*
);
extern
const
struct
file_operations
cifs_dir_ops
;
extern
int
cifs_dir_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_readdir
(
struct
file
*
file
,
void
*
direntry
,
filldir_t
filldir
);
extern
int
cifs_readdir
(
struct
file
*
file
,
struct
dir_context
*
ctx
);
/* Functions related to dir entries */
extern
const
struct
dentry_operations
cifs_dentry_ops
;
...
...
fs/cifs/readdir.c
View file @
be4ccdcc
...
...
@@ -537,14 +537,14 @@ static int cifs_save_resume_key(const char *current_entry,
* every entry (do not increment for . or .. entry).
*/
static
int
find_cifs_entry
(
const
unsigned
int
xid
,
struct
cifs_tcon
*
tcon
,
find_cifs_entry
(
const
unsigned
int
xid
,
struct
cifs_tcon
*
tcon
,
loff_t
pos
,
struct
file
*
file
,
char
**
current_entry
,
int
*
num_to_ret
)
{
__u16
search_flags
;
int
rc
=
0
;
int
pos_in_buf
=
0
;
loff_t
first_entry_in_buffer
;
loff_t
index_to_find
=
file
->
f_
pos
;
loff_t
index_to_find
=
pos
;
struct
cifsFileInfo
*
cfile
=
file
->
private_data
;
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
file
->
f_path
.
dentry
->
d_sb
);
struct
TCP_Server_Info
*
server
=
tcon
->
ses
->
server
;
...
...
@@ -659,8 +659,9 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon,
return
rc
;
}
static
int
cifs_filldir
(
char
*
find_entry
,
struct
file
*
file
,
filldir_t
filldir
,
void
*
dirent
,
char
*
scratch_buf
,
unsigned
int
max_len
)
static
int
cifs_filldir
(
char
*
find_entry
,
struct
file
*
file
,
struct
dir_context
*
ctx
,
char
*
scratch_buf
,
unsigned
int
max_len
)
{
struct
cifsFileInfo
*
file_info
=
file
->
private_data
;
struct
super_block
*
sb
=
file
->
f_path
.
dentry
->
d_sb
;
...
...
@@ -740,13 +741,11 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
cifs_prime_dcache
(
file
->
f_dentry
,
&
name
,
&
fattr
);
ino
=
cifs_uniqueid_to_ino_t
(
fattr
.
cf_uniqueid
);
rc
=
filldir
(
dirent
,
name
.
name
,
name
.
len
,
file
->
f_pos
,
ino
,
fattr
.
cf_dtype
);
return
rc
;
return
!
dir_emit
(
ctx
,
name
.
name
,
name
.
len
,
ino
,
fattr
.
cf_dtype
);
}
int
cifs_readdir
(
struct
file
*
file
,
void
*
direntry
,
filldir_t
filldir
)
int
cifs_readdir
(
struct
file
*
file
,
struct
dir_context
*
ctx
)
{
int
rc
=
0
;
unsigned
int
xid
;
...
...
@@ -772,103 +771,86 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
goto
rddir2_exit
;
}
switch
((
int
)
file
->
f_pos
)
{
case
0
:
if
(
filldir
(
direntry
,
"."
,
1
,
file
->
f_pos
,
file_inode
(
file
)
->
i_ino
,
DT_DIR
)
<
0
)
{
cifs_dbg
(
VFS
,
"Filldir for current dir failed
\n
"
);
rc
=
-
ENOMEM
;
break
;
}
file
->
f_pos
++
;
case
1
:
if
(
filldir
(
direntry
,
".."
,
2
,
file
->
f_pos
,
parent_ino
(
file
->
f_path
.
dentry
),
DT_DIR
)
<
0
)
{
cifs_dbg
(
VFS
,
"Filldir for parent dir failed
\n
"
);
rc
=
-
ENOMEM
;
break
;
}
file
->
f_pos
++
;
default:
/* 1) If search is active,
is in current search buffer?
if it before then restart search
if after then keep searching till find it */
if
(
file
->
private_data
==
NULL
)
{
rc
=
-
EINVAL
;
free_xid
(
xid
);
return
rc
;
}
cifsFile
=
file
->
private_data
;
if
(
cifsFile
->
srch_inf
.
endOfSearch
)
{
if
(
cifsFile
->
srch_inf
.
emptyDir
)
{
cifs_dbg
(
FYI
,
"End of search, empty dir
\n
"
);
rc
=
0
;
break
;
}
}
/* else {
cifsFile->invalidHandle = true;
tcon->ses->server->close(xid, tcon, &cifsFile->fid);
} */
if
(
!
dir_emit_dots
(
file
,
ctx
))
goto
rddir2_exit
;
tcon
=
tlink_tcon
(
cifsFile
->
tlink
);
rc
=
find_cifs_entry
(
xid
,
tcon
,
file
,
&
current_entry
,
&
num_to_fill
);
if
(
rc
)
{
cifs_dbg
(
FYI
,
"fce error %d
\n
"
,
rc
);
goto
rddir2_exit
;
}
else
if
(
current_entry
!=
NULL
)
{
cifs_dbg
(
FYI
,
"entry %lld found
\n
"
,
file
->
f_pos
);
}
else
{
cifs_dbg
(
FYI
,
"could not find entry
\n
"
);
/* 1) If search is active,
is in current search buffer?
if it before then restart search
if after then keep searching till find it */
if
(
file
->
private_data
==
NULL
)
{
rc
=
-
EINVAL
;
goto
rddir2_exit
;
}
cifsFile
=
file
->
private_data
;
if
(
cifsFile
->
srch_inf
.
endOfSearch
)
{
if
(
cifsFile
->
srch_inf
.
emptyDir
)
{
cifs_dbg
(
FYI
,
"End of search, empty dir
\n
"
);
rc
=
0
;
goto
rddir2_exit
;
}
cifs_dbg
(
FYI
,
"loop through %d times filling dir for net buf %p
\n
"
,
num_to_fill
,
cifsFile
->
srch_inf
.
ntwrk_buf_start
);
max_len
=
tcon
->
ses
->
server
->
ops
->
calc_smb_size
(
cifsFile
->
srch_inf
.
ntwrk_buf_start
);
end_of_smb
=
cifsFile
->
srch_inf
.
ntwrk_buf_start
+
max_len
;
tmp_buf
=
kmalloc
(
UNICODE_NAME_MAX
,
GFP_KERNEL
);
if
(
tmp_buf
==
NULL
)
{
rc
=
-
ENOMEM
;
}
/* else {
cifsFile->invalidHandle = true;
tcon->ses->server->close(xid, tcon, &cifsFile->fid);
} */
tcon
=
tlink_tcon
(
cifsFile
->
tlink
);
rc
=
find_cifs_entry
(
xid
,
tcon
,
ctx
->
pos
,
file
,
&
current_entry
,
&
num_to_fill
);
if
(
rc
)
{
cifs_dbg
(
FYI
,
"fce error %d
\n
"
,
rc
);
goto
rddir2_exit
;
}
else
if
(
current_entry
!=
NULL
)
{
cifs_dbg
(
FYI
,
"entry %lld found
\n
"
,
ctx
->
pos
);
}
else
{
cifs_dbg
(
FYI
,
"could not find entry
\n
"
);
goto
rddir2_exit
;
}
cifs_dbg
(
FYI
,
"loop through %d times filling dir for net buf %p
\n
"
,
num_to_fill
,
cifsFile
->
srch_inf
.
ntwrk_buf_start
);
max_len
=
tcon
->
ses
->
server
->
ops
->
calc_smb_size
(
cifsFile
->
srch_inf
.
ntwrk_buf_start
);
end_of_smb
=
cifsFile
->
srch_inf
.
ntwrk_buf_start
+
max_len
;
tmp_buf
=
kmalloc
(
UNICODE_NAME_MAX
,
GFP_KERNEL
);
if
(
tmp_buf
==
NULL
)
{
rc
=
-
ENOMEM
;
goto
rddir2_exit
;
}
for
(
i
=
0
;
i
<
num_to_fill
;
i
++
)
{
if
(
current_entry
==
NULL
)
{
/* evaluate whether this case is an error */
cifs_dbg
(
VFS
,
"past SMB end, num to fill %d i %d
\n
"
,
num_to_fill
,
i
);
break
;
}
for
(
i
=
0
;
(
i
<
num_to_fill
)
&&
(
rc
==
0
);
i
++
)
{
if
(
current_entry
==
NULL
)
{
/* evaluate whether this case is an error */
cifs_dbg
(
VFS
,
"past SMB end, num to fill %d i %d
\n
"
,
num_to_fill
,
i
);
break
;
}
/*
* if buggy server returns . and .. late do we want to
* check for that here?
*/
rc
=
cifs_filldir
(
current_entry
,
file
,
filldir
,
direntry
,
tmp_buf
,
max_len
);
if
(
rc
==
-
EOVERFLOW
)
{
/*
* if buggy server returns . and .. late do we want to
* check for that here?
*/
rc
=
cifs_filldir
(
current_entry
,
file
,
ctx
,
tmp_buf
,
max_len
);
if
(
rc
)
{
if
(
rc
>
0
)
rc
=
0
;
break
;
}
file
->
f_pos
++
;
if
(
file
->
f_pos
==
cifsFile
->
srch_inf
.
index_of_last_entry
)
{
cifs_dbg
(
FYI
,
"last entry in buf at pos %lld %s
\n
"
,
file
->
f_pos
,
tmp_buf
);
cifs_save_resume_key
(
current_entry
,
cifsFile
);
break
;
}
else
current_entry
=
nxt_dir_entry
(
current_entry
,
end_of_smb
,
cifsFile
->
srch_inf
.
info_level
);
break
;
}
kfree
(
tmp_buf
);
break
;
}
/* end switch */
ctx
->
pos
++
;
if
(
ctx
->
pos
==
cifsFile
->
srch_inf
.
index_of_last_entry
)
{
cifs_dbg
(
FYI
,
"last entry in buf at pos %lld %s
\n
"
,
ctx
->
pos
,
tmp_buf
);
cifs_save_resume_key
(
current_entry
,
cifsFile
);
break
;
}
else
current_entry
=
nxt_dir_entry
(
current_entry
,
end_of_smb
,
cifsFile
->
srch_inf
.
info_level
);
}
kfree
(
tmp_buf
);
rddir2_exit:
free_xid
(
xid
);
...
...
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