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
70e39deb
Commit
70e39deb
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.1.44pre2
parent
d5977cd7
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
243 additions
and
269 deletions
+243
-269
Documentation/Configure.help
Documentation/Configure.help
+6
-4
Makefile
Makefile
+1
-1
drivers/block/ide.c
drivers/block/ide.c
+1
-0
drivers/block/ide.h
drivers/block/ide.h
+1
-1
drivers/block/triton.c
drivers/block/triton.c
+88
-26
drivers/char/rtc.c
drivers/char/rtc.c
+1
-1
drivers/net/Config.in
drivers/net/Config.in
+2
-6
drivers/pci/pci.c
drivers/pci/pci.c
+1
-1
fs/dcache.c
fs/dcache.c
+92
-204
fs/namei.c
fs/namei.c
+1
-1
fs/readdir.c
fs/readdir.c
+2
-2
fs/super.c
fs/super.c
+2
-2
include/linux/dalloc.h
include/linux/dalloc.h
+13
-14
include/linux/fs.h
include/linux/fs.h
+2
-0
include/linux/pci.h
include/linux/pci.h
+1
-1
scripts/ksymoops.cc
scripts/ksymoops.cc
+29
-5
No files found.
Documentation/Configure.help
View file @
70e39deb
...
...
@@ -287,17 +287,19 @@ CONFIG_BLK_DEV_RZ1000
Linux. This may slow disk throughput by a few percent, but at least
things will operate 100% reliably. If unsure, say Y.
Intel 82371 PIIX (Triton I/II) DMA support
Intel 82371 PIIX (Triton I/II)
, VIA VP-1
DMA support
CONFIG_BLK_DEV_TRITON
If your PCI system uses an IDE harddrive (as opposed to SCSI, say)
and includes the Intel Triton I/II IDE interface chipset (i82371FB,
i82371SB or i82371AB), you will want to enable this option to allow
use of bus-mastering DMA data transfers. Read the comments at the
i82371SB or i82371AB), or the VIA VP-1 IDE interface chipset
(VT82C586), you will want to enable this option to allow use of
bus-mastering DMA data transfers. Read the comments at the
beginning of drivers/block/triton.c and Documentation/ide.txt.
You can get the latest version of the hdparm utility via
ftp (user: anonymous) from
sunsite.unc.edu/pub/Linux/kernel/patches/diskdrives/; it is
used to tune your harddisk. It is safe to say Y to this question.
used to tune your harddisk.
It is safe to say Y to this question.
Other IDE chipset support
CONFIG_IDE_CHIPSETS
...
...
Makefile
View file @
70e39deb
VERSION
=
2
PATCHLEVEL
=
1
SUBLEVEL
=
4
3
SUBLEVEL
=
4
4
ARCH
:=
$(
shell
uname
-m
|
sed
-e
s/i.86/i386/
-e
s/sun4u/sparc64/
)
...
...
drivers/block/ide.c
View file @
70e39deb
...
...
@@ -2603,6 +2603,7 @@ __initfunc(static void probe_for_hwifs (void))
ide_probe_pci
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82371SB_1
,
&
ide_init_triton
,
0
);
ide_probe_pci
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82371AB
,
&
ide_init_triton
,
0
);
#endif
/* CONFIG_BLK_DEV_TRITON */
ide_probe_pci
(
PCI_VENDOR_ID_VIA
,
PCI_DEVICE_ID_VIA_82C586_1
,
&
ide_init_triton
,
0
);
#ifdef CONFIG_BLK_DEV_OPTI621
ide_probe_pci
(
PCI_VENDOR_ID_OPTI
,
PCI_DEVICE_ID_OPTI_82C621
,
&
ide_init_opti621
,
0
);
#endif
/* CONFIG_BLK_DEV_OPTI621 */
...
...
drivers/block/ide.h
View file @
70e39deb
...
...
@@ -298,7 +298,7 @@ typedef void (ide_selectproc_t) (ide_drive_t *);
typedef
enum
{
ide_unknown
,
ide_generic
,
ide_triton
,
ide_cmd640
,
ide_dtc2278
,
ide_ali14xx
,
ide_qd6580
,
ide_umc8672
,
ide_ht6560b
,
ide_promise
}
ide_promise
,
ide_via
}
hwif_chipset_t
;
typedef
struct
hwif_s
{
...
...
drivers/block/triton.c
View file @
70e39deb
...
...
@@ -122,15 +122,25 @@ static unsigned int piix_key;
#define PIIX_FLAGS_PREFETCH 4
#define PIIX_FLAGS_FAST_DMA 8
typedef
struct
{
unsigned
d0_flags
:
4
;
unsigned
d1_flags
:
4
;
unsigned
recovery
:
2
;
unsigned
reserved
:
2
;
unsigned
sample
:
2
;
unsigned
sidetim_enabled
:
1
;
unsigned
ports_enabled
:
1
;
}
piix_timing_t
;
union
chip_en_reg_u
{
struct
{
unsigned
d0_flags
:
4
;
unsigned
d1_flags
:
4
;
unsigned
recovery
:
2
;
unsigned
reserved
:
2
;
unsigned
sample
:
2
;
unsigned
sidetim_enabled
:
1
;
unsigned
ports_enabled
:
1
;
}
piix_s
;
struct
{
unsigned
sec_en
:
1
;
unsigned
pri_en
:
1
;
unsigned
reserved
:
14
;
}
via_s
;
};
typedef
union
chip_en_reg_u
piix_timing_t
;
typedef
struct
{
unsigned
pri_recovery
:
2
;
...
...
@@ -269,16 +279,16 @@ static int piix_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
printk
(
"%s: pcibios read failed
\n
"
,
HWIF
(
drive
)
->
name
);
return
1
;
}
dflags
=
drive
->
select
.
b
.
unit
?
timing
.
d1_flags
:
timing
.
d0_flags
;
dflags
=
drive
->
select
.
b
.
unit
?
timing
.
piix_s
.
d1_flags
:
timing
.
piix_s
.
d0_flags
;
if
(
dflags
&
PIIX_FLAGS_FAST_PIO
)
{
if
(
func
==
ide_dma_on
&&
drive
->
media
==
ide_disk
)
dflags
|=
PIIX_FLAGS_FAST_DMA
;
else
dflags
&=
~
PIIX_FLAGS_FAST_DMA
;
if
(
drive
->
select
.
b
.
unit
==
0
)
timing
.
d0_flags
=
dflags
;
timing
.
piix_s
.
d0_flags
=
dflags
;
else
timing
.
d1_flags
=
dflags
;
timing
.
piix_s
.
d1_flags
=
dflags
;
if
(
pcibios_write_config_word
(
piix_pci_bus
,
piix_pci_fn
,
reg
,
*
(
short
*
)
&
timing
))
{
printk
(
"%s: pcibios write failed
\n
"
,
HWIF
(
drive
)
->
name
);
return
1
;
...
...
@@ -456,8 +466,14 @@ void ide_init_triton (byte bus, byte fn)
chipset
=
"PIIX4"
;
else
if
(
devid
==
PCI_DEVICE_ID_INTEL_82371SB_1
)
chipset
=
"PIIX3"
;
else
else
if
(
devid
==
PCI_DEVICE_ID_INTEL_82371_1
)
chipset
=
"PIIX"
;
else
if
(
devid
==
PCI_DEVICE_ID_VIA_82C586_1
)
chipset
=
"VP1"
;
else
{
printk
(
"Unknown PCI IDE interface 0x%x
\n
"
,
devid
);
goto
quit
;
}
printk
(
"%s: bus-master IDE device on PCI bus %d function %d
\n
"
,
chipset
,
bus
,
fn
);
...
...
@@ -470,13 +486,24 @@ void ide_init_triton (byte bus, byte fn)
printk
(
"%s: IDE ports are not enabled (BIOS)
\n
"
,
chipset
);
goto
quit
;
}
if
((
rc
=
pcibios_read_config_word
(
bus
,
fn
,
0x40
,
(
short
*
)
&
timings
[
0
])))
goto
quit
;
if
((
rc
=
pcibios_read_config_word
(
bus
,
fn
,
0x42
,
(
short
*
)
&
timings
[
1
])))
goto
quit
;
if
((
!
timings
[
0
].
ports_enabled
)
&&
(
!
timings
[
1
].
ports_enabled
))
{
printk
(
"%s: neither IDE port is enabled
\n
"
,
chipset
);
goto
quit
;
if
(
devid
==
PCI_DEVICE_ID_VIA_82C586_1
)
{
/* pri and sec channel enables are in port 0x40 */
if
((
rc
=
pcibios_read_config_word
(
bus
,
fn
,
0x40
,
(
short
*
)
&
timings
[
0
])))
goto
quit
;
if
((
!
timings
[
0
].
via_s
.
pri_en
&&
(
!
timings
[
0
].
via_s
.
sec_en
)))
{
printk
(
"%s: neither IDE port is enabled
\n
"
,
chipset
);
goto
quit
;
}
}
else
{
/* INTEL piix */
if
((
rc
=
pcibios_read_config_word
(
bus
,
fn
,
0x40
,
(
short
*
)
&
timings
[
0
])))
goto
quit
;
if
((
rc
=
pcibios_read_config_word
(
bus
,
fn
,
0x42
,
(
short
*
)
&
timings
[
1
])))
goto
quit
;
if
((
!
timings
[
0
].
piix_s
.
ports_enabled
)
&&
(
!
timings
[
1
].
piix_s
.
ports_enabled
))
{
printk
(
"%s: neither IDE port is enabled
\n
"
,
chipset
);
goto
quit
;
}
}
/*
...
...
@@ -526,10 +553,30 @@ void ide_init_triton (byte bus, byte fn)
case
0x170
:
pri_sec
=
1
;
break
;
default:
continue
;
}
if
(
devid
==
PCI_DEVICE_ID_VIA_82C586_1
)
{
timing
=
timings
[
0
];
switch
(
h
)
{
case
0
:
if
(
!
timing
.
piix_s
.
ports_enabled
)
{
printk
(
"port 0 DMA not enabled
\n
"
);
continue
;
}
case
1
:
if
(
!
timing
.
piix_s
.
sidetim_enabled
)
{
printk
(
"port 1 DMA not enabled
\n
"
);
continue
;
}
}
hwif
->
chipset
=
ide_via
;
}
else
{
/* PIIX */
timing
=
timings
[
pri_sec
];
if
(
!
timing
.
ports_enabled
)
/* interface disabled? */
if
(
!
timing
.
p
iix_s
.
p
orts_enabled
)
/* interface disabled? */
continue
;
hwif
->
chipset
=
ide_triton
;
}
if
(
dma_enabled
)
init_piix_dma
(
hwif
,
bmiba
+
(
pri_sec
?
8
:
0
));
#ifdef DISPLAY_PIIX_TIMINGS
...
...
@@ -539,17 +586,32 @@ void ide_init_triton (byte bus, byte fn)
{
const
char
*
slave
;
piix_sidetim_t
sidetim
;
byte
sample
=
5
-
timing
.
sample
;
byte
recovery
=
4
-
timing
.
recovery
;
byte
sample
=
5
-
timing
.
piix_s
.
sample
;
byte
recovery
=
4
-
timing
.
piix_s
.
recovery
;
unsigned
int
drvtim
;
if
(
devid
==
PCI_DEVICE_ID_VIA_82C586_1
)
{
pcibios_read_config_dword
(
bus
,
fn
,
0x48
,
&
drvtim
);
if
(
pri_sec
==
0
)
{
printk
(
" %s master: active_pulse_CLKs=%d, recovery_CLKs=%d
\n
"
,
hwif
->
name
,
1
+
(
drvtim
>>
28
),
1
+
((
drvtim
&
0x0f000000
)
>>
24
));
printk
(
" %s slave: active_pulse_CLKs=%d, recovery_CLKs=%d
\n
"
,
hwif
->
name
,
1
+
((
drvtim
&
0xf00000
)
>>
20
),
1
+
((
drvtim
&
0x0f0000
)
>>
16
));
continue
;
}
else
{
printk
(
" %s master: active_pulse_CLKs=%d, recovery_CLKs=%d
\n
"
,
hwif
->
name
,
1
+
((
drvtim
&
0xf000
)
>>
12
),
1
+
((
drvtim
&
0x0f00
)
>>
8
));
printk
(
" %s slave: active_pulse_CLKs=%d, recovery_CLKs=%d
\n
"
,
hwif
->
name
,
1
+
((
drvtim
&
0xf0
)
>>
4
),
1
+
(
drvtim
&
0x0f
));
continue
;
}
}
if
((
devid
==
PCI_DEVICE_ID_INTEL_82371SB_1
||
devid
==
PCI_DEVICE_ID_INTEL_82371AB
)
&&
timing
.
sidetim_enabled
&&
timing
.
piix_s
.
sidetim_enabled
&&
!
pcibios_read_config_byte
(
bus
,
fn
,
0x44
,
(
byte
*
)
&
sidetim
))
slave
=
""
;
/* PIIX3 and later */
else
slave
=
"/slave"
;
/* PIIX, or PIIX3 in compatibility mode */
printk
(
" %s master%s: sample_CLKs=%d, recovery_CLKs=%d
\n
"
,
hwif
->
name
,
slave
,
sample
,
recovery
);
print_piix_drive_flags
(
"master:"
,
timing
.
d0_flags
);
print_piix_drive_flags
(
"master:"
,
timing
.
piix_s
.
d0_flags
);
if
(
!*
slave
)
{
if
(
pri_sec
==
0
)
{
sample
=
5
-
sidetim
.
pri_sample
;
...
...
@@ -560,7 +622,7 @@ void ide_init_triton (byte bus, byte fn)
}
printk
(
" slave : sample_CLKs=%d, recovery_CLKs=%d
\n
"
,
sample
,
recovery
);
}
print_piix_drive_flags
(
"slave :"
,
timing
.
d1_flags
);
print_piix_drive_flags
(
"slave :"
,
timing
.
piix_s
.
d1_flags
);
}
#endif
/* DISPLAY_PIIX_TIMINGS */
}
...
...
drivers/char/rtc.c
View file @
70e39deb
...
...
@@ -180,7 +180,7 @@ static long rtc_read(struct inode *inode, struct file *file, char *buf,
data
=
rtc_irq_data
;
rtc_irq_data
=
0
;
restore_flags
(
flags
);
retval
=
put_user
(
data
,
(
unsigned
long
*
)
buf
)
)
?:
sizeof
(
unsigned
long
);
retval
=
put_user
(
data
,
(
unsigned
long
*
)
buf
)
?:
sizeof
(
unsigned
long
);
}
current
->
state
=
TASK_RUNNING
;
...
...
drivers/net/Config.in
View file @
70e39deb
...
...
@@ -143,12 +143,8 @@ if [ "$CONFIG_NET_RADIO" != "n" ]; then
bool 'Soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8
bool 'Soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800
bool 'Soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600
if [ -f drivers/net/soundmodem/sm_afsk2666.c ]; then
bool 'Soundmodem support for 2666 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK2666
fi
if [ -f drivers/net/soundmodem/sm_psk4800.c ]; then
bool 'Soundmodem support for 4800 baud PSK modulation' CONFIG_SOUNDMODEM_PSK4800
fi
#bool 'Soundmodem support for 2666 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK2666
#bool 'Soundmodem support for 4800 baud PSK modulation' CONFIG_SOUNDMODEM_PSK4800
fi
fi
tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP
...
...
drivers/pci/pci.c
View file @
70e39deb
...
...
@@ -204,7 +204,7 @@ struct pci_dev_info dev_info[] = {
DEVICE
(
VIA
,
VIA_82C586_1
,
"VT 82C586 Apollo VP-1"
),
DEVICE
(
VIA
,
VIA_82C576
,
"VT 82C576 3V"
),
DEVICE
(
VIA
,
VIA_82C585
,
"VT 82C585VP Apollo VP-1"
),
DEVICE
(
VIA
,
VIA_82C586
_0
,
"VT 82C586 Apollo VP-1"
),
DEVICE
(
VIA
,
VIA_82C586
,
"VT 82C586 Apollo VP-1"
),
DEVICE
(
VIA
,
VIA_82C416
,
"VT 82C416MV"
),
DEVICE
(
VORTEX
,
VORTEX_GDT60x0
,
"GDT 60x0"
),
DEVICE
(
VORTEX
,
VORTEX_GDT6000B
,
"GDT 6000b"
),
...
...
fs/dcache.c
View file @
70e39deb
...
...
@@ -71,6 +71,7 @@
#include <linux/fs.h>
#include <linux/dalloc.h>
#include <linux/dlists.h>
#include <linux/malloc.h>
/* this should be removed after the beta phase */
/* #define DEBUG */
...
...
@@ -90,33 +91,6 @@
#define D_RECURSIVE 4
#define D_NO_FREE 8
/* adjust these constants if you know a probability distribution ... */
#define D_SMALL 16
#define D_MEDIUM 64
#define D_LARGE 256
#define D_HUGE D_MAXLEN
#define BASE_DHEADER(x) (struct dheader*)((unsigned long)(x) & ~(PAGE_SIZE-1))
#define BYTE_ADD(x,n) (void*)((char*)(x) + (n))
#define BYTE_SUB(x,n) (void*)((char*)(x) - (n))
/* This is for global allocation of dentries. Remove this when
* converting to SLAB.
*/
struct
dheader
{
struct
dentry
*
emptylist
;
short
free
,
maxfree
;
struct
dheader
*
next
;
struct
dheader
*
prev
;
};
struct
anchors
{
struct
dheader
*
free
;
/* each contains at least 1 empty dentry */
struct
dheader
*
full
;
/* all the used up ones */
struct
dheader
*
dir_free
;
struct
dheader
*
dir_full
;
};
/* This is only used for directory dentries. Think of it as an extension
* of the dentry.
* It is defined as separate struct, so it uses up space only
...
...
@@ -133,9 +107,6 @@ struct ddir {
unsigned
short
dd_negs
;
/* # of negative entries */
};
DEF_INSERT
(
header
,
struct
dheader
,
next
,
prev
)
DEF_REMOVE
(
header
,
struct
dheader
,
next
,
prev
)
DEF_INSERT
(
alias
,
struct
dentry
,
d_next
,
d_prev
)
DEF_REMOVE
(
alias
,
struct
dentry
,
d_next
,
d_prev
)
...
...
@@ -145,13 +116,10 @@ DEF_REMOVE(hash,struct dentry,d_hash_next,d_hash_prev)
DEF_INSERT
(
basket
,
struct
dentry
,
d_basket_next
,
d_basket_prev
)
DEF_REMOVE
(
basket
,
struct
dentry
,
d_basket_next
,
d_basket_prev
)
static
struct
anchors
anchors
[
4
];
struct
dentry
*
the_root
=
NULL
;
unsigned
long
name_cache_init
(
unsigned
long
mem_start
,
unsigned
long
mem_end
)
{
memset
(
anchors
,
0
,
sizeof
(
anchors
));
return
mem_start
;
}
...
...
@@ -260,7 +228,7 @@ void printpath(struct dentry * entry)
{
if
(
!
IS_ROOT
(
entry
))
printpath
(
entry
->
d_parent
);
printk
(
"/%s"
,
entry
->
d_name
);
printk
(
"/%s"
,
entry
->
d_name
.
name
);
}
static
inline
long
has_sons
(
struct
ddir
*
ddir
)
...
...
@@ -310,82 +278,42 @@ static void d_panic(void)
panic
(
"VFS: dcache directory corruption"
);
}
/*
* IF this is a directory, the ddir has been allocated right
* after the dentry.
*/
static
inline
struct
ddir
*
d_dir
(
struct
dentry
*
entry
)
{
struct
ddir
*
res
=
BYTE_SUB
(
entry
,
sizeof
(
struct
ddir
));
if
(
!
(
entry
->
d_flag
&
D_DIR
))
d_panic
();
#ifdef DEBUG
if
(
!
entry
)
panic
(
"entry NULL!"
);
if
(
BASE_DHEADER
(
res
)
!=
BASE_DHEADER
(
entry
))
printk
(
"Scheisse!!!
\n
"
);
#endif
return
res
;
return
(
struct
ddir
*
)
(
entry
+
1
);
}
static
/*inline*/
struct
dheader
*
dinit
(
int
isdir
,
int
size
)
#define NAME_ALLOC_LEN(len) ((len+16) & ~15)
struct
dentry
*
d_alloc
(
struct
dentry
*
parent
,
int
len
,
int
isdir
)
{
struct
d
header
*
res
=
(
struct
dheader
*
)
__get_free_page
(
GFP_KERNEL
)
;
int
restlen
=
PAGE_SIZE
-
sizeof
(
struct
dheader
);
struct
dentry
*
ptr
=
BYTE_ADD
(
res
,
sizeof
(
struct
dheader
))
;
struct
d
entry
*
res
;
int
size
=
sizeof
(
struct
dentry
);
int
flag
=
0
;
if
(
!
res
)
return
NULL
;
memset
(
res
,
0
,
sizeof
(
struct
dheader
));
if
(
isdir
)
{
ptr
=
BYTE_ADD
(
ptr
,
sizeof
(
struct
ddir
));
if
(
isdir
)
{
size
+=
sizeof
(
struct
ddir
);
flag
=
D_DIR
;
}
if
(
BASE_DHEADER
(
ptr
)
!=
res
)
panic
(
"Bad kernel page alignment"
);
size
+=
sizeof
(
struct
dentry
)
-
D_MAXLEN
;
res
->
emptylist
=
NULL
;
res
->
free
=
0
;
while
(
restlen
>=
size
)
{
#ifdef DEBUG
ins
(
ptr
);
if
(
BASE_DHEADER
(
ptr
)
!=
res
)
panic
(
"Wrong dinit!"
);
#endif
ptr
->
d_next
=
res
->
emptylist
;
res
->
emptylist
=
ptr
;
ptr
=
BYTE_ADD
(
ptr
,
size
);
res
->
free
++
;
restlen
-=
size
;
}
res
->
maxfree
=
res
->
free
;
return
res
;
}
res
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
res
)
return
NULL
;
memset
(
res
,
0
,
size
);
res
->
d_flag
=
flag
;
static
/*inline*/
struct
dentry
*
__dalloc
(
struct
anchors
*
anchor
,
struct
dentry
*
parent
,
int
isdir
,
int
len
,
int
size
)
{
struct
dheader
**
free
=
isdir
?
&
anchor
->
dir_free
:
&
anchor
->
free
;
struct
dheader
**
full
=
isdir
?
&
anchor
->
dir_full
:
&
anchor
->
full
;
struct
dheader
*
base
=
*
free
;
struct
dentry
*
res
;
if
(
!
base
)
{
base
=
dinit
(
isdir
,
size
);
if
(
!
base
)
return
NULL
;
insert_header
(
free
,
base
);
}
base
->
free
--
;
res
=
base
->
emptylist
;
if
(
!
(
base
->
emptylist
=
res
->
d_next
))
{
remove_header
(
free
,
base
);
insert_header
(
full
,
base
);
}
memset
(
res
,
0
,
sizeof
(
struct
dentry
)
-
D_MAXLEN
);
if
(
isdir
)
{
res
->
d_flag
=
D_DIR
;
memset
(
d_dir
(
res
),
0
,
sizeof
(
struct
ddir
));
res
->
d_name
.
name
=
kmalloc
(
NAME_ALLOC_LEN
(
len
),
GFP_KERNEL
);
if
(
!
res
->
d_name
.
name
)
{
kfree
(
res
);
return
NULL
;
}
res
->
d_len
=
len
;
res
->
d_name
.
len
=
len
;
res
->
d_parent
=
parent
;
if
(
parent
)
{
struct
ddir
*
pdir
=
d_dir
(
parent
);
...
...
@@ -403,33 +331,6 @@ static /*inline*/ struct dentry * __dalloc(struct anchors * anchor,
return
res
;
}
struct
dentry
*
d_alloc
(
struct
dentry
*
parent
,
int
len
,
int
isdir
)
{
int
i
,
size
;
#ifdef DEBUG
if
(
the_root
)
recursive_test
(
the_root
);
LOG
(
"d_alloc"
,
parent
);
#endif
if
(
len
>=
D_MEDIUM
)
{
if
(
len
>=
D_LARGE
)
{
i
=
3
;
size
=
D_HUGE
;
}
else
{
i
=
2
;
size
=
D_LARGE
;
}
}
else
if
(
len
>=
D_SMALL
)
{
i
=
1
;
size
=
D_MEDIUM
;
}
else
{
i
=
0
;
size
=
D_SMALL
;
}
return
__dalloc
(
&
anchors
[
i
],
parent
,
isdir
,
len
,
size
);
}
extern
blocking
struct
dentry
*
d_alloc_root
(
struct
inode
*
root_inode
)
{
struct
dentry
*
res
=
the_root
;
...
...
@@ -442,7 +343,7 @@ extern blocking struct dentry * d_alloc_root(struct inode * root_inode)
the_root
=
res
=
d_alloc
(
NULL
,
0
,
1
);
LOG
(
"d_alloc_root"
,
res
);
res
->
d_parent
=
res
;
res
->
d_name
[
0
]
=
'\0'
;
res
->
d_name
.
name
[
0
]
=
'\0'
;
ddir
=
d_dir
(
res
);
ddir
->
dd_alloced
=
999
;
/* protect from deletion */
}
...
...
@@ -460,8 +361,8 @@ static inline unsigned long d_hash(char first, char last)
static
inline
struct
dentry
**
d_base_entry
(
struct
ddir
*
pdir
,
struct
dentry
*
entry
)
{
return
&
pdir
->
dd_hashtable
[
d_hash
(
entry
->
d_name
[
0
],
entry
->
d_name
[
entry
->
d_
len
-
1
])];
return
&
pdir
->
dd_hashtable
[
d_hash
(
entry
->
d_name
.
name
[
0
],
entry
->
d_name
.
name
[
entry
->
d_name
.
len
-
1
])];
}
static
inline
struct
dentry
**
d_base_qstr
(
struct
ddir
*
pdir
,
...
...
@@ -569,12 +470,8 @@ static /*inline*/ void _d_handle_zombie(struct dentry * entry,
}
static
/*inline*/
blocking
void
_d_del
(
struct
dentry
*
entry
,
struct
anchors
*
anchor
,
int
flags
)
{
struct
dheader
**
free
;
struct
dheader
**
full
;
struct
dheader
*
base
=
BASE_DHEADER
(
entry
);
struct
ddir
*
ddir
=
NULL
;
struct
ddir
*
pdir
;
struct
inode
*
inode
=
entry
->
d_flag
&
D_PRELIMINARY
?
NULL
:
entry
->
u
.
d_inode
;
...
...
@@ -587,13 +484,6 @@ static /*inline*/ blocking void _d_del(struct dentry * entry,
printk
(
"VFS: dcache parent is NULL
\n
"
);
return
;
}
if
(
entry
->
d_flag
&
D_DIR
)
{
free
=
&
anchor
->
dir_free
;
full
=
&
anchor
->
dir_full
;
}
else
{
free
=
&
anchor
->
free
;
full
=
&
anchor
->
full
;
}
pdir
=
d_dir
(
entry
->
d_parent
);
if
(
!
IS_ROOT
(
entry
))
_d_remove_from_parent
(
entry
,
pdir
,
inode
,
flags
);
...
...
@@ -636,50 +526,23 @@ static /*inline*/ blocking void _d_del(struct dentry * entry,
}
}
if
(
!
(
flags
&
D_NO_FREE
)
&&
!
(
entry
->
d_flag
&
D_ZOMBIE
))
{
base
->
free
++
;
if
(
base
->
free
==
base
->
maxfree
)
{
#ifndef DEBUG
remove_header
(
free
,
base
);
free_page
((
unsigned
long
)
base
);
goto
done
;
#endif
}
entry
->
d_next
=
base
->
emptylist
;
base
->
emptylist
=
entry
;
if
(
!
entry
->
d_next
)
{
remove_header
(
full
,
base
);
insert_header
(
free
,
base
);
}
kfree
(
entry
->
d_name
.
name
);
kfree
(
entry
);
#ifdef DEBUG
x_freed
++
;
#endif
}
#ifndef DEBUG
done:
#else
#ifdef DEBUG
x_free
++
;
#endif
}
blocking
void
d_del
(
struct
dentry
*
entry
,
int
flags
)
{
int
i
;
if
(
!
entry
)
return
;
LOG
(
"d_clear"
,
entry
);
if
(
entry
->
d_len
>=
D_MEDIUM
)
{
if
(
entry
->
d_len
>=
D_LARGE
)
{
i
=
3
;
}
else
{
i
=
2
;
}
}
else
if
(
entry
->
d_len
>=
D_SMALL
)
{
i
=
1
;
}
else
{
i
=
0
;
}
_d_del
(
entry
,
&
anchors
[
i
],
flags
);
_d_del
(
entry
,
flags
);
}
static
inline
struct
dentry
*
__dlookup
(
struct
dentry
**
base
,
...
...
@@ -694,10 +557,10 @@ static inline struct dentry * __dlookup(struct dentry ** base,
if
(
appendix
)
totallen
+=
appendix
->
len
;
do
{
if
(
tmp
->
d_len
==
totallen
&&
if
(
tmp
->
d_
name
.
len
==
totallen
&&
!
(
tmp
->
d_flag
&
D_DUPLICATE
)
&&
!
strncmp
(
tmp
->
d_name
,
name
->
name
,
name
->
len
)
&&
(
!
appendix
||
!
strncmp
(
tmp
->
d_name
+
name
->
len
,
!
strncmp
(
tmp
->
d_name
.
name
,
name
->
name
,
name
->
len
)
&&
(
!
appendix
||
!
strncmp
(
tmp
->
d_name
.
name
+
name
->
len
,
appendix
->
name
,
appendix
->
len
)))
return
tmp
;
tmp
=
tmp
->
d_hash_next
;
...
...
@@ -755,7 +618,7 @@ static /*inline*/ blocking void _d_insert_to_parent(struct dentry * entry,
if
(
inode
&&
inode
->
i_dentry
&&
(
entry
->
d_flag
&
D_DIR
))
{
struct
dentry
*
tmp
=
inode
->
i_dentry
;
printk
(
"Auweia inode=%p entry=%p (%p %p %s)
\n
"
,
inode
,
entry
,
parent
->
u
.
d_inode
,
parent
,
parent
->
d_name
);
inode
,
entry
,
parent
->
u
.
d_inode
,
parent
,
parent
->
d_name
.
name
);
printk
(
"entry path="
);
printpath
(
entry
);
printk
(
"
\n
"
);
do
{
TST
(
"auweia"
,
tmp
);
...
...
@@ -801,15 +664,15 @@ blocking void d_add(struct dentry * entry, struct inode * inode,
LOG
(
"d_add"
,
entry
);
#endif
if
(
ininame
)
{
if
(
ininame
->
len
!=
entry
->
d_len
)
{
if
(
ininame
->
len
!=
entry
->
d_
name
.
len
)
{
printk
(
"VFS: d_add with wrong string length"
);
entry
->
d_len
=
ininame
->
len
;
/* kludge */
entry
->
d_
name
.
len
=
ininame
->
len
;
/* kludge */
}
memcpy
(
entry
->
d_name
,
ininame
->
name
,
ininame
->
len
);
entry
->
d_name
[
ininame
->
len
]
=
'\0'
;
memcpy
(
entry
->
d_name
.
name
,
ininame
->
name
,
ininame
->
len
);
entry
->
d_name
.
name
[
ininame
->
len
]
=
'\0'
;
}
else
{
dummy
.
name
=
entry
->
d_name
;
dummy
.
len
=
entry
->
d_len
;
dummy
.
name
=
entry
->
d_name
.
name
;
dummy
.
len
=
entry
->
d_
name
.
len
;
ininame
=
&
dummy
;
}
if
(
entry
->
d_flag
&
D_HASHED
)
...
...
@@ -871,11 +734,45 @@ blocking void d_entry_preliminary(struct dentry * parent,
}
}
static
inline
void
alloc_new_name
(
struct
dentry
*
entry
,
int
len
)
{
int
alloc_len
=
NAME_ALLOC_LEN
(
len
);
char
*
name
;
if
(
alloc_len
==
NAME_ALLOC_LEN
(
entry
->
d_name
.
len
))
return
;
name
=
kmalloc
(
alloc_len
,
GFP_KERNEL
);
if
(
!
name
)
printk
(
"out of memory for dcache
\n
"
);
kfree
(
entry
->
d_name
.
name
);
entry
->
d_name
.
name
=
name
;
}
static
inline
void
d_remove_old_parent
(
struct
dentry
*
entry
)
{
struct
ddir
*
pdir
;
struct
inode
*
inode
;
pdir
=
d_dir
(
entry
->
d_parent
);
inode
=
entry
->
u
.
d_inode
;
_d_remove_from_parent
(
entry
,
pdir
,
inode
,
D_NO_CLEAR_INODE
);
}
static
inline
void
d_add_new_parent
(
struct
dentry
*
entry
,
struct
inode
*
new_parent
)
{
struct
ddir
*
pdir
;
struct
inode
*
inode
;
pdir
=
d_dir
(
entry
->
d_parent
=
new_parent
->
i_dentry
);
inode
=
entry
->
u
.
d_inode
;
_d_insert_to_parent
(
entry
,
pdir
,
inode
,
&
entry
->
d_name
,
entry
->
d_flag
);
}
blocking
void
d_move
(
struct
dentry
*
entry
,
struct
inode
*
newdir
,
struct
qstr
*
newname
,
struct
qstr
*
newapp
)
{
struct
ddir
tmp
;
struct
dentry
*
new
;
struct
inode
*
inode
;
int
len
;
int
flags
;
...
...
@@ -891,38 +788,29 @@ blocking void d_move(struct dentry * entry, struct inode * newdir,
return
;
}
#if 0
printk("d_move %p '%s' -> '%s%s' dent_count=%d\n", inode, entry->d_name,
printk("d_move %p '%s' -> '%s%s' dent_count=%d\n", inode, entry->d_name
.name
,
newname->name, newapp ? newapp->name : "", inode->i_dent_count);
#endif
if
(
flags
&
D_ZOMBIE
)
{
printk
(
"VFS: moving zombie entry
\n
"
);
}
if
(
flags
&
D_DIR
)
{
struct
ddir
*
ddir
=
d_dir
(
entry
);
memcpy
(
&
tmp
,
ddir
,
sizeof
(
struct
ddir
)
);
d_remove_old_parent
(
entry
);
/* Simulate empty dir for d_del(). */
memset
(
ddir
,
0
,
sizeof
(
struct
ddir
));
}
len
=
newname
->
len
;
if
(
newapp
)
{
len
+=
newapp
->
len
;
flags
|=
D_BASKET
;
}
else
flags
&=
~
D_BASKET
;
new
=
d_alloc
(
newdir
->
i_dentry
,
len
,
flags
&
D_DIR
);
memcpy
(
new
->
d_
name
,
newname
->
name
,
newname
->
len
);
alloc_new_name
(
entry
,
len
);
memcpy
(
entry
->
d_name
.
name
,
newname
->
name
,
newname
->
len
);
if
(
newapp
)
memcpy
(
new
->
d_name
+
newname
->
len
,
newapp
->
name
,
newapp
->
len
);
new
->
d_name
[
len
]
=
'\0'
;
d_del
(
entry
,
D_NO_CLEAR_INODE
);
d_add
(
new
,
inode
,
NULL
,
flags
&
(
D_DIR
|
D_BASKET
));
if
(
flags
&
D_DIR
)
{
struct
ddir
*
ddir
=
d_dir
(
new
);
memcpy
(
ddir
,
&
tmp
,
sizeof
(
struct
ddir
));
}
memcpy
(
entry
->
d_name
.
name
+
newname
->
len
,
newapp
->
name
,
newapp
->
len
);
entry
->
d_name
.
name
[
len
]
=
'\0'
;
entry
->
d_name
.
len
=
len
;
d_add_new_parent
(
entry
,
newdir
);
}
int
d_path
(
struct
dentry
*
entry
,
struct
inode
*
chroot
,
char
*
buf
)
...
...
@@ -939,8 +827,8 @@ int d_path(struct dentry * entry, struct inode * chroot, char * buf)
*
buf
++
=
'/'
;
len
++
;
}
memcpy
(
buf
,
entry
->
d_name
,
entry
->
d_
len
);
return
len
+
entry
->
d_len
;
memcpy
(
buf
,
entry
->
d_name
.
name
,
entry
->
d_name
.
len
);
return
len
+
entry
->
d_
name
.
len
;
}
}
...
...
@@ -966,7 +854,7 @@ blocking struct inode * d_inode(struct dentry ** changing_entry)
#ifdef CONFIG_DCACHE_PRELOAD
if
(
entry
->
d_flag
&
D_PRELIMINARY
)
{
struct
qstr
name
=
{
entry
->
d_name
,
entry
->
d_
len
};
struct
qstr
name
=
{
entry
->
d_name
.
name
,
entry
->
d_name
.
len
};
struct
ddir
*
pdir
=
d_dir
(
entry
->
d_parent
);
struct
dentry
**
base
=
d_base_qstr
(
pdir
,
&
name
,
NULL
);
struct
dentry
*
found
;
...
...
@@ -1014,7 +902,7 @@ blocking struct inode * d_inode(struct dentry ** changing_entry)
d_del
(
entry
,
D_NO_CLEAR_INODE
);
*
changing_entry
=
found
;
}
else
if
(
S_ISDIR
(
inode
->
i_mode
))
{
struct
dentry
*
new
=
d_alloc
(
entry
->
d_parent
,
entry
->
d_len
,
1
);
struct
dentry
*
new
=
d_alloc
(
entry
->
d_parent
,
entry
->
d_
name
.
len
,
1
);
if
(
new
)
d_add
(
new
,
inode
,
&
name
,
D_DIR
);
*
changing_entry
=
new
;
...
...
fs/namei.c
View file @
70e39deb
...
...
@@ -951,7 +951,7 @@ static void basket_name(struct inode * dir, struct dentry * entry)
{
char prefix[32];
struct qstr prename = { prefix, 14 };
struct qstr entname = { entry->d_name
, entry->d_
len };
struct qstr entname = { entry->d_name
.name, entry->d_name.
len };
struct inode * inode;
struct dentry * old = entry; /* dummy */
int i;
...
...
fs/readdir.c
View file @
70e39deb
...
...
@@ -266,8 +266,8 @@ asmlinkage int sys_getdents(unsigned int fd, void * dirent, unsigned int count)
if
(
inode
)
{
nr
++
;
if
(
nr
>
(
file
->
f_pos
&
~
BASKET_BIT
))
{
int
err
=
filldir
(
&
buf
,
ptr
->
d_name
,
ptr
->
d_len
,
int
err
=
filldir
(
&
buf
,
ptr
->
d_name
.
name
,
ptr
->
d_
name
.
len
,
file
->
f_pos
,
inode
->
i_ino
);
if
(
err
)
...
...
fs/super.c
View file @
70e39deb
...
...
@@ -765,9 +765,9 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
struct
dentry
*
old
=
dir_i
->
i_dentry
;
struct
dentry
*
new
;
vfs_lock
();
new
=
d_alloc
(
old
->
d_parent
,
old
->
d_len
,
1
);
new
=
d_alloc
(
old
->
d_parent
,
old
->
d_
name
.
len
,
1
);
if
(
new
)
{
struct
qstr
copy
=
{
old
->
d_name
,
old
->
d_
len
};
struct
qstr
copy
=
{
old
->
d_name
.
name
,
old
->
d_name
.
len
};
d_add
(
new
,
sb
->
s_mounted
,
&
copy
,
D_DUPLICATE
);
vfs_unlock
();
}
else
{
...
...
include/linux/dalloc.h
View file @
70e39deb
...
...
@@ -9,7 +9,7 @@
* <schoebel@informatik.uni-stuttgart.de>.
*/
#define D_MAXLEN
1024
#define D_MAXLEN 1024
/* public flags for d_add() */
#define D_NORMAL 0
...
...
@@ -26,6 +26,16 @@
#define IS_ROOT(x) ((x) == (x)->d_parent)
/* "quick string" -- I introduced this to shorten the parameter list
* of many routines. Think of it as a (str,stlen) pair.
* Storing the len instead of doing strlen() very often is performance
* critical.
*/
struct
qstr
{
char
*
name
;
int
len
;
};
struct
dentry
{
union
{
struct
inode
*
d_inode
;
/* Where the name belongs to */
...
...
@@ -38,19 +48,8 @@ struct dentry {
struct
dentry
*
d_hash_prev
;
struct
dentry
*
d_basket_next
;
struct
dentry
*
d_basket_prev
;
short
d_len
;
/* set by dalloc() */
short
d_flag
;
char
d_name
[
D_MAXLEN
];
};
/* "quick string" -- I introduced this to shorten the parameter list
* of many routines. Think of it as a (str,stlen) pair.
* Storing the len instead of doing strlen() very often is performance
* critical.
*/
struct
qstr
{
const
char
*
name
;
int
len
;
struct
qstr
d_name
;
unsigned
int
d_flag
;
};
extern
struct
dentry
*
the_root
;
...
...
include/linux/fs.h
View file @
70e39deb
...
...
@@ -15,7 +15,9 @@
#include <linux/net.h>
#include <linux/kdev_t.h>
#include <linux/ioctl.h>
#include <asm/atomic.h>
#include <asm/bitops.h>
/* Prefixes for routines (having no effect), but indicate what
* the routine may do. This can greatly ease reasoning about routines...
...
...
include/linux/pci.h
View file @
70e39deb
...
...
@@ -497,7 +497,7 @@
#define PCI_DEVICE_ID_VIA_82C586_1 0x0571
#define PCI_DEVICE_ID_VIA_82C576 0x0576
#define PCI_DEVICE_ID_VIA_82C585 0x0585
#define PCI_DEVICE_ID_VIA_82C586
_0
0x0586
#define PCI_DEVICE_ID_VIA_82C586 0x0586
#define PCI_DEVICE_ID_VIA_82C416 0x1571
#define PCI_VENDOR_ID_VORTEX 0x1119
...
...
scripts/ksymoops.cc
View file @
70e39deb
...
...
@@ -31,6 +31,7 @@
// * Only resolves operands of jump and call instructions.
#include <fstream.h>
#include <strstream.h>
#include <iomanip.h>
#include <stdio.h>
#include <string.h>
...
...
@@ -184,9 +185,23 @@ NameList::decode(unsigned char* code, long eip_addr)
char
buf
[
1024
];
int
lines
=
0
;
int
eip_seen
=
0
;
long
offset
;
while
(
fgets
(
buf
,
sizeof
(
buf
),
objdump_FILE
))
{
if
(
eip_seen
&&
buf
[
4
]
==
':'
)
{
// assume objdump from binutils 2.8..., reformat to old style
offset
=
strtol
(
buf
,
0
,
16
);
char
newbuf
[
sizeof
(
buf
)];
memset
(
newbuf
,
'\0'
,
sizeof
(
newbuf
));
ostrstream
ost
(
newbuf
,
sizeof
(
newbuf
));
ost
.
width
(
8
);
ost
<<
offset
;
ost
<<
" <_EIP+"
<<
offset
<<
">: "
<<
&
buf
[
6
]
<<
ends
;
strcpy
(
buf
,
newbuf
);
}
if
(
!
strnequ
(
&
buf
[
9
],
"<_EIP"
,
5
))
continue
;
eip_seen
=
1
;
if
(
strstr
(
buf
,
" is out of bounds"
))
break
;
lines
++
;
...
...
@@ -195,19 +210,28 @@ NameList::decode(unsigned char* code, long eip_addr)
cout
<<
buf
;
continue
;
}
long
offset
=
strtol
(
buf
,
0
,
16
);
char
*
bp_0
=
strchr
(
buf
,
'>'
)
+
2
;
offset
=
strtol
(
buf
,
0
,
16
);
char
*
bp_0
=
strchr
(
buf
,
'>'
);
KSym
*
ksym
=
find
(
eip_addr
+
offset
);
if
(
bp_0
)
bp_0
+=
2
;
else
bp_0
=
strchr
(
buf
,
':'
);
if
(
ksym
)
cout
<<
*
ksym
<<
' '
;
char
*
bp
=
bp_0
;
char
*
bp_1
=
strstr
(
bp_0
,
"
\t
"
);
// objdump from binutils 2.8...
if
(
bp_1
)
++
bp_1
;
else
bp_1
=
bp_0
;
char
*
bp
=
bp_1
;
while
(
!
isspace
(
*
bp
))
bp
++
;
while
(
isspace
(
*
bp
))
bp
++
;
if
(
*
bp
!=
'0'
)
{
if
(
!
isxdigit
(
*
bp
)
)
{
cout
<<
bp_0
;
}
else
if
(
*
bp_
0
==
'j'
||
strnequ
(
bp_0
,
"call"
,
4
))
{
// a jump or call insn
}
else
if
(
*
bp_
1
==
'j'
||
strnequ
(
bp_1
,
"call"
,
4
))
{
// a jump or call insn
long
rel_addr
=
strtol
(
bp
,
0
,
16
);
ksym
=
find
(
eip_addr
+
rel_addr
);
if
(
ksym
)
{
...
...
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