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
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