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
Kirill Smelkov
linux
Commits
07ca08b1
Commit
07ca08b1
authored
May 20, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/davem/net-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
df13121f
a45a6dde
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
133 additions
and
189 deletions
+133
-189
fs/dcache.c
fs/dcache.c
+12
-7
fs/namespace.c
fs/namespace.c
+1
-10
fs/open.c
fs/open.c
+2
-2
fs/proc/base.c
fs/proc/base.c
+12
-10
fs/proc/task_mmu.c
fs/proc/task_mmu.c
+67
-148
fs/seq_file.c
fs/seq_file.c
+31
-0
include/linux/seq_file.h
include/linux/seq_file.h
+4
-0
mm/swapfile.c
mm/swapfile.c
+4
-12
No files found.
fs/dcache.c
View file @
07ca08b1
...
...
@@ -1275,7 +1275,7 @@ void d_move(struct dentry * dentry, struct dentry * target)
* the string " (deleted)" is appended. Note that this is ambiguous. Returns
* the buffer.
*
* "buflen" should be
%PAGE_SIZE or mor
e. Caller holds the dcache_lock.
* "buflen" should be
positiv
e. Caller holds the dcache_lock.
*/
static
char
*
__d_path
(
struct
dentry
*
dentry
,
struct
vfsmount
*
vfsmnt
,
struct
dentry
*
root
,
struct
vfsmount
*
rootmnt
,
...
...
@@ -1290,9 +1290,13 @@ static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
if
(
!
IS_ROOT
(
dentry
)
&&
d_unhashed
(
dentry
))
{
buflen
-=
10
;
end
-=
10
;
if
(
buflen
<
0
)
goto
Elong
;
memcpy
(
end
,
" (deleted)"
,
10
);
}
if
(
buflen
<
1
)
goto
Elong
;
/* Get '/' right */
retval
=
end
-
1
;
*
retval
=
'/'
;
...
...
@@ -1315,7 +1319,7 @@ static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
namelen
=
dentry
->
d_name
.
len
;
buflen
-=
namelen
+
1
;
if
(
buflen
<
0
)
return
ERR_PTR
(
-
ENAMETOOLONG
)
;
goto
Elong
;
end
-=
namelen
;
memcpy
(
end
,
dentry
->
d_name
.
name
,
namelen
);
*--
end
=
'/'
;
...
...
@@ -1328,12 +1332,13 @@ static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
global_root:
namelen
=
dentry
->
d_name
.
len
;
buflen
-=
namelen
;
if
(
buflen
>=
0
)
{
retval
-=
namelen
-
1
;
/* hit the slash */
memcpy
(
retval
,
dentry
->
d_name
.
name
,
namelen
);
}
else
retval
=
ERR_PTR
(
-
ENAMETOOLONG
);
if
(
buflen
<
0
)
goto
Elong
;
retval
-=
namelen
-
1
;
/* hit the slash */
memcpy
(
retval
,
dentry
->
d_name
.
name
,
namelen
);
return
retval
;
Elong:
return
ERR_PTR
(
-
ENAMETOOLONG
);
}
/* write full pathname into buffer and return start of pathname */
...
...
fs/namespace.c
View file @
07ca08b1
...
...
@@ -211,19 +211,10 @@ static int show_vfsmnt(struct seq_file *m, void *v)
{
0
,
NULL
}
};
struct
proc_fs_info
*
fs_infop
;
char
*
path_buf
,
*
path
;
path_buf
=
(
char
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
!
path_buf
)
return
-
ENOMEM
;
path
=
d_path
(
mnt
->
mnt_root
,
mnt
,
path_buf
,
PAGE_SIZE
);
if
(
IS_ERR
(
path
))
path
=
" (too long)"
;
mangle
(
m
,
mnt
->
mnt_devname
?
mnt
->
mnt_devname
:
"none"
);
seq_putc
(
m
,
' '
);
mangle
(
m
,
path
);
free_page
((
unsigned
long
)
path_buf
);
seq_path
(
m
,
mnt
,
mnt
->
mnt_root
,
"
\t\n\\
"
);
seq_putc
(
m
,
' '
);
mangle
(
m
,
mnt
->
mnt_sb
->
s_type
->
name
);
seq_puts
(
m
,
mnt
->
mnt_sb
->
s_flags
&
MS_RDONLY
?
" ro"
:
" rw"
);
...
...
fs/open.c
View file @
07ca08b1
...
...
@@ -671,8 +671,8 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
if
(
f
->
f_flags
&
O_DIRECT
)
{
if
(
!
inode
->
i_mapping
||
!
inode
->
i_mapping
->
a_ops
||
!
inode
->
i_mapping
->
a_ops
->
direct_IO
)
{
error
=
-
EINVAL
;
goto
cleanup_all
;
fput
(
f
)
;
f
=
ERR_PTR
(
-
EINVAL
)
;
}
}
...
...
fs/proc/base.c
View file @
07ca08b1
...
...
@@ -322,21 +322,23 @@ static int proc_permission(struct inode *inode, int mask)
return
proc_check_root
(
inode
);
}
extern
ssize_t
proc_pid_read_maps
(
struct
task_struct
*
,
struct
file
*
,
char
*
,
size_t
,
loff_t
*
);
static
ssize_t
pid_maps_read
(
struct
file
*
file
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
extern
struct
seq_operations
proc_pid_maps_op
;
static
int
maps_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
inode
*
inode
=
file
->
f_dentry
->
d_inode
;
struct
task_struct
*
task
=
proc_task
(
inode
);
ssize_t
res
;
res
=
proc_pid_read_maps
(
task
,
file
,
buf
,
count
,
ppos
);
return
res
;
int
ret
=
seq_open
(
file
,
&
proc_pid_maps_op
);
if
(
!
ret
)
{
struct
seq_file
*
m
=
file
->
private_data
;
m
->
private
=
task
;
}
return
ret
;
}
static
struct
file_operations
proc_maps_operations
=
{
.
read
=
pid_maps_read
,
.
open
=
maps_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
seq_release
,
};
extern
struct
seq_operations
mounts_op
;
...
...
fs/proc/task_mmu.c
View file @
07ca08b1
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
char
*
task_mem
(
struct
mm_struct
*
mm
,
char
*
buffer
)
...
...
@@ -75,167 +75,86 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
return
size
;
}
/*
* The way we support synthetic files > 4K
* - without storing their contents in some buffer and
* - without walking through the entire synthetic file until we reach the
* position of the requested data
* is to cleverly encode the current position in the file's f_pos field.
* There is no requirement that a read() call which returns `count' bytes
* of data increases f_pos by exactly `count'.
*
* This idea is Linus' one. Bruno implemented it.
*/
/*
* For the /proc/<pid>/maps file, we use fixed length records, each containing
* a single line.
*
* f_pos = (number of the vma in the task->mm->mmap list) * PAGE_SIZE
* + (index into the line)
*/
/* for systems with sizeof(void*) == 4: */
#define MAPS_LINE_FORMAT4 "%08lx-%08lx %s %08lx %02x:%02x %lu"
#define MAPS_LINE_MAX4 49
/* sum of 8 1 8 1 4 1 8 1 5 1 10 1 */
/* for systems with sizeof(void*) == 8: */
#define MAPS_LINE_FORMAT8 "%016lx-%016lx %s %016lx %02x:%02x %lu"
#define MAPS_LINE_MAX8 73
/* sum of 16 1 16 1 4 1 16 1 5 1 10 1 */
#define MAPS_LINE_FORMAT (sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8)
#define MAPS_LINE_MAX (sizeof(void*) == 4 ? MAPS_LINE_MAX4 : MAPS_LINE_MAX8)
static
int
proc_pid_maps_get_line
(
char
*
buf
,
struct
vm_area_struct
*
map
)
static
int
show_map
(
struct
seq_file
*
m
,
void
*
v
)
{
/* produce the next line */
char
*
line
;
char
str
[
5
];
int
flags
;
dev_t
dev
;
unsigned
long
ino
;
struct
vm_area_struct
*
map
=
v
;
struct
file
*
file
=
map
->
vm_file
;
int
flags
=
map
->
vm_flags
;
unsigned
long
ino
=
0
;
dev_t
dev
=
0
;
int
len
;
flags
=
map
->
vm_flags
;
str
[
0
]
=
flags
&
VM_READ
?
'r'
:
'-'
;
str
[
1
]
=
flags
&
VM_WRITE
?
'w'
:
'-'
;
str
[
2
]
=
flags
&
VM_EXEC
?
'x'
:
'-'
;
str
[
3
]
=
flags
&
VM_MAYSHARE
?
's'
:
'p'
;
str
[
4
]
=
0
;
dev
=
0
;
ino
=
0
;
if
(
map
->
vm_file
!=
NULL
)
{
if
(
file
)
{
struct
inode
*
inode
=
map
->
vm_file
->
f_dentry
->
d_inode
;
dev
=
inode
->
i_sb
->
s_dev
;
ino
=
inode
->
i_ino
;
line
=
d_path
(
map
->
vm_file
->
f_dentry
,
map
->
vm_file
->
f_vfsmnt
,
buf
,
PAGE_SIZE
);
buf
[
PAGE_SIZE
-
1
]
=
'\n'
;
line
-=
MAPS_LINE_MAX
;
if
(
line
<
buf
)
line
=
buf
;
}
else
line
=
buf
;
len
=
sprintf
(
line
,
MAPS_LINE_FORMAT
,
map
->
vm_start
,
map
->
vm_end
,
str
,
map
->
vm_pgoff
<<
PAGE_SHIFT
,
MAJOR
(
dev
),
MINOR
(
dev
),
ino
);
if
(
map
->
vm_file
)
{
int
i
;
for
(
i
=
len
;
i
<
MAPS_LINE_MAX
;
i
++
)
line
[
i
]
=
' '
;
len
=
buf
+
PAGE_SIZE
-
line
;
memmove
(
buf
,
line
,
len
);
}
else
line
[
len
++
]
=
'\n'
;
return
len
;
}
seq_printf
(
m
,
"%0*lx-%0*lx %c%c%c%c %0*lx %02x:%02x %lu %n"
,
2
*
sizeof
(
void
*
),
map
->
vm_start
,
2
*
sizeof
(
void
*
),
map
->
vm_end
,
flags
&
VM_READ
?
'r'
:
'-'
,
flags
&
VM_WRITE
?
'w'
:
'-'
,
flags
&
VM_EXEC
?
'x'
:
'-'
,
flags
&
VM_MAYSHARE
?
's'
:
'p'
,
2
*
sizeof
(
void
*
),
map
->
vm_pgoff
<<
PAGE_SHIFT
,
MAJOR
(
dev
),
MINOR
(
dev
),
ino
,
&
len
);
if
(
map
->
vm_file
)
{
len
=
25
+
sizeof
(
void
*
)
*
6
-
len
;
if
(
len
<
1
)
len
=
1
;
seq_printf
(
m
,
"%*c"
,
len
,
' '
);
seq_path
(
m
,
file
->
f_vfsmnt
,
file
->
f_dentry
,
"
\t\n\\
"
);
}
seq_putc
(
m
,
'\n'
);
return
0
;
}
ssize_t
proc_pid_read_maps
(
struct
task_struct
*
task
,
struct
file
*
file
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
static
void
*
m_start
(
struct
seq_file
*
m
,
loff_t
*
pos
)
{
struct
mm_struct
*
mm
;
struct
task_struct
*
task
=
m
->
private
;
struct
mm_struct
*
mm
=
get_task_mm
(
task
);
struct
vm_area_struct
*
map
;
char
*
tmp
,
*
kbuf
;
long
retval
;
int
off
,
lineno
,
loff
;
/* reject calls with out of range parameters immediately */
retval
=
0
;
if
(
*
ppos
>
LONG_MAX
)
goto
out
;
if
(
count
==
0
)
goto
out
;
off
=
(
long
)
*
ppos
;
/*
* We might sleep getting the page, so get it first.
*/
retval
=
-
ENOMEM
;
kbuf
=
(
char
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
!
kbuf
)
goto
out
;
tmp
=
(
char
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
!
tmp
)
goto
out_free1
;
mm
=
get_task_mm
(
task
);
retval
=
0
;
loff_t
l
=
*
pos
;
if
(
!
mm
)
goto
out_free2
;
return
NULL
;
down_read
(
&
mm
->
mmap_sem
);
map
=
mm
->
mmap
;
lineno
=
0
;
loff
=
0
;
if
(
count
>
PAGE_SIZE
)
count
=
PAGE_SIZE
;
while
(
map
)
{
int
len
;
if
(
off
>
PAGE_SIZE
)
{
off
-=
PAGE_SIZE
;
goto
next
;
}
len
=
proc_pid_maps_get_line
(
tmp
,
map
);
len
-=
off
;
if
(
len
>
0
)
{
if
(
retval
+
len
>
count
)
{
/* only partial line transfer possible */
len
=
count
-
retval
;
/* save the offset where the next read
* must start */
loff
=
len
+
off
;
}
memcpy
(
kbuf
+
retval
,
tmp
+
off
,
len
);
retval
+=
len
;
}
off
=
0
;
next:
if
(
!
loff
)
lineno
++
;
if
(
retval
>=
count
)
break
;
if
(
loff
)
BUG
();
while
(
l
--
&&
map
)
map
=
map
->
vm_next
;
if
(
!
map
)
{
up_read
(
&
mm
->
mmap_sem
);
mmput
(
mm
);
}
return
map
;
}
static
void
m_stop
(
struct
seq_file
*
m
,
void
*
v
)
{
struct
vm_area_struct
*
map
=
v
;
if
(
map
)
{
struct
mm_struct
*
mm
=
map
->
vm_mm
;
up_read
(
&
mm
->
mmap_sem
);
mmput
(
mm
);
}
up_read
(
&
mm
->
mmap_sem
);
mmput
(
mm
);
if
(
retval
>
count
)
BUG
();
if
(
copy_to_user
(
buf
,
kbuf
,
retval
))
retval
=
-
EFAULT
;
else
*
ppos
=
(
lineno
<<
PAGE_SHIFT
)
+
loff
;
out_free2:
free_page
((
unsigned
long
)
tmp
);
out_free1:
free_page
((
unsigned
long
)
kbuf
);
out:
return
retval
;
}
static
void
*
m_next
(
struct
seq_file
*
m
,
void
*
v
,
loff_t
*
pos
)
{
struct
vm_area_struct
*
map
=
v
;
(
*
pos
)
++
;
if
(
map
->
vm_next
)
return
map
->
vm_next
;
m_stop
(
m
,
v
);
return
NULL
;
}
struct
seq_operations
proc_pid_maps_op
=
{
.
start
=
m_start
,
.
next
=
m_next
,
.
stop
=
m_stop
,
.
show
=
show_map
};
fs/seq_file.c
View file @
07ca08b1
...
...
@@ -297,6 +297,37 @@ int seq_printf(struct seq_file *m, const char *f, ...)
return
-
1
;
}
int
seq_path
(
struct
seq_file
*
m
,
struct
vfsmount
*
mnt
,
struct
dentry
*
dentry
,
char
*
esc
)
{
if
(
m
->
count
<
m
->
size
)
{
char
*
s
=
m
->
buf
+
m
->
count
;
char
*
p
=
d_path
(
dentry
,
mnt
,
s
,
m
->
size
-
m
->
count
);
if
(
!
IS_ERR
(
p
))
{
while
(
s
<=
p
)
{
char
c
=
*
p
++
;
if
(
!
c
)
{
p
=
m
->
buf
+
m
->
count
;
m
->
count
=
s
-
m
->
buf
;
return
s
-
p
;
}
else
if
(
!
strchr
(
esc
,
c
))
{
*
s
++
=
c
;
}
else
if
(
s
+
4
>
p
)
{
break
;
}
else
{
*
s
++
=
'\\'
;
*
s
++
=
'0'
+
((
c
&
0300
)
>>
6
);
*
s
++
=
'0'
+
((
c
&
070
)
>>
3
);
*
s
++
=
'0'
+
(
c
&
07
);
}
}
}
}
m
->
count
=
m
->
size
;
return
-
1
;
}
static
void
*
single_start
(
struct
seq_file
*
p
,
loff_t
*
pos
)
{
return
NULL
+
(
*
pos
==
0
);
...
...
include/linux/seq_file.h
View file @
07ca08b1
...
...
@@ -8,6 +8,8 @@
struct
seq_operations
;
struct
file
;
struct
vfsmount
;
struct
dentry
;
struct
inode
;
struct
seq_file
{
...
...
@@ -58,6 +60,8 @@ static inline int seq_puts(struct seq_file *m, const char *s)
int
seq_printf
(
struct
seq_file
*
,
const
char
*
,
...)
__attribute__
((
format
(
printf
,
2
,
3
)));
int
seq_path
(
struct
seq_file
*
,
struct
vfsmount
*
,
struct
dentry
*
,
char
*
);
int
single_open
(
struct
file
*
,
int
(
*
)(
struct
seq_file
*
,
void
*
),
void
*
);
int
single_release
(
struct
inode
*
,
struct
file
*
);
int
seq_release_private
(
struct
inode
*
,
struct
file
*
);
...
...
mm/swapfile.c
View file @
07ca08b1
...
...
@@ -1118,14 +1118,9 @@ static void *swap_start(struct seq_file *swap, loff_t *pos)
struct
swap_info_struct
*
ptr
=
swap_info
;
int
i
;
loff_t
l
=
*
pos
;
char
*
page
=
(
char
*
)
__get_free_page
(
GFP_KERNEL
);
swap
->
private
=
page
;
/* save for swap_show */
swap_list_lock
();
if
(
!
page
)
return
ERR_PTR
(
-
ENOMEM
);
for
(
i
=
0
;
i
<
nr_swapfiles
;
i
++
,
ptr
++
)
{
if
(
!
(
ptr
->
flags
&
SWP_USED
)
||
!
ptr
->
swap_map
)
continue
;
...
...
@@ -1154,24 +1149,21 @@ static void *swap_next(struct seq_file *swap, void *v, loff_t *pos)
static
void
swap_stop
(
struct
seq_file
*
swap
,
void
*
v
)
{
swap_list_unlock
();
free_page
((
unsigned
long
)
swap
->
private
);
swap
->
private
=
NULL
;
}
static
int
swap_show
(
struct
seq_file
*
swap
,
void
*
v
)
{
struct
swap_info_struct
*
ptr
=
v
;
struct
file
*
file
;
char
*
path
;
int
len
;
if
(
v
==
swap_info
)
seq_puts
(
swap
,
"Filename
\t\t\t\t
Type
\t\t
Size
\t
Used
\t
Priority
\n
"
);
file
=
ptr
->
swap_file
;
path
=
d_path
(
file
->
f_dentry
,
file
->
f_vfsmnt
,
swap
->
private
,
PAGE_SIZE
);
seq_printf
(
swap
,
"%-39s %s
\t
%d
\t
%ld
\t
%d
\n
"
,
path
,
len
=
seq_path
(
swap
,
file
->
f_vfsmnt
,
file
->
f_dentry
,
"
\t\n\\
"
);
seq_printf
(
swap
,
"%*s %s
\t
%d
\t
%ld
\t
%d
\n
"
,
len
<
40
?
40
-
len
:
1
,
" "
,
S_ISBLK
(
file
->
f_dentry
->
d_inode
->
i_mode
)
?
"partition"
:
"file
\t
"
,
ptr
->
pages
<<
(
PAGE_SHIFT
-
10
),
...
...
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