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
2730f0af
Commit
2730f0af
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.1.45pre2
parent
0d1267fe
Changes
43
Hide whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
759 additions
and
815 deletions
+759
-815
CREDITS
CREDITS
+16
-1
MAINTAINERS
MAINTAINERS
+5
-0
Makefile
Makefile
+1
-1
arch/alpha/defconfig
arch/alpha/defconfig
+5
-7
arch/i386/defconfig
arch/i386/defconfig
+1
-4
drivers/char/cyclades.c
drivers/char/cyclades.c
+315
-79
drivers/char/psaux.c
drivers/char/psaux.c
+5
-5
drivers/scsi/BusLogic.h
drivers/scsi/BusLogic.h
+1
-0
drivers/scsi/tmscsim.c
drivers/scsi/tmscsim.c
+7
-42
fs/Config.in
fs/Config.in
+0
-20
fs/autofs/root.c
fs/autofs/root.c
+3
-3
fs/binfmt_aout.c
fs/binfmt_aout.c
+1
-1
fs/binfmt_elf.c
fs/binfmt_elf.c
+2
-3
fs/binfmt_em86.c
fs/binfmt_em86.c
+1
-1
fs/binfmt_java.c
fs/binfmt_java.c
+2
-2
fs/binfmt_script.c
fs/binfmt_script.c
+1
-1
fs/dcache.c
fs/dcache.c
+124
-254
fs/dquot.c
fs/dquot.c
+1
-1
fs/exec.c
fs/exec.c
+2
-2
fs/ext2/namei.c
fs/ext2/namei.c
+8
-8
fs/ext2/truncate.c
fs/ext2/truncate.c
+28
-167
fs/filesystems.c
fs/filesystems.c
+0
-5
fs/inode.c
fs/inode.c
+2
-2
fs/minix/inode.c
fs/minix/inode.c
+0
-1
fs/minix/namei.c
fs/minix/namei.c
+5
-5
fs/namei.c
fs/namei.c
+58
-40
fs/nfs/dir.c
fs/nfs/dir.c
+5
-5
fs/open.c
fs/open.c
+13
-22
fs/proc/link.c
fs/proc/link.c
+2
-3
fs/proc/omirr.c
fs/proc/omirr.c
+0
-1
fs/super.c
fs/super.c
+1
-2
include/linux/cyclades.h
include/linux/cyclades.h
+22
-5
include/linux/dcache.h
include/linux/dcache.h
+105
-0
include/linux/fs.h
include/linux/fs.h
+9
-14
include/linux/nametrans.h
include/linux/nametrans.h
+0
-69
include/linux/omirr.h
include/linux/omirr.h
+0
-17
include/linux/slab.h
include/linux/slab.h
+1
-1
init/main.c
init/main.c
+1
-8
kernel/sys.c
kernel/sys.c
+1
-2
kernel/sysctl.c
kernel/sysctl.c
+0
-5
mm/slab.c
mm/slab.c
+3
-3
net/socket.c
net/socket.c
+0
-1
net/unix/af_unix.c
net/unix/af_unix.c
+2
-2
No files found.
CREDITS
View file @
2730f0af
...
...
@@ -107,7 +107,9 @@ S: USA
N: Randolph Bentson
E: bentson@grieg.seaslug.org
D: author of driver for Cyclades Cyclom-Y async mux
D: author of driver for Cyclom-Y and Cyclades-Z async mux
P: 1024/39ED5729 5C A8 7A F4 B2 7A D1 3E B5 3B 81 CF 47 30 11 71
W: http://www.aa.net/~bentson/
S: 2322 37th Ave SW
S: Seattle, Washington 98126-2010
S: USA
...
...
@@ -793,6 +795,12 @@ S: Schlehenweg 9
S: D-91080 Uttenreuth
S: Germany
N: Jaroslav Kysela
E: perex@jcu.cz
D: Original Author and Maintainer for HP 10/100 Mbit Network Adapters
W: http://www.pf.jcu.cz/~perex
S: Unix Centre of Pedagogical Faculty, University of South Bohemia
N: Bas Laarhoven
E: bas@vimec.nl
D: Loadable modules and ftape driver
...
...
@@ -842,6 +850,13 @@ S: PO Box 371
S: North Little Rock, Arkansas 72115
S: US
N: Siegfried "Frieder" Loeffler (dg1sek)
E: floeff@tunix.mathematik.uni-stuttgart.de, fl@LF.net
W: http://www.mathematik.uni-stuttgart.de/~floeff
D: Busmaster driver for HP 10/100 Mbit Network Adapters
S: University of Stuttgart, Germany and
S: Ecole Nationale Superieure des Telecommunications, Paris
N: Martin von Loewis
E: loewis@informatik.hu-berlin.de
D: script binary format
...
...
MAINTAINERS
View file @
2730f0af
...
...
@@ -107,6 +107,11 @@ P: Jean Tourrilhes
M: jt@hplb.hpl.hp.com
S: Maintained
HP100: Driver for HP 10/100 Mbit/s Network Adapter Series
P: Jarsolav Kysela
M: perex@jcu.cz
S: Maintained
APM DRIVER
P: Rik Faith & Stephen Rothwell
M: faith@cs.unc.edu, Stephen.Rothwell@canb.auug.org.au
...
...
Makefile
View file @
2730f0af
VERSION
=
2
PATCHLEVEL
=
1
SUBLEVEL
=
4
4
SUBLEVEL
=
4
5
ARCH
:=
$(
shell
uname
-m
|
sed
-e
s/i.86/i386/
-e
s/sun4u/sparc64/
)
...
...
arch/alpha/defconfig
View file @
2730f0af
...
...
@@ -195,9 +195,6 @@ CONFIG_DE4X5=y
# Filesystems
#
# CONFIG_QUOTA is not set
# CONFIG_DCACHE_PRELOAD is not set
# CONFIG_OMIRR is not set
# CONFIG_TRANS_NAMES is not set
# CONFIG_MINIX_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_FAT_FS is not set
...
...
@@ -205,12 +202,13 @@ CONFIG_EXT2_FS=y
# CONFIG_VFAT_FS is not set
# CONFIG_UMSDOS_FS is not set
CONFIG_PROC_FS=y
# CONFIG_NFS_FS is not set
CONFIG_NFS_FS=y
# CONFIG_ROOT_NFS is not set
# CONFIG_NFSD is not set
# CONFIG_SUNRPC is not set
# CONFIG_LOCKD is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
# CONFIG_ISO9660_FS is not set
CONFIG_ISO9660_FS=y
# CONFIG_HPFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_AFFS_FS is not set
...
...
arch/i386/defconfig
View file @
2730f0af
...
...
@@ -192,9 +192,6 @@ CONFIG_EEXPRESS_PRO100=y
# Filesystems
#
# CONFIG_QUOTA is not set
# CONFIG_DCACHE_PRELOAD is not set
# CONFIG_OMIRR is not set
# CONFIG_TRANS_NAMES is not set
# CONFIG_MINIX_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_FAT_FS is not set
...
...
@@ -208,7 +205,7 @@ CONFIG_NFS_FS=y
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
# CONFIG_ISO9660_FS is not set
CONFIG_ISO9660_FS=y
# CONFIG_HPFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_AFFS_FS is not set
...
...
drivers/char/cyclades.c
View file @
2730f0af
#define BLOCKMOVE
static
char
rcsid
[]
=
"$Revision: 1.36.4.
27 $$Date: 1997/03/26 10:3
0:00 $"
;
"$Revision: 1.36.4.
33 $$Date: 1997/06/27 19:0
0:00 $"
;
/*
* linux/drivers/char/cyclades.c
...
...
@@ -29,6 +29,50 @@ static char rcsid[] =
* void cleanup_module(void);
*
* $Log: cyclades.c,v $
* Revision 1.36.4.33 1997/06/27 19:00:00 ivan
* Fixes related to kernel version conditional
* compilation.
*
* Revision 1.36.4.32 1997/06/14 19:30:00 ivan
* Compatibility issues between kernels 2.0.x and
* 2.1.x (mainly related to clear_bit function).
*
* Revision 1.36.4.31 1997/06/03 15:30:00 ivan
* Changes to define the memory window according to the
* board type.
*
* Revision 1.36.4.30 1997/05/16 15:30:00 daniel
* Changes to suport new cycladesZ boards.
*
* Revision 1.36.4.29 1997/05/12 11:30:00 daniel
* Merge of Bentson's and Daniel's version 1.36.4.28.
* Corrects bug in cy_detect_pci: check if there are more
* ports than the number of static structs allocated.
* Warning message during initialization if this driver is
* used with the new generation of cycladesZ boards. Those
* will be supported only in next release of the driver.
* Corrects bug in cy_detect_pci and cy_detect_isa that
* returned wrong number of VALID boards, when a cyclomY
* was found with no serial modules connected.
* Changes to use current (2.1.x) kernel subroutine names
* and created macros for compilation with 2.0.x kernel,
* instead of the other way around.
*
* Revision 1.36.4.28 1997/05/?? ??:00:00 bentson
* Change queue_task_irq_off to queue_task_irq.
* The inline function queue_task_irq_off (tqueue.h)
* was removed from latest releases of 2.1.x kernel.
* Use of macro __initfunc to mark the initialization
* routines, so memory can be reused.
* Also incorporate implementation of critical region
* in function cleanup_module() created by anonymous
* linuxer.
*
* Revision 1.36.4.28 1997/04/25 16:00:00 daniel
* Change to support new firmware that solves DCD problem:
* application could fail to receive SIGHUP signal when DCD
* varying too fast.
*
* Revision 1.36.4.27 1997/03/26 10:30:00 daniel
* Changed for suport linux versions 2.1.X.
* Backward compatible with linux versions 2.0.X.
...
...
@@ -98,7 +142,7 @@ static char rcsid[] =
* after -Y stuff (to make changes clearer)
*
* Revision 1.36.4.12 1996/07/11 15:40:55 bentson
* Add code to poll Cycl
om
-Z. Add code to get & set RS-232 control.
* Add code to poll Cycl
ades
-Z. Add code to get & set RS-232 control.
* Add code to send break. Clear firmware ID word at startup (so
* that other code won't talk to inactive board).
*
...
...
@@ -391,7 +435,13 @@ static char rcsid[] =
constant in the definition below. No other change is necessary to
support more boards/ports. */
#define NR_PORTS 64
//#define NR_PORTS 64
#define NR_PORTS 128
#define ZE_V1_NPORTS 64
#define ZO_V1 0
#define ZO_V2 1
#define ZE_V1 2
#define SERIAL_PARANOIA_CHECK
#undef SERIAL_DEBUG_OPEN
...
...
@@ -453,35 +503,51 @@ static char rcsid[] =
#include <linux/kernel.h>
#include <linux/bios32.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/version.h>
#if
LINUX_VERSION_CODE >= 131328
#if
(LINUX_VERSION_CODE >= 0x020100)
#include <asm/uaccess.h>
#include <linux/init.h>
#define memcpy_fromfs copy_from_user
#define memcpy_tofs copy_to_user
#define put_fs_long put_user
#define vremap ioremap
#define cy_put_user put_user
static
unsigned
long
get_fs_long
(
unsigned
long
*
addr
)
static
unsigned
long
cy_get_user
(
unsigned
long
*
addr
)
{
unsigned
long
result
=
0
;
int
error
=
get_user
(
result
,
addr
);
if
(
error
)
printk
(
"cyclades:
get_fs_long
: error == %d
\n
"
,
error
);
printk
(
"cyclades:
cy_get_user
: error == %d
\n
"
,
error
);
return
result
;
}
#else
#define __initfunc(__arginit) __arginit
#define copy_from_user memcpy_fromfs
#define copy_to_user memcpy_tofs
#define cy_get_user get_fs_long
#define cy_put_user put_fs_long
#define ioremap vremap
#endif
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#define IS_CYC_Z(card) ((card).num_chips == 1)
#define Z_FPGA_CHECK(card) \
((((struct RUNTIME_9060 *)((card).ctl_addr))->init_ctrl&(1<<17))!=0)
#define ISZLOADED(card) (((ZO_V1==((struct RUNTIME_9060 *) \
((card).ctl_addr))->mail_box_0) || \
Z_FPGA_CHECK(card)) && \
(ZFIRM_ID==((struct FIRM_ID *) \
((card).base_addr+ID_ADDRESS))->signature))
#define WAKEUP_CHARS (SERIAL_XMIT_SIZE-256)
#define STD_COM_FLAGS (0)
...
...
@@ -548,7 +614,7 @@ static struct cyclades_card *IRQ_cards[16];
/*
* tmp_buf is used as a temporary buffer by serial_write. We need to
* lock it in case the
memcpy_fromfs
blocks while swapping in a page,
* lock it in case the
copy_from_user
blocks while swapping in a page,
* and some other program tries to do a serial write at the same time.
* Since the lock will only come under contention when the system is
* swapping and available memory is low, it makes sense to share one
...
...
@@ -698,10 +764,12 @@ static void CP4(int data)
{
(
data
<
10
)
?
CP
(
data
+
'0'
)
:
CP
(
data
+
'A'
-
10
);
}
/* CP4 */
static
void
CP8
(
int
data
)
{
CP4
((
data
>>
4
)
&
0x0f
);
CP4
(
data
&
0x0f
);
}
/* CP8 */
#if 0
static void CP16(int data)
{ CP8((data>>8) & 0xff); CP8(data & 0xff); }/* CP16 */
static void CP32(long data)
{ CP16((data>>16) & 0xffff); CP16(data & 0xffff); }/* CP32 */
#endif
/*
...
...
@@ -758,6 +826,7 @@ do_softint(void *private_)
if
(
!
tty
)
return
;
#if (LINUX_VERSION_CODE >= 0x020125)
if
(
test_and_clear_bit
(
Cy_EVENT_HANGUP
,
&
info
->
event
))
{
tty_hangup
(
info
->
tty
);
wake_up_interruptible
(
&
info
->
open_wait
);
...
...
@@ -774,6 +843,24 @@ do_softint(void *private_)
}
wake_up_interruptible
(
&
tty
->
write_wait
);
}
#else
if
(
clear_bit
(
Cy_EVENT_HANGUP
,
&
info
->
event
))
{
tty_hangup
(
info
->
tty
);
wake_up_interruptible
(
&
info
->
open_wait
);
info
->
flags
&=
~
(
ASYNC_NORMAL_ACTIVE
|
ASYNC_CALLOUT_ACTIVE
);
}
if
(
clear_bit
(
Cy_EVENT_OPEN_WAKEUP
,
&
info
->
event
))
{
wake_up_interruptible
(
&
info
->
open_wait
);
}
if
(
clear_bit
(
Cy_EVENT_WRITE_WAKEUP
,
&
info
->
event
))
{
if
((
tty
->
flags
&
(
1
<<
TTY_DO_WRITE_WAKEUP
))
&&
tty
->
ldisc
.
write_wakeup
){
(
tty
->
ldisc
.
write_wakeup
)(
tty
);
}
wake_up_interruptible
(
&
tty
->
write_wait
);
}
#endif
}
/* do_softint */
...
...
@@ -1351,7 +1438,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/***********************************************************/
/********* End of block of Cyclom-Y specific code **********/
/******** Start of block of Cycl
om
-Z specific code *********/
/******** Start of block of Cycl
ades
-Z specific code *********/
/***********************************************************/
...
...
@@ -1365,7 +1452,7 @@ cyz_fetch_msg( struct cyclades_card *cinfo,
unsigned
long
loc_doorbell
;
firm_id
=
(
struct
FIRM_ID
*
)(
cinfo
->
base_addr
+
ID_ADDRESS
);
if
(
firm_id
->
signature
!=
ZFIRM_ID
){
if
(
!
ISZLOADED
(
*
cinfo
)
){
return
(
-
1
);
}
zfw_ctrl
=
(
struct
ZFW_CTRL
*
)
...
...
@@ -1397,7 +1484,7 @@ cyz_issue_cmd( struct cyclades_card *cinfo,
int
index
;
firm_id
=
(
struct
FIRM_ID
*
)(
cinfo
->
base_addr
+
ID_ADDRESS
);
if
(
firm_id
->
signature
!=
ZFIRM_ID
){
if
(
!
ISZLOADED
(
*
cinfo
)
){
return
(
-
1
);
}
zfw_ctrl
=
(
struct
ZFW_CTRL
*
)
...
...
@@ -1408,7 +1495,7 @@ cyz_issue_cmd( struct cyclades_card *cinfo,
pci_doorbell
=
&
((
struct
RUNTIME_9060
*
)
(
cinfo
->
ctl_addr
))
->
pci_doorbell
;
while
(
(
*
pci_doorbell
&
0xff
)
!=
0
){
if
(
index
++
==
100
){
if
(
index
++
==
100
0
){
return
(
-
1
);
}
udelay
(
50L
);
...
...
@@ -1421,6 +1508,7 @@ cyz_issue_cmd( struct cyclades_card *cinfo,
}
/* cyz_issue_cmd */
#if 0
static int
cyz_update_channel( struct cyclades_card *cinfo,
u_long channel, u_char mode, u_char cmd)
...
...
@@ -1430,7 +1518,7 @@ cyz_update_channel( struct cyclades_card *cinfo,
struct ZFW_CTRL *zfw_ctrl;
struct CH_CTRL *ch_ctrl;
if
(
firm_id
->
signature
!=
ZFIRM_ID
){
if (
!ISZLOADED(*cinfo)
){
return (-1);
}
zfw_ctrl =
...
...
@@ -1442,6 +1530,7 @@ cyz_update_channel( struct cyclades_card *cinfo,
return cyz_issue_cmd(cinfo, channel, cmd, 0L);
} /* cyz_update_channel */
#endif
static
void
...
...
@@ -1467,6 +1556,7 @@ cyz_poll(unsigned long arg)
u_long
channel
;
u_char
cmd
;
u_long
*
param
;
u_long
hw_ver
,
fw_ver
;
cyz_timerlist
.
expires
=
jiffies
+
100
;
...
...
@@ -1476,7 +1566,7 @@ cyz_poll(unsigned long arg)
firm_id
=
(
struct
FIRM_ID
*
)
(
cinfo
->
base_addr
+
ID_ADDRESS
);
if
(
firm_id
->
signature
!=
ZFIRM_ID
){
if
(
!
ISZLOADED
(
*
cinfo
)
){
continue
;
}
...
...
@@ -1484,6 +1574,8 @@ cyz_poll(unsigned long arg)
(
struct
ZFW_CTRL
*
)
(
cinfo
->
base_addr
+
firm_id
->
zfwctrl_addr
);
board_ctrl
=
&
zfw_ctrl
->
board_ctrl
;
fw_ver
=
board_ctrl
->
fw_version
;
hw_ver
=
((
struct
RUNTIME_9060
*
)(
cinfo
->
ctl_addr
))
->
mail_box_0
;
while
(
cyz_fetch_msg
(
cinfo
,
&
channel
,
&
cmd
,
&
param
)
==
1
){
char_count
=
0
;
...
...
@@ -1514,7 +1606,9 @@ cyz_poll(unsigned long arg)
break
;
case
C_CM_MDCD
:
if
(
info
->
flags
&
ASYNC_CHECK_CD
){
if
(
ch_ctrl
[
channel
].
rs_status
&
C_RS_DCD
){
if
(((
hw_ver
!=
0
||
fw_ver
>
241
)
?
((
u_long
)
param
)
:
ch_ctrl
[
channel
].
rs_status
)
&
C_RS_DCD
)
{
/* SP("Open Wakeup\n"); */
cy_sched_event
(
info
,
Cy_EVENT_OPEN_WAKEUP
);
...
...
@@ -1709,7 +1803,7 @@ cyz_poll(unsigned long arg)
}
/* cyz_poll */
/********** End of block of Cycl
om
-Z specific code *********/
/********** End of block of Cycl
ades
-Z specific code *********/
/***********************************************************/
...
...
@@ -1794,7 +1888,7 @@ startup(struct cyclades_port * info)
base_addr
=
(
unsigned
char
*
)
(
cy_card
[
card
].
base_addr
);
firm_id
=
(
struct
FIRM_ID
*
)
(
base_addr
+
ID_ADDRESS
);
if
(
firm_id
->
signature
!=
ZFIRM_ID
){
if
(
!
ISZLOADED
(
cy_card
[
card
])
){
return
-
ENODEV
;
}
...
...
@@ -1951,7 +2045,7 @@ shutdown(struct cyclades_port * info)
#endif
firm_id
=
(
struct
FIRM_ID
*
)
(
base_addr
+
ID_ADDRESS
);
if
(
firm_id
->
signature
!=
ZFIRM_ID
)
{
if
(
!
ISZLOADED
(
cy_card
[
card
]))
{
return
;
}
...
...
@@ -2143,7 +2237,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
base_addr
=
(
char
*
)(
cinfo
->
base_addr
);
firm_id
=
(
struct
FIRM_ID
*
)
(
base_addr
+
ID_ADDRESS
);
if
(
firm_id
->
signature
!=
ZFIRM_ID
){
if
(
!
ISZLOADED
(
*
cinfo
)
){
return
-
EINVAL
;
}
...
...
@@ -2237,11 +2331,17 @@ cy_open(struct tty_struct *tty, struct file * filp)
will make the user pay attention.
*/
if
(
IS_CYC_Z
(
cy_card
[
info
->
card
]))
{
struct
FIRM_ID
*
firm_id
=
(
struct
FIRM_ID
*
)
(
cy_card
[
info
->
card
].
base_addr
+
ID_ADDRESS
);
if
(
firm_id
->
signature
!=
ZFIRM_ID
){
printk
(
"Cyclom-Z firmware not yet loaded
\n
"
);
if
(
!
ISZLOADED
(
cy_card
[
info
->
card
]))
{
if
(((
ZE_V1
==
((
struct
RUNTIME_9060
*
)
((
cy_card
[
info
->
card
]).
ctl_addr
))
->
mail_box_0
)
&&
Z_FPGA_CHECK
(
cy_card
[
info
->
card
]))
&&
(
ZFIRM_HLT
==
((
struct
FIRM_ID
*
)
((
cy_card
[
info
->
card
]).
base_addr
+
ID_ADDRESS
))
->
signature
))
{
printk
(
"Cyclades-Z Error: you need an external power supply for this number of ports.
\n\r
Firmware halted.
\r\n
"
);
}
else
{
printk
(
"Cyclades-Z firmware not yet loaded
\n
"
);
}
return
-
ENODEV
;
}
}
...
...
@@ -2448,7 +2548,7 @@ cy_write(struct tty_struct * tty, int from_user,
}
if
(
from_user
)
{
memcpy_fromfs
(
tmp_buf
,
buf
,
c
);
copy_from_user
(
tmp_buf
,
buf
,
c
);
c
=
MIN
(
c
,
MIN
(
SERIAL_XMIT_SIZE
-
info
->
xmit_cnt
-
1
,
SERIAL_XMIT_SIZE
-
info
->
xmit_head
));
memcpy
(
info
->
xmit_buf
+
info
->
xmit_head
,
tmp_buf
,
c
);
...
...
@@ -2816,7 +2916,7 @@ set_line_char(struct cyclades_port * info)
firm_id
=
(
struct
FIRM_ID
*
)
(
cy_card
[
card
].
base_addr
+
ID_ADDRESS
);
if
(
firm_id
->
signature
!=
ZFIRM_ID
)
{
if
(
!
ISZLOADED
(
cy_card
[
card
]))
{
return
;
}
...
...
@@ -2956,7 +3056,7 @@ get_serial_info(struct cyclades_port * info,
tmp
.
baud_base
=
info
->
baud
;
tmp
.
custom_divisor
=
0
;
/*!!!*/
tmp
.
hub6
=
0
;
/*!!!*/
memcpy_tofs
(
retinfo
,
&
tmp
,
sizeof
(
*
retinfo
));
copy_to_user
(
retinfo
,
&
tmp
,
sizeof
(
*
retinfo
));
return
0
;
}
/* get_serial_info */
...
...
@@ -2970,7 +3070,7 @@ set_serial_info(struct cyclades_port * info,
if
(
!
new_info
)
return
-
EFAULT
;
memcpy_fromfs
(
&
new_serial
,
new_info
,
sizeof
(
new_serial
));
copy_from_user
(
&
new_serial
,
new_info
,
sizeof
(
new_serial
));
old_info
=
*
info
;
if
(
!
suser
())
{
...
...
@@ -3051,7 +3151,7 @@ get_modem_info(struct cyclades_port * info, unsigned int *value)
firm_id
=
(
struct
FIRM_ID
*
)
(
cy_card
[
card
].
base_addr
+
ID_ADDRESS
);
if
(
firm_id
->
signature
==
ZFIRM_ID
)
{
if
(
ISZLOADED
(
cy_card
[
card
]))
{
zfw_ctrl
=
(
struct
ZFW_CTRL
*
)
(
cy_card
[
card
].
base_addr
+
firm_id
->
zfwctrl_addr
);
...
...
@@ -3070,7 +3170,7 @@ get_modem_info(struct cyclades_port * info, unsigned int *value)
}
}
put_fs_long
(
result
,(
unsigned
long
*
)
value
);
cy_put_user
(
result
,(
unsigned
long
*
)
value
);
return
0
;
}
/* get_modem_info */
...
...
@@ -3082,7 +3182,7 @@ set_modem_info(struct cyclades_port * info, unsigned int cmd,
int
card
,
chip
,
channel
,
index
;
unsigned
char
*
base_addr
;
unsigned
long
flags
;
unsigned
int
arg
=
get_fs_long
((
unsigned
long
*
)
value
);
unsigned
int
arg
=
cy_get_user
((
unsigned
long
*
)
value
);
struct
FIRM_ID
*
firm_id
;
struct
ZFW_CTRL
*
zfw_ctrl
;
struct
BOARD_CTRL
*
board_ctrl
;
...
...
@@ -3180,7 +3280,7 @@ set_modem_info(struct cyclades_port * info, unsigned int cmd,
firm_id
=
(
struct
FIRM_ID
*
)
(
cy_card
[
card
].
base_addr
+
ID_ADDRESS
);
if
(
firm_id
->
signature
==
ZFIRM_ID
)
{
if
(
ISZLOADED
(
cy_card
[
card
]))
{
zfw_ctrl
=
(
struct
ZFW_CTRL
*
)
(
cy_card
[
card
].
base_addr
+
firm_id
->
zfwctrl_addr
);
...
...
@@ -3281,7 +3381,7 @@ static int
get_mon_info
(
struct
cyclades_port
*
info
,
struct
cyclades_monitor
*
mon
)
{
memcpy_tofs
(
mon
,
&
info
->
mon
,
sizeof
(
struct
cyclades_monitor
));
copy_to_user
(
mon
,
&
info
->
mon
,
sizeof
(
struct
cyclades_monitor
));
info
->
mon
.
int_count
=
0
;
info
->
mon
.
char_count
=
0
;
info
->
mon
.
char_max
=
0
;
...
...
@@ -3335,7 +3435,7 @@ get_threshold(struct cyclades_port * info, unsigned long *value)
+
(
cy_chip_offset
[
chip
]
<<
index
));
tmp
=
base_addr
[
CyCOR3
<<
index
]
&
CyREC_FIFO
;
put_fs_long
(
tmp
,
value
);
cy_put_user
(
tmp
,
value
);
}
else
{
// Nothing to do!
}
...
...
@@ -3354,7 +3454,7 @@ set_default_threshold(struct cyclades_port * info, unsigned long value)
static
int
get_default_threshold
(
struct
cyclades_port
*
info
,
unsigned
long
*
value
)
{
put_fs_long
(
info
->
default_threshold
,
value
);
cy_put_user
(
info
->
default_threshold
,
value
);
return
0
;
}
/* get_default_threshold */
...
...
@@ -3401,7 +3501,7 @@ get_timeout(struct cyclades_port * info, unsigned long *value)
+
(
cy_chip_offset
[
chip
]
<<
index
));
tmp
=
base_addr
[
CyRTPR
<<
index
];
put_fs_long
(
tmp
,
value
);
cy_put_user
(
tmp
,
value
);
}
else
{
// Nothing to do!
}
...
...
@@ -3420,7 +3520,7 @@ set_default_timeout(struct cyclades_port * info, unsigned long value)
static
int
get_default_timeout
(
struct
cyclades_port
*
info
,
unsigned
long
*
value
)
{
put_fs_long
(
info
->
default_timeout
,
value
);
cy_put_user
(
info
->
default_timeout
,
value
);
return
0
;
}
/* get_default_timeout */
...
...
@@ -3530,7 +3630,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
ret_val
=
error
;
break
;
}
put_fs_long
(
C_CLOCAL
(
tty
)
?
1
:
0
,
cy_put_user
(
C_CLOCAL
(
tty
)
?
1
:
0
,
(
unsigned
long
*
)
arg
);
break
;
case
TIOCSSOFTCAR
:
...
...
@@ -3541,7 +3641,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
break
;
}
arg
=
get_fs_long
((
unsigned
long
*
)
arg
);
arg
=
cy_get_user
((
unsigned
long
*
)
arg
);
tty
->
termios
->
c_cflag
=
((
tty
->
termios
->
c_cflag
&
~
CLOCAL
)
|
(
arg
?
CLOCAL
:
0
));
...
...
@@ -3967,8 +4067,8 @@ cy_detect_isa(void))
}
/* probe for CD1400... */
#if
LINUX_VERSION_CODE >= 131328
cy_isa_address
=
v
remap
((
unsigned
int
)
cy_isa_address
,
0x2000
);
#if
(LINUX_VERSION_CODE >= 0x020100)
cy_isa_address
=
io
remap
((
unsigned
int
)
cy_isa_address
,
0x2000
);
#endif
cy_isa_nchan
=
4
*
cyy_init_card
(
cy_isa_address
,
0
);
if
(
cy_isa_nchan
==
0
)
{
...
...
@@ -3988,6 +4088,7 @@ cy_detect_isa(void))
printk
(
"Cyclom-Y/ISA found at 0x%x "
,
(
unsigned
int
)
cy_isa_address
);
printk
(
"but no more channels are available.
\n
"
);
printk
(
"Change NR_PORTS in cyclades.c and recompile kernel.
\n
"
);
return
(
nboard
);
}
/* fill the next cy_card structure available */
...
...
@@ -3998,6 +4099,7 @@ cy_detect_isa(void))
printk
(
"Cyclom-Y/ISA found at 0x%x "
,
(
unsigned
int
)
cy_isa_address
);
printk
(
"but no more cards can be used .
\n
"
);
printk
(
"Change NR_CARDS in cyclades.c and recompile kernel.
\n
"
);
return
(
nboard
);
}
...
...
@@ -4051,6 +4153,8 @@ cy_detect_pci(void))
unsigned
int
cy_pci_addr0
,
cy_pci_addr1
,
cy_pci_addr2
;
unsigned
short
i
,
j
,
cy_pci_nchan
;
unsigned
short
device_id
,
dev_index
=
0
,
board_index
=
0
;
unsigned
long
mailbox
;
unsigned
int
Ze_addr0
[
NR_CARDS
],
Ze_addr2
[
NR_CARDS
],
ZeIndex
=
0
;
if
(
pcibios_present
()
==
0
)
{
/* PCI bus not present */
return
(
0
);
...
...
@@ -4070,6 +4174,9 @@ cy_detect_pci(void))
}
}
if
(
device_id
==
0
)
break
;
/* read PCI configuration area */
pcibios_read_config_byte
(
cyy_bus
,
cyy_dev_fn
,
PCI_INTERRUPT_LINE
,
&
cy_pci_irq
);
...
...
@@ -4081,9 +4188,7 @@ cy_detect_pci(void))
PCI_BASE_ADDRESS_2
,
&
cy_pci_addr2
);
pcibios_read_config_byte
(
cyy_bus
,
cyy_dev_fn
,
PCI_REVISION_ID
,
&
cyy_rev_id
);
if
(
device_id
==
0
){
break
;
}
else
if
((
device_id
==
PCI_DEVICE_ID_CYCLOM_Y_Lo
)
if
((
device_id
==
PCI_DEVICE_ID_CYCLOM_Y_Lo
)
||
(
device_id
==
PCI_DEVICE_ID_CYCLOM_Y_Hi
)){
#ifdef CY_PCI_DEBUG
printk
(
"Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, "
,
...
...
@@ -4096,11 +4201,11 @@ cy_detect_pci(void))
cy_pci_addr1
&=
0xfffffffc
;
cy_pci_addr2
&=
0xfffffff0
;
#if
LINUX_VERSION_CODE < 131328
#if
(LINUX_VERSION_CODE < 0x020100)
if
((
ulong
)
cy_pci_addr2
>=
0x100000
)
/* above 1M? */
#endif
cy_pci_addr2
=
(
unsigned
int
)
v
remap
(
cy_pci_addr2
,
CyPCI_Ywin
);
(
unsigned
int
)
io
remap
(
cy_pci_addr2
,
CyPCI_Ywin
);
#ifdef CY_PCI_DEBUG
printk
(
"Cyclom-Y/PCI: relocate winaddr=0x%x ioaddr=0x%x
\n
"
,
...
...
@@ -4112,12 +4217,14 @@ cy_detect_pci(void))
printk
(
"Cyclom-Y PCI host card with "
);
printk
(
"no Serial-Modules at 0x%x.
\n
"
,
(
unsigned
int
)
cy_pci_addr2
);
i
--
;
continue
;
}
if
((
cy_next_channel
+
cy_pci_nchan
)
>
NR_PORTS
)
{
printk
(
"Cyclom-Y/PCI found at 0x%x "
,
(
unsigned
int
)
cy_pci_addr2
);
printk
(
"but no channels are available.
\n
"
);
printk
(
"Change NR_PORTS in cyclades.c and recompile kernel.
\n
"
);
return
(
i
);
}
/* fill the next cy_card structure available */
...
...
@@ -4128,6 +4235,7 @@ cy_detect_pci(void))
printk
(
"Cyclom-Y/PCI found at 0x%x "
,
(
unsigned
int
)
cy_pci_addr2
);
printk
(
"but no more cards can be used.
\n
"
);
printk
(
"Change NR_CARDS in cyclades.c and recompile kernel.
\n
"
);
return
(
i
);
}
...
...
@@ -4167,65 +4275,101 @@ cy_detect_pci(void))
cy_next_channel
+=
cy_pci_nchan
;
}
else
if
(
device_id
==
PCI_DEVICE_ID_CYCLOM_Z_Lo
){
/* print message */
printk
(
"Cycl
om
-Z/PCI (bus=0x0%x, pci_id=0x%x, "
,
printk
(
"Cycl
ades
-Z/PCI (bus=0x0%x, pci_id=0x%x, "
,
cyy_bus
,
cyy_dev_fn
);
printk
(
"rev_id=%d) IRQ%d
\n
"
,
cyy_rev_id
,
(
int
)
cy_pci_irq
);
printk
(
"Cycl
om
-Z/PCI: found winaddr=0x%x ctladdr=0x%x
\n
"
,
printk
(
"Cycl
ades
-Z/PCI: found winaddr=0x%x ctladdr=0x%x
\n
"
,
cy_pci_addr2
,
cy_pci_addr0
);
printk
(
"Cycl
om
-Z/PCI not supported for low addresses
\n
"
);
printk
(
"Cycl
ades
-Z/PCI not supported for low addresses
\n
"
);
break
;
}
else
if
(
device_id
==
PCI_DEVICE_ID_CYCLOM_Z_Hi
){
#ifdef CY_PCI_DEBUG
printk
(
"Cycl
om
-Z/PCI (bus=0x0%x, pci_id=0x%x, "
,
printk
(
"Cycl
ades
-Z/PCI (bus=0x0%x, pci_id=0x%x, "
,
cyy_bus
,
cyy_dev_fn
);
printk
(
"rev_id=%d) IRQ%d
\n
"
,
cyy_rev_id
,
(
int
)
cy_pci_irq
);
printk
(
"Cycl
om
-Z/PCI: found winaddr=0x%x ctladdr=0x%x
\n
"
,
printk
(
"Cycl
ades
-Z/PCI: found winaddr=0x%x ctladdr=0x%x
\n
"
,
cy_pci_addr2
,
cy_pci_addr0
);
#endif
cy_pci_addr2
&=
0xfffffff0
;
cy_pci_addr2
=
(
unsigned
int
)
vremap
(
cy_pci_addr2
&
PAGE_MASK
,
PAGE_ALIGN
(
CyPCI_Zwin
))
+
(
cy_pci_addr2
&
(
PAGE_SIZE
-
1
));
cy_pci_addr0
&=
0xfffffff0
;
cy_pci_addr0
=
(
unsigned
int
)
v
remap
(
cy_pci_addr0
=
(
unsigned
int
)
io
remap
(
cy_pci_addr0
&
PAGE_MASK
,
PAGE_ALIGN
(
CyPCI_Zctl
))
+
(
cy_pci_addr0
&
(
PAGE_SIZE
-
1
));
mailbox
=
((
struct
RUNTIME_9060
*
)
cy_pci_addr0
)
->
mail_box_0
;
cy_pci_addr2
&=
0xfffffff0
;
if
(
mailbox
==
ZE_V1
)
{
cy_pci_addr2
=
(
unsigned
int
)
ioremap
(
cy_pci_addr2
&
PAGE_MASK
,
PAGE_ALIGN
(
CyPCI_Ze_win
))
+
(
cy_pci_addr2
&
(
PAGE_SIZE
-
1
));
if
(
ZeIndex
==
NR_CARDS
)
{
printk
(
"Cyclades-Z/PCI found at 0x%x "
,
(
unsigned
int
)
cy_pci_addr2
);
printk
(
"but no more cards can be used.
\n
"
);
printk
(
"Change NR_CARDS in cyclades.c and recompile kernel.
\n
"
);
}
else
{
Ze_addr0
[
ZeIndex
]
=
cy_pci_addr0
;
Ze_addr2
[
ZeIndex
]
=
cy_pci_addr2
;
ZeIndex
++
;
}
i
--
;
continue
;
}
else
{
cy_pci_addr2
=
(
unsigned
int
)
ioremap
(
cy_pci_addr2
&
PAGE_MASK
,
PAGE_ALIGN
(
CyPCI_Zwin
))
+
(
cy_pci_addr2
&
(
PAGE_SIZE
-
1
));
}
#ifdef CY_PCI_DEBUG
printk
(
"Cycl
om
-Z/PCI: relocate winaddr=0x%x ctladdr=0x%x
\n
"
,
printk
(
"Cycl
ades
-Z/PCI: relocate winaddr=0x%x ctladdr=0x%x
\n
"
,
cy_pci_addr2
,
cy_pci_addr0
);
((
struct
RUNTIME_9060
*
)(
cy_pci_addr0
))
if
(
mailbox
==
ZO_V1
)
{
((
struct
RUNTIME_9060
*
)(
cy_pci_addr0
))
->
loc_addr_base
=
WIN_CREG
;
PAUSE
printk
(
"Cyclom-Z/PCI: FPGA id %lx, ver %lx
\n
"
,
0xff
&
((
struct
CUSTOM_REG
*
)(
cy_pci_addr2
))
->
fpga_id
,
0xff
&
((
struct
CUSTOM_REG
*
)(
cy_pci_addr2
))
->
fpga_version
);
((
struct
RUNTIME_9060
*
)(
cy_pci_addr0
))
->
loc_addr_base
=
WIN_RAM
;
PAUSE
printk
(
"Cyclades-Z/PCI: FPGA id %lx, ver %lx
\n
"
,
0xff
&
((
struct
CUSTOM_REG
*
)(
cy_pci_addr2
))
->
fpga_id
,
0xff
&
((
struct
CUSTOM_REG
*
)(
cy_pci_addr2
))
->
fpga_version
);
((
struct
RUNTIME_9060
*
)(
cy_pci_addr0
))
->
loc_addr_base
=
WIN_RAM
;
}
else
{
printk
(
"Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded
\n
"
);
}
#endif
/* The following clears the firmware id word. This ensures
that the driver will not attempt to talk to the board
until it has been properly initialized.
*/
PAUSE
*
(
unsigned
long
*
)(
cy_pci_addr2
+
ID_ADDRESS
)
=
0L
;
if
(
mailbox
==
ZO_V1
)
*
(
unsigned
long
*
)(
cy_pci_addr2
+
ID_ADDRESS
)
=
0L
;
/* This must be a Cycl
om
-8Zo/PCI. The extendable
/* This must be a Cycl
ades
-8Zo/PCI. The extendable
version will have a different device_id and will
be allocated its maximum number of ports. */
cy_pci_nchan
=
8
;
if
((
cy_next_channel
+
cy_pci_nchan
)
>
NR_PORTS
)
{
printk
(
"Cyclades-Z/PCI found at 0x%x "
,
(
unsigned
int
)
cy_pci_addr2
);
printk
(
"but no channels are available.
\n
"
);
printk
(
"Change NR_PORTS in cyclades.c and recompile kernel.
\n
"
);
return
(
i
);
}
/* fill the next cy_card structure available */
for
(
j
=
0
;
j
<
NR_CARDS
;
j
++
)
{
if
(
cy_card
[
j
].
base_addr
==
0
)
break
;
}
if
(
j
==
NR_CARDS
)
{
/* no more cy_cards available */
printk
(
"Cycl
om
-Z/PCI found at 0x%x "
,
printk
(
"Cycl
ades
-Z/PCI found at 0x%x "
,
(
unsigned
int
)
cy_pci_addr2
);
printk
(
"but no more cards can be used.
\n
"
);
printk
(
"Change NR_CARDS in cyclades.c and recompile kernel.
\n
"
);
return
(
i
);
}
...
...
@@ -4235,9 +4379,9 @@ cy_detect_pci(void))
SA_INTERRUPT
,
"cyclomZ"
,
NULL
))
{
printk
(
"Could not allocate IRQ%d "
,
(
unsigned
int
)
cy_pci_addr2
);
printk
(
"for Cyclom-Z/PCI at 0x%x.
\n
"
,
cy_pci_irq
);
printk
(
"for Cyclades-Z/PCI at 0x%x.
\n
"
,
(
unsigned
int
)
cy_pci_addr2
);
return
(
i
);
}
}
...
...
@@ -4254,12 +4398,12 @@ cy_detect_pci(void))
/* print message */
/* don't report IRQ if board is no IRQ */
if
(
(
cy_pci_irq
<
15
)
&&
(
cy_pci_irq
>
1
)
)
{
printk
(
"Cycl
om
-Z/PCI #%d: 0x%x-0x%x, IRQ%d, "
,
printk
(
"Cycl
ades
-Z/PCI #%d: 0x%x-0x%x, IRQ%d, "
,
j
+
1
,
cy_pci_addr2
,
(
cy_pci_addr2
+
CyPCI_Zwin
-
1
),
(
int
)
cy_pci_irq
);
}
else
{
printk
(
"Cycl
om
-Z/PCI #%d: 0x%x-0x%x, "
,
printk
(
"Cycl
ades
-Z/PCI #%d: 0x%x-0x%x, "
,
j
+
1
,
cy_pci_addr2
,
(
cy_pci_addr2
+
CyPCI_Zwin
-
1
));
}
...
...
@@ -4268,6 +4412,93 @@ cy_detect_pci(void))
cy_next_channel
+=
cy_pci_nchan
;
}
}
for
(;
ZeIndex
!=
0
&&
i
<
NR_CARDS
;
i
++
)
{
cy_pci_addr0
=
Ze_addr0
[
0
];
cy_pci_addr2
=
Ze_addr2
[
0
];
for
(
j
=
0
;
j
<
ZeIndex
-
1
;
j
++
)
{
Ze_addr0
[
j
]
=
Ze_addr0
[
j
+
1
];
Ze_addr2
[
j
]
=
Ze_addr2
[
j
+
1
];
}
ZeIndex
--
;
mailbox
=
((
struct
RUNTIME_9060
*
)
cy_pci_addr0
)
->
mail_box_0
;
#ifdef CY_PCI_DEBUG
printk
(
"Cyclades-Z/PCI: relocate winaddr=0x%x ctladdr=0x%x
\n
"
,
cy_pci_addr2
,
cy_pci_addr0
);
printk
(
"Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded
\n
"
);
#endif
/* The following clears the firmware id word. This ensures
that the driver will not attempt to talk to the board
until it has been properly initialized.
*/
PAUSE
/* This must be the new Cyclades-Ze/PCI. */
cy_pci_nchan
=
ZE_V1_NPORTS
;
if
((
cy_next_channel
+
cy_pci_nchan
)
>
NR_PORTS
)
{
printk
(
"Cyclades-Z/PCI found at 0x%x "
,
(
unsigned
int
)
cy_pci_addr2
);
printk
(
"but no channels are available.
\n
"
);
printk
(
"Change NR_PORTS in cyclades.c and recompile kernel.
\n
"
);
return
(
i
);
}
/* fill the next cy_card structure available */
for
(
j
=
0
;
j
<
NR_CARDS
;
j
++
)
{
if
(
cy_card
[
j
].
base_addr
==
0
)
break
;
}
if
(
j
==
NR_CARDS
)
{
/* no more cy_cards available */
printk
(
"Cyclades-Z/PCI found at 0x%x "
,
(
unsigned
int
)
cy_pci_addr2
);
printk
(
"but no more cards can be used.
\n
"
);
printk
(
"Change NR_CARDS in cyclades.c and recompile kernel.
\n
"
);
return
(
i
);
}
/* allocate IRQ only if board has an IRQ */
if
(
(
1
<
cy_pci_irq
)
&&
(
cy_pci_irq
<
15
)
)
{
if
(
request_irq
(
cy_pci_irq
,
cyz_interrupt
,
SA_INTERRUPT
,
"cyclomZ"
,
NULL
))
{
printk
(
"Could not allocate IRQ%d "
,
cy_pci_irq
);
printk
(
"for Cyclades-Z/PCI at 0x%x.
\n
"
,
(
unsigned
int
)
cy_pci_addr2
);
return
(
i
);
}
}
/* set cy_card */
cy_card
[
j
].
base_addr
=
cy_pci_addr2
;
cy_card
[
j
].
ctl_addr
=
cy_pci_addr0
;
cy_card
[
j
].
irq
=
(
int
)
cy_pci_irq
;
cy_card
[
j
].
bus_index
=
1
;
cy_card
[
j
].
first_line
=
cy_next_channel
;
cy_card
[
j
].
num_chips
=
1
;
IRQ_cards
[
cy_pci_irq
]
=
&
cy_card
[
j
];
/* print message */
/* don't report IRQ if board is no IRQ */
if
(
(
cy_pci_irq
<
15
)
&&
(
cy_pci_irq
>
1
)
)
{
printk
(
"Cyclades-Z/PCI #%d: 0x%x-0x%x, IRQ%d, "
,
j
+
1
,
cy_pci_addr2
,
(
cy_pci_addr2
+
CyPCI_Ze_win
-
1
),
(
int
)
cy_pci_irq
);
}
else
{
printk
(
"Cyclades-Z/PCI #%d: 0x%x-0x%x, "
,
j
+
1
,
cy_pci_addr2
,
(
cy_pci_addr2
+
CyPCI_Ze_win
-
1
));
}
printk
(
"%d channels starting from port %d.
\n
"
,
cy_pci_nchan
,
cy_next_channel
);
cy_next_channel
+=
cy_pci_nchan
;
}
if
(
ZeIndex
!=
0
)
{
printk
(
"Cyclades-Z/PCI found at 0x%x "
,
(
unsigned
int
)
Ze_addr2
[
0
]);
printk
(
"but no more cards can be used.
\n
"
);
printk
(
"Change NR_CARDS in cyclades.c and recompile kernel.
\n
"
);
}
return
(
i
);
#else
return
(
0
);
...
...
@@ -4319,6 +4550,8 @@ cy_init(void))
struct
cyclades_card
*
cinfo
;
int
number_z_boards
=
0
;
int
board
,
port
,
i
;
unsigned
long
mailbox
;
int
nports
;
show_version
();
...
...
@@ -4416,10 +4649,13 @@ cy_init(void))
/* initialize per-port data structures for each valid board found */
for
(
board
=
0
;
board
<
cy_nboard
;
board
++
)
{
cinfo
=
&
cy_card
[
board
];
if
(
cinfo
->
num_chips
==
1
){
/* Cycl
om
-8Zo/PCI */
if
(
cinfo
->
num_chips
==
1
){
/* Cycl
ades
-8Zo/PCI */
number_z_boards
++
;
mailbox
=
((
struct
RUNTIME_9060
*
)
cy_card
[
board
].
ctl_addr
)
->
mail_box_0
;
nports
=
(
mailbox
==
ZE_V1
)
?
ZE_V1_NPORTS
:
8
;
for
(
port
=
cinfo
->
first_line
;
port
<
cinfo
->
first_line
+
8
;
port
<
cinfo
->
first_line
+
nports
;
port
++
)
{
info
=
&
cy_port
[
port
];
...
...
@@ -4523,7 +4759,7 @@ cy_init(void))
cyz_timerlist
.
expires
=
jiffies
+
1
;
add_timer
(
&
cyz_timerlist
);
#ifdef CY_PCI_DEBUG
printk
(
"Cycl
om
-Z polling initialized
\n
"
);
printk
(
"Cycl
ades
-Z polling initialized
\n
"
);
#endif
}
...
...
drivers/char/psaux.c
View file @
2730f0af
...
...
@@ -168,6 +168,11 @@ static void aux_write_dev(int val)
outb_p
(
val
,
KBD_DATA_REG
);
/* Write data */
}
/*
* Write to device & handle returned ack
*/
#ifdef INITIALIZE_DEVICE
__initfunc
(
static
void
aux_write_dev_nosleep
(
int
val
))
{
poll_aux_status_nosleep
();
...
...
@@ -176,11 +181,6 @@ __initfunc(static void aux_write_dev_nosleep(int val))
outb_p
(
val
,
KBD_DATA_REG
);
}
/*
* Write to device & handle returned ack
*/
#ifdef INITIALIZE_DEVICE
__initfunc
(
static
int
aux_write_ack
(
int
val
))
{
aux_write_dev_nosleep
(
val
);
...
...
drivers/scsi/BusLogic.h
View file @
2730f0af
...
...
@@ -29,6 +29,7 @@
#include <linux/config.h>
/*
Define types for some of the structures that interface with the rest
of the Linux Kernel and SCSI Subsystem.
...
...
drivers/scsi/tmscsim.c
View file @
2730f0af
...
...
@@ -50,13 +50,8 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/config.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE < 66354
/* 1.3.50 */
#include "../block/blk.h"
#else
#include <linux/init.h>
#include <linux/blk.h>
#endif
#include "scsi.h"
#include "hosts.h"
...
...
@@ -69,13 +64,10 @@
#define PCI_DEVICE_ID_AMD53C974 PCI_DEVICE_ID_AMD_SCSI
#ifndef VERSION_ELF_1_2_13
struct
proc_dir_entry
proc_scsi_tmscsim
=
{
PROC_SCSI_DC390T
,
7
,
"tmscsim"
,
S_IFDIR
|
S_IRUGO
|
S_IXUGO
,
2
};
#endif
static
USHORT
DC390_StartSCSI
(
PACB
pACB
,
PDCB
pDCB
,
PSRB
pSRB
);
static
void
DC390_DataOut_0
(
PACB
pACB
,
PSRB
pSRB
,
PUCHAR
psstatus
);
...
...
@@ -675,11 +667,7 @@ DoNextCmd( PACB pACB, PDCB pDCB )
* Description:
* Return the disk geometry for the given SCSI device.
***********************************************************************/
#ifdef VERSION_ELF_1_2_13
int
DC390_bios_param
(
Disk
*
disk
,
int
devno
,
int
geom
[])
#else
int
DC390_bios_param
(
Disk
*
disk
,
kdev_t
devno
,
int
geom
[])
#endif
{
int
heads
,
sectors
,
cylinders
;
PACB
pACB
;
...
...
@@ -1046,14 +1034,10 @@ void DC390_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd )
***********************************************************************/
void
DC390_initSRB
(
PSRB
psrb
)
{
#ifndef VERSION_ELF_1_2_13
#ifdef DC390_DEBUG0
printk
(
"DC390 init: %08lx %08lx,"
,(
ULONG
)
psrb
,(
ULONG
)
virt_to_bus
(
psrb
));
#endif
psrb
->
PhysSRB
=
virt_to_bus
(
psrb
);
#else
psrb
->
PhysSRB
=
(
ULONG
)
psrb
;
#endif
}
...
...
@@ -1084,7 +1068,7 @@ void DC390_linkSRB( PACB pACB )
* Inputs : psh - pointer to this host adapter's structure
*
***********************************************************************/
void
DC390_initACB
(
PSH
psh
,
ULONG
io_port
,
UCHAR
Irq
,
USHORT
index
)
__initfunc
(
void
DC390_initACB
(
PSH
psh
,
ULONG
io_port
,
UCHAR
Irq
,
USHORT
index
)
)
{
PACB
pACB
;
USHORT
i
;
...
...
@@ -1098,7 +1082,6 @@ void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
pACB
=
(
PACB
)
psh
->
hostdata
;
#ifndef VERSION_ELF_1_2_13
psh
->
max_id
=
8
;
#ifdef CONFIG_SCSI_MULTI_LUN
if
(
eepromBuf
[
index
][
EE_MODE2
]
&
LUN_CHECK
)
...
...
@@ -1106,7 +1089,6 @@ void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
else
#endif
psh
->
max_lun
=
1
;
#endif
pACB
->
max_id
=
7
;
if
(
pACB
->
max_id
==
eepromBuf
[
index
][
EE_ADAPT_SCSI_ID
]
)
...
...
@@ -1155,7 +1137,7 @@ void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
* Inputs : psh - pointer to this host adapter's structure
*
***********************************************************************/
int
DC390_initAdapter
(
PSH
psh
,
ULONG
io_port
,
UCHAR
Irq
,
USHORT
index
)
__initfunc
(
int
DC390_initAdapter
(
PSH
psh
,
ULONG
io_port
,
UCHAR
Irq
,
USHORT
index
)
)
{
USHORT
ioport
;
UCHAR
bval
;
...
...
@@ -1179,11 +1161,7 @@ int DC390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
if
(
!
used_irq
)
{
#ifdef VERSION_ELF_1_2_13
if
(
request_irq
(
Irq
,
DC390_Interrupt
,
SA_INTERRUPT
,
"tmscsim"
))
#else
if
(
request_irq
(
Irq
,
DC390_Interrupt
,
SA_INTERRUPT
,
"tmscsim"
,
NULL
))
#endif
{
printk
(
"DC390: register IRQ error!
\n
"
);
return
(
-
1
);
...
...
@@ -1533,8 +1511,8 @@ DC390_ToMech( USHORT Mechnum, USHORT BusDevFunNum )
* field of the pACB structure MUST have been set.
***********************************************************************/
static
int
DC390_init
(
PSHT
psht
,
ULONG
io_port
,
UCHAR
Irq
,
USHORT
index
,
USHORT
MechNum
)
__initfunc
(
static
int
DC390_init
(
PSHT
psht
,
ULONG
io_port
,
UCHAR
Irq
,
USHORT
index
,
USHORT
MechNum
)
)
{
PSH
psh
;
PACB
pACB
;
...
...
@@ -1614,8 +1592,8 @@ DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, USHORT index, USHORT MechNum)
*
***********************************************************************/
int
DC390_detect
(
Scsi_Host_Template
*
psht
)
__initfunc
(
int
DC390_detect
(
Scsi_Host_Template
*
psht
)
)
{
#ifdef FOR_PCI_OK
UCHAR
pci_bus
,
pci_device_fn
;
...
...
@@ -1626,19 +1604,13 @@ DC390_detect(Scsi_Host_Template *psht)
UCHAR
irq
;
UCHAR
istatus
;
#ifndef VERSION_ELF_1_2_13
UINT
io_port
;
#else
ULONG
io_port
;
#endif
USHORT
adaptCnt
=
0
;
/* Number of boards detected */
USHORT
pci_index
=
0
;
/* Device index to PCI BIOS calls */
USHORT
MechNum
,
BusDevFunNum
;
ULONG
wlval
;
#ifndef VERSION_ELF_1_2_13
psht
->
proc_dir
=
&
proc_scsi_tmscsim
;
#endif
InitialTime
=
1
;
pSHT_start
=
psht
;
...
...
@@ -1726,8 +1698,6 @@ DC390_detect(Scsi_Host_Template *psht)
}
#ifndef VERSION_ELF_1_2_13
/********************************************************************
* Function: tmscsim_set_info()
*
...
...
@@ -1848,7 +1818,6 @@ int tmscsim_proc_info(char *buffer, char **start,
else
return
length
;
}
#endif
/* VERSION_ELF_1_2_13 */
#ifdef MODULE
...
...
@@ -1909,11 +1878,7 @@ int DC390_release(struct Scsi_Host *host)
#ifdef DC390_DEBUG0
printk
(
"DC390: Free IRQ %i."
,
host
->
irq
);
#endif
#ifndef VERSION_ELF_1_2_13
free_irq
(
host
->
irq
,
NULL
);
#else
free_irq
(
host
->
irq
);
#endif
}
}
...
...
fs/Config.in
View file @
2730f0af
...
...
@@ -5,26 +5,6 @@ mainmenu_option next_comment
comment 'Filesystems'
bool 'Quota support' CONFIG_QUOTA
bool 'Preload dcache entries in readdir() [ALPHA, currently dangerous!]' CONFIG_DCACHE_PRELOAD
bool 'Include support for omirr online mirror' CONFIG_OMIRR
bool 'Translate filename suffixes' CONFIG_TRANS_NAMES
if [ "$CONFIG_TRANS_NAMES" = "y" ]; then
bool ' Restrict translation to specific gid' CONFIG_TRANS_RESTRICT
if [ "$CONFIG_TRANS_RESTRICT" = "y" ]; then
int ' Enter gid to compile in' CONFIG_TRANS_GID 4
fi
bool ' Translate nodename' CONFIG_TR_NODENAME
bool ' Translate compiled-in kernelname' CONFIG_TR_KERNNAME
if [ "$CONFIG_TR_KERNNAME" = "y" ]; then
string ' Enter kernelname string to compile in' CONFIG_KERNNAME banana
fi
bool ' Translate compiled-in kerneltype' CONFIG_TR_KERNTYPE
if [ "$CONFIG_TR_KERNTYPE" = "y" ]; then
string ' Enter kerneltype string to compile in' CONFIG_KERNTYPE default
fi
bool ' Translate machine type' CONFIG_TR_MACHINE
bool ' Translate sysname' CONFIG_TR_SYSNAME
fi
tristate 'Minix fs support' CONFIG_MINIX_FS
tristate 'Second extended fs support' CONFIG_EXT2_FS
...
...
fs/autofs/root.c
View file @
2730f0af
...
...
@@ -136,7 +136,7 @@ static int autofs_root_lookup(struct inode *dir, struct qstr *str, struct inode
return
-
EACCES
;
}
if
(
!
oz_mode
&&
S_ISDIR
(
res
->
i_mode
)
&&
res
->
i_dentry
->
d_covers
==
res
->
i_dentry
)
{
if
(
!
oz_mode
&&
S_ISDIR
(
res
->
i_mode
)
&&
i_dentry
(
res
)
->
d_covers
==
i_dentry
(
res
)
)
{
/* Not a mount point yet, call 1-800-DAEMON */
DPRINTK
((
"autofs: waiting on non-mountpoint dir, inode = %lu, pid = %u, pgrp = %u
\n
"
,
res
->
i_ino
,
current
->
pid
,
current
->
pgrp
));
iput
(
res
);
...
...
@@ -208,7 +208,7 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c
memcpy
(
ent
->
name
,
dentry
->
d_name
.
name
,
ent
->
len
=
dentry
->
d_name
.
len
);
autofs_hash_insert
(
dh
,
ent
);
d_instantiate
(
dentry
,
iget
(
dir
->
i_sb
,
ent
->
ino
)
,
0
);
d_instantiate
(
dentry
,
iget
(
dir
->
i_sb
,
ent
->
ino
));
return
0
;
}
...
...
@@ -295,7 +295,7 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
ent
->
ino
=
sbi
->
next_dir_ino
++
;
autofs_hash_insert
(
dh
,
ent
);
dir
->
i_nlink
++
;
d_instantiate
(
dentry
,
iget
(
dir
->
i_sb
,
ent
->
ino
)
,
D_DIR
);
d_instantiate
(
dentry
,
iget
(
dir
->
i_sb
,
ent
->
ino
));
return
0
;
}
...
...
fs/binfmt_aout.c
View file @
2730f0af
...
...
@@ -114,7 +114,7 @@ do_aout_core_dump(long signr, struct pt_regs * regs)
#else
corefile
[
4
]
=
'\0'
;
#endif
if
(
open_namei
(
corefile
,
O_CREAT
|
2
|
O_TRUNC
,
0600
,
&
inode
,
NULL
))
{
if
(
open_namei
(
corefile
,
O_CREAT
|
2
|
O_TRUNC
,
0600
,
&
inode
))
{
inode
=
NULL
;
goto
end_coredump
;
}
...
...
fs/binfmt_elf.c
View file @
2730f0af
...
...
@@ -501,8 +501,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if
(
retval
>=
0
)
{
old_fs
=
get_fs
();
/* This could probably be optimized */
set_fs
(
get_ds
());
retval
=
open_namei
(
elf_interpreter
,
0
,
0
,
&
interpreter_inode
,
NULL
);
retval
=
open_namei
(
elf_interpreter
,
0
,
0
,
&
interpreter_inode
);
set_fs
(
old_fs
);
}
...
...
@@ -1078,7 +1077,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
#else
corefile
[
4
]
=
'\0'
;
#endif
if
(
open_namei
(
corefile
,
O_CREAT
|
2
|
O_TRUNC
,
0600
,
&
inode
,
NULL
))
{
if
(
open_namei
(
corefile
,
O_CREAT
|
2
|
O_TRUNC
,
0600
,
&
inode
))
{
inode
=
NULL
;
goto
end_coredump
;
}
...
...
fs/binfmt_em86.c
View file @
2730f0af
...
...
@@ -79,7 +79,7 @@ static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
* Note that we use open_namei() as the name is now in kernel
* space, and we don't need to copy it.
*/
retval
=
open_namei
(
interp
,
0
,
0
,
&
bprm
->
inode
,
NULL
);
retval
=
open_namei
(
interp
,
0
,
0
,
&
bprm
->
inode
);
if
(
retval
)
return
retval
;
bprm
->
dont_iput
=
0
;
...
...
fs/binfmt_java.c
View file @
2730f0af
...
...
@@ -78,7 +78,7 @@ static int do_load_java(struct linux_binprm *bprm,struct pt_regs *regs)
* OK, now restart the process with the interpreter's inode.
*/
bprm
->
filename
=
binfmt_java_interpreter
;
retval
=
open_namei
(
binfmt_java_interpreter
,
0
,
0
,
&
bprm
->
inode
,
NULL
);
retval
=
open_namei
(
binfmt_java_interpreter
,
0
,
0
,
&
bprm
->
inode
);
if
(
retval
)
return
retval
;
bprm
->
dont_iput
=
0
;
...
...
@@ -121,7 +121,7 @@ static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
* OK, now restart the process with the interpreter's inode.
*/
bprm
->
filename
=
binfmt_java_appletviewer
;
retval
=
open_namei
(
binfmt_java_appletviewer
,
0
,
0
,
&
bprm
->
inode
,
NULL
);
retval
=
open_namei
(
binfmt_java_appletviewer
,
0
,
0
,
&
bprm
->
inode
);
if
(
retval
)
return
retval
;
bprm
->
dont_iput
=
0
;
...
...
fs/binfmt_script.c
View file @
2730f0af
...
...
@@ -77,7 +77,7 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
/*
* OK, now restart the process with the interpreter's inode.
*/
retval
=
open_namei
(
interp
,
0
,
0
,
&
bprm
->
inode
,
NULL
);
retval
=
open_namei
(
interp
,
0
,
0
,
&
bprm
->
inode
);
if
(
retval
)
return
retval
;
bprm
->
dont_iput
=
0
;
...
...
fs/dcache.c
View file @
2730f0af
...
...
@@ -16,25 +16,8 @@
#include <linux/string.h>
#include <linux/mm.h>
#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*/
/*#undef DEBUG*/
/*#define DEBUG_DDIR_COUNT*/
void
printpath
(
struct
dentry
*
entry
);
DEF_INSERT
(
alias
,
struct
dentry
,
d_next
,
d_prev
)
DEF_REMOVE
(
alias
,
struct
dentry
,
d_next
,
d_prev
)
DEF_INSERT
(
hash
,
struct
dentry
,
d_hash_next
,
d_hash_prev
)
DEF_REMOVE
(
hash
,
struct
dentry
,
d_hash_next
,
d_hash_prev
)
struct
dentry
*
the_root
=
NULL
;
/*
* This is the single most critical data structure when it comes
* to the dcache: the hashtable for lookups. Somebody should try
...
...
@@ -46,102 +29,59 @@ struct dentry * the_root = NULL;
#define D_HASHBITS 10
#define D_HASHSIZE (1UL << D_HASHBITS)
#define D_HASHMASK (D_HASHSIZE-1)
struct
dentry
*
dentry_hashtable
[
D_HASHSIZE
];
static
inline
unsigned
long
dentry_hash
(
struct
dentry
*
dir
,
int
name_hash
)
{
unsigned
long
hash
=
name_hash
+
(
unsigned
long
)
dir
;
hash
=
hash
^
(
hash
>>
D_HASHBITS
)
^
(
hash
>>
D_HASHBITS
*
2
);
return
hash
&
D_HASHMASK
;
}
unsigned
long
name_cache_init
(
unsigned
long
mem_start
,
unsigned
long
mem_end
)
{
return
mem_start
;
}
#ifdef DEBUG
/* throw this away after the beta phase */
/*************************************************************************/
extern
void
xcheck
(
char
*
txt
,
struct
inode
*
p
);
static
int
x_alloc
=
0
;
static
int
x_freed
=
0
;
static
int
x_free
=
0
;
struct
list_head
dentry_hashtable
[
D_HASHSIZE
];
static
void
*
tst
[
20000
];
static
int
cnt
=
0
;
static
void
ins
(
void
*
ptr
)
{
extern
int
inodes_stat
;
tst
[
cnt
++
]
=
ptr
;
if
(
cnt
%
1000
==
0
)
printk
(
"------%d allocated: %d: %d %d %d
\n
"
,
inodes_stat
,
cnt
,
x_alloc
,
x_freed
,
x_free
);
if
(
cnt
>=
20000
)
panic
(
"stop"
);
}
#if 0
static inline int search(void* ptr)
{
int i;
for(i = cnt-1; i>=0; i--)
if (tst[i] == ptr)
return i;
return -1;
}
#define TST(n,x) if(search(x)<0) printk("%s bad ptr %p line %d\n", n, x, __LINE__)
#else
#define TST(n,x)
/*nothing*/
#endif
void
LOG
(
char
*
txt
,
struct
dentry
*
entry
)
void
d_free
(
struct
dentry
*
dentry
)
{
static
int
count
=
0
;
if
(
entry
)
{
TST
(
txt
,
entry
);
}
if
(
count
)
{
count
--
;
printk
(
"%s: entry=%p
\n
"
,
txt
,
entry
);
if
(
dentry
)
{
kfree
(
dentry
->
d_name
.
name
);
kfree
(
dentry
);
}
}
#ifdef DEBUG_DDIR_COUNT
void
recursive_test
(
struct
dentry
*
entry
)
{
}
#else
#define recursive_test(e)
/*nothing*/
#endif
#else
#define TST(n,x)
/*nothing*/
#define LOG(n,x)
/*nothing*/
#define xcheck(t,i)
/*nothing*/
#define recursive_test(e)
/*nothing*/
/*****************************************************************************/
#endif
void
printpath
(
struct
dentry
*
entry
)
{
if
(
!
IS_ROOT
(
entry
))
printpath
(
entry
->
d_parent
);
printk
(
"/%s"
,
entry
->
d_name
.
name
);
}
void
d_free
(
struct
dentry
*
dentry
)
void
dput
(
struct
dentry
*
dentry
)
{
repeat:
if
(
dentry
)
{
kfree
(
dentry
->
d_name
.
name
);
kfree
(
dentry
);
dentry
->
d_count
--
;
if
(
dentry
->
d_count
<
0
)
{
printk
(
"dentry->count = %d for %s
\n
"
,
dentry
->
d_count
,
dentry
->
d_name
.
name
);
return
;
}
/*
* This is broken right now: we should really put
* the dentry on a free list to be reclaimed later
* when we think we should throw it away.
*
* Instead we free it completely if the inode count
* indicates that we're the only ones holding onto
* the inode - if not we just fall back on the old
* (broken) behaviour of not reclaiming it at all.
*/
if
(
!
dentry
->
d_count
&&
(
!
dentry
->
d_inode
||
atomic_read
(
&
dentry
->
d_inode
->
i_count
)
==
1
))
{
struct
dentry
*
parent
=
dentry
->
d_parent
;
if
(
parent
!=
dentry
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
if
(
inode
)
{
list_del
(
&
dentry
->
d_list
);
iput
(
inode
);
dentry
->
d_inode
=
NULL
;
}
list_del
(
&
dentry
->
d_hash
);
d_free
(
dentry
);
dentry
=
parent
;
goto
repeat
;
}
}
}
}
#define NAME_ALLOC_LEN(len) ((len+16) & ~15)
struct
dentry
*
d_alloc
(
struct
dentry
*
parent
,
struct
qstr
*
name
,
int
isdir
)
struct
dentry
*
d_alloc
(
struct
dentry
*
parent
,
const
struct
qstr
*
name
)
{
char
*
str
;
struct
dentry
*
res
;
...
...
@@ -164,123 +104,89 @@ struct dentry * d_alloc(struct dentry * parent, struct qstr *name, int isdir)
res
->
d_parent
=
parent
;
res
->
d_mounts
=
res
;
res
->
d_covers
=
res
;
res
->
d_flag
=
isdir
?
D_DIR
:
0
;
res
->
d_flag
s
=
0
;
res
->
d_name
.
name
=
str
;
res
->
d_name
.
len
=
name
->
len
;
res
->
d_name
.
hash
=
name
->
hash
;
#ifdef DEBUG
x_alloc
++
;
#endif
return
res
;
}
extern
blocking
struct
dentry
*
d_alloc_root
(
struct
inode
*
root_inode
,
struct
dentry
*
old_root
)
/*
* Fill in inode information in the entry.
*
* This turns negative dentries into productive full members
* of society.
*
* NOTE! This assumes that the inode count has been incremented
* (or otherwise set) by the caller to indicate that it is now
* in use by the dcache..
*/
void
d_instantiate
(
struct
dentry
*
entry
,
struct
inode
*
inode
)
{
struct
dentry
*
res
;
struct
qstr
name
=
{
"/"
,
1
,
0
};
/* dummy qstr */
if
(
inode
)
list_add
(
&
entry
->
d_list
,
&
inode
->
i_dentry
);
if
(
!
root_inode
)
return
NULL
;
res
=
d_alloc
(
NULL
,
&
name
,
1
);
LOG
(
"d_alloc_root"
,
res
);
res
->
d_parent
=
res
;
d_instantiate
(
res
,
root_inode
,
D_DIR
);
return
res
;
entry
->
d_inode
=
inode
;
}
st
atic
inline
struct
dentry
**
d_base_qstr
(
struct
dentry
*
parent
,
struct
qstr
*
s
)
st
ruct
dentry
*
d_alloc_root
(
struct
inode
*
root_inode
,
struct
dentry
*
old_root
)
{
return
dentry_hashtable
+
dentry_hash
(
parent
,
s
->
hash
);
}
struct
dentry
*
res
=
NULL
;
static
inline
struct
dentry
**
d_base_entry
(
struct
dentry
*
pdir
,
struct
dentry
*
entry
)
{
return
d_base_qstr
(
pdir
,
&
entry
->
d_name
);
if
(
root_inode
)
{
res
=
d_alloc
(
NULL
,
&
(
const
struct
qstr
)
{
"/"
,
1
,
0
});
res
->
d_parent
=
res
;
d_instantiate
(
res
,
root_inode
);
}
return
res
;
}
static
/*inline*/
blocking
void
_d_remove_from_parent
(
struct
dentry
*
entry
,
struct
dentry
*
parent
)
static
inline
struct
list_head
*
d_hash
(
struct
dentry
*
parent
,
unsigned
long
hash
)
{
if
(
entry
->
d_flag
&
D_HASHED
)
{
struct
dentry
**
base
=
d_base_entry
(
parent
,
entry
);
remove_hash
(
base
,
entry
);
entry
->
d_flag
&=
~
D_HASHED
;
}
hash
+=
(
unsigned
long
)
parent
;
hash
=
hash
^
(
hash
>>
D_HASHBITS
)
^
(
hash
>>
D_HASHBITS
*
2
);
return
dentry_hashtable
+
(
hash
&
D_HASHMASK
);
}
static
inline
struct
dentry
*
__dlookup
(
struct
dentry
*
base
,
struct
dentry
*
parent
,
struct
qstr
*
name
)
static
inline
struct
dentry
*
__dlookup
(
struct
list_head
*
head
,
struct
dentry
*
parent
,
struct
qstr
*
name
)
{
if
(
base
)
{
struct
dentry
*
tmp
=
base
;
int
len
=
name
->
len
;
int
hash
=
name
->
hash
;
const
unsigned
char
*
str
=
name
->
name
;
do
{
if
(
tmp
->
d_name
.
hash
==
hash
&&
tmp
->
d_name
.
len
==
len
&&
tmp
->
d_parent
==
parent
&&
!
(
tmp
->
d_flag
&
D_DUPLICATE
)
&&
!
memcmp
(
tmp
->
d_name
.
name
,
str
,
len
))
return
tmp
;
tmp
=
tmp
->
d_hash_next
;
}
while
(
tmp
!=
base
);
struct
list_head
*
tmp
=
head
->
next
;
int
len
=
name
->
len
;
int
hash
=
name
->
hash
;
const
unsigned
char
*
str
=
name
->
name
;
while
(
tmp
!=
head
)
{
struct
dentry
*
dentry
=
list_entry
(
tmp
,
struct
dentry
,
d_hash
);
tmp
=
tmp
->
next
;
if
(
dentry
->
d_name
.
hash
!=
hash
)
continue
;
if
(
dentry
->
d_name
.
len
!=
len
)
continue
;
if
(
dentry
->
d_parent
!=
parent
)
continue
;
if
(
memcmp
(
dentry
->
d_name
.
name
,
str
,
len
))
continue
;
return
dentry
;
}
return
NULL
;
}
struct
dentry
*
d_lookup
(
struct
dentry
*
dir
,
struct
qstr
*
name
)
{
struct
dentry
**
base
=
d_base_qstr
(
dir
,
name
);
return
__dlookup
(
*
base
,
dir
,
name
);
return
__dlookup
(
d_hash
(
dir
,
name
->
hash
),
dir
,
name
);
}
static
/*inline*/
blocking
void
_d_insert_to_parent
(
struct
dentry
*
entry
,
struct
dentry
*
parent
,
struct
inode
*
inode
,
int
flags
)
static
inline
void
d_insert_to_parent
(
struct
dentry
*
entry
,
struct
dentry
*
parent
)
{
struct
dentry
**
base
;
base
=
d_base_qstr
(
parent
,
&
entry
->
d_name
);
if
(
entry
->
d_flag
&
D_HASHED
)
{
printk
(
"VFS: dcache entry is already hashed
\n
"
);
return
;
}
insert_hash
(
base
,
entry
);
entry
->
d_flag
|=
D_HASHED
;
list_add
(
&
entry
->
d_hash
,
d_hash
(
dget
(
parent
),
entry
->
d_name
.
hash
));
}
/*
* Fill in inode information in the entry.
*
* This turns negative dentries into productive full members
* of society.
*
* NOTE! This assumes that the inode count has been incremented
* (or otherwise set) by the caller to indicate that it is now
* in use by the dcache..
*/
void
d_instantiate
(
struct
dentry
*
entry
,
struct
inode
*
inode
,
int
flags
)
static
inline
void
d_remove_from_parent
(
struct
dentry
*
dentry
,
struct
dentry
*
parent
)
{
entry
->
d_flag
=
(
entry
->
d_flag
&
~
D_NEGATIVE
)
|
flags
;
if
(
inode
&&
!
(
flags
&
D_NEGATIVE
))
{
if
(
entry
->
d_flag
&
D_DIR
)
{
if
(
inode
->
i_dentry
)
{
printk
(
"VFS: creating dcache directory alias
\n
"
);
return
;
}
}
insert_alias
(
&
inode
->
i_dentry
,
entry
);
}
entry
->
d_inode
=
inode
;
list_del
(
&
dentry
->
d_hash
);
dput
(
parent
);
}
/*
...
...
@@ -293,39 +199,19 @@ void d_instantiate(struct dentry *entry, struct inode * inode, int flags)
*/
void
d_delete
(
struct
dentry
*
dentry
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
_d_remove_from_parent
(
dentry
,
dentry
->
d_parent
);
if
(
inode
)
{
remove_alias
(
&
inode
->
i_dentry
,
dentry
);
dentry
->
d_inode
=
NULL
;
iput
(
inode
);
}
list_del
(
&
dentry
->
d_hash
);
/*
* Make the hash lists point to itself.. When we
* later dput this, we want the list_del() there
* to not do anything strange..
*/
INIT_LIST_HEAD
(
&
dentry
->
d_hash
);
}
blocking
void
d_add
(
struct
dentry
*
entry
,
struct
inode
*
inode
,
int
flags
)
void
d_add
(
struct
dentry
*
entry
,
struct
inode
*
inode
)
{
struct
dentry
*
parent
=
entry
->
d_parent
;
#ifdef DEBUG
if
(
inode
)
xcheck
(
"d_add"
,
inode
);
if
(
IS_ROOT
(
entry
))
{
printk
(
"VFS: d_add for root dentry "
);
printpath
(
entry
);
printk
(
" -> "
);
printk
(
"
\n
"
);
return
;
}
if
(
!
parent
)
panic
(
"d_add with parent==NULL"
);
LOG
(
"d_add"
,
entry
);
#endif
if
(
entry
->
d_flag
&
D_HASHED
)
printk
(
"VFS: d_add of already added dcache entry
\n
"
);
_d_insert_to_parent
(
entry
,
parent
,
inode
,
flags
);
d_instantiate
(
entry
,
inode
,
flags
);
d_insert_to_parent
(
entry
,
entry
->
d_parent
);
d_instantiate
(
entry
,
inode
);
}
static
inline
void
alloc_new_name
(
struct
dentry
*
entry
,
struct
qstr
*
newname
)
...
...
@@ -347,47 +233,18 @@ static inline void alloc_new_name(struct dentry * entry, struct qstr *newname)
entry
->
d_name
.
hash
=
hash
;
}
static
inline
void
d_remove_old_parent
(
struct
dentry
*
entry
)
void
d_move
(
struct
dentry
*
dentry
,
struct
dentry
*
newdir
,
struct
qstr
*
newname
)
{
struct
dentry
*
parent
;
struct
inode
*
inode
;
parent
=
entry
->
d_parent
;
inode
=
entry
->
d_inode
;
_d_remove_from_parent
(
entry
,
parent
);
}
static
inline
void
d_add_new_parent
(
struct
dentry
*
entry
,
struct
dentry
*
parent
)
{
struct
inode
*
inode
;
entry
->
d_parent
=
parent
;
inode
=
entry
->
d_inode
;
_d_insert_to_parent
(
entry
,
parent
,
inode
,
entry
->
d_flag
);
}
blocking
void
d_move
(
struct
dentry
*
entry
,
struct
dentry
*
newdir
,
struct
qstr
*
newname
)
{
struct
inode
*
inode
;
int
flags
;
if
(
!
entry
)
if
(
!
dentry
)
return
;
inode
=
entry
->
d_inode
;
flags
=
entry
->
d_flag
;
if
(
!
inode
)
{
printk
(
"VFS: moving negative dcache entry
\n
"
);
}
if
(
flags
&
D_ZOMBIE
)
{
printk
(
"VFS: moving zombie entry
\n
"
);
}
if
(
!
dentry
->
d_inode
)
printk
(
"VFS: moving negative dcache entry
\n
"
);
d_remove_old_parent
(
entry
);
alloc_new_name
(
entry
,
newname
);
d_add_new_parent
(
entry
,
newdir
);
d_remove_from_parent
(
dentry
,
dentry
->
d_parent
);
alloc_new_name
(
dentry
,
newname
);
dentry
->
d_parent
=
newdir
;
d_insert_to_parent
(
dentry
,
newdir
);
}
int
d_path
(
struct
dentry
*
entry
,
struct
dentry
*
chroot
,
char
*
buf
)
...
...
@@ -407,3 +264,16 @@ int d_path(struct dentry * entry, struct dentry * chroot, char * buf)
return
len
+
entry
->
d_name
.
len
;
}
}
void
dcache_init
(
void
)
{
int
i
;
struct
list_head
*
d
=
dentry_hashtable
;
i
=
D_HASHSIZE
;
do
{
INIT_LIST_HEAD
(
d
);
d
++
;
i
--
;
}
while
(
i
);
}
fs/dquot.c
View file @
2730f0af
...
...
@@ -959,7 +959,7 @@ int quota_on(kdev_t dev, short type, char *path)
return
(
-
EBUSY
);
if
((
error
=
getname
(
path
,
&
tmp
))
!=
0
)
return
(
error
);
error
=
open_namei
(
tmp
,
O_RDWR
,
0600
,
&
inode
,
0
);
error
=
open_namei
(
tmp
,
O_RDWR
,
0600
,
&
inode
);
putname
(
tmp
);
if
(
error
)
return
(
error
);
...
...
fs/exec.c
View file @
2730f0af
...
...
@@ -587,7 +587,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
bprm
->
p
=
copy_strings
(
1
,
dynloader
,
bprm
->
page
,
bprm
->
p
,
2
);
bprm
->
argc
++
;
bprm
->
loader
=
bprm
->
p
;
retval
=
open_namei
(
dynloader
[
0
],
0
,
0
,
&
bprm
->
inode
,
NULL
);
retval
=
open_namei
(
dynloader
[
0
],
0
,
0
,
&
bprm
->
inode
);
if
(
retval
)
return
retval
;
bprm
->
dont_iput
=
0
;
...
...
@@ -649,7 +649,7 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
bprm
.
p
=
PAGE_SIZE
*
MAX_ARG_PAGES
-
sizeof
(
void
*
);
for
(
i
=
0
;
i
<
MAX_ARG_PAGES
;
i
++
)
/* clear page-table */
bprm
.
page
[
i
]
=
0
;
retval
=
open_namei
(
filename
,
0
,
0
,
&
bprm
.
inode
,
NULL
);
retval
=
open_namei
(
filename
,
0
,
0
,
&
bprm
.
inode
);
if
(
retval
)
return
retval
;
bprm
.
filename
=
filename
;
...
...
fs/ext2/namei.c
View file @
2730f0af
...
...
@@ -346,10 +346,10 @@ static int ext2_delete_entry (struct ext2_dir_entry * dir,
/*
* By the time this is called, we already have created
* the directory cache entry for the new file, but it
* is so far
marked "D_NEGATIVE"
.
* is so far
negative - it has no inode
.
*
* If the create succeeds,
remove the D_NEGATIVE flag,
*
and fill in the inode information with d_instantiate().
* If the create succeeds,
we fill in the inode information
*
with d_instantiate().
*/
int
ext2_create
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
int
mode
)
{
...
...
@@ -382,7 +382,7 @@ int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
wait_on_buffer
(
bh
);
}
brelse
(
bh
);
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -439,7 +439,7 @@ int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
wait_on_buffer
(
bh
);
}
brelse
(
bh
);
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -503,7 +503,7 @@ int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
}
dir
->
i_nlink
++
;
mark_inode_dirty
(
dir
);
d_instantiate
(
dentry
,
inode
,
D_DIR
);
d_instantiate
(
dentry
,
inode
);
brelse
(
bh
);
return
0
;
}
...
...
@@ -775,7 +775,7 @@ int ext2_symlink (struct inode * dir, struct dentry *dentry, const char * symnam
wait_on_buffer
(
bh
);
}
brelse
(
bh
);
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -810,7 +810,7 @@ int ext2_link (struct inode * inode, struct inode * dir, struct dentry *dentry)
inode
->
i_ctime
=
CURRENT_TIME
;
mark_inode_dirty
(
inode
);
atomic_inc
(
&
inode
->
i_count
);
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
fs/ext2/truncate.c
View file @
2730f0af
...
...
@@ -110,7 +110,8 @@ static int trunc_direct (struct inode * inode)
return
retry
;
}
static
int
trunc_indirect
(
struct
inode
*
inode
,
int
offset
,
u32
*
p
)
static
int
trunc_indirect
(
struct
inode
*
inode
,
int
offset
,
u32
*
p
,
int
in_inode
)
{
int
i
,
tmp
;
struct
buffer_head
*
bh
;
...
...
@@ -124,16 +125,16 @@ static int trunc_indirect (struct inode * inode, int offset, u32 * p)
#define INDIRECT_BLOCK ((int)DIRECT_BLOCK - offset)
int
indirect_block
=
INDIRECT_BLOCK
;
tmp
=
*
p
;
tmp
=
in_inode
?
*
p
:
le32_to_cpu
(
*
p
)
;
if
(
!
tmp
)
return
0
;
ind_bh
=
bread
(
inode
->
i_dev
,
tmp
,
inode
->
i_sb
->
s_blocksize
);
if
(
tmp
!=
*
p
)
{
if
(
tmp
!=
(
in_inode
?
*
p
:
le32_to_cpu
(
*
p
))
)
{
brelse
(
ind_bh
);
return
1
;
}
if
(
!
ind_bh
)
{
*
p
=
0
;
*
p
=
in_inode
?
0
:
cpu_to_le32
(
0
)
;
return
0
;
}
repeat:
...
...
@@ -184,100 +185,15 @@ static int trunc_indirect (struct inode * inode, int offset, u32 * p)
if
(
ind_bh
->
b_count
!=
1
)
retry
=
1
;
else
{
tmp
=
*
p
;
*
p
=
0
;
tmp
=
in_inode
?
*
p
:
le32_to_cpu
(
*
p
)
;
*
p
=
in_inode
?
0
:
cpu_to_le32
(
0
)
;
inode
->
i_blocks
-=
blocks
;
mark_inode_dirty
(
inode
);
ext2_free_blocks
(
inode
,
tmp
,
1
);
bforget
(
ind_bh
);
ind_bh
=
NULL
;
}
if
(
IS_SYNC
(
inode
)
&&
buffer_dirty
(
ind_bh
))
{
ll_rw_block
(
WRITE
,
1
,
&
ind_bh
);
wait_on_buffer
(
ind_bh
);
}
brelse
(
ind_bh
);
return
retry
;
}
static
int
trunc_indirect_swab32
(
struct
inode
*
inode
,
int
offset
,
u32
*
p
)
{
int
i
,
tmp
;
struct
buffer_head
*
bh
;
struct
buffer_head
*
ind_bh
;
u32
*
ind
;
unsigned
long
block_to_free
=
0
;
unsigned
long
free_count
=
0
;
int
retry
=
0
;
int
addr_per_block
=
EXT2_ADDR_PER_BLOCK
(
inode
->
i_sb
);
int
blocks
=
inode
->
i_sb
->
s_blocksize
/
512
;
int
indirect_block
=
INDIRECT_BLOCK
;
tmp
=
le32_to_cpu
(
*
p
);
if
(
!
tmp
)
return
0
;
ind_bh
=
bread
(
inode
->
i_dev
,
tmp
,
inode
->
i_sb
->
s_blocksize
);
if
(
tmp
!=
le32_to_cpu
(
*
p
))
{
brelse
(
ind_bh
);
return
1
;
}
if
(
!
ind_bh
)
{
*
p
=
cpu_to_le32
(
0
);
return
0
;
}
repeat:
for
(
i
=
indirect_block
;
i
<
addr_per_block
;
i
++
)
{
if
(
i
<
0
)
i
=
0
;
if
(
i
<
indirect_block
)
goto
repeat
;
ind
=
i
+
(
u32
*
)
ind_bh
->
b_data
;
tmp
=
le32_to_cpu
(
*
ind
);
if
(
!
tmp
)
continue
;
bh
=
get_hash_table
(
inode
->
i_dev
,
tmp
,
inode
->
i_sb
->
s_blocksize
);
if
(
i
<
indirect_block
)
{
brelse
(
bh
);
goto
repeat
;
}
if
((
bh
&&
bh
->
b_count
!=
1
)
||
tmp
!=
le32_to_cpu
(
*
ind
))
{
retry
=
1
;
brelse
(
bh
);
continue
;
}
*
ind
=
cpu_to_le32
(
0
);
mark_buffer_dirty
(
ind_bh
,
1
);
bforget
(
bh
);
if
(
free_count
==
0
)
{
block_to_free
=
tmp
;
free_count
++
;
}
else
if
(
free_count
>
0
&&
block_to_free
==
tmp
-
free_count
)
free_count
++
;
else
{
ext2_free_blocks
(
inode
,
block_to_free
,
free_count
);
block_to_free
=
tmp
;
free_count
=
1
;
}
/* ext2_free_blocks (inode, tmp, 1); */
inode
->
i_blocks
-=
blocks
;
mark_inode_dirty
(
inode
);
}
if
(
free_count
>
0
)
ext2_free_blocks
(
inode
,
block_to_free
,
free_count
);
ind
=
(
u32
*
)
ind_bh
->
b_data
;
for
(
i
=
0
;
i
<
addr_per_block
;
i
++
)
if
(
le32_to_cpu
(
*
(
ind
++
)))
break
;
if
(
i
>=
addr_per_block
)
if
(
ind_bh
->
b_count
!=
1
)
retry
=
1
;
else
{
tmp
=
le32_to_cpu
(
*
p
);
*
p
=
cpu_to_le32
(
0
);
inode
->
i_blocks
-=
blocks
;
mark_inode_dirty
(
inode
);
ext2_free_blocks
(
inode
,
tmp
,
1
);
}
if
(
IS_SYNC
(
inode
)
&&
buffer_dirty
(
ind_bh
))
{
if
(
IS_SYNC
(
inode
)
&&
ind_bh
&&
buffer_dirty
(
ind_bh
))
{
ll_rw_block
(
WRITE
,
1
,
&
ind_bh
);
wait_on_buffer
(
ind_bh
);
}
...
...
@@ -286,7 +202,7 @@ static int trunc_indirect_swab32 (struct inode * inode, int offset, u32 * p)
}
static
int
trunc_dindirect
(
struct
inode
*
inode
,
int
offset
,
u32
*
p
)
u32
*
p
,
int
in_inode
)
{
int
i
,
tmp
;
struct
buffer_head
*
dind_bh
;
...
...
@@ -297,75 +213,16 @@ static int trunc_dindirect (struct inode * inode, int offset,
#define DINDIRECT_BLOCK (((int)DIRECT_BLOCK - offset) / addr_per_block)
int
dindirect_block
=
DINDIRECT_BLOCK
;
tmp
=
*
p
;
if
(
!
tmp
)
return
0
;
dind_bh
=
bread
(
inode
->
i_dev
,
tmp
,
inode
->
i_sb
->
s_blocksize
);
if
(
tmp
!=
*
p
)
{
brelse
(
dind_bh
);
return
1
;
}
if
(
!
dind_bh
)
{
*
p
=
0
;
return
0
;
}
repeat:
for
(
i
=
dindirect_block
;
i
<
addr_per_block
;
i
++
)
{
if
(
i
<
0
)
i
=
0
;
if
(
i
<
dindirect_block
)
goto
repeat
;
dind
=
i
+
(
u32
*
)
dind_bh
->
b_data
;
tmp
=
le32_to_cpu
(
*
dind
);
if
(
!
tmp
)
continue
;
retry
|=
trunc_indirect_swab32
(
inode
,
offset
+
(
i
*
addr_per_block
),
dind
);
mark_buffer_dirty
(
dind_bh
,
1
);
}
dind
=
(
u32
*
)
dind_bh
->
b_data
;
for
(
i
=
0
;
i
<
addr_per_block
;
i
++
)
if
(
le32_to_cpu
(
*
(
dind
++
)))
break
;
if
(
i
>=
addr_per_block
)
if
(
dind_bh
->
b_count
!=
1
)
retry
=
1
;
else
{
tmp
=
*
p
;
*
p
=
0
;
inode
->
i_blocks
-=
blocks
;
mark_inode_dirty
(
inode
);
ext2_free_blocks
(
inode
,
tmp
,
1
);
}
if
(
IS_SYNC
(
inode
)
&&
buffer_dirty
(
dind_bh
))
{
ll_rw_block
(
WRITE
,
1
,
&
dind_bh
);
wait_on_buffer
(
dind_bh
);
}
brelse
(
dind_bh
);
return
retry
;
}
static
int
trunc_dindirect_swab32
(
struct
inode
*
inode
,
int
offset
,
u32
*
p
)
{
int
i
,
tmp
;
struct
buffer_head
*
dind_bh
;
u32
*
dind
;
int
retry
=
0
;
int
addr_per_block
=
EXT2_ADDR_PER_BLOCK
(
inode
->
i_sb
);
int
blocks
=
inode
->
i_sb
->
s_blocksize
/
512
;
int
dindirect_block
=
DINDIRECT_BLOCK
;
tmp
=
le32_to_cpu
(
*
p
);
tmp
=
in_inode
?
*
p
:
le32_to_cpu
(
*
p
);
if
(
!
tmp
)
return
0
;
dind_bh
=
bread
(
inode
->
i_dev
,
tmp
,
inode
->
i_sb
->
s_blocksize
);
if
(
tmp
!=
le32_to_cpu
(
*
p
))
{
if
(
tmp
!=
(
in_inode
?
*
p
:
le32_to_cpu
(
*
p
)
))
{
brelse
(
dind_bh
);
return
1
;
}
if
(
!
dind_bh
)
{
*
p
=
cpu_to_le32
(
0
);
*
p
=
in_inode
?
0
:
cpu_to_le32
(
0
);
return
0
;
}
repeat:
...
...
@@ -378,8 +235,8 @@ static int trunc_dindirect_swab32 (struct inode * inode, int offset,
tmp
=
le32_to_cpu
(
*
dind
);
if
(
!
tmp
)
continue
;
retry
|=
trunc_indirect
_swab32
(
inode
,
offset
+
(
i
*
addr_per_block
),
dind
);
retry
|=
trunc_indirect
(
inode
,
offset
+
(
i
*
addr_per_block
),
dind
,
0
);
mark_buffer_dirty
(
dind_bh
,
1
);
}
dind
=
(
u32
*
)
dind_bh
->
b_data
;
...
...
@@ -390,13 +247,15 @@ static int trunc_dindirect_swab32 (struct inode * inode, int offset,
if
(
dind_bh
->
b_count
!=
1
)
retry
=
1
;
else
{
tmp
=
le32_to_cpu
(
*
p
);
*
p
=
cpu_to_le32
(
0
);
tmp
=
in_inode
?
*
p
:
le32_to_cpu
(
*
p
);
*
p
=
in_inode
?
0
:
cpu_to_le32
(
0
);
inode
->
i_blocks
-=
blocks
;
mark_inode_dirty
(
inode
);
ext2_free_blocks
(
inode
,
tmp
,
1
);
bforget
(
dind_bh
);
dind_bh
=
0
;
}
if
(
IS_SYNC
(
inode
)
&&
buffer_dirty
(
dind_bh
))
{
if
(
IS_SYNC
(
inode
)
&&
dind_bh
&&
buffer_dirty
(
dind_bh
))
{
ll_rw_block
(
WRITE
,
1
,
&
dind_bh
);
wait_on_buffer
(
dind_bh
);
}
...
...
@@ -436,9 +295,9 @@ static int trunc_tindirect (struct inode * inode)
if
(
i
<
tindirect_block
)
goto
repeat
;
tind
=
i
+
(
u32
*
)
tind_bh
->
b_data
;
retry
|=
trunc_dindirect
_swab32
(
inode
,
EXT2_NDIR_BLOCKS
+
retry
|=
trunc_dindirect
(
inode
,
EXT2_NDIR_BLOCKS
+
addr_per_block
+
(
i
+
1
)
*
addr_per_block
*
addr_per_block
,
tind
);
tind
,
0
);
mark_buffer_dirty
(
tind_bh
,
1
);
}
tind
=
(
u32
*
)
tind_bh
->
b_data
;
...
...
@@ -454,8 +313,10 @@ static int trunc_tindirect (struct inode * inode)
inode
->
i_blocks
-=
blocks
;
mark_inode_dirty
(
inode
);
ext2_free_blocks
(
inode
,
tmp
,
1
);
bforget
(
tind_bh
);
tind_bh
=
0
;
}
if
(
IS_SYNC
(
inode
)
&&
buffer_dirty
(
tind_bh
))
{
if
(
IS_SYNC
(
inode
)
&&
tind_bh
&&
buffer_dirty
(
tind_bh
))
{
ll_rw_block
(
WRITE
,
1
,
&
tind_bh
);
wait_on_buffer
(
tind_bh
);
}
...
...
@@ -479,10 +340,10 @@ void ext2_truncate (struct inode * inode)
while
(
1
)
{
retry
=
trunc_direct
(
inode
);
retry
|=
trunc_indirect
(
inode
,
EXT2_IND_BLOCK
,
(
u32
*
)
&
inode
->
u
.
ext2_i
.
i_data
[
EXT2_IND_BLOCK
]);
(
u32
*
)
&
inode
->
u
.
ext2_i
.
i_data
[
EXT2_IND_BLOCK
]
,
1
);
retry
|=
trunc_dindirect
(
inode
,
EXT2_IND_BLOCK
+
EXT2_ADDR_PER_BLOCK
(
inode
->
i_sb
),
(
u32
*
)
&
inode
->
u
.
ext2_i
.
i_data
[
EXT2_DIND_BLOCK
]);
(
u32
*
)
&
inode
->
u
.
ext2_i
.
i_data
[
EXT2_DIND_BLOCK
]
,
1
);
retry
|=
trunc_tindirect
(
inode
);
if
(
!
retry
)
break
;
...
...
fs/filesystems.c
View file @
2730f0af
...
...
@@ -8,7 +8,6 @@
#include <linux/config.h>
#include <linux/fs.h>
#include <linux/nametrans.h>
#include <linux/minix_fs.h>
#include <linux/ext2_fs.h>
...
...
@@ -45,10 +44,6 @@ __initfunc(static void do_sys_setup(void))
binfmt_setup
();
#ifdef CONFIG_TRANS_NAMES
init_nametrans
();
#endif
#ifdef CONFIG_EXT2_FS
init_ext2_fs
();
#endif
...
...
fs/inode.c
View file @
2730f0af
...
...
@@ -7,8 +7,6 @@
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/dalloc.h>
#include <linux/list.h>
/*
* New inode.c implementation.
...
...
@@ -105,6 +103,7 @@ static inline void init_once(struct inode * inode)
{
memset
(
inode
,
0
,
sizeof
(
*
inode
));
init_waitqueue
(
&
inode
->
i_wait
);
INIT_LIST_HEAD
(
&
inode
->
i_dentry
);
sema_init
(
&
inode
->
i_sem
,
1
);
}
...
...
@@ -301,6 +300,7 @@ void clean_inode(struct inode *inode)
inode
->
i_sock
=
0
;
inode
->
i_op
=
NULL
;
inode
->
i_nlink
=
1
;
inode
->
i_writecount
=
0
;
memset
(
&
inode
->
i_dquot
,
0
,
sizeof
(
inode
->
i_dquot
));
sema_init
(
&
inode
->
i_sem
,
1
);
}
...
...
fs/minix/inode.c
View file @
2730f0af
...
...
@@ -18,7 +18,6 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/locks.h>
#include <linux/dalloc.h>
#include <linux/init.h>
#include <asm/system.h>
...
...
fs/minix/namei.c
View file @
2730f0af
...
...
@@ -227,7 +227,7 @@ int minix_create(struct inode * dir, struct dentry *dentry, int mode)
de
->
inode
=
inode
->
i_ino
;
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -280,7 +280,7 @@ int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
de
->
inode
=
inode
->
i_ino
;
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -340,7 +340,7 @@ int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
dir
->
i_nlink
++
;
dir
->
i_dirt
=
1
;
brelse
(
bh
);
d_instantiate
(
dentry
,
inode
,
D_DIR
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -563,7 +563,7 @@ int minix_symlink(struct inode * dir, struct dentry *dentry,
de
->
inode
=
inode
->
i_ino
;
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -598,7 +598,7 @@ int minix_link(struct inode * inode, struct inode * dir,
inode
->
i_nlink
++
;
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
fs/namei.c
View file @
2730f0af
...
...
@@ -19,10 +19,7 @@
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/dalloc.h>
#include <linux/nametrans.h>
#include <linux/proc_fs.h>
#include <linux/omirr.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
...
...
@@ -236,9 +233,9 @@ void put_write_access(struct inode * inode)
* We get the directory semaphore, and after getting that we also
* make sure that nobody added the entry to the dcache in the meantime..
*/
static
struct
dentry
*
real_lookup
(
struct
dentry
*
dentry
,
struct
qstr
*
name
)
static
struct
dentry
*
real_lookup
(
struct
dentry
*
parent
,
struct
qstr
*
name
)
{
struct
inode
*
dir
=
dentry
->
d_inode
;
struct
inode
*
dir
=
parent
->
d_inode
;
struct
dentry
*
result
;
struct
inode
*
inode
;
int
error
=
-
ENOTDIR
;
...
...
@@ -252,26 +249,21 @@ static struct dentry * real_lookup(struct dentry * dentry, struct qstr * name)
if
(
!
error
||
error
==
-
ENOENT
)
{
struct
dentry
*
new
;
int
isdir
=
0
,
flags
=
D_NOCHECKDUP
;
if
(
error
)
{
flags
=
D_NEGATIVE
;
if
(
error
)
inode
=
NULL
;
}
else
if
(
S_ISDIR
(
inode
->
i_mode
))
{
isdir
=
1
;
flags
=
D_DIR
|
D_NOCHECKDUP
;
}
new
=
d_alloc
(
dentry
,
name
,
isdir
);
new
=
d_alloc
(
parent
,
name
);
/*
* Ok, now we can't sleep any more. Double-check that
* nobody else added this in the meantime..
*/
result
=
d_lookup
(
dentry
,
name
);
result
=
d_lookup
(
parent
,
name
);
if
(
result
)
{
d_free
(
new
);
}
else
{
d_add
(
new
,
inode
,
flags
);
d_add
(
new
,
inode
);
result
=
new
;
}
}
...
...
@@ -280,16 +272,39 @@ static struct dentry * real_lookup(struct dentry * dentry, struct qstr * name)
}
/* Internal lookup() using the new generic dcache. */
static
inline
struct
dentry
*
cached_lookup
(
struct
dentry
*
dentry
,
struct
qstr
*
name
)
static
inline
struct
dentry
*
cached_lookup
(
struct
dentry
*
parent
,
struct
qstr
*
name
)
{
return
d_lookup
(
dentry
,
name
);
struct
dentry
*
dentry
=
d_lookup
(
parent
,
name
);
if
(
dentry
)
{
/*
* FIXME! We should have something like
dentry = dentry->revalidate(dentry);
* here - we need to ask the low-level filesystem permission
* to use the cached entry (NFS needs to time them out, and
* /proc might go away etc).
*/
/*
* The parent d_count _should_ be at least 2: one for the
* dentry we found, and one for the fact that we are using
* it.
*/
if
(
parent
->
d_count
<=
1
)
{
printk
(
"lookup of %s success in %s, but parent count is %d
\n
"
,
dentry
->
d_name
,
parent
->
d_name
,
parent
->
d_count
);
}
}
return
dentry
;
}
/*
* "." and ".." are special - ".." especially so because it has to be able
* to know about the current root directory and parent relationships
*/
static
struct
dentry
*
reserved_lookup
(
struct
dentry
*
dir
,
struct
qstr
*
name
)
static
struct
dentry
*
reserved_lookup
(
struct
dentry
*
parent
,
struct
qstr
*
name
)
{
struct
dentry
*
result
=
NULL
;
if
(
name
->
name
[
0
]
==
'.'
)
{
...
...
@@ -300,12 +315,12 @@ static struct dentry * reserved_lookup(struct dentry * dir, struct qstr * name)
if
(
name
->
name
[
1
]
!=
'.'
)
break
;
if
(
dir
!=
current
->
fs
->
root
)
{
dir
=
dir
->
d_covers
->
d_parent
;
if
(
parent
!=
current
->
fs
->
root
)
{
parent
=
parent
->
d_covers
->
d_parent
;
}
/* fallthrough */
case
1
:
result
=
dget
(
dir
);
result
=
dget
(
parent
);
break
;
}
}
...
...
@@ -425,7 +440,7 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
dentry
=
lookup
(
base
,
&
this
);
if
(
IS_ERR
(
dentry
))
break
;
if
(
dentry
->
d_flag
&
D_NEGATIVE
)
if
(
!
dentry
->
d_inode
)
break
;
/* Last component? */
...
...
@@ -466,8 +481,8 @@ int __namei(const char *pathname, struct inode **res_inode, int follow_link)
if
(
!
IS_ERR
(
dentry
))
{
error
=
-
ENOENT
;
if
(
dentry
)
{
if
(
!
(
dentry
->
d_flag
&
D_NEGATIVE
))
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
inode
*
inode
=
dentry
->
d_inode
;
if
(
inode
)
{
atomic_inc
(
&
inode
->
i_count
);
*
res_inode
=
inode
;
error
=
0
;
...
...
@@ -509,20 +524,21 @@ static inline struct inode *lock_parent(struct dentry *dentry)
* which is a lot more logical, and also allows the "no perm" needed
* for symlinks (where the permissions are checked later).
*/
int
open_namei
(
const
char
*
pathname
,
int
flag
,
int
mode
,
struct
inode
**
res_inode
,
struct
dentry
*
base
)
int
open_namei
(
const
char
*
pathname
,
int
flag
,
int
mode
,
struct
inode
**
res_inode
)
{
int
error
;
int
acc_mode
;
struct
inode
*
inode
;
struct
dentry
*
dentry
;
mode
&=
S_IALLUGO
&
~
current
->
fs
->
umask
;
mode
|=
S_IFREG
;
dentry
=
lookup_dentry
(
pathname
,
base
,
1
);
dentry
=
lookup_dentry
(
pathname
,
NULL
,
1
);
if
(
IS_ERR
(
dentry
))
return
PTR_ERR
(
dentry
);
acc_mode
=
ACC_MODE
(
flag
);
if
(
flag
&
O_CREAT
)
{
struct
inode
*
dir
;
...
...
@@ -531,7 +547,7 @@ int open_namei(const char * pathname, int flag, int mode,
* The existence test must be done _after_ getting the directory
* semaphore - the dentry might otherwise change.
*/
if
(
!
(
dentry
->
d_flag
&
D_NEGATIVE
)
)
{
if
(
dentry
->
d_inode
)
{
error
=
0
;
if
(
flag
&
O_EXCL
)
error
=
-
EEXIST
;
...
...
@@ -543,6 +559,8 @@ int open_namei(const char * pathname, int flag, int mode,
if
(
dir
->
i_sb
&&
dir
->
i_sb
->
dq_op
)
dir
->
i_sb
->
dq_op
->
initialize
(
dir
,
-
1
);
error
=
dir
->
i_op
->
create
(
dir
,
dentry
,
mode
);
/* Don't check for write permission */
acc_mode
=
0
;
}
up
(
&
dir
->
i_sem
);
iput
(
dir
);
...
...
@@ -551,15 +569,15 @@ int open_namei(const char * pathname, int flag, int mode,
}
error
=
-
ENOENT
;
if
(
dentry
->
d_flag
&
D_NEGATIVE
)
inode
=
dentry
->
d_inode
;
if
(
!
inode
)
goto
exit
;
inode
=
dentry
->
d_inode
;
error
=
-
EISDIR
;
if
(
S_ISDIR
(
inode
->
i_mode
)
&&
(
flag
&
2
))
if
(
S_ISDIR
(
inode
->
i_mode
)
&&
(
flag
&
FMODE_WRITE
))
goto
exit
;
error
=
permission
(
inode
,
ACC_MODE
(
flag
)
);
error
=
permission
(
inode
,
acc_mode
);
if
(
error
)
goto
exit
;
...
...
@@ -636,7 +654,7 @@ int do_mknod(const char * filename, int mode, dev_t dev)
dir
=
lock_parent
(
dentry
);
error
=
-
EEXIST
;
if
(
!
(
dentry
->
d_flag
&
D_NEGATIVE
)
)
if
(
dentry
->
d_inode
)
goto
exit_lock
;
error
=
-
EROFS
;
...
...
@@ -710,7 +728,7 @@ static inline int do_mkdir(const char * pathname, int mode)
dir
=
lock_parent
(
dentry
);
error
=
-
EEXIST
;
if
(
!
(
dentry
->
d_flag
&
D_NEGATIVE
)
)
if
(
dentry
->
d_inode
)
goto
exit_lock
;
error
=
-
EROFS
;
...
...
@@ -766,7 +784,7 @@ static inline int do_rmdir(const char * name)
dir
=
lock_parent
(
dentry
);
error
=
-
ENOENT
;
if
(
dentry
->
d_flag
&
D_NEGATIVE
)
if
(
!
dentry
->
d_inode
)
goto
exit_lock
;
error
=
-
EROFS
;
...
...
@@ -894,7 +912,7 @@ static inline int do_symlink(const char * oldname, const char * newname)
goto
exit
;
error
=
-
EEXIST
;
if
(
!
(
dentry
->
d_flag
&
D_NEGATIVE
)
)
if
(
dentry
->
d_inode
)
goto
exit
;
dir
=
lock_parent
(
dentry
);
...
...
@@ -961,18 +979,18 @@ static inline int do_link(const char * oldname, const char * newname)
dir
=
lock_parent
(
new_dentry
);
error
=
-
ENOENT
;
if
(
old_dentry
->
d_flag
&
D_NEGATIVE
)
inode
=
old_dentry
->
d_inode
;
if
(
!
inode
)
goto
exit_lock
;
error
=
-
EEXIST
;
if
(
!
(
new_dentry
->
d_flag
&
D_NEGATIVE
)
)
if
(
new_dentry
->
d_inode
)
goto
exit_lock
;
error
=
-
EROFS
;
if
(
IS_RDONLY
(
dir
))
goto
exit_lock
;
inode
=
old_dentry
->
d_inode
;
error
=
-
EXDEV
;
if
(
dir
->
i_dev
!=
inode
->
i_dev
)
goto
exit_lock
;
...
...
@@ -1067,7 +1085,7 @@ static inline int do_rename(const char * oldname, const char * newname)
double_down
(
&
new_dir
->
i_sem
,
&
old_dir
->
i_sem
);
error
=
-
ENOENT
;
if
(
old_dentry
->
d_flag
&
D_NEGATIVE
)
if
(
!
old_dentry
->
d_inode
)
goto
exit_lock
;
error
=
permission
(
old_dir
,
MAY_WRITE
|
MAY_EXEC
);
...
...
fs/nfs/dir.c
View file @
2730f0af
...
...
@@ -395,7 +395,7 @@ static int nfs_create(struct inode *dir, struct dentry * dentry, int mode)
if
(
!
inode
)
return
-
EACCES
;
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -434,7 +434,7 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde
if
(
!
inode
)
return
-
EACCES
;
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -471,7 +471,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if
(
!
inode
)
return
-
EACCES
;
d_instantiate
(
dentry
,
inode
,
D_DIR
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -561,7 +561,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
if
(
!
inode
)
return
-
EACCES
;
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -588,7 +588,7 @@ static int nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentr
return
error
;
atomic_inc
(
&
inode
->
i_count
);
d_instantiate
(
dentry
,
inode
,
0
);
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
fs/open.c
View file @
2730f0af
...
...
@@ -4,7 +4,6 @@
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/config.h>
#include <linux/vfs.h>
#include <linux/types.h>
#include <linux/utime.h>
...
...
@@ -21,7 +20,6 @@
#include <linux/file.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/omirr.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
...
...
@@ -211,11 +209,6 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times)
goto
iput_and_out
;
}
error
=
notify_change
(
inode
,
&
newattrs
);
#ifdef CONFIG_OMIRR
if
(
!
error
)
omirr_printall
(
inode
,
" U %ld %ld %ld "
,
CURRENT_TIME
,
newattrs
.
ia_atime
,
newattrs
.
ia_mtime
);
#endif
iput_and_out:
iput
(
inode
);
out:
...
...
@@ -257,11 +250,6 @@ asmlinkage int sys_utimes(char * filename, struct timeval * utimes)
goto
iput_and_out
;
}
error
=
notify_change
(
inode
,
&
newattrs
);
#ifdef CONFIG_OMIRR
if
(
!
error
)
omirr_printall
(
inode
,
" U %ld %ld %ld "
,
CURRENT_TIME
,
newattrs
.
ia_atime
,
newattrs
.
ia_mtime
);
#endif
iput_and_out:
iput
(
inode
);
out:
...
...
@@ -312,11 +300,11 @@ asmlinkage int sys_chdir(const char * filename)
goto
out
;
error
=
-
ENOENT
;
if
(
dentry
->
d_flag
&
D_NEGATIVE
)
inode
=
dentry
->
d_inode
;
if
(
!
inode
)
goto
dput_and_out
;
error
=
-
ENOTDIR
;
inode
=
dentry
->
d_inode
;
if
(
!
S_ISDIR
(
inode
->
i_mode
))
goto
dput_and_out
;
...
...
@@ -340,7 +328,6 @@ asmlinkage int sys_fchdir(unsigned int fd)
{
struct
file
*
file
;
struct
inode
*
inode
;
struct
dentry
*
dentry
,
*
tmp
;
int
error
;
lock_kernel
();
...
...
@@ -361,10 +348,14 @@ asmlinkage int sys_fchdir(unsigned int fd)
if
(
error
)
goto
out
;
dentry
=
dget
(
inode
->
i_dentry
);
tmp
=
current
->
fs
->
pwd
;
current
->
fs
->
pwd
=
dentry
;
dput
(
tmp
);
{
struct
dentry
*
dentry
,
*
tmp
;
dentry
=
dget
(
i_dentry
(
inode
));
tmp
=
current
->
fs
->
pwd
;
current
->
fs
->
pwd
=
dentry
;
dput
(
tmp
);
}
out:
unlock_kernel
();
return
error
;
...
...
@@ -384,11 +375,11 @@ asmlinkage int sys_chroot(const char * filename)
goto
out
;
error
=
-
ENOENT
;
if
(
dentry
->
d_flag
&
D_NEGATIVE
)
inode
=
dentry
->
d_inode
;
if
(
!
inode
)
goto
dput_and_out
;
error
=
-
ENOTDIR
;
inode
=
dentry
->
d_inode
;
if
(
!
S_ISDIR
(
inode
->
i_mode
))
goto
dput_and_out
;
...
...
@@ -619,7 +610,7 @@ static int do_open(const char * filename,int flags,int mode, int fd)
flag
++
;
if
(
flag
&
O_TRUNC
)
flag
|=
2
;
error
=
open_namei
(
filename
,
flag
,
mode
,
&
inode
,
NULL
);
error
=
open_namei
(
filename
,
flag
,
mode
,
&
inode
);
if
(
error
)
goto
cleanup_file
;
if
(
f
->
f_mode
&
FMODE_WRITE
)
{
...
...
fs/proc/link.c
View file @
2730f0af
...
...
@@ -14,7 +14,6 @@
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/dalloc.h>
static
int
proc_readlink
(
struct
inode
*
,
char
*
,
int
);
static
struct
dentry
*
proc_follow_link
(
struct
inode
*
,
struct
dentry
*
);
...
...
@@ -105,7 +104,7 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base
vma
=
p
->
mm
->
mmap
;
while
(
vma
)
{
if
(
vma
->
vm_flags
&
VM_EXECUTABLE
)
return
dget
(
vma
->
vm_inode
->
i_dentry
);
return
dget
(
i_dentry
(
vma
->
vm_inode
)
);
vma
=
vma
->
vm_next
;
}
...
...
@@ -123,7 +122,7 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base
break
;
if
(
!
p
->
files
->
fd
[
ino
]
->
f_inode
)
break
;
result
=
dget
(
p
->
files
->
fd
[
ino
]
->
f_inode
->
i_dentry
);
result
=
dget
(
i_dentry
(
p
->
files
->
fd
[
ino
]
->
f_inode
)
);
break
;
}
}
...
...
fs/proc/omirr.c
View file @
2730f0af
...
...
@@ -7,7 +7,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/dalloc.h>
#include <linux/omirr.h>
#include <asm/uaccess.h>
...
...
fs/super.c
View file @
2730f0af
...
...
@@ -33,7 +33,6 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/fd.h>
#include <linux/dalloc.h>
#include <linux/init.h>
#include <asm/system.h>
...
...
@@ -745,7 +744,7 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
if
(
IS_ERR
(
dir_d
))
return
error
;
if
(
dir_d
->
d_flag
&
D_NEGATIVE
)
{
if
(
!
dir_d
->
d_inode
)
{
dput
(
dir_d
);
return
-
ENOENT
;
}
...
...
include/linux/cyclades.h
View file @
2730f0af
/* $Revision:
1.7 $$Date: 1997/03/26
10:30:00 $
/* $Revision:
2.0 $$Date: 1997/06/30
10:30:00 $
* linux/include/linux/cyclades.h
*
* This file is maintained by Marcio Saito <marcio@cyclades.com> and
...
...
@@ -6,6 +6,14 @@
*
* This file contains the general definitions for the cyclades.c driver
*$Log: cyclades.h,v $
*Revision 2.0 1997/06/30 10:30:00 ivan
*added some new doorbell command constants related to IOCTLW and
*UART error signaling
*
*Revision 1.8 1997/06/03 15:30:00 ivan
*added constant ZFIRM_HLT
*added constant CyPCI_Ze_win ( = 2 * Cy_PCI_Zwin)
*
*Revision 1.7 1997/03/26 10:30:00 daniel
*new entries at the end of cyclades_port struct to reallocate
*variables illegally allocated within card memory.
...
...
@@ -86,6 +94,8 @@ typedef unsigned char ucchar; /* 8 bits, unsigned */
*/
#define DP_WINDOW_SIZE (0x00080000)
/* window size 512 Kb */
#define ZE_DP_WINDOW_SIZE (0x00100000)
/* window size 1 Mb (Ze and
8Zo V.2 */
#define CTRL_WINDOW_SIZE (0x00000100)
/* runtime regs 256 bytes */
/*
...
...
@@ -183,6 +193,7 @@ struct RUNTIME_9060 {
#define ID_ADDRESS 0x00000180L
/* signature/pointer address */
#define ZFIRM_ID 0x5557465AL
/* ZFIRM/U signature */
#define ZFIRM_HLT 0x59505B5CL
/* ZFIRM needs external power supply */
struct
FIRM_ID
{
uclong
signature
;
/* ZFIRM/U signature */
uclong
zfwctrl_addr
;
/* pointer to ZFW_CTRL structure */
...
...
@@ -238,7 +249,10 @@ struct FIRM_ID {
#define C_IN_RXBRK 0x00001000
/* Break received */
#define C_IN_PR_ERROR 0x00002000
/* parity error */
#define C_IN_FR_ERROR 0x00004000
/* frame error */
#define C_IN_OVR_ERROR 0x00008000
/* overrun error */
#define C_IN_RXOFL 0x00010000
/* RX buffer overflow */
#define C_IN_IOCTLW 0x00020000
/* I/O control w/ wait */
/* flow control */
#define C_FL_OXX 0x00000001
/* output Xon/Xoff flow control */
...
...
@@ -294,6 +308,8 @@ struct FIRM_ID {
#define C_CM_RXBRK 0x84
/* Break received */
#define C_CM_PR_ERROR 0x85
/* Parity error */
#define C_CM_FR_ERROR 0x86
/* Frame error */
#define C_CM_OVR_ERROR 0x87
/* Overrun error */
#define C_CM_RXOFL 0x88
/* RX buffer overflow */
#define C_CM_CMDERROR 0x90
/* command error */
#define C_CM_FATAL 0x91
/* fatal error */
#define C_CM_HW_RESET 0x92
/* reset board */
...
...
@@ -468,9 +484,10 @@ struct cyclades_port {
#define CyMaxChipsPerCard 8
#define CyPCI_Ywin 0x4000
#define CyPCI_Zctl 0x100
#define CyPCI_Zwin 0x80000
#define CyPCI_Ywin 0x4000
#define CyPCI_Zctl 0x100
#define CyPCI_Zwin 0x80000
#define CyPCI_Ze_win (2 * CyPCI_Zwin)
/**** CD1400 registers ****/
...
...
include/linux/d
alloc
.h
→
include/linux/d
cache
.h
View file @
2730f0af
#ifndef DALLOC_H
#define DALLOC_H
#ifndef __LINUX_DCACHE_H
#define __LINUX_DCACHE_H
/*
*
$Id: dalloc.h,v 1.3 1997/06/13 04:39:34 davem Exp $
*
linux/include/linux/dcache.h
*
* include/linux/dalloc.h - alloc routines for dcache
* alloc / free space for pathname strings
* Copyright (C) 1997, Thomas Schoebel-Theuer,
* <schoebel@informatik.uni-stuttgart.de>.
* Directory cache data structures
*/
#define D_MAXLEN 1024
/* public flags for d_add() */
#define D_NORMAL 0
#define D_BASKET 1
/* put into basket (deleted/unref'd files) */
#define D_DUPLICATE 2
/* allow duplicate entries */
#define D_NOCHECKDUP 4
/* no not check for duplicates */
#define D_NEGATIVE 8
/* negative entry */
#define D_PRELOADED 16
#define D_DIR 32
/* directory entry - look out for allocation issues */
#define D_HASHED 64
#define D_ZOMBIE 128
#define D_INC_DDIR 512
/* public flags for d_del() */
#define D_REMOVE 0
#define D_NO_CLEAR_INODE 1
#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,hash) pair.
* Storing the len instead of doing strlen() very often is performance
* critical.
/*
* "quick string" -- eases parameter passing, but more importantly
* saves "metadata" about the string (ie length and the hash).
*/
struct
qstr
{
const
unsigned
char
*
name
;
int
len
,
hash
;
unsigned
int
len
,
hash
;
};
/* Name hashing routines. Initial hash value */
...
...
@@ -58,63 +39,44 @@ static inline unsigned long end_name_hash(unsigned long hash)
}
struct
dentry
{
unsigned
int
d_flag
;
unsigned
int
d_
count
;
struct
inode
*
d_inode
;
/* Where the name belongs to */
int
d_count
;
unsigned
int
d_
flags
;
struct
inode
*
d_inode
;
/* Where the name belongs to
- NULL is negative
*/
struct
dentry
*
d_parent
;
/* parent directory */
struct
dentry
*
d_mounts
;
/* mount information */
struct
dentry
*
d_covers
;
struct
dentry
*
d_next
;
/* hardlink aliasname / empty list */
struct
dentry
*
d_prev
;
/* hardlink aliasname */
struct
dentry
*
d_hash_next
;
struct
dentry
*
d_hash_prev
;
struct
dentry
*
d_basket_next
;
struct
dentry
*
d_basket_prev
;
struct
list_head
d_list
;
/* hardlink aliasname / empty list */
struct
list_head
d_hash
;
struct
qstr
d_name
;
};
extern
struct
dentry
*
the_root
;
/*
* These are the low-level FS interfaces to the dcache..
*/
extern
void
d_instantiate
(
struct
dentry
*
,
struct
inode
*
,
int
);
extern
void
d_instantiate
(
struct
dentry
*
,
struct
inode
*
);
extern
void
d_delete
(
struct
dentry
*
);
/* Note that all these routines must be called with vfs_lock() held */
/* get inode, if necessary retrieve it with iget() */
extern
blocking
struct
inode
*
d_inode
(
struct
dentry
**
changing_entry
);
extern
struct
inode
*
d_inode
(
struct
dentry
**
changing_entry
);
/* allocate/de-allocate */
extern
void
d_free
(
struct
dentry
*
);
extern
struct
dentry
*
d_alloc
(
struct
dentry
*
parent
,
struct
qstr
*
name
,
int
isdir
);
extern
struct
dentry
*
d_alloc
(
struct
dentry
*
parent
,
const
struct
qstr
*
name
);
/* only used at mount-time */
extern
blocking
struct
dentry
*
d_alloc_root
(
struct
inode
*
root_inode
,
struct
dentry
*
old_root
);
extern
struct
dentry
*
d_alloc_root
(
struct
inode
*
root_inode
,
struct
dentry
*
old_root
);
/*
* This adds the entry to the hash queues and initializes "d_inode".
* The entry was actually filled in earlier during "d_alloc()"
*/
extern
blocking
void
d_add
(
struct
dentry
*
entry
,
struct
inode
*
inode
,
int
flags
);
/* combination of d_alloc() and d_add(), less lookup overhead */
extern
blocking
struct
dentry
*
d_entry
(
struct
dentry
*
parent
,
struct
qstr
*
name
,
struct
inode
*
inode
);
extern
blocking
void
d_entry_preliminary
(
struct
dentry
*
parent
,
struct
qstr
*
name
,
unsigned
long
ino
);
/* recursive d_del() all successors */
extern
blocking
void
d_del
(
struct
dentry
*
entry
,
int
flags
);
extern
void
d_add
(
struct
dentry
*
entry
,
struct
inode
*
inode
);
/* used for rename() and baskets */
extern
blocking
void
d_move
(
struct
dentry
*
entry
,
struct
dentry
*
newparent
,
struct
qstr
*
newname
);
extern
void
d_move
(
struct
dentry
*
entry
,
struct
dentry
*
newparent
,
struct
qstr
*
newname
);
/* appendix may either be NULL or be used for transname suffixes */
extern
struct
dentry
*
d_lookup
(
struct
dentry
*
dir
,
struct
qstr
*
name
);
...
...
@@ -122,19 +84,7 @@ extern struct dentry * d_lookup(struct dentry * dir, struct qstr * name);
/* write full pathname into buffer and return length */
extern
int
d_path
(
struct
dentry
*
entry
,
struct
dentry
*
chroot
,
char
*
buf
);
extern
struct
dentry
*
d_basket
(
struct
dentry
*
dir_entry
);
extern
int
d_isbasket
(
struct
dentry
*
entry
);
/*
* Whee..
*/
static
inline
void
dput
(
struct
dentry
*
dentry
)
{
if
(
dentry
)
dentry
->
d_count
--
;
}
/* Allocation counts.. */
static
inline
struct
dentry
*
dget
(
struct
dentry
*
dentry
)
{
if
(
dentry
)
...
...
@@ -142,4 +92,14 @@ static inline struct dentry * dget(struct dentry *dentry)
return
dentry
;
}
#endif
extern
void
dput
(
struct
dentry
*
);
/*
* This is ugly. The inode:dentry relationship is a 1:n
* relationship, so we have to return one (random) dentry
* from the list. We select the first one..
*/
#define i_dentry(inode) \
list_entry((inode)->i_dentry.next, struct dentry, d_list)
#endif
/* __LINUX_DCACHE_H */
include/linux/fs.h
View file @
2730f0af
...
...
@@ -16,16 +16,12 @@
#include <linux/kdev_t.h>
#include <linux/ioctl.h>
#include <linux/list.h>
#include <linux/dcache.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...
*/
#define blocking
/*routine may schedule()*/
#include <linux/dalloc.h>
/*
* It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix
...
...
@@ -155,7 +151,7 @@ extern int max_files, nr_files;
extern
void
buffer_init
(
void
);
extern
void
inode_init
(
void
);
extern
void
file_table_init
(
void
);
extern
unsigned
long
name_cache_init
(
unsigned
long
start
,
unsigned
long
en
d
);
extern
void
dcache_init
(
voi
d
);
typedef
char
buffer_block
[
BLOCK_SIZE
];
...
...
@@ -331,7 +327,7 @@ struct inode {
struct
page
*
i_pages
;
struct
dquot
*
i_dquot
[
MAXQUOTAS
];
struct
dentry
*
i_dentry
;
struct
list_head
i_dentry
;
unsigned
int
i_state
;
...
...
@@ -685,8 +681,7 @@ extern int notify_change(struct inode *, struct iattr *);
extern
int
permission
(
struct
inode
*
inode
,
int
mask
);
extern
int
get_write_access
(
struct
inode
*
inode
);
extern
void
put_write_access
(
struct
inode
*
inode
);
extern
int
open_namei
(
const
char
*
pathname
,
int
flag
,
int
mode
,
struct
inode
**
res_inode
,
struct
dentry
*
base
);
extern
int
open_namei
(
const
char
*
pathname
,
int
flag
,
int
mode
,
struct
inode
**
res_inode
);
extern
int
do_mknod
(
const
char
*
filename
,
int
mode
,
dev_t
dev
);
extern
int
do_pipe
(
int
*
);
...
...
@@ -738,18 +733,18 @@ extern inline void vfs_unlock(void)
extern
void
_get_inode
(
struct
inode
*
inode
);
extern
void
iput
(
struct
inode
*
inode
);
extern
blocking
struct
inode
*
iget
(
struct
super_block
*
sb
,
unsigned
long
nr
);
extern
blocking
void
clear_inode
(
struct
inode
*
inode
);
extern
blocking
struct
inode
*
get_empty_inode
(
void
);
extern
struct
inode
*
iget
(
struct
super_block
*
sb
,
unsigned
long
nr
);
extern
void
clear_inode
(
struct
inode
*
inode
);
extern
struct
inode
*
get_empty_inode
(
void
);
/* Please prefer to use this function in future, instead of using
* a get_empty_inode()/insert_inode_hash() combination.
* It allows for better checking and less race conditions.
*/
blocking
struct
inode
*
get_empty_inode_hashed
(
dev_t
i_dev
,
unsigned
long
i_ino
);
extern
struct
inode
*
get_empty_inode_hashed
(
dev_t
i_dev
,
unsigned
long
i_ino
);
extern
void
insert_inode_hash
(
struct
inode
*
);
extern
blocking
struct
inode
*
get_pipe_inode
(
void
);
extern
struct
inode
*
get_pipe_inode
(
void
);
extern
int
get_unused_fd
(
void
);
extern
void
put_unused_fd
(
int
);
extern
struct
file
*
get_empty_filp
(
void
);
...
...
include/linux/nametrans.h
deleted
100644 → 0
View file @
0d1267fe
#ifndef NAMETRANS_H
#define NAMETRANS_H
/*
* $Id: nametrans.h,v 1.1 1997/06/04 08:26:57 davem Exp $
*
* include/linux/nametrans.h - context-dependend filename suffixes.
* Copyright (C) 1997, Thomas Schoebel-Theuer,
* <schoebel@informatik.uni-stuttgart.de>.
*/
#include <linux/dalloc.h>
#include <linux/sysctl.h>
#define MAX_DEFAULT_TRANSLEN 128
/* only filenames matching the following length restrictions can be
* translated. I introduced these restrictions because they *greatly*
* simplify buffer management (no need to allocate kernel pages and free them).
* The maximal total length of a context-dependend filename is the
* sum of both constants. */
#define MAX_TRANS_FILELEN 128
/* max len of a name that could be translated */
#define MAX_TRANS_SUFFIX 64
/* max len of a #keyword=value# suffix */
/* max number of translations */
#define MAX_TRANSLATIONS 16
struct
translations
{
int
count
;
struct
qstr
name
[
MAX_TRANSLATIONS
];
struct
qstr
c_name
[
MAX_TRANSLATIONS
];
};
/* global/default translations */
extern
char
nametrans_txt
[
MAX_DEFAULT_TRANSLEN
];
/* Any changer of a built-in translation must set this flag */
extern
int
translations_dirty
;
/* called once at boot time */
extern
void
init_nametrans
(
void
);
/* set global translations */
extern
void
nametrans_setup
(
char
*
line
);
/* return reusable global buffer. needed by VFS. */
struct
translations
*
get_translations
(
char
*
env
);
/* if the _first_ environment variable is "NAMETRANS", return
* a pointer to the list of appendices.
* You can set the first environment variable using
* 'env - NAMETRANS=... "`env`" command ...'
*/
extern
char
*
env_transl
(
void
);
/* if name has the correct suffix "#keyword=correct_context#",
* return position of the suffix, else 0.
*/
extern
char
*
testname
(
int
restricted
,
char
*
name
);
/* for use in kernel/sysctrl.h */
extern
int
nametrans_dostring
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
*
buffer
,
size_t
*
lenp
);
extern
int
nametrans_string
(
ctl_table
*
table
,
int
*
name
,
int
nlen
,
void
*
oldval
,
size_t
*
oldlenp
,
void
*
newval
,
size_t
newlen
,
void
**
context
);
#endif
include/linux/omirr.h
deleted
100644 → 0
View file @
0d1267fe
/*
* fs/proc/omirr.c - online mirror support
*
* (C) 1997 Thomas Schoebel-Theuer
*/
#ifndef OMIRR_H
#define OMIRR_H
#include <linux/fs.h>
#include <linux/dalloc.h>
extern
int
omirr_print
(
struct
dentry
*
ent1
,
struct
dentry
*
ent2
,
struct
qstr
*
suffix
,
const
char
*
fmt
,
...);
extern
int
omirr_printall
(
struct
inode
*
inode
,
const
char
*
fmt
,
...);
#endif
include/linux/slab.h
View file @
2730f0af
...
...
@@ -57,7 +57,7 @@ extern void kmem_cache_free(kmem_cache_t *, void *);
extern
void
*
kmalloc
(
size_t
,
int
);
extern
void
kfree
(
const
void
*
);
extern
void
kfree_s
(
void
*
,
size_t
);
extern
void
kfree_s
(
const
void
*
,
size_t
);
extern
int
kmem_cache_reap
(
int
,
int
,
int
);
extern
int
get_slabinfo
(
char
*
);
...
...
init/main.c
View file @
2730f0af
...
...
@@ -32,7 +32,6 @@
#include <linux/slab.h>
#include <linux/major.h>
#include <linux/blk.h>
#include <linux/nametrans.h>
#include <linux/init.h>
#ifdef CONFIG_ROOT_NFS
#include <linux/nfs_fs.h>
...
...
@@ -558,12 +557,6 @@ __initfunc(static int checksetup(char *line))
ide_setup
(
line
);
return
1
;
}
#endif
#ifdef CONFIG_TRANS_NAMES
if
(
!
strncmp
(
line
,
"nametrans="
,
10
))
{
nametrans_setup
(
line
+
10
);
return
1
;
}
#endif
while
(
bootsetups
[
i
].
str
)
{
int
n
=
strlen
(
bootsetups
[
i
].
str
);
...
...
@@ -886,7 +879,6 @@ __initfunc(asmlinkage void start_kernel(void))
memory_start
=
kmem_cache_init
(
memory_start
,
memory_end
);
sti
();
calibrate_delay
();
memory_start
=
name_cache_init
(
memory_start
,
memory_end
);
#ifdef CONFIG_BLK_DEV_INITRD
if
(
initrd_start
&&
!
initrd_below_start_ok
&&
initrd_start
<
memory_start
)
{
printk
(
KERN_CRIT
"initrd overwritten (0x%08lx < 0x%08lx) - "
...
...
@@ -901,6 +893,7 @@ __initfunc(asmlinkage void start_kernel(void))
#endif
uidcache_init
();
filescache_init
();
dcache_init
();
vma_init
();
buffer_init
();
inode_init
();
...
...
kernel/sys.c
View file @
2730f0af
...
...
@@ -21,7 +21,6 @@
#include <linux/fcntl.h>
#include <linux/acct.h>
#include <linux/tty.h>
#include <linux/nametrans.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/notifier.h>
...
...
@@ -431,7 +430,7 @@ asmlinkage int sys_acct(const char *name)
if
((
error
=
getname
(
name
,
&
tmp
))
!=
0
)
goto
out
;
error
=
open_namei
(
tmp
,
O_RDWR
,
0600
,
&
inode
,
0
);
error
=
open_namei
(
tmp
,
O_RDWR
,
0600
,
&
inode
);
putname
(
tmp
);
if
(
error
)
goto
out
;
...
...
kernel/sysctl.c
View file @
2730f0af
...
...
@@ -16,7 +16,6 @@
#include <linux/mm.h>
#include <linux/sysctl.h>
#include <linux/swapctl.h>
#include <linux/nametrans.h>
#include <linux/proc_fs.h>
#include <linux/malloc.h>
#include <linux/stat.h>
...
...
@@ -172,10 +171,6 @@ static ctl_table kern_table[] = {
{
KERN_JAVA_APPLETVIEWER
,
"java-appletviewer"
,
binfmt_java_appletviewer
,
64
,
0644
,
NULL
,
&
proc_dostring
,
&
sysctl_string
},
#endif
#ifdef CONFIG_TRANS_NAMES
{
KERN_NAMETRANS
,
"nametrans"
,
nametrans_txt
,
MAX_DEFAULT_TRANSLEN
,
0644
,
NULL
,
&
nametrans_dostring
,
&
nametrans_string
},
#endif
#ifdef __sparc__
{
KERN_SPARC_REBOOT
,
"reboot-cmd"
,
reboot_command
,
256
,
0644
,
NULL
,
&
proc_dostring
,
&
sysctl_string
},
...
...
mm/slab.c
View file @
2730f0af
...
...
@@ -1275,7 +1275,7 @@ kmem_report_alloc_err(const char *str, kmem_cache_t * cachep)
}
static
void
kmem_report_free_err
(
const
char
*
str
,
void
*
objp
,
kmem_cache_t
*
cachep
)
kmem_report_free_err
(
const
char
*
str
,
const
void
*
objp
,
kmem_cache_t
*
cachep
)
{
if
(
cachep
)
SLAB_STATS_INC_ERR
(
cachep
);
...
...
@@ -1456,7 +1456,7 @@ __kmem_cache_alloc(kmem_cache_t *cachep, int flags)
* it should be in this state _before_ it is released.
*/
static
inline
void
__kmem_cache_free
(
kmem_cache_t
*
cachep
,
void
*
objp
)
__kmem_cache_free
(
kmem_cache_t
*
cachep
,
const
void
*
objp
)
{
kmem_slab_t
*
slabp
;
kmem_bufctl_t
*
bufp
;
...
...
@@ -1653,7 +1653,7 @@ kfree(const void *objp)
}
void
kfree_s
(
void
*
objp
,
size_t
size
)
kfree_s
(
const
void
*
objp
,
size_t
size
)
{
struct
page
*
page
;
int
nr
;
...
...
net/socket.c
View file @
2730f0af
...
...
@@ -67,7 +67,6 @@
#include <linux/socket.h>
#include <linux/fcntl.h>
#include <linux/file.h>
#include <linux/dalloc.h>
#include <linux/net.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
...
...
net/unix/af_unix.c
View file @
2730f0af
...
...
@@ -459,7 +459,7 @@ static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len,
{
old_fs
=
get_fs
();
set_fs
(
get_ds
());
err
=
open_namei
(
sunname
->
sun_path
,
2
,
S_IFSOCK
,
&
inode
,
NULL
);
err
=
open_namei
(
sunname
->
sun_path
,
2
,
S_IFSOCK
,
&
inode
);
set_fs
(
old_fs
);
if
(
err
<
0
)
{
...
...
@@ -550,7 +550,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
err
=
do_mknod
(
sunaddr
->
sun_path
,
S_IFSOCK
|
S_IRWXUGO
,
0
);
if
(
!
err
)
err
=
open_namei
(
sunaddr
->
sun_path
,
2
,
S_IFSOCK
,
&
inode
,
NULL
);
err
=
open_namei
(
sunaddr
->
sun_path
,
2
,
S_IFSOCK
,
&
inode
);
set_fs
(
old_fs
);
...
...
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