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
f0c3b509
Commit
f0c3b509
authored
May 16, 2013
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[readdir] convert procfs
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
68c61471
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
284 additions
and
489 deletions
+284
-489
fs/hppfs/hppfs.c
fs/hppfs/hppfs.c
+14
-19
fs/proc/base.c
fs/proc/base.c
+133
-230
fs/proc/fd.c
fs/proc/fd.c
+40
-56
fs/proc/generic.c
fs/proc/generic.c
+38
-62
fs/proc/internal.h
fs/proc/internal.h
+4
-4
fs/proc/namespaces.c
fs/proc/namespaces.c
+18
-56
fs/proc/proc_net.c
fs/proc/proc_net.c
+4
-5
fs/proc/proc_sysctl.c
fs/proc/proc_sysctl.c
+27
-44
fs/proc/root.c
fs/proc/root.c
+6
-13
No files found.
fs/hppfs/hppfs.c
View file @
f0c3b509
...
...
@@ -542,8 +542,8 @@ static const struct file_operations hppfs_file_fops = {
};
struct
hppfs_dirent
{
void
*
vfs_dirent
;
filldir_t
filldi
r
;
struct
dir_context
ctx
;
struct
dir_context
*
calle
r
;
struct
dentry
*
dentry
;
};
...
...
@@ -555,34 +555,29 @@ static int hppfs_filldir(void *d, const char *name, int size,
if
(
file_removed
(
dirent
->
dentry
,
name
))
return
0
;
return
(
*
dirent
->
filldir
)(
dirent
->
vfs_dirent
,
name
,
size
,
offset
,
inode
,
type
);
dirent
->
caller
->
pos
=
dirent
->
ctx
.
pos
;
return
!
dir_emit
(
dirent
->
caller
,
name
,
size
,
inode
,
type
);
}
static
int
hppfs_readdir
(
struct
file
*
file
,
void
*
ent
,
filldir_t
filldir
)
static
int
hppfs_readdir
(
struct
file
*
file
,
struct
dir_context
*
ctx
)
{
struct
hppfs_private
*
data
=
file
->
private_data
;
struct
file
*
proc_file
=
data
->
proc_file
;
int
(
*
readdir
)(
struct
file
*
,
void
*
,
filldir_t
);
struct
hppfs_dirent
dirent
=
((
struct
hppfs_dirent
)
{
.
vfs_dirent
=
ent
,
.
filldir
=
filldir
,
.
dentry
=
file
->
f_path
.
dentry
});
struct
hppfs_dirent
d
=
{
.
ctx
.
actor
=
hppfs_filldir
,
.
caller
=
ctx
,
.
dentry
=
file
->
f_path
.
dentry
};
int
err
;
readdir
=
file_inode
(
proc_file
)
->
i_fop
->
readdir
;
proc_file
->
f_pos
=
file
->
f_pos
;
err
=
(
*
readdir
)(
proc_file
,
&
dirent
,
hppfs_filldir
);
file
->
f_pos
=
proc_file
->
f_pos
;
proc_file
->
f_pos
=
ctx
->
pos
;
err
=
iterate_dir
(
proc_file
,
&
d
.
ctx
);
ctx
->
pos
=
d
.
ctx
.
pos
;
return
err
;
}
static
const
struct
file_operations
hppfs_dir_fops
=
{
.
owner
=
NULL
,
.
readdir
=
hppfs_readdir
,
.
iterate
=
hppfs_readdir
,
.
open
=
hppfs_dir_open
,
.
llseek
=
default_llseek
,
.
release
=
hppfs_release
,
...
...
fs/proc/base.c
View file @
f0c3b509
This diff is collapsed.
Click to expand it.
fs/proc/fd.c
View file @
f0c3b509
...
...
@@ -219,74 +219,58 @@ static struct dentry *proc_lookupfd_common(struct inode *dir,
return
result
;
}
static
int
proc_readfd_common
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
,
instantiate_t
instantiate
)
static
int
proc_readfd_common
(
struct
file
*
file
,
struct
dir_context
*
ctx
,
instantiate_t
instantiate
)
{
struct
dentry
*
dentry
=
filp
->
f_path
.
dentry
;
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
task_struct
*
p
=
get_proc_task
(
inode
);
struct
task_struct
*
p
=
get_proc_task
(
file_inode
(
file
));
struct
files_struct
*
files
;
unsigned
int
fd
,
ino
;
int
retval
;
unsigned
int
fd
;
retval
=
-
ENOENT
;
if
(
!
p
)
goto
out_no_task
;
retval
=
0
;
fd
=
filp
->
f_pos
;
switch
(
fd
)
{
case
0
:
if
(
filldir
(
dirent
,
"."
,
1
,
0
,
inode
->
i_ino
,
DT_DIR
)
<
0
)
goto
out
;
filp
->
f_pos
++
;
case
1
:
ino
=
parent_ino
(
dentry
);
if
(
filldir
(
dirent
,
".."
,
2
,
1
,
ino
,
DT_DIR
)
<
0
)
goto
out
;
filp
->
f_pos
++
;
default:
files
=
get_files_struct
(
p
);
if
(
!
files
)
goto
out
;
rcu_read_lock
();
for
(
fd
=
filp
->
f_pos
-
2
;
fd
<
files_fdtable
(
files
)
->
max_fds
;
fd
++
,
filp
->
f_pos
++
)
{
char
name
[
PROC_NUMBUF
];
int
len
;
int
rv
;
if
(
!
fcheck_files
(
files
,
fd
))
continue
;
rcu_read_unlock
();
return
-
ENOENT
;
len
=
snprintf
(
name
,
sizeof
(
name
),
"%d"
,
fd
);
rv
=
proc_fill_cache
(
filp
,
dirent
,
filldir
,
name
,
len
,
instantiate
,
p
,
(
void
*
)(
unsigned
long
)
fd
);
if
(
rv
<
0
)
goto
out_fd_loop
;
rcu_read_lock
();
}
rcu_read_unlock
();
out_fd_loop:
put_files_struct
(
files
);
if
(
!
dir_emit_dots
(
file
,
ctx
))
goto
out
;
if
(
!
dir_emit_dots
(
file
,
ctx
))
goto
out
;
files
=
get_files_struct
(
p
);
if
(
!
files
)
goto
out
;
rcu_read_lock
();
for
(
fd
=
ctx
->
pos
-
2
;
fd
<
files_fdtable
(
files
)
->
max_fds
;
fd
++
,
ctx
->
pos
++
)
{
char
name
[
PROC_NUMBUF
];
int
len
;
if
(
!
fcheck_files
(
files
,
fd
))
continue
;
rcu_read_unlock
();
len
=
snprintf
(
name
,
sizeof
(
name
),
"%d"
,
fd
);
if
(
!
proc_fill_cache
(
file
,
ctx
,
name
,
len
,
instantiate
,
p
,
(
void
*
)(
unsigned
long
)
fd
))
goto
out_fd_loop
;
rcu_read_lock
();
}
rcu_read_unlock
();
out_fd_loop:
put_files_struct
(
files
);
out:
put_task_struct
(
p
);
out_no_task:
return
retval
;
return
0
;
}
static
int
proc_readfd
(
struct
file
*
fil
p
,
void
*
dirent
,
filldir_t
filldir
)
static
int
proc_readfd
(
struct
file
*
fil
e
,
struct
dir_context
*
ctx
)
{
return
proc_readfd_common
(
fil
p
,
dirent
,
filldir
,
proc_fd_instantiate
);
return
proc_readfd_common
(
fil
e
,
ctx
,
proc_fd_instantiate
);
}
const
struct
file_operations
proc_fd_operations
=
{
.
read
=
generic_read_dir
,
.
readdir
=
proc_readfd
,
.
iterate
=
proc_readfd
,
.
llseek
=
default_llseek
,
};
...
...
@@ -351,9 +335,9 @@ proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags)
return
proc_lookupfd_common
(
dir
,
dentry
,
proc_fdinfo_instantiate
);
}
static
int
proc_readfdinfo
(
struct
file
*
fil
p
,
void
*
dirent
,
filldir_t
filldir
)
static
int
proc_readfdinfo
(
struct
file
*
fil
e
,
struct
dir_context
*
ctx
)
{
return
proc_readfd_common
(
fil
p
,
dirent
,
filldir
,
return
proc_readfd_common
(
fil
e
,
ctx
,
proc_fdinfo_instantiate
);
}
...
...
@@ -364,6 +348,6 @@ const struct inode_operations proc_fdinfo_inode_operations = {
const
struct
file_operations
proc_fdinfo_operations
=
{
.
read
=
generic_read_dir
,
.
readdir
=
proc_readfdinfo
,
.
iterate
=
proc_readfdinfo
,
.
llseek
=
default_llseek
,
};
fs/proc/generic.c
View file @
f0c3b509
...
...
@@ -233,76 +233,52 @@ struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
* value of the readdir() call, as long as it's non-negative
* for success..
*/
int
proc_readdir_de
(
struct
proc_dir_entry
*
de
,
struct
file
*
fil
p
,
void
*
dirent
,
filldir_t
filldir
)
int
proc_readdir_de
(
struct
proc_dir_entry
*
de
,
struct
file
*
fil
e
,
struct
dir_context
*
ctx
)
{
unsigned
int
ino
;
int
i
;
struct
inode
*
inode
=
file_inode
(
filp
);
int
ret
=
0
;
ino
=
inode
->
i_ino
;
i
=
filp
->
f_pos
;
switch
(
i
)
{
case
0
:
if
(
filldir
(
dirent
,
"."
,
1
,
i
,
ino
,
DT_DIR
)
<
0
)
goto
out
;
i
++
;
filp
->
f_pos
++
;
/* fall through */
case
1
:
if
(
filldir
(
dirent
,
".."
,
2
,
i
,
parent_ino
(
filp
->
f_path
.
dentry
),
DT_DIR
)
<
0
)
goto
out
;
i
++
;
filp
->
f_pos
++
;
/* fall through */
default:
spin_lock
(
&
proc_subdir_lock
);
de
=
de
->
subdir
;
i
-=
2
;
for
(;;)
{
if
(
!
de
)
{
ret
=
1
;
spin_unlock
(
&
proc_subdir_lock
);
goto
out
;
}
if
(
!
i
)
break
;
de
=
de
->
next
;
i
--
;
}
do
{
struct
proc_dir_entry
*
next
;
/* filldir passes info to user space */
pde_get
(
de
);
spin_unlock
(
&
proc_subdir_lock
);
if
(
filldir
(
dirent
,
de
->
name
,
de
->
namelen
,
filp
->
f_pos
,
de
->
low_ino
,
de
->
mode
>>
12
)
<
0
)
{
pde_put
(
de
);
goto
out
;
}
spin_lock
(
&
proc_subdir_lock
);
filp
->
f_pos
++
;
next
=
de
->
next
;
pde_put
(
de
);
de
=
next
;
}
while
(
de
);
if
(
!
dir_emit_dots
(
file
,
ctx
))
return
0
;
spin_lock
(
&
proc_subdir_lock
);
de
=
de
->
subdir
;
i
=
ctx
->
pos
-
2
;
for
(;;)
{
if
(
!
de
)
{
spin_unlock
(
&
proc_subdir_lock
);
return
0
;
}
if
(
!
i
)
break
;
de
=
de
->
next
;
i
--
;
}
ret
=
1
;
out:
return
ret
;
do
{
struct
proc_dir_entry
*
next
;
pde_get
(
de
);
spin_unlock
(
&
proc_subdir_lock
);
if
(
!
dir_emit
(
ctx
,
de
->
name
,
de
->
namelen
,
de
->
low_ino
,
de
->
mode
>>
12
))
{
pde_put
(
de
);
return
0
;
}
spin_lock
(
&
proc_subdir_lock
);
ctx
->
pos
++
;
next
=
de
->
next
;
pde_put
(
de
);
de
=
next
;
}
while
(
de
);
spin_unlock
(
&
proc_subdir_lock
);
return
0
;
}
int
proc_readdir
(
struct
file
*
fil
p
,
void
*
dirent
,
filldir_t
filldir
)
int
proc_readdir
(
struct
file
*
fil
e
,
struct
dir_context
*
ctx
)
{
struct
inode
*
inode
=
file_inode
(
fil
p
);
struct
inode
*
inode
=
file_inode
(
fil
e
);
return
proc_readdir_de
(
PDE
(
inode
),
fil
p
,
dirent
,
filldir
);
return
proc_readdir_de
(
PDE
(
inode
),
fil
e
,
ctx
);
}
/*
...
...
@@ -313,7 +289,7 @@ int proc_readdir(struct file *filp, void *dirent, filldir_t filldir)
static
const
struct
file_operations
proc_dir_operations
=
{
.
llseek
=
generic_file_llseek
,
.
read
=
generic_read_dir
,
.
readdir
=
proc_readdir
,
.
iterate
=
proc_readdir
,
};
/*
...
...
fs/proc/internal.h
View file @
f0c3b509
...
...
@@ -165,14 +165,14 @@ extern int proc_setattr(struct dentry *, struct iattr *);
extern
struct
inode
*
proc_pid_make_inode
(
struct
super_block
*
,
struct
task_struct
*
);
extern
int
pid_revalidate
(
struct
dentry
*
,
unsigned
int
);
extern
int
pid_delete_dentry
(
const
struct
dentry
*
);
extern
int
proc_pid_readdir
(
struct
file
*
,
void
*
,
filldir_t
);
extern
int
proc_pid_readdir
(
struct
file
*
,
struct
dir_context
*
);
extern
struct
dentry
*
proc_pid_lookup
(
struct
inode
*
,
struct
dentry
*
,
unsigned
int
);
extern
loff_t
mem_lseek
(
struct
file
*
,
loff_t
,
int
);
/* Lookups */
typedef
struct
dentry
*
instantiate_t
(
struct
inode
*
,
struct
dentry
*
,
struct
task_struct
*
,
const
void
*
);
extern
int
proc_fill_cache
(
struct
file
*
,
void
*
,
filldir_t
,
const
char
*
,
int
,
extern
bool
proc_fill_cache
(
struct
file
*
,
struct
dir_context
*
,
const
char
*
,
int
,
instantiate_t
,
struct
task_struct
*
,
const
void
*
);
/*
...
...
@@ -183,8 +183,8 @@ extern spinlock_t proc_subdir_lock;
extern
struct
dentry
*
proc_lookup
(
struct
inode
*
,
struct
dentry
*
,
unsigned
int
);
extern
struct
dentry
*
proc_lookup_de
(
struct
proc_dir_entry
*
,
struct
inode
*
,
struct
dentry
*
);
extern
int
proc_readdir
(
struct
file
*
,
void
*
,
filldir_t
);
extern
int
proc_readdir_de
(
struct
proc_dir_entry
*
,
struct
file
*
,
void
*
,
filldir_t
);
extern
int
proc_readdir
(
struct
file
*
,
struct
dir_context
*
);
extern
int
proc_readdir_de
(
struct
proc_dir_entry
*
,
struct
file
*
,
struct
dir_context
*
);
static
inline
struct
proc_dir_entry
*
pde_get
(
struct
proc_dir_entry
*
pde
)
{
...
...
fs/proc/namespaces.c
View file @
f0c3b509
...
...
@@ -213,74 +213,36 @@ static struct dentry *proc_ns_instantiate(struct inode *dir,
return
error
;
}
static
int
proc_ns_fill_cache
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
,
struct
task_struct
*
task
,
const
struct
proc_ns_operations
*
ops
)
static
int
proc_ns_dir_readdir
(
struct
file
*
file
,
struct
dir_context
*
ctx
)
{
return
proc_fill_cache
(
filp
,
dirent
,
filldir
,
ops
->
name
,
strlen
(
ops
->
name
),
proc_ns_instantiate
,
task
,
ops
);
}
static
int
proc_ns_dir_readdir
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
)
{
int
i
;
struct
dentry
*
dentry
=
filp
->
f_path
.
dentry
;
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
task_struct
*
task
=
get_proc_task
(
inode
);
struct
task_struct
*
task
=
get_proc_task
(
file_inode
(
file
));
const
struct
proc_ns_operations
**
entry
,
**
last
;
ino_t
ino
;
int
ret
;
ret
=
-
ENOENT
;
if
(
!
task
)
goto
out_no_task
;
return
-
ENOENT
;
ret
=
0
;
i
=
filp
->
f_pos
;
switch
(
i
)
{
case
0
:
ino
=
inode
->
i_ino
;
if
(
filldir
(
dirent
,
"."
,
1
,
i
,
ino
,
DT_DIR
)
<
0
)
goto
out
;
i
++
;
filp
->
f_pos
++
;
/* fall through */
case
1
:
ino
=
parent_ino
(
dentry
);
if
(
filldir
(
dirent
,
".."
,
2
,
i
,
ino
,
DT_DIR
)
<
0
)
goto
out
;
i
++
;
filp
->
f_pos
++
;
/* fall through */
default:
i
-=
2
;
if
(
i
>=
ARRAY_SIZE
(
ns_entries
))
{
ret
=
1
;
goto
out
;
}
entry
=
ns_entries
+
i
;
last
=
&
ns_entries
[
ARRAY_SIZE
(
ns_entries
)
-
1
];
while
(
entry
<=
last
)
{
if
(
proc_ns_fill_cache
(
filp
,
dirent
,
filldir
,
task
,
*
entry
)
<
0
)
goto
out
;
filp
->
f_pos
++
;
entry
++
;
}
if
(
!
dir_emit_dots
(
file
,
ctx
))
goto
out
;
if
(
ctx
->
pos
>=
2
+
ARRAY_SIZE
(
ns_entries
))
goto
out
;
entry
=
ns_entries
+
(
ctx
->
pos
-
2
);
last
=
&
ns_entries
[
ARRAY_SIZE
(
ns_entries
)
-
1
];
while
(
entry
<=
last
)
{
const
struct
proc_ns_operations
*
ops
=
*
entry
;
if
(
!
proc_fill_cache
(
file
,
ctx
,
ops
->
name
,
strlen
(
ops
->
name
),
proc_ns_instantiate
,
task
,
ops
))
break
;
ctx
->
pos
++
;
entry
++
;
}
ret
=
1
;
out:
put_task_struct
(
task
);
out_no_task:
return
ret
;
return
0
;
}
const
struct
file_operations
proc_ns_dir_operations
=
{
.
read
=
generic_read_dir
,
.
readdir
=
proc_ns_dir_readdir
,
.
iterate
=
proc_ns_dir_readdir
,
};
static
struct
dentry
*
proc_ns_dir_lookup
(
struct
inode
*
dir
,
...
...
fs/proc/proc_net.c
View file @
f0c3b509
...
...
@@ -160,16 +160,15 @@ const struct inode_operations proc_net_inode_operations = {
.
getattr
=
proc_tgid_net_getattr
,
};
static
int
proc_tgid_net_readdir
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
)
static
int
proc_tgid_net_readdir
(
struct
file
*
file
,
struct
dir_context
*
ctx
)
{
int
ret
;
struct
net
*
net
;
ret
=
-
EINVAL
;
net
=
get_proc_task_net
(
file_inode
(
fil
p
));
net
=
get_proc_task_net
(
file_inode
(
fil
e
));
if
(
net
!=
NULL
)
{
ret
=
proc_readdir_de
(
net
->
proc_net
,
fil
p
,
dirent
,
filldir
);
ret
=
proc_readdir_de
(
net
->
proc_net
,
fil
e
,
ctx
);
put_net
(
net
);
}
return
ret
;
...
...
@@ -178,7 +177,7 @@ static int proc_tgid_net_readdir(struct file *filp, void *dirent,
const
struct
file_operations
proc_net_operations
=
{
.
llseek
=
generic_file_llseek
,
.
read
=
generic_read_dir
,
.
readdir
=
proc_tgid_net_readdir
,
.
iterate
=
proc_tgid_net_readdir
,
};
static
__net_init
int
proc_net_ns_init
(
struct
net
*
net
)
...
...
fs/proc/proc_sysctl.c
View file @
f0c3b509
...
...
@@ -573,12 +573,12 @@ static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
return
ret
;
}
static
int
proc_sys_fill_cache
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
,
static
bool
proc_sys_fill_cache
(
struct
file
*
file
,
struct
dir_context
*
ctx
,
struct
ctl_table_header
*
head
,
struct
ctl_table
*
table
)
{
struct
dentry
*
child
,
*
dir
=
fil
p
->
f_path
.
dentry
;
struct
dentry
*
child
,
*
dir
=
fil
e
->
f_path
.
dentry
;
struct
inode
*
inode
;
struct
qstr
qname
;
ino_t
ino
=
0
;
...
...
@@ -595,38 +595,38 @@ static int proc_sys_fill_cache(struct file *filp, void *dirent,
inode
=
proc_sys_make_inode
(
dir
->
d_sb
,
head
,
table
);
if
(
!
inode
)
{
dput
(
child
);
return
-
ENOMEM
;
return
false
;
}
else
{
d_set_d_op
(
child
,
&
proc_sys_dentry_operations
);
d_add
(
child
,
inode
);
}
}
else
{
return
-
ENOMEM
;
return
false
;
}
}
inode
=
child
->
d_inode
;
ino
=
inode
->
i_ino
;
type
=
inode
->
i_mode
>>
12
;
dput
(
child
);
return
!!
filldir
(
dirent
,
qname
.
name
,
qname
.
len
,
filp
->
f_pos
,
ino
,
type
);
return
dir_emit
(
ctx
,
qname
.
name
,
qname
.
len
,
ino
,
type
);
}
static
int
proc_sys_link_fill_cache
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
,
static
bool
proc_sys_link_fill_cache
(
struct
file
*
file
,
struct
dir_context
*
ctx
,
struct
ctl_table_header
*
head
,
struct
ctl_table
*
table
)
{
int
err
,
ret
=
0
;
bool
ret
=
true
;
head
=
sysctl_head_grab
(
head
);
if
(
S_ISLNK
(
table
->
mode
))
{
/* It is not an error if we can not follow the link ignore it */
err
=
sysctl_follow_link
(
&
head
,
&
table
,
current
->
nsproxy
);
int
err
=
sysctl_follow_link
(
&
head
,
&
table
,
current
->
nsproxy
);
if
(
err
)
goto
out
;
}
ret
=
proc_sys_fill_cache
(
fil
p
,
dirent
,
filldir
,
head
,
table
);
ret
=
proc_sys_fill_cache
(
fil
e
,
ctx
,
head
,
table
);
out:
sysctl_head_finish
(
head
);
return
ret
;
...
...
@@ -634,67 +634,50 @@ static int proc_sys_link_fill_cache(struct file *filp, void *dirent,
static
int
scan
(
struct
ctl_table_header
*
head
,
ctl_table
*
table
,
unsigned
long
*
pos
,
struct
file
*
file
,
void
*
dirent
,
filldir_t
filldir
)
struct
dir_context
*
ctx
)
{
int
res
;
bool
res
;
if
((
*
pos
)
++
<
file
->
f_
pos
)
return
0
;
if
((
*
pos
)
++
<
ctx
->
pos
)
return
true
;
if
(
unlikely
(
S_ISLNK
(
table
->
mode
)))
res
=
proc_sys_link_fill_cache
(
file
,
dirent
,
filldir
,
head
,
table
);
res
=
proc_sys_link_fill_cache
(
file
,
ctx
,
head
,
table
);
else
res
=
proc_sys_fill_cache
(
file
,
dirent
,
filldir
,
head
,
table
);
res
=
proc_sys_fill_cache
(
file
,
ctx
,
head
,
table
);
if
(
res
==
0
)
file
->
f_
pos
=
*
pos
;
if
(
res
)
ctx
->
pos
=
*
pos
;
return
res
;
}
static
int
proc_sys_readdir
(
struct
file
*
fil
p
,
void
*
dirent
,
filldir_t
filldir
)
static
int
proc_sys_readdir
(
struct
file
*
fil
e
,
struct
dir_context
*
ctx
)
{
struct
dentry
*
dentry
=
filp
->
f_path
.
dentry
;
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
ctl_table_header
*
head
=
grab_header
(
inode
);
struct
ctl_table_header
*
head
=
grab_header
(
file_inode
(
file
));
struct
ctl_table_header
*
h
=
NULL
;
struct
ctl_table
*
entry
;
struct
ctl_dir
*
ctl_dir
;
unsigned
long
pos
;
int
ret
=
-
EINVAL
;
if
(
IS_ERR
(
head
))
return
PTR_ERR
(
head
);
ctl_dir
=
container_of
(
head
,
struct
ctl_dir
,
header
);
ret
=
0
;
/* Avoid a switch here: arm builds fail with missing __cmpdi2 */
if
(
filp
->
f_pos
==
0
)
{
if
(
filldir
(
dirent
,
"."
,
1
,
filp
->
f_pos
,
inode
->
i_ino
,
DT_DIR
)
<
0
)
goto
out
;
filp
->
f_pos
++
;
}
if
(
filp
->
f_pos
==
1
)
{
if
(
filldir
(
dirent
,
".."
,
2
,
filp
->
f_pos
,
parent_ino
(
dentry
),
DT_DIR
)
<
0
)
goto
out
;
filp
->
f_pos
++
;
}
if
(
!
dir_emit_dots
(
file
,
ctx
))
return
0
;
pos
=
2
;
for
(
first_entry
(
ctl_dir
,
&
h
,
&
entry
);
h
;
next_entry
(
&
h
,
&
entry
))
{
ret
=
scan
(
h
,
entry
,
&
pos
,
filp
,
dirent
,
filldir
);
if
(
ret
)
{
if
(
!
scan
(
h
,
entry
,
&
pos
,
file
,
ctx
))
{
sysctl_head_finish
(
h
);
break
;
}
}
ret
=
1
;
out:
sysctl_head_finish
(
head
);
return
ret
;
return
0
;
}
static
int
proc_sys_permission
(
struct
inode
*
inode
,
int
mask
)
...
...
@@ -769,7 +752,7 @@ static const struct file_operations proc_sys_file_operations = {
static
const
struct
file_operations
proc_sys_dir_file_operations
=
{
.
read
=
generic_read_dir
,
.
readdir
=
proc_sys_readdir
,
.
iterate
=
proc_sys_readdir
,
.
llseek
=
generic_file_llseek
,
};
...
...
fs/proc/root.c
View file @
f0c3b509
...
...
@@ -202,21 +202,14 @@ static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentr
return
proc_pid_lookup
(
dir
,
dentry
,
flags
);
}
static
int
proc_root_readdir
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
)
static
int
proc_root_readdir
(
struct
file
*
file
,
struct
dir_context
*
ctx
)
{
unsigned
int
nr
=
filp
->
f_pos
;
int
ret
;
if
(
nr
<
FIRST_PROCESS_ENTRY
)
{
int
error
=
proc_readdir
(
filp
,
dirent
,
filldir
);
if
(
error
<=
0
)
return
error
;
filp
->
f_pos
=
FIRST_PROCESS_ENTRY
;
if
(
ctx
->
pos
<
FIRST_PROCESS_ENTRY
)
{
proc_readdir
(
file
,
ctx
);
ctx
->
pos
=
FIRST_PROCESS_ENTRY
;
}
ret
=
proc_pid_readdir
(
filp
,
dirent
,
filldir
);
return
ret
;
return
proc_pid_readdir
(
file
,
ctx
);
}
/*
...
...
@@ -226,7 +219,7 @@ static int proc_root_readdir(struct file * filp,
*/
static
const
struct
file_operations
proc_root_operations
=
{
.
read
=
generic_read_dir
,
.
readdir
=
proc_root_readdir
,
.
iterate
=
proc_root_readdir
,
.
llseek
=
default_llseek
,
};
...
...
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