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
20fca9a1
Commit
20fca9a1
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.1.123pre1
parent
f85f3898
Changes
39
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
513 additions
and
400 deletions
+513
-400
Documentation/sound/AWE32
Documentation/sound/AWE32
+1
-1
arch/i386/kernel/process.c
arch/i386/kernel/process.c
+7
-4
drivers/char/console.c
drivers/char/console.c
+199
-156
drivers/char/console_macros.h
drivers/char/console_macros.h
+1
-2
drivers/char/consolemap.c
drivers/char/consolemap.c
+18
-0
drivers/char/selection.c
drivers/char/selection.c
+1
-1
drivers/char/sysrq.c
drivers/char/sysrq.c
+5
-1
drivers/char/tty_io.c
drivers/char/tty_io.c
+18
-6
drivers/char/vt.c
drivers/char/vt.c
+7
-56
drivers/video/vgacon.c
drivers/video/vgacon.c
+30
-20
fs/affs/symlink.c
fs/affs/symlink.c
+3
-3
fs/autofs/symlink.c
fs/autofs/symlink.c
+3
-2
fs/coda/symlink.c
fs/coda/symlink.c
+4
-3
fs/ext2/symlink.c
fs/ext2/symlink.c
+4
-3
fs/inode.c
fs/inode.c
+6
-2
fs/isofs/symlink.c
fs/isofs/symlink.c
+4
-3
fs/minix/symlink.c
fs/minix/symlink.c
+4
-3
fs/msdos/namei.c
fs/msdos/namei.c
+67
-34
fs/namei.c
fs/namei.c
+44
-19
fs/nfs/symlink.c
fs/nfs/symlink.c
+3
-3
fs/pipe.c
fs/pipe.c
+20
-7
fs/proc/link.c
fs/proc/link.c
+4
-3
fs/proc/proc_devtree.c
fs/proc/proc_devtree.c
+4
-3
fs/proc/root.c
fs/proc/root.c
+5
-7
fs/romfs/inode.c
fs/romfs/inode.c
+3
-2
fs/sysv/symlink.c
fs/sysv/symlink.c
+4
-3
fs/ufs/symlink.c
fs/ufs/symlink.c
+2
-2
fs/umsdos/symlink.c
fs/umsdos/symlink.c
+3
-2
include/linux/console.h
include/linux/console.h
+1
-5
include/linux/console_struct.h
include/linux/console_struct.h
+4
-1
include/linux/dcache.h
include/linux/dcache.h
+1
-1
include/linux/fs.h
include/linux/fs.h
+4
-3
include/linux/nbd.h
include/linux/nbd.h
+1
-1
include/linux/selection.h
include/linux/selection.h
+0
-2
include/linux/tty.h
include/linux/tty.h
+5
-6
include/linux/vt_buffer.h
include/linux/vt_buffer.h
+0
-3
include/linux/vt_kern.h
include/linux/vt_kern.h
+10
-7
init/main.c
init/main.c
+1
-1
kernel/exit.c
kernel/exit.c
+12
-19
No files found.
Documentation/sound/AWE32
View file @
20fca9a1
...
...
@@ -51,7 +51,7 @@ Then WaveTable goes. For some reason Plug-n-Play detects only one I/O port,
but the wavetable needs THREE! My working string is:
"(CONFIGURE CTL044/1132685 (LD 2 (IO 0 (BASE 0x0620)) (IO 1 (BASE 0x0A20))
(IO
3
(BASE 0x0E20)) (ACT Y) ))"
(IO
2
(BASE 0x0E20)) (ACT Y) ))"
Resources 0x0620, 0x0A20 and 0x0E20 should work. Other on-board devices:
Gameport and StereoEnhance are not required to be inited.
...
...
arch/i386/kernel/process.c
View file @
20fca9a1
...
...
@@ -540,10 +540,10 @@ void release_thread(struct task_struct *dead_task)
static
inline
void
unlazy_fpu
(
struct
task_struct
*
tsk
)
{
if
(
tsk
->
flags
&
PF_USEDFPU
)
{
tsk
->
flags
&=
~
PF_USEDFPU
;
__asm__
(
"fnsave %0"
:
"=m"
(
tsk
->
tss
.
i387
));
stts
();
asm
volatile
(
"fwait"
);
tsk
->
flags
&=
~
PF_USEDFPU
;
stts
();
}
}
...
...
@@ -737,8 +737,11 @@ void __switch_to(struct task_struct *prev, struct task_struct *next)
asm
volatile
(
"lldt %0"
:
:
"g"
(
*
(
unsigned
short
*
)
&
next
->
tss
.
ldt
));
/* Re-load page tables */
if
(
next
->
tss
.
cr3
!=
prev
->
tss
.
cr3
)
asm
volatile
(
"movl %0,%%cr3"
:
:
"r"
(
next
->
tss
.
cr3
));
{
unsigned
long
new_cr3
=
next
->
tss
.
cr3
;
if
(
new_cr3
!=
prev
->
tss
.
cr3
)
asm
volatile
(
"movl %0,%%cr3"
:
:
"r"
(
new_cr3
));
}
/*
* Restore %fs and %gs.
...
...
drivers/char/console.c
View file @
20fca9a1
This diff is collapsed.
Click to expand it.
drivers/char/console_macros.h
View file @
20fca9a1
...
...
@@ -26,8 +26,6 @@
#define utf (vc_cons[currcons].d->vc_utf)
#define utf_count (vc_cons[currcons].d->vc_utf_count)
#define utf_char (vc_cons[currcons].d->vc_utf_char)
#define video_mem_start (vc_cons[currcons].d->vc_video_mem_start)
#define video_mem_end (vc_cons[currcons].d->vc_video_mem_end)
#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)
#define disp_ctrl (vc_cons[currcons].d->vc_disp_ctrl)
#define toggle_meta (vc_cons[currcons].d->vc_toggle_meta)
...
...
@@ -64,6 +62,7 @@
#define cursor_type (vc_cons[currcons].d->vc_cursor_type)
#define display_fg (vc_cons[currcons].d->vc_display_fg)
#define complement_mask (vc_cons[currcons].d->vc_complement_mask)
#define s_complement_mask (vc_cons[currcons].d->vc_s_complement_mask)
#define hi_font_mask (vc_cons[currcons].d->vc_hi_font_mask)
#define vcmode (vt_cons[currcons]->vc_mode)
...
...
drivers/char/consolemap.c
View file @
20fca9a1
...
...
@@ -575,6 +575,24 @@ con_set_default_unimap(int con)
return
err
;
}
int
con_copy_unimap
(
int
dstcon
,
int
srccon
)
{
struct
vc_data
*
sconp
=
vc_cons
[
srccon
].
d
;
struct
vc_data
*
dconp
=
vc_cons
[
dstcon
].
d
;
struct
uni_pagedir
*
q
;
if
(
!
vc_cons_allocated
(
srccon
)
||
!*
sconp
->
vc_uni_pagedir_loc
)
return
-
EINVAL
;
if
(
*
dconp
->
vc_uni_pagedir_loc
==
*
sconp
->
vc_uni_pagedir_loc
)
return
0
;
con_free_unimap
(
dstcon
);
q
=
(
struct
uni_pagedir
*
)
*
sconp
->
vc_uni_pagedir_loc
;
q
->
refcount
++
;
*
dconp
->
vc_uni_pagedir_loc
=
(
long
)
q
;
return
0
;
}
int
con_get_unimap
(
int
con
,
ushort
ct
,
ushort
*
uct
,
struct
unipair
*
list
)
{
...
...
drivers/char/selection.c
View file @
20fca9a1
...
...
@@ -123,7 +123,7 @@ int set_selection(const unsigned long arg, struct tty_struct *tty, int user)
int
i
,
ps
,
pe
;
unsigned
int
currcons
=
fg_console
;
do_
unblank_screen
();
unblank_screen
();
poke_blanked_console
();
{
unsigned
short
*
args
,
xs
,
ys
,
xe
,
ye
;
...
...
drivers/char/sysrq.c
View file @
20fca9a1
/* -*- linux-c -*-
*
* $Id: sysrq.c,v 1.
7 1997/11/06 15:57:09
mj Exp $
* $Id: sysrq.c,v 1.
15 1998/08/23 14:56:41
mj Exp $
*
* Linux Magic System Request Key Hacks
*
...
...
@@ -70,12 +70,14 @@ void handle_sysrq(int key, struct pt_regs *pt_regs,
printk
(
"Keyboard mode set to XLATE
\n
"
);
}
break
;
#ifdef CONFIG_VT
case
'k'
:
/* K -- SAK */
printk
(
"SAK
\n
"
);
if
(
tty
)
do_SAK
(
tty
);
reset_vc
(
fg_console
);
break
;
#endif
case
'b'
:
/* B -- boot immediately */
printk
(
"Resetting
\n
"
);
machine_restart
(
NULL
);
...
...
@@ -131,8 +133,10 @@ void handle_sysrq(int key, struct pt_regs *pt_regs,
default:
/* Unknown: help */
if
(
kbd
)
printk
(
"unRaw "
);
#ifdef CONFIG_VT
if
(
tty
)
printk
(
"saK "
);
#endif
printk
(
"Boot "
#ifdef CONFIG_APM
"Off "
...
...
drivers/char/tty_io.c
View file @
20fca9a1
...
...
@@ -126,11 +126,11 @@ static ssize_t tty_write(struct file *, const char *, size_t, loff_t *);
static
unsigned
int
tty_poll
(
struct
file
*
,
poll_table
*
);
static
int
tty_open
(
struct
inode
*
,
struct
file
*
);
static
int
tty_release
(
struct
inode
*
,
struct
file
*
);
static
int
tty_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
);
int
tty_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
);
static
int
tty_fasync
(
int
fd
,
struct
file
*
filp
,
int
on
);
#ifdef CONFIG_8xx
extern
long
console_8xx_init
(
void
);
extern
long
console_8xx_init
(
long
,
long
);
extern
int
rs_8xx_init
(
void
);
#endif
/* CONFIG_8xx */
...
...
@@ -640,7 +640,13 @@ static inline ssize_t do_tty_write(
size_t
count
)
{
ssize_t
ret
=
0
,
written
=
0
;
struct
inode
*
inode
=
file
->
f_dentry
->
d_inode
;
up
(
&
inode
->
i_sem
);
if
(
down_interruptible
(
&
inode
->
i_atomic_write
))
{
down
(
&
inode
->
i_sem
);
return
-
ERESTARTSYS
;
}
for
(;;)
{
unsigned
long
size
=
PAGE_SIZE
*
2
;
if
(
size
>
count
)
...
...
@@ -663,6 +669,8 @@ static inline ssize_t do_tty_write(
file
->
f_dentry
->
d_inode
->
i_mtime
=
CURRENT_TIME
;
ret
=
written
;
}
up
(
&
inode
->
i_atomic_write
);
down
(
&
inode
->
i_sem
);
return
ret
;
}
...
...
@@ -1604,8 +1612,8 @@ static int send_break(struct tty_struct *tty, int duration)
/*
* Split this up, as gcc can choke on it otherwise..
*/
static
int
tty_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
int
tty_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
tty_struct
*
tty
,
*
real_tty
;
int
retval
;
...
...
@@ -2004,7 +2012,11 @@ long __init console_init(long kmem_start, long kmem_end)
kmem_start
=
con_init
(
kmem_start
);
#endif
#ifdef CONFIG_SERIAL_CONSOLE
#ifdef CONFIG_8xx
kmem_start
=
console_8xx_init
(
kmem_start
,
kmem_end
);
#else
kmem_start
=
serial_console_init
(
kmem_start
,
kmem_end
);
#endif
/* CONFIG_8xx */
#endif
return
kmem_start
;
}
...
...
drivers/char/vt.c
View file @
20fca9a1
...
...
@@ -73,45 +73,6 @@ unsigned int video_scan_lines;
#define GPLAST 0x3df
#define GPNUM (GPLAST - GPFIRST + 1)
/*
* This function is called when the size of the physical screen has been
* changed. If either the row or col argument is nonzero, set the appropriate
* entry in each winsize structure for all the virtual consoles, then
* send SIGWINCH to all processes with a virtual console as controlling
* tty.
*/
static
int
kd_size_changed
(
int
row
,
int
col
)
{
struct
task_struct
*
p
;
int
i
;
if
(
!
row
&&
!
col
)
return
0
;
for
(
i
=
0
;
i
<
MAX_NR_CONSOLES
;
i
++
)
{
if
(
console_driver
.
table
[
i
]
)
{
if
(
row
)
console_driver
.
table
[
i
]
->
winsize
.
ws_row
=
row
;
if
(
col
)
console_driver
.
table
[
i
]
->
winsize
.
ws_col
=
col
;
}
}
read_lock
(
&
tasklist_lock
);
for_each_task
(
p
)
{
if
(
p
->
tty
&&
MAJOR
(
p
->
tty
->
device
)
==
TTY_MAJOR
&&
MINOR
(
p
->
tty
->
device
)
<=
MAX_NR_CONSOLES
&&
MINOR
(
p
->
tty
->
device
)
)
{
send_sig
(
SIGWINCH
,
p
,
1
);
}
}
read_unlock
(
&
tasklist_lock
);
return
0
;
}
/*
* Generates sound of some frequency for some number of clock ticks
*
...
...
@@ -553,7 +514,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
* explicitly blank/unblank the screen if switching modes
*/
if
(
arg
==
KD_TEXT
)
do_
unblank_screen
();
unblank_screen
();
else
do_blank_screen
(
1
);
return
0
;
...
...
@@ -781,7 +742,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if
(
arg
==
0
||
arg
>
MAX_NR_CONSOLES
)
return
-
ENXIO
;
arg
--
;
i
=
vc_allocate
(
arg
,
0
);
i
=
vc_allocate
(
arg
);
if
(
i
)
return
i
;
set_console
(
arg
);
...
...
@@ -833,7 +794,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/
int
newvt
=
vt_cons
[
console
]
->
vt_newvt
;
vt_cons
[
console
]
->
vt_newvt
=
-
1
;
i
=
vc_allocate
(
newvt
,
0
);
i
=
vc_allocate
(
newvt
);
if
(
i
)
return
i
;
/*
...
...
@@ -893,8 +854,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return
i
;
__get_user
(
ll
,
&
vtsizes
->
v_rows
);
__get_user
(
cc
,
&
vtsizes
->
v_cols
);
i
=
vc_resize_all
(
ll
,
cc
);
return
i
?
i
:
kd_size_changed
(
ll
,
cc
);
return
vc_resize_all
(
ll
,
cc
);
}
case
VT_RESIZEX
:
...
...
@@ -942,12 +902,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if
(
clin
)
video_font_height
=
clin
;
i
=
vc_resize_all
(
ll
,
cc
);
if
(
i
)
return
i
;
kd_size_changed
(
ll
,
cc
);
return
0
;
return
vc_resize_all
(
ll
,
cc
);
}
case
PIO_FONT
:
{
...
...
@@ -1201,7 +1156,7 @@ void complete_change_console(unsigned int new_console)
* unblank the screen later.
*/
old_vc_mode
=
vt_cons
[
fg_console
]
->
vc_mode
;
update
_screen
(
new_console
);
switch
_screen
(
new_console
);
/*
* If this new console is under process control, send it a signal
...
...
@@ -1239,15 +1194,11 @@ void complete_change_console(unsigned int new_console)
if
(
old_vc_mode
!=
vt_cons
[
new_console
]
->
vc_mode
)
{
if
(
vt_cons
[
new_console
]
->
vc_mode
==
KD_TEXT
)
do_
unblank_screen
();
unblank_screen
();
else
do_blank_screen
(
1
);
}
/* Set the colour palette for this VT */
if
(
vt_cons
[
new_console
]
->
vc_mode
==
KD_TEXT
)
set_palette
()
;
/*
* Wake anyone waiting for their VT to activate
*/
...
...
drivers/video/vgacon.c
View file @
20fca9a1
...
...
@@ -64,8 +64,6 @@
*/
#undef TRIDENT_GLITCH
#undef VGA_CAN_DO_64KB
#define dac_reg 0x3c8
#define dac_val 0x3c9
#define attrib_port 0x3c0
...
...
@@ -115,6 +113,7 @@ static int vga_palette_blanked;
static
int
vga_is_gfx
;
static
int
vga_512_chars
;
static
int
vga_video_font_height
;
static
unsigned
int
vga_rolled_over
=
0
;
void
no_scroll
(
char
*
str
,
int
*
ints
)
...
...
@@ -190,7 +189,7 @@ __initfunc(static const char *vgacon_startup(void))
display_desc
=
"*MDA"
;
request_region
(
0x3b0
,
12
,
"mda"
);
request_region
(
0x3bf
,
1
,
"mda"
);
vga_video_font_height
=
1
6
;
vga_video_font_height
=
1
4
;
}
}
else
/* If not, it is color. */
...
...
@@ -453,9 +452,8 @@ static int vgacon_switch(struct vc_data *c)
*/
vga_video_num_columns
=
c
->
vc_cols
;
vga_video_num_lines
=
c
->
vc_rows
;
if
(
vga_is_gfx
)
return
1
;
scr_memcpyw_to
((
u16
*
)
c
->
vc_origin
,
(
u16
*
)
c
->
vc_screenbuf
,
c
->
vc_screenbuf_size
);
if
(
!
vga_is_gfx
)
scr_memcpyw_to
((
u16
*
)
c
->
vc_origin
,
(
u16
*
)
c
->
vc_screenbuf
,
c
->
vc_screenbuf_size
);
return
0
;
/* Redrawing not needed */
}
...
...
@@ -474,8 +472,7 @@ static void vga_set_palette(struct vc_data *c, unsigned char *table)
static
int
vgacon_set_palette
(
struct
vc_data
*
c
,
unsigned
char
*
table
)
{
#ifdef CAN_LOAD_PALETTE
if
(
vga_video_type
!=
VIDEO_TYPE_VGAC
||
vga_palette_blanked
)
if
(
vga_video_type
!=
VIDEO_TYPE_VGAC
||
vga_palette_blanked
||
!
CON_IS_VISIBLE
(
c
))
return
-
EINVAL
;
vga_set_palette
(
c
,
table
);
return
0
;
...
...
@@ -637,10 +634,11 @@ static int vgacon_blank(struct vc_data *c, int blank)
vga_palette_blanked
=
1
;
return
0
;
}
scr_memsetw
((
void
*
)
vga_vram_base
,
BLANK
,
vc_cons
[
0
].
d
->
vc_screenbuf_size
);
vgacon_set_origin
(
c
);
scr_memsetw
((
void
*
)
vga_vram_base
,
BLANK
,
c
->
vc_screenbuf_size
);
return
1
;
case
-
1
:
/* Entering graphic mode */
scr_memsetw
((
void
*
)
vga_vram_base
,
BLANK
,
vc_cons
[
0
].
d
->
vc_screenbuf_size
);
scr_memsetw
((
void
*
)
vga_vram_base
,
BLANK
,
c
->
vc_screenbuf_size
);
vga_is_gfx
=
1
;
return
1
;
default:
/* VESA blanking */
...
...
@@ -899,14 +897,24 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
if
(
!
lines
)
/* Turn scrollback off */
c
->
vc_visible_origin
=
c
->
vc_origin
;
else
{
int
p
=
c
->
vc_visible_origin
-
vga_vram_base
;
int
margin
=
c
->
vc_rows
/
4
*
c
->
vc_size_row
;
p
+=
lines
*
c
->
vc_size_row
;
if
(
lines
<
0
&&
p
<
margin
)
int
vram_size
=
vga_vram_end
-
vga_vram_base
;
int
margin
=
c
->
vc_size_row
*
4
;
int
ul
,
we
,
p
,
st
;
if
(
vga_rolled_over
>
(
c
->
vc_scr_end
-
vga_vram_base
)
+
margin
)
{
ul
=
c
->
vc_scr_end
-
vga_vram_base
;
we
=
vga_rolled_over
+
c
->
vc_size_row
;
}
else
{
ul
=
0
;
we
=
vram_size
;
}
p
=
(
c
->
vc_visible_origin
-
vga_vram_base
-
ul
+
we
)
%
we
+
lines
*
c
->
vc_size_row
;
st
=
(
c
->
vc_origin
-
vga_vram_base
-
ul
+
we
)
%
we
;
if
(
p
<
margin
)
p
=
0
;
c
->
vc_visible_origin
=
p
+
vga_vram_base
;
if
(
lines
>
0
&&
c
->
vc_visible_origin
>
c
->
vc_origin
-
margin
)
c
->
vc_visible_origin
=
c
->
vc_origin
;
if
(
p
>
st
-
margin
)
p
=
st
;
c
->
vc_visible_origin
=
vga_vram_base
+
(
p
+
ul
)
%
we
;
}
vga_set_mem_top
(
c
);
return
1
;
...
...
@@ -919,6 +927,7 @@ static int vgacon_set_origin(struct vc_data *c)
return
0
;
c
->
vc_origin
=
c
->
vc_visible_origin
=
vga_vram_base
;
vga_set_mem_top
(
c
);
vga_rolled_over
=
0
;
return
1
;
}
...
...
@@ -935,9 +944,8 @@ static void vgacon_save_screen(struct vc_data *c)
c
->
vc_x
=
ORIG_X
;
c
->
vc_y
=
ORIG_Y
;
}
if
(
vga_is_gfx
)
return
;
scr_memcpyw_from
((
u16
*
)
c
->
vc_screenbuf
,
(
u16
*
)
c
->
vc_origin
,
c
->
vc_screenbuf_size
);
if
(
!
vga_is_gfx
)
scr_memcpyw_from
((
u16
*
)
c
->
vc_screenbuf
,
(
u16
*
)
c
->
vc_origin
,
c
->
vc_screenbuf_size
);
}
static
int
vgacon_scroll
(
struct
vc_data
*
c
,
int
t
,
int
b
,
int
dir
,
int
lines
)
...
...
@@ -962,6 +970,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
(
u16
*
)(
oldo
+
delta
),
c
->
vc_screenbuf_size
-
delta
);
c
->
vc_origin
=
vga_vram_base
;
vga_rolled_over
=
oldo
-
vga_vram_base
;
}
else
c
->
vc_origin
+=
delta
;
scr_memsetw
((
u16
*
)(
c
->
vc_origin
+
c
->
vc_screenbuf_size
-
delta
),
c
->
vc_video_erase_char
,
delta
);
...
...
@@ -971,6 +980,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
(
u16
*
)
oldo
,
c
->
vc_screenbuf_size
-
delta
);
c
->
vc_origin
=
vga_vram_end
-
c
->
vc_screenbuf_size
;
vga_rolled_over
=
0
;
}
else
c
->
vc_origin
-=
delta
;
c
->
vc_scr_end
=
c
->
vc_origin
+
c
->
vc_screenbuf_size
;
...
...
fs/affs/symlink.c
View file @
20fca9a1
...
...
@@ -20,7 +20,7 @@
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
static
int
affs_readlink
(
struct
dentry
*
,
char
*
,
int
);
static
struct
dentry
*
affs_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
);
static
struct
dentry
*
affs_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
,
unsigned
int
);
struct
inode_operations
affs_symlink_inode_operations
=
{
NULL
,
/* no file-operations */
...
...
@@ -98,7 +98,7 @@ affs_readlink(struct dentry *dentry, char *buffer, int buflen)
}
static
struct
dentry
*
affs_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
affs_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
buffer_head
*
bh
;
...
...
@@ -150,7 +150,7 @@ affs_follow_link(struct dentry *dentry, struct dentry *base)
}
buffer
[
i
]
=
'\0'
;
affs_brelse
(
bh
);
base
=
lookup_dentry
(
buffer
,
base
,
1
);
base
=
lookup_dentry
(
buffer
,
base
,
follow
);
kfree
(
buffer
);
return
base
;
}
...
...
fs/autofs/symlink.c
View file @
20fca9a1
...
...
@@ -27,12 +27,13 @@ static int autofs_readlink(struct dentry *dentry, char *buffer, int buflen)
}
static
struct
dentry
*
autofs_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
autofs_symlink
*
sl
;
sl
=
(
struct
autofs_symlink
*
)
dentry
->
d_inode
->
u
.
generic_ip
;
return
lookup_dentry
(
sl
->
data
,
base
,
1
);
return
lookup_dentry
(
sl
->
data
,
base
,
follow
);
}
struct
inode_operations
autofs_symlink_inode_operations
=
{
...
...
fs/coda/symlink.c
View file @
20fca9a1
...
...
@@ -26,7 +26,7 @@
#include <linux/coda_proc.h>
static
int
coda_readlink
(
struct
dentry
*
de
,
char
*
buffer
,
int
length
);
static
struct
dentry
*
coda_follow_link
(
struct
dentry
*
,
struct
dentry
*
);
static
struct
dentry
*
coda_follow_link
(
struct
dentry
*
,
struct
dentry
*
,
unsigned
int
);
struct
inode_operations
coda_symlink_inode_operations
=
{
NULL
,
/* no file-operations */
...
...
@@ -86,7 +86,8 @@ static int coda_readlink(struct dentry *de, char *buffer, int length)
}
static
struct
dentry
*
coda_follow_link
(
struct
dentry
*
de
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
de
->
d_inode
;
int
error
;
...
...
@@ -116,7 +117,7 @@ static struct dentry *coda_follow_link(struct dentry *de,
memcpy
(
path
,
mem
,
len
);
path
[
len
]
=
0
;
base
=
lookup_dentry
(
path
,
base
,
1
);
base
=
lookup_dentry
(
path
,
base
,
follow
);
kfree
(
path
);
return
base
;
}
fs/ext2/symlink.c
View file @
20fca9a1
...
...
@@ -25,7 +25,7 @@
#include <linux/stat.h>
static
int
ext2_readlink
(
struct
dentry
*
,
char
*
,
int
);
static
struct
dentry
*
ext2_follow_link
(
struct
dentry
*
,
struct
dentry
*
);
static
struct
dentry
*
ext2_follow_link
(
struct
dentry
*
,
struct
dentry
*
,
unsigned
int
);
/*
* symlinks can't do much...
...
...
@@ -52,7 +52,8 @@ struct inode_operations ext2_symlink_inode_operations = {
};
static
struct
dentry
*
ext2_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
buffer_head
*
bh
=
NULL
;
...
...
@@ -68,7 +69,7 @@ static struct dentry * ext2_follow_link(struct dentry * dentry,
link
=
bh
->
b_data
;
}
UPDATE_ATIME
(
inode
);
base
=
lookup_dentry
(
link
,
base
,
1
);
base
=
lookup_dentry
(
link
,
base
,
follow
);
if
(
bh
)
brelse
(
bh
);
return
base
;
...
...
fs/inode.c
View file @
20fca9a1
...
...
@@ -131,6 +131,7 @@ static inline void init_once(struct inode * inode)
INIT_LIST_HEAD
(
&
inode
->
i_hash
);
INIT_LIST_HEAD
(
&
inode
->
i_dentry
);
sema_init
(
&
inode
->
i_sem
,
1
);
sema_init
(
&
inode
->
i_atomic_write
,
1
);
}
static
inline
void
write_inode
(
struct
inode
*
inode
)
...
...
@@ -714,8 +715,11 @@ if (inode->i_count)
printk
(
KERN_ERR
"iput: device %s inode %ld count changed, count=%d
\n
"
,
kdevname
(
inode
->
i_dev
),
inode
->
i_ino
,
inode
->
i_count
);
if
(
atomic_read
(
&
inode
->
i_sem
.
count
)
!=
1
)
printk
(
KERN_ERR
"iput: Aieee, semaphore in use device %s, count=%d
\n
"
,
kdevname
(
inode
->
i_dev
),
atomic_read
(
&
inode
->
i_sem
.
count
));
printk
(
KERN_ERR
"iput: Aieee, semaphore in use inode %s/%ld, count=%d
\n
"
,
kdevname
(
inode
->
i_dev
),
inode
->
i_ino
,
atomic_read
(
&
inode
->
i_sem
.
count
));
if
(
atomic_read
(
&
inode
->
i_atomic_write
.
count
)
!=
1
)
printk
(
KERN_ERR
"iput: Aieee, atomic write semaphore in use inode %s/%ld, count=%d
\n
"
,
kdevname
(
inode
->
i_dev
),
inode
->
i_ino
,
atomic_read
(
&
inode
->
i_sem
.
count
));
#endif
}
if
(
inode
->
i_count
>
(
1
<<
31
))
{
...
...
fs/isofs/symlink.c
View file @
20fca9a1
...
...
@@ -19,7 +19,7 @@
#include <asm/uaccess.h>
static
int
isofs_readlink
(
struct
dentry
*
,
char
*
,
int
);
static
struct
dentry
*
isofs_follow_link
(
struct
dentry
*
,
struct
dentry
*
);
static
struct
dentry
*
isofs_follow_link
(
struct
dentry
*
,
struct
dentry
*
,
unsigned
int
);
/*
* symlinks can't do much...
...
...
@@ -66,7 +66,8 @@ static int isofs_readlink(struct dentry * dentry, char * buffer, int buflen)
}
static
struct
dentry
*
isofs_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
char
*
pnt
;
...
...
@@ -76,7 +77,7 @@ static struct dentry * isofs_follow_link(struct dentry * dentry,
return
ERR_PTR
(
-
ELOOP
);
}
base
=
lookup_dentry
(
pnt
,
base
,
1
);
base
=
lookup_dentry
(
pnt
,
base
,
follow
);
kfree
(
pnt
);
return
base
;
...
...
fs/minix/symlink.c
View file @
20fca9a1
...
...
@@ -15,7 +15,7 @@
#include <asm/uaccess.h>
static
int
minix_readlink
(
struct
dentry
*
,
char
*
,
int
);
static
struct
dentry
*
minix_follow_link
(
struct
dentry
*
,
struct
dentry
*
);
static
struct
dentry
*
minix_follow_link
(
struct
dentry
*
,
struct
dentry
*
,
unsigned
int
);
/*
* symlinks can't do much...
...
...
@@ -41,7 +41,8 @@ struct inode_operations minix_symlink_inode_operations = {
};
static
struct
dentry
*
minix_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
buffer_head
*
bh
;
...
...
@@ -52,7 +53,7 @@ static struct dentry * minix_follow_link(struct dentry * dentry,
return
ERR_PTR
(
-
EIO
);
}
UPDATE_ATIME
(
inode
);
base
=
lookup_dentry
(
bh
->
b_data
,
base
,
1
);
base
=
lookup_dentry
(
bh
->
b_data
,
base
,
follow
);
brelse
(
bh
);
return
base
;
}
...
...
fs/msdos/namei.c
View file @
20fca9a1
...
...
@@ -266,6 +266,7 @@ int msdos_lookup(struct inode *dir,struct dentry *dentry)
res
=
msdos_find
(
dir
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
&
bh
,
&
de
,
&
ino
);
if
(
res
==
-
ENOENT
)
goto
add
;
if
(
res
<
0
)
...
...
@@ -275,7 +276,7 @@ int msdos_lookup(struct inode *dir,struct dentry *dentry)
/* try to get the inode */
res
=
-
EACCES
;
inode
=
iget
(
dir
->
i_
sb
,
ino
);
inode
=
iget
(
sb
,
ino
);
if
(
!
inode
)
goto
out
;
if
(
!
inode
->
i_sb
||
...
...
@@ -289,9 +290,9 @@ int msdos_lookup(struct inode *dir,struct dentry *dentry)
iput
(
inode
);
goto
out
;
}
res
=
0
;
add:
d_add
(
dentry
,
inode
);
res
=
0
;
out:
return
res
;
}
...
...
@@ -446,14 +447,14 @@ int msdos_rmdir(struct inode *dir, struct dentry *dentry)
if
(
dir
->
i_dev
!=
inode
->
i_dev
||
dir
==
inode
)
printk
(
"msdos_rmdir: impossible condition
\n
"
);
/*
*
Prune any child dentries, then verify that
*
the directory is empty and
not in use.
*
Check whether the directory is empty, then prune
*
any child dentries and make sure it's
not in use.
*/
shrink_dcache_parent
(
dentry
);
res
=
msdos_empty
(
inode
);
if
(
res
)
goto
rmdir_done
;
res
=
-
EBUSY
;
shrink_dcache_parent
(
dentry
);
if
(
dentry
->
d_count
>
1
)
{
#ifdef MSDOS_DEBUG
printk
(
"msdos_rmdir: %s/%s busy, d_count=%d
\n
"
,
...
...
@@ -476,6 +477,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count);
de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
bh
,
1
);
res
=
0
;
rmdir_done:
fat_brelse
(
sb
,
bh
);
return
res
;
...
...
@@ -499,18 +501,21 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
return
res
;
is_hid
=
(
dentry
->
d_name
.
name
[
0
]
==
'.'
)
&&
(
msdos_name
[
0
]
!=
'.'
);
fat_lock_creation
();
if
(
fat_scan
(
dir
,
msdos_name
,
&
bh
,
&
de
,
&
ino
,
SCAN_ANY
)
>=
0
)
{
fat_unlock_creation
();
/* N.B. does this need to be released on the other path? */
fat_brelse
(
sb
,
bh
);
return
-
EEXIST
;
}
if
(
fat_scan
(
dir
,
msdos_name
,
&
bh
,
&
de
,
&
ino
,
SCAN_ANY
)
>=
0
)
goto
out_exist
;
res
=
msdos_create_entry
(
dir
,
msdos_name
,
1
,
is_hid
,
&
inode
);
if
(
res
<
0
)
goto
out_unlock
;
dir
->
i_nlink
++
;
inode
->
i_nlink
=
2
;
/* no need to mark them dirty */
MSDOS_I
(
inode
)
->
i_busy
=
1
;
/* prevent lookups */
/*
* Instantiate the dentry now, in case we need to cleanup.
*/
d_instantiate
(
dentry
,
inode
);
if
((
res
=
fat_add_cluster
(
inode
))
<
0
)
goto
mkdir_error
;
if
((
res
=
msdos_create_entry
(
inode
,
MSDOS_DOT
,
1
,
0
,
&
dot
))
<
0
)
...
...
@@ -521,9 +526,9 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
dot
->
i_nlink
=
inode
->
i_nlink
;
mark_inode_dirty
(
dot
);
iput
(
dot
);
if
((
res
=
msdos_create_entry
(
inode
,
MSDOS_DOTDOT
,
1
,
0
,
&
dot
))
<
0
)
goto
mkdir_error
;
fat_unlock_creation
();
dot
->
i_size
=
dir
->
i_size
;
MSDOS_I
(
dot
)
->
i_start
=
MSDOS_I
(
dir
)
->
i_start
;
MSDOS_I
(
dot
)
->
i_logstart
=
MSDOS_I
(
dir
)
->
i_logstart
;
...
...
@@ -531,15 +536,22 @@ int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode)
mark_inode_dirty
(
dot
);
MSDOS_I
(
inode
)
->
i_busy
=
0
;
iput
(
dot
);
d_instantiate
(
dentry
,
inode
);
return
0
;
res
=
0
;
mkdir_error:
if
(
msdos_rmdir
(
dir
,
dentry
)
<
0
)
fat_fs_panic
(
dir
->
i_sb
,
"rmdir in mkdir failed"
);
out_unlock:
fat_unlock_creation
();
return
res
;
mkdir_error:
printk
(
"msdos_mkdir: error=%d, attempting cleanup
\n
"
,
res
);
if
(
msdos_rmdir
(
dir
,
dentry
)
<
0
)
fat_fs_panic
(
dir
->
i_sb
,
"rmdir in mkdir failed"
);
goto
out_unlock
;
out_exist:
fat_brelse
(
sb
,
bh
);
res
=
-
EEXIST
;
goto
out_unlock
;
}
/***** Unlink a file */
...
...
@@ -636,10 +648,14 @@ static int msdos_rename_same(struct inode *old_dir,char *old_name,
if
((
old_de
->
attr
&
ATTR_SYS
))
goto
out_error
;
if
(
S_ISDIR
(
new_inode
->
i_mode
))
{
/* make sure it's empty */
error
=
msdos_empty
(
new_inode
);
if
(
error
)
goto
out_error
;
#ifdef MSDOS_CHECK_BUSY
/* check for a busy dentry */
error
=
-
EBUSY
;
if
(
new_dentry
->
d_count
>
1
)
{
/* check for a busy dentry */
error
=
-
EBUSY
;
shrink_dcache_parent
(
new_dentry
);
if
(
new_dentry
->
d_count
>
1
)
{
printk
(
"msdos_rename_same: %s/%s busy, count=%d
\n
"
,
...
...
@@ -647,20 +663,19 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
new_dentry
->
d_count
);
goto
out_error
;
}
}
#endif
if
(
S_ISDIR
(
new_inode
->
i_mode
))
{
new_dir
->
i_nlink
--
;
mark_inode_dirty
(
new_dir
);
}
new_inode
->
i_nlink
=
0
;
MSDOS_I
(
new_inode
)
->
i_busy
=
1
;
mark_inode_dirty
(
new_inode
);
#ifdef MSDOS_CHECK_BUSY
/* d_delete the dentry, as we killed its inode */
d_delete
(
new_dentry
);
#endif
/*
* Make it negative if it's not busy;
* otherwise let d_move() drop it.
*/
if
(
new_dentry
->
d_count
==
1
)
d_delete
(
new_dentry
);
new_de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
new_bh
,
1
);
...
...
@@ -763,16 +778,22 @@ new_dentry->d_count);
}
#endif
if
(
S_ISDIR
(
new_inode
->
i_mode
))
{
/* make sure it's empty */
error
=
msdos_empty
(
new_inode
);
if
(
error
)
goto
out_new
;
new_dir
->
i_nlink
--
;
mark_inode_dirty
(
new_dir
);
}
new_inode
->
i_nlink
=
0
;
MSDOS_I
(
new_inode
)
->
i_busy
=
1
;
mark_inode_dirty
(
new_inode
);
#ifdef MSDOS_CHECK_BUSY
/* d_delete the dentry, as we killed its inode */
d_delete
(
new_dentry
);
#endif
/*
* Make it negative if it's not busy;
* otherwise let d_move() drop it.
*/
if
(
new_dentry
->
d_count
==
1
)
d_delete
(
new_dentry
);
new_de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
new_bh
,
1
);
fat_brelse
(
sb
,
new_bh
);
...
...
@@ -804,12 +825,20 @@ new_dentry->d_count);
free_inode
=
iget
(
sb
,
free_ino
);
if
(
!
free_inode
)
goto
out_iput
;
/* make sure it's not busy! */
if
(
MSDOS_I
(
free_inode
)
->
i_busy
)
printk
(
KERN_ERR
"msdos_rename_diff: new inode %ld busy!
\n
"
,
(
ino_t
)
free_ino
);
if
(
!
list_empty
(
&
free_inode
->
i_dentry
))
printk
(
"msdos_rename_diff: free inode has aliases??
\n
"
);
msdos_read_inode
(
free_inode
);
fat_mark_buffer_dirty
(
sb
,
free_bh
,
1
);
/*
* Make sure the old dentry isn't busy,
* as we need to change inodes ...
*/
error
=
-
EBUSY
;
if
(
old_dentry
->
d_count
>
1
)
{
shrink_dcache_parent
(
old_dentry
);
if
(
old_dentry
->
d_count
>
1
)
{
...
...
@@ -836,6 +865,11 @@ old_dentry->d_count);
MSDOS_I
(
free_inode
)
->
i_logstart
=
MSDOS_I
(
old_inode
)
->
i_logstart
;
MSDOS_I
(
free_inode
)
->
i_attrs
=
MSDOS_I
(
old_inode
)
->
i_attrs
;
/* release the old inode's resources */
MSDOS_I
(
old_inode
)
->
i_start
=
0
;
MSDOS_I
(
old_inode
)
->
i_logstart
=
0
;
old_inode
->
i_nlink
=
0
;
/*
* Install the new inode ...
*/
...
...
@@ -845,7 +879,6 @@ old_dentry->d_count);
mark_inode_dirty
(
old_inode
);
old_de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
old_bh
,
1
);
fat_mark_buffer_dirty
(
sb
,
free_bh
,
1
);
iput
(
old_inode
);
/* a directory? */
...
...
@@ -854,13 +887,13 @@ old_dentry->d_count);
MSDOS_I
(
dotdot_inode
)
->
i_logstart
=
MSDOS_I
(
new_dir
)
->
i_logstart
;
dotdot_de
->
start
=
CT_LE_W
(
MSDOS_I
(
new_dir
)
->
i_logstart
);
dotdot_de
->
starthi
=
CT_LE_W
((
MSDOS_I
(
new_dir
)
->
i_logstart
)
>>
16
);
mark_inode_dirty
(
dotdot_inode
);
fat_mark_buffer_dirty
(
sb
,
dotdot_bh
,
1
);
old_dir
->
i_nlink
--
;
new_dir
->
i_nlink
++
;
/* no need to mark them dirty */
dotdot_inode
->
i_nlink
=
new_dir
->
i_nlink
;
mark_inode_dirty
(
dotdot_inode
);
iput
(
dotdot_inode
);
fat_mark_buffer_dirty
(
sb
,
dotdot_bh
,
1
);
fat_brelse
(
sb
,
dotdot_bh
);
}
...
...
fs/namei.c
View file @
20fca9a1
...
...
@@ -280,7 +280,18 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
return
result
;
}
static
struct
dentry
*
do_follow_link
(
struct
dentry
*
base
,
struct
dentry
*
dentry
)
/*
* The bitmask for a follow event: normal
* follow, and follow requires a directory
* entry due to a slash ('/') after the
* name, and whether to continue to parse
* the name..
*/
#define FOLLOW_LINK (1)
#define FOLLOW_DIRECTORY (2)
#define FOLLOW_CONTINUE (4)
static
struct
dentry
*
do_follow_link
(
struct
dentry
*
base
,
struct
dentry
*
dentry
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
...
...
@@ -290,7 +301,7 @@ static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry
current
->
link_count
++
;
/* This eats the base */
result
=
inode
->
i_op
->
follow_link
(
dentry
,
base
);
result
=
inode
->
i_op
->
follow_link
(
dentry
,
base
,
follow
);
current
->
link_count
--
;
dput
(
dentry
);
return
result
;
...
...
@@ -320,9 +331,10 @@ static inline struct dentry * follow_mount(struct dentry * dentry)
* This is the basic name resolution function, turning a pathname
* into the final dentry.
*/
struct
dentry
*
lookup_dentry
(
const
char
*
name
,
struct
dentry
*
base
,
int
follow_link
)
struct
dentry
*
lookup_dentry
(
const
char
*
name
,
struct
dentry
*
base
,
unsigned
int
follow_link
)
{
struct
dentry
*
dentry
;
struct
inode
*
inode
;
if
(
*
name
==
'/'
)
{
if
(
base
)
...
...
@@ -338,35 +350,34 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
if
(
!*
name
)
goto
return_base
;
inode
=
base
->
d_inode
;
follow_link
&=
FOLLOW_LINK
|
FOLLOW_DIRECTORY
;
/* At this point we know we have a real path component. */
for
(;;)
{
int
err
;
unsigned
long
hash
;
struct
qstr
this
;
struct
inode
*
inode
;
char
c
,
follow
;
unsigned
int
follow
;
unsigned
int
c
;
dentry
=
ERR_PTR
(
-
ENOENT
);
inode
=
base
->
d_inode
;
if
(
!
inode
)
break
;
dentry
=
ERR_PTR
(
-
ENOTDIR
);
if
(
!
inode
->
i_op
||
!
inode
->
i_op
->
lookup
)
break
;
err
=
permission
(
inode
,
MAY_EXEC
);
dentry
=
ERR_PTR
(
err
);
if
(
err
)
break
;
this
.
name
=
name
;
c
=
*
name
;
c
=
*
(
const
unsigned
char
*
)
name
;
hash
=
init_name_hash
();
do
{
name
++
;
hash
=
partial_name_hash
(
c
,
hash
);
c
=
*
++
name
;
c
=
*
(
const
unsigned
char
*
)
name
;
}
while
(
c
&&
(
c
!=
'/'
));
this
.
len
=
name
-
(
const
char
*
)
this
.
name
;
this
.
hash
=
end_name_hash
(
hash
);
...
...
@@ -374,10 +385,14 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
/* remove trailing slashes? */
follow
=
follow_link
;
if
(
c
)
{
follow
|=
c
;
char
tmp
;
follow
|=
FOLLOW_DIRECTORY
;
do
{
c
=
*++
name
;
}
while
(
c
==
'/'
);
tmp
=
*++
name
;
}
while
(
tmp
==
'/'
);
if
(
tmp
)
follow
|=
FOLLOW_CONTINUE
;
}
/*
...
...
@@ -410,8 +425,18 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
if
(
!
follow
)
break
;
base
=
do_follow_link
(
base
,
dentry
);
if
(
c
&&
!
IS_ERR
(
base
))
base
=
do_follow_link
(
base
,
dentry
,
follow
);
if
(
IS_ERR
(
base
))
goto
return_base
;
dentry
=
ERR_PTR
(
-
ENOTDIR
);
inode
=
base
->
d_inode
;
if
(
follow
&
FOLLOW_DIRECTORY
)
{
if
(
!
inode
||
!
inode
->
i_op
||
!
inode
->
i_op
->
lookup
)
break
;
}
if
(
follow
&
FOLLOW_CONTINUE
)
continue
;
return_base:
...
...
@@ -431,7 +456,7 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
* namei exists in two versions: namei/lnamei. The only difference is
* that namei follows links, while lnamei does not.
*/
struct
dentry
*
__namei
(
const
char
*
pathname
,
int
follow_link
)
struct
dentry
*
__namei
(
const
char
*
pathname
,
unsigned
int
follow_link
)
{
char
*
name
;
struct
dentry
*
dentry
;
...
...
fs/nfs/symlink.c
View file @
20fca9a1
...
...
@@ -19,7 +19,7 @@
#include <asm/uaccess.h>
static
int
nfs_readlink
(
struct
dentry
*
,
char
*
,
int
);
static
struct
dentry
*
nfs_follow_link
(
struct
dentry
*
,
struct
dentry
*
);
static
struct
dentry
*
nfs_follow_link
(
struct
dentry
*
,
struct
dentry
*
,
unsigned
int
);
/*
* symlinks can't do much...
...
...
@@ -68,7 +68,7 @@ static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen)
}
static
struct
dentry
*
nfs_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
nfs_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
,
unsigned
int
follow
)
{
int
error
;
unsigned
int
len
;
...
...
@@ -94,7 +94,7 @@ nfs_follow_link(struct dentry * dentry, struct dentry *base)
path
[
len
]
=
0
;
kfree
(
mem
);
result
=
lookup_dentry
(
path
,
base
,
1
);
result
=
lookup_dentry
(
path
,
base
,
follow
);
kfree
(
path
);
out:
return
result
;
...
...
fs/pipe.c
View file @
20fca9a1
...
...
@@ -92,7 +92,7 @@ static ssize_t pipe_write(struct file * filp, const char * buf,
size_t
count
,
loff_t
*
ppos
)
{
struct
inode
*
inode
=
filp
->
f_dentry
->
d_inode
;
ssize_t
chars
=
0
,
free
=
0
,
written
=
0
;
ssize_t
chars
=
0
,
free
=
0
,
written
=
0
,
err
=
0
;
char
*
pipebuf
;
if
(
ppos
!=
&
filp
->
f_pos
)
...
...
@@ -107,16 +107,26 @@ static ssize_t pipe_write(struct file * filp, const char * buf,
free
=
count
;
else
free
=
1
;
/* can't do it atomically, wait for any free space */
up
(
&
inode
->
i_sem
);
if
(
down_interruptible
(
&
inode
->
i_atomic_write
))
{
down
(
&
inode
->
i_sem
);
return
-
ERESTARTSYS
;
}
while
(
count
>
0
)
{
while
((
PIPE_FREE
(
*
inode
)
<
free
)
||
PIPE_LOCK
(
*
inode
))
{
if
(
!
PIPE_READERS
(
*
inode
))
{
/* no readers */
send_sig
(
SIGPIPE
,
current
,
0
);
return
written
?
:-
EPIPE
;
err
=
-
EPIPE
;
goto
errout
;
}
if
(
signal_pending
(
current
))
{
err
=
-
ERESTARTSYS
;
goto
errout
;
}
if
(
filp
->
f_flags
&
O_NONBLOCK
)
{
err
=
-
EAGAIN
;
goto
errout
;
}
if
(
signal_pending
(
current
))
return
written
?
:-
ERESTARTSYS
;
if
(
filp
->
f_flags
&
O_NONBLOCK
)
return
written
?
:-
EAGAIN
;
interruptible_sleep_on
(
&
PIPE_WAIT
(
*
inode
));
}
PIPE_LOCK
(
*
inode
)
++
;
...
...
@@ -139,7 +149,10 @@ static ssize_t pipe_write(struct file * filp, const char * buf,
}
inode
->
i_ctime
=
inode
->
i_mtime
=
CURRENT_TIME
;
mark_inode_dirty
(
inode
);
return
written
;
errout:
up
(
&
inode
->
i_atomic_write
);
down
(
&
inode
->
i_sem
);
return
written
?
written
:
err
;
}
static
long
long
pipe_lseek
(
struct
file
*
file
,
long
long
offset
,
int
orig
)
...
...
fs/proc/link.c
View file @
20fca9a1
...
...
@@ -17,7 +17,7 @@
#include <linux/stat.h>
static
int
proc_readlink
(
struct
dentry
*
,
char
*
,
int
);
static
struct
dentry
*
proc_follow_link
(
struct
dentry
*
,
struct
dentry
*
);
static
struct
dentry
*
proc_follow_link
(
struct
dentry
*
,
struct
dentry
*
,
unsigned
int
);
/*
* links can't do much...
...
...
@@ -57,7 +57,8 @@ struct inode_operations proc_link_inode_operations = {
};
static
struct
dentry
*
proc_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
task_struct
*
p
;
...
...
@@ -172,7 +173,7 @@ static int proc_readlink(struct dentry * dentry, char * buffer, int buflen)
{
int
error
;
dentry
=
proc_follow_link
(
dentry
,
NULL
);
dentry
=
proc_follow_link
(
dentry
,
NULL
,
1
);
error
=
PTR_ERR
(
dentry
);
if
(
!
IS_ERR
(
dentry
))
{
error
=
-
ENOENT
;
...
...
fs/proc/proc_devtree.c
View file @
20fca9a1
...
...
@@ -42,7 +42,7 @@ static int property_read_proc(char *page, char **start, off_t off,
*/
static
int
devtree_readlink
(
struct
dentry
*
,
char
*
,
int
);
static
struct
dentry
*
devtree_follow_link
(
struct
dentry
*
,
struct
dentry
*
);
static
struct
dentry
*
devtree_follow_link
(
struct
dentry
*
,
struct
dentry
*
,
unsigned
int
);
struct
inode_operations
devtree_symlink_inode_operations
=
{
NULL
,
/* no file-operations */
...
...
@@ -66,7 +66,8 @@ struct inode_operations devtree_symlink_inode_operations = {
};
static
struct
dentry
*
devtree_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
proc_dir_entry
*
de
;
...
...
@@ -74,7 +75,7 @@ static struct dentry *devtree_follow_link(struct dentry *dentry,
de
=
(
struct
proc_dir_entry
*
)
inode
->
u
.
generic_ip
;
link
=
(
char
*
)
de
->
data
;
return
lookup_dentry
(
link
,
base
,
1
);
return
lookup_dentry
(
link
,
base
,
follow
);
}
static
int
devtree_readlink
(
struct
dentry
*
dentry
,
char
*
buffer
,
int
buflen
)
...
...
fs/proc/root.c
View file @
20fca9a1
...
...
@@ -55,9 +55,6 @@ static struct file_operations proc_dir_operations = {
NULL
/* can't fsync */
};
int
proc_readlink
(
struct
dentry
*
dentry
,
char
*
buffer
,
int
buflen
);
struct
dentry
*
proc_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
);
/*
* proc directories can do almost nothing..
*/
...
...
@@ -388,12 +385,13 @@ static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen)
}
static
struct
dentry
*
proc_self_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
char
tmp
[
30
];
sprintf
(
tmp
,
"%d"
,
current
->
pid
);
return
lookup_dentry
(
tmp
,
base
,
1
);
return
lookup_dentry
(
tmp
,
base
,
follow
);
}
int
proc_readlink
(
struct
dentry
*
dentry
,
char
*
buffer
,
int
buflen
)
...
...
@@ -420,7 +418,7 @@ int proc_readlink(struct dentry * dentry, char * buffer, int buflen)
return
len
;
}
struct
dentry
*
proc_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
proc_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
proc_dir_entry
*
de
;
...
...
@@ -435,7 +433,7 @@ struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base)
if
(
de
->
readlink_proc
)
len
=
de
->
readlink_proc
(
de
,
page
);
d
=
lookup_dentry
(
page
,
base
,
1
);
d
=
lookup_dentry
(
page
,
base
,
follow
);
free_page
((
unsigned
long
)
page
);
return
d
;
}
...
...
fs/romfs/inode.c
View file @
20fca9a1
...
...
@@ -451,7 +451,8 @@ romfs_readlink(struct dentry *dentry, char *buffer, int len)
}
static
struct
dentry
*
romfs_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
char
*
link
;
...
...
@@ -470,7 +471,7 @@ static struct dentry *romfs_follow_link(struct dentry *dentry,
}
else
link
[
len
]
=
0
;
dentry
=
lookup_dentry
(
link
,
base
,
1
);
dentry
=
lookup_dentry
(
link
,
base
,
follow
);
kfree
(
link
);
if
(
0
)
{
...
...
fs/sysv/symlink.c
View file @
20fca9a1
...
...
@@ -21,7 +21,7 @@
#include <asm/uaccess.h>
static
int
sysv_readlink
(
struct
dentry
*
,
char
*
,
int
);
static
struct
dentry
*
sysv_follow_link
(
struct
dentry
*
,
struct
dentry
*
);
static
struct
dentry
*
sysv_follow_link
(
struct
dentry
*
,
struct
dentry
*
,
unsigned
int
);
/*
* symlinks can't do much...
...
...
@@ -47,7 +47,8 @@ struct inode_operations sysv_symlink_inode_operations = {
};
static
struct
dentry
*
sysv_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
buffer_head
*
bh
;
...
...
@@ -58,7 +59,7 @@ static struct dentry *sysv_follow_link(struct dentry * dentry,
return
ERR_PTR
(
-
EIO
);
}
UPDATE_ATIME
(
inode
);
base
=
lookup_dentry
(
bh
->
b_data
,
base
,
1
);
base
=
lookup_dentry
(
bh
->
b_data
,
base
,
follow
);
brelse
(
bh
);
return
base
;
}
...
...
fs/ufs/symlink.c
View file @
20fca9a1
...
...
@@ -43,7 +43,7 @@
static
struct
dentry
*
ufs_follow_link
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
;
struct
buffer_head
*
bh
;
...
...
@@ -67,7 +67,7 @@ static struct dentry * ufs_follow_link(struct dentry * dentry,
link
=
(
char
*
)
inode
->
u
.
ufs_i
.
i_u1
.
i_symlink
;
}
UPDATE_ATIME
(
inode
);
base
=
lookup_dentry
(
link
,
base
,
1
);
base
=
lookup_dentry
(
link
,
base
,
follow
);
if
(
bh
)
brelse
(
bh
);
UFSD
((
"EXIT
\n
"
))
...
...
fs/umsdos/symlink.c
View file @
20fca9a1
...
...
@@ -64,7 +64,8 @@ static int UMSDOS_readlink (struct dentry *dentry, char *buffer, int buflen)
/* this one mostly stolen from romfs :) */
static
struct
dentry
*
UMSDOS_followlink
(
struct
dentry
*
dentry
,
struct
dentry
*
base
)
struct
dentry
*
base
,
unsigned
int
follow
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
char
*
symname
;
...
...
@@ -91,7 +92,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name));
}
symname
[
len
]
=
0
;
dentry
=
lookup_dentry
(
symname
,
base
,
1
);
dentry
=
lookup_dentry
(
symname
,
base
,
follow
);
kfree
(
symname
);
if
(
0
)
{
...
...
include/linux/console.h
View file @
20fca9a1
...
...
@@ -53,15 +53,11 @@ extern struct consw compat_con; /* console wrapper */
extern
struct
consw
prom_con
;
/* SPARC PROM console */
void
take_over_console
(
struct
consw
*
sw
,
int
first
,
int
last
,
int
deflt
);
/* flag bits */
#define CON_INITED (1)
void
give_up_console
(
struct
consw
*
sw
);
/* scroll */
#define SM_UP (1)
#define SM_DOWN (2)
#define SM_LEFT (3)
#define SM_RIGHT (4)
/* cursor */
#define CM_DRAW (1)
...
...
include/linux/console_struct.h
View file @
20fca9a1
...
...
@@ -19,7 +19,6 @@ struct vc_data {
struct
consw
*
vc_sw
;
unsigned
short
*
vc_screenbuf
;
/* In-memory character/attribute buffer */
unsigned
int
vc_screenbuf_size
;
unsigned
short
vc_video_erase_char
;
/* Background erase character */
unsigned
char
vc_attr
;
/* Current attributes */
unsigned
char
vc_def_color
;
/* Default colors */
unsigned
char
vc_color
;
/* Foreground & background */
...
...
@@ -28,6 +27,8 @@ struct vc_data {
unsigned
char
vc_halfcolor
;
/* Color for half intensity mode */
unsigned
short
vc_complement_mask
;
/* [#] Xor mask for mouse pointer */
unsigned
short
vc_hi_font_mask
;
/* [#] Attribute set for upper 256 chars of font or 0 if not supported */
unsigned
short
vc_video_erase_char
;
/* Background erase character */
unsigned
short
vc_s_complement_mask
;
/* Saved mouse pointer mask */
unsigned
int
vc_x
,
vc_y
;
/* Cursor position */
unsigned
int
vc_top
,
vc_bottom
;
/* Scrolling region */
unsigned
int
vc_state
;
/* Escape sequence parser state */
...
...
@@ -104,3 +105,5 @@ extern struct vc vc_cons [MAX_NR_CONSOLES];
#define CUR_SWMASK 0xfff0
#define CUR_DEFAULT CUR_UNDERLINE
#define CON_IS_VISIBLE(conp) (*conp->vc_display_fg == conp)
include/linux/dcache.h
View file @
20fca9a1
...
...
@@ -27,7 +27,7 @@ struct qstr {
#define init_name_hash() 0
/* partial hash update function. Assume roughly 4 bits per character */
static
__inline__
unsigned
long
partial_name_hash
(
unsigned
char
c
,
unsigned
long
prevhash
)
static
__inline__
unsigned
long
partial_name_hash
(
unsigned
long
c
,
unsigned
long
prevhash
)
{
prevhash
=
(
prevhash
<<
4
)
|
(
prevhash
>>
(
8
*
sizeof
(
unsigned
long
)
-
4
));
return
prevhash
^
c
;
...
...
include/linux/fs.h
View file @
20fca9a1
...
...
@@ -348,6 +348,7 @@ struct inode {
unsigned
long
i_version
;
unsigned
long
i_nrpages
;
struct
semaphore
i_sem
;
struct
semaphore
i_atomic_write
;
struct
inode_operations
*
i_op
;
struct
super_block
*
i_sb
;
struct
wait_queue
*
i_wait
;
...
...
@@ -622,7 +623,7 @@ struct inode_operations {
int
(
*
rename
)
(
struct
inode
*
,
struct
dentry
*
,
struct
inode
*
,
struct
dentry
*
);
int
(
*
readlink
)
(
struct
dentry
*
,
char
*
,
int
);
struct
dentry
*
(
*
follow_link
)
(
struct
dentry
*
,
struct
dentry
*
);
struct
dentry
*
(
*
follow_link
)
(
struct
dentry
*
,
struct
dentry
*
,
unsigned
int
);
int
(
*
readpage
)
(
struct
file
*
,
struct
page
*
);
int
(
*
writepage
)
(
struct
file
*
,
struct
page
*
);
int
(
*
bmap
)
(
struct
inode
*
,
int
);
...
...
@@ -783,8 +784,8 @@ extern ino_t find_inode_number(struct dentry *, struct qstr *);
#define PTR_ERR(ptr) ((long)(ptr))
#define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000))
extern
struct
dentry
*
lookup_dentry
(
const
char
*
,
struct
dentry
*
,
int
);
extern
struct
dentry
*
__namei
(
const
char
*
,
int
);
extern
struct
dentry
*
lookup_dentry
(
const
char
*
,
struct
dentry
*
,
unsigned
int
);
extern
struct
dentry
*
__namei
(
const
char
*
,
unsigned
int
);
#define namei(pathname) __namei(pathname, 1)
#define lnamei(pathname) __namei(pathname, 0)
...
...
include/linux/nbd.h
View file @
20fca9a1
...
...
@@ -35,7 +35,6 @@ nbd_end_request(struct request *req)
}
#define MAX_NBD 128
#endif
struct
nbd_device
{
int
refcnt
;
...
...
@@ -51,6 +50,7 @@ struct nbd_device {
struct
request
*
tail
;
struct
semaphore
queue_lock
;
};
#endif
/* This now IS in some kind of include file... */
...
...
include/linux/selection.h
View file @
20fca9a1
...
...
@@ -21,7 +21,6 @@ extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry);
#define video_num_columns (vc_cons[currcons].d->vc_cols)
#define video_num_lines (vc_cons[currcons].d->vc_rows)
#define video_size_row (vc_cons[currcons].d->vc_size_row)
#define video_screen_size (vc_cons[currcons].d->vc_screenbuf_size)
#define can_do_color (vc_cons[currcons].d->vc_can_do_color)
extern
int
console_blanked
;
...
...
@@ -31,7 +30,6 @@ extern int default_red[];
extern
int
default_grn
[];
extern
int
default_blu
[];
extern
void
do_unblank_screen
(
void
);
extern
unsigned
short
*
screen_pos
(
int
currcons
,
int
w_offset
,
int
viewed
);
extern
u16
screen_glyph
(
int
currcons
,
int
offset
);
extern
void
complement_pos
(
int
currcons
,
int
offset
);
...
...
include/linux/tty.h
View file @
20fca9a1
...
...
@@ -9,7 +9,7 @@
* These constants are also useful for user-level apps (e.g., VC
* resizing).
*/
#define MIN_NR_CONSOLES
1
/* must be at least 1 */
#define MIN_NR_CONSOLES
1
/* must be at least 1 */
#define MAX_NR_CONSOLES 63
/* serial lines start at 64 */
#define MAX_NR_USER_CONSOLES 63
/* must be root to allocate above this */
/* Note: the ioctl VT_GETSTATE does not work for
...
...
@@ -87,7 +87,10 @@ struct screen_info {
unsigned
char
blue_pos
;
/* 0x2b */
unsigned
char
rsvd_size
;
/* 0x2c */
unsigned
char
rsvd_pos
;
/* 0x2d */
/* 0x2e -- 0x3f reserved for future expansion */
unsigned
short
vesapm_seg
;
/* 0x2e */
unsigned
short
vesapm_off
;
/* 0x30 */
unsigned
short
pages
;
/* 0x32 */
/* 0x34 -- 0x3f reserved for future expansion */
};
extern
struct
screen_info
screen_info
;
...
...
@@ -390,10 +393,6 @@ extern long serial_console_init(long kmem_start, long kmem_end);
extern
int
pcxe_open
(
struct
tty_struct
*
tty
,
struct
file
*
filp
);
/* console.c */
extern
void
update_screen
(
int
new_console
);
/* printk.c */
extern
void
console_print
(
const
char
*
);
...
...
include/linux/vt_buffer.h
View file @
20fca9a1
...
...
@@ -16,9 +16,6 @@
#include <linux/config.h>
#ifdef CONFIG_VGA_CONSOLE
#if !defined(CONFIG_FB) && !defined(CONFIG_FB_MODULE)
#define VT_BUF_VRAM_ONLY
#endif
#include <asm/vga.h>
#endif
...
...
include/linux/vt_kern.h
View file @
20fca9a1
...
...
@@ -35,27 +35,29 @@ void (*kd_mksound)(unsigned int hz, unsigned int ticks);
/* console.c */
struct
console_font_op
;
struct
consw
;
int
vc_allocate
(
unsigned
int
console
,
int
init
);
int
vc_allocate
(
unsigned
int
console
);
int
vc_cons_allocated
(
unsigned
int
console
);
int
vc_resize
(
unsigned
int
lines
,
unsigned
int
cols
,
unsigned
int
first
,
unsigned
int
last
);
#define vc_resize_all(l, c) vc_resize(l, c, 0, MAX_NR_CONSOLES-1)
#define vc_resize_con(l, c, x) vc_resize(l, c, x, x)
void
vc_disallocate
(
unsigned
int
console
);
void
poke_blanked_console
(
void
);
void
set_vesa_blanking
(
unsigned
long
arg
);
void
vesa_blank
(
void
);
void
vesa_powerdown
(
void
);
void
reset_palette
(
int
currcons
);
void
set_palette
(
void
);
void
do_blank_screen
(
int
nopowersave
);
void
set_palette
(
int
currcons
);
void
do_blank_screen
(
int
gfx_mode
);
void
unblank_screen
(
void
);
void
poke_blanked_console
(
void
);
int
con_font_op
(
int
currcons
,
struct
console_font_op
*
op
);
int
con_set_cmap
(
unsigned
char
*
cmap
);
int
con_get_cmap
(
unsigned
char
*
cmap
);
void
scrollback
(
int
);
void
scrollfront
(
int
);
void
update_region
(
int
currcons
,
unsigned
long
start
,
int
count
);
void
redraw_screen
(
int
new_console
,
int
is_switch
);
#define update_screen(x) redraw_screen(x, 0)
#define switch_screen(x) redraw_screen(x, 1)
struct
tty_struct
;
int
tioclinux
(
struct
tty_struct
*
tty
,
unsigned
long
arg
);
...
...
@@ -75,6 +77,7 @@ int con_get_unimap(int currcons, ushort ct, ushort *uct, struct unipair *list);
int
con_set_default_unimap
(
int
currcons
);
void
con_free_unimap
(
int
currcons
);
void
con_protect_unimap
(
int
currcons
,
int
rdonly
);
int
con_copy_unimap
(
int
dstcons
,
int
srccons
);
/* vt.c */
...
...
init/main.c
View file @
20fca9a1
...
...
@@ -77,7 +77,7 @@ extern long console_init(long, long);
extern
void
sock_init
(
void
);
extern
void
uidcache_init
(
void
);
extern
void
mca_init
(
void
);
extern
long
sbus_init
(
long
,
long
);
extern
long
sbus_init
(
void
);
extern
long
powermac_init
(
unsigned
long
,
unsigned
long
);
extern
void
sysctl_init
(
void
);
extern
void
filescache_init
(
void
);
...
...
kernel/exit.c
View file @
20fca9a1
...
...
@@ -415,15 +415,6 @@ asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct
struct
wait_queue
wait
=
{
current
,
NULL
};
struct
task_struct
*
p
;
if
(
stat_addr
)
{
if
(
verify_area
(
VERIFY_WRITE
,
stat_addr
,
sizeof
(
*
stat_addr
)))
return
-
EFAULT
;
}
if
(
ru
)
{
if
(
verify_area
(
VERIFY_WRITE
,
ru
,
sizeof
(
*
ru
)))
return
-
EFAULT
;
}
if
(
options
&
~
(
WNOHANG
|
WUNTRACED
|
__WCLONE
))
return
-
EINVAL
;
...
...
@@ -453,21 +444,23 @@ asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct
if
(
!
(
options
&
WUNTRACED
)
&&
!
(
p
->
flags
&
PF_PTRACED
))
continue
;
read_unlock
(
&
tasklist_lock
);
if
(
ru
!=
NULL
)
getrusage
(
p
,
RUSAGE_BOTH
,
ru
);
if
(
stat_addr
)
__put_user
((
p
->
exit_code
<<
8
)
|
0x7f
,
stat_addr
);
p
->
exit_code
=
0
;
retval
=
p
->
pid
;
retval
=
ru
?
getrusage
(
p
,
RUSAGE_BOTH
,
ru
)
:
0
;
if
(
!
retval
&&
stat_addr
)
retval
=
put_user
((
p
->
exit_code
<<
8
)
|
0x7f
,
stat_addr
);
if
(
!
retval
)
{
p
->
exit_code
=
0
;
retval
=
p
->
pid
;
}
goto
end_wait4
;
case
TASK_ZOMBIE
:
current
->
times
.
tms_cutime
+=
p
->
times
.
tms_utime
+
p
->
times
.
tms_cutime
;
current
->
times
.
tms_cstime
+=
p
->
times
.
tms_stime
+
p
->
times
.
tms_cstime
;
read_unlock
(
&
tasklist_lock
);
if
(
ru
!=
NULL
)
getrusage
(
p
,
RUSAGE_BOTH
,
ru
);
if
(
stat_addr
)
__put_user
(
p
->
exit_code
,
stat_addr
);
retval
=
ru
?
getrusage
(
p
,
RUSAGE_BOTH
,
ru
)
:
0
;
if
(
!
retval
&&
stat_addr
)
retval
=
put_user
(
p
->
exit_code
,
stat_addr
);
if
(
retval
)
goto
end_wait4
;
retval
=
p
->
pid
;
if
(
p
->
p_opptr
!=
p
->
p_pptr
)
{
write_lock_irq
(
&
tasklist_lock
);
...
...
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