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
1b7a152c
Commit
1b7a152c
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 1.1.62
parent
a6614639
Changes
62
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
62 changed files
with
1185 additions
and
1128 deletions
+1185
-1128
CREDITS
CREDITS
+17
-0
Makefile
Makefile
+1
-1
README
README
+36
-14
arch/i386/config.in
arch/i386/config.in
+1
-0
drivers/block/cdu31a.c
drivers/block/cdu31a.c
+12
-0
drivers/block/floppy.c
drivers/block/floppy.c
+6
-5
drivers/char/ChangeLog
drivers/char/ChangeLog
+7
-0
drivers/char/n_tty.c
drivers/char/n_tty.c
+5
-4
drivers/char/tty_io.c
drivers/char/tty_io.c
+6
-0
drivers/scsi/README.st
drivers/scsi/README.st
+6
-4
drivers/scsi/fdomain.c
drivers/scsi/fdomain.c
+60
-39
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+1
-0
drivers/scsi/st.c
drivers/scsi/st.c
+71
-8
drivers/scsi/st.h
drivers/scsi/st.h
+1
-0
drivers/sound/configure.c
drivers/sound/configure.c
+1
-1
drivers/sound/soundcard.c
drivers/sound/soundcard.c
+6
-0
fs/block_dev.c
fs/block_dev.c
+9
-3
fs/exec.c
fs/exec.c
+20
-17
fs/ext2/CHANGES
fs/ext2/CHANGES
+6
-0
fs/ext2/balloc.c
fs/ext2/balloc.c
+4
-1
fs/ext2/super.c
fs/ext2/super.c
+47
-2
fs/msdos/file.c
fs/msdos/file.c
+63
-36
fs/namei.c
fs/namei.c
+38
-18
fs/nfs/proc.c
fs/nfs/proc.c
+1
-14
fs/nfs/symlink.c
fs/nfs/symlink.c
+1
-8
fs/open.c
fs/open.c
+17
-6
fs/sysv/INTRO
fs/sysv/INTRO
+0
-6
fs/sysv/Makefile
fs/sysv/Makefile
+1
-1
fs/sysv/README
fs/sysv/README
+1
-1
fs/sysv/balloc.c
fs/sysv/balloc.c
+30
-40
fs/sysv/dir.c
fs/sysv/dir.c
+2
-5
fs/sysv/file.c
fs/sysv/file.c
+19
-68
fs/sysv/fsync.c
fs/sysv/fsync.c
+9
-12
fs/sysv/ialloc.c
fs/sysv/ialloc.c
+33
-19
fs/sysv/inode.c
fs/sysv/inode.c
+255
-122
fs/sysv/namei.c
fs/sysv/namei.c
+19
-29
fs/sysv/symlink.c
fs/sysv/symlink.c
+4
-4
fs/sysv/truncate.c
fs/sysv/truncate.c
+33
-258
include/linux/ext2_fs.h
include/linux/ext2_fs.h
+6
-1
include/linux/ext2_fs_sb.h
include/linux/ext2_fs_sb.h
+2
-0
include/linux/fs.h
include/linux/fs.h
+3
-0
include/linux/interrupt.h
include/linux/interrupt.h
+1
-0
include/linux/mm.h
include/linux/mm.h
+2
-1
include/linux/mtio.h
include/linux/mtio.h
+3
-1
include/linux/sched.h
include/linux/sched.h
+2
-3
include/linux/shm.h
include/linux/shm.h
+6
-16
include/linux/sysv_fs.h
include/linux/sysv_fs.h
+13
-42
include/linux/sysv_fs_i.h
include/linux/sysv_fs_i.h
+0
-4
include/linux/sysv_fs_sb.h
include/linux/sysv_fs_sb.h
+60
-44
include/linux/tqueue.h
include/linux/tqueue.h
+1
-1
ipc/shm.c
ipc/shm.c
+156
-190
ipc/util.c
ipc/util.c
+0
-10
kernel/exit.c
kernel/exit.c
+0
-3
kernel/fork.c
kernel/fork.c
+5
-4
kernel/ksyms.c
kernel/ksyms.c
+6
-0
kernel/sched.c
kernel/sched.c
+7
-0
mm/mmap.c
mm/mmap.c
+40
-22
mm/mprotect.c
mm/mprotect.c
+10
-0
mm/swap.c
mm/swap.c
+5
-1
net/inet/devinet.c
net/inet/devinet.c
+0
-36
net/inet/icmp.c
net/inet/icmp.c
+7
-2
net/inet/udp.c
net/inet/udp.c
+1
-1
No files found.
CREDITS
View file @
1b7a152c
...
...
@@ -733,6 +733,15 @@ S: 520 Edgemont Road
S: Charlottesville, Virginia 22903
S: USA
N: Matthias Urlichs
E: urlichs@noris.de
E: urlichs@smurf.sub.org
D: Consultant, developer, kernel hacker
D: Playing with Streams, ISDN, and BSD networking code for Linux
S: Schleiermacherstrasse 12
S: 90491 Nuernberg
S: Germany
N: Patrick Volkerding
E: volkerdi@ftp.cdrom.com
D: Produced the Slackware distribution, updated the SVGAlib
...
...
@@ -809,6 +818,7 @@ S: New York, New York 10025
S: USA
N: Eric Youngdale
E: eric@aib.com
E: ericy@cais.com
D: General kernel hacker
D: SCSI iso9660 and ELF
...
...
@@ -822,3 +832,10 @@ D: XFree86 and kernel development
S: 1507 145th Place SE #B5
S: Bellevue, Washington 98007
S: USA
N: Leonard N. Zubkoff
E: lnz@dandelion.com
D: XFree86 and BusLogic driver additions
S: 3078 Sulphur Spring Court
S: San Jose, California 95148
S: USA
Makefile
View file @
1b7a152c
VERSION
=
1
PATCHLEVEL
=
1
SUBLEVEL
=
6
1
SUBLEVEL
=
6
2
ARCH
=
i386
...
...
README
View file @
1b7a152c
Linux kernel release 1.
0
Linux kernel release 1.
1.xx
These are the release notes for linux version 1.
0
. Read them carefully,
These are the release notes for linux version 1.
1
. Read them carefully,
as they tell you what this is all about, explain how to install the
kernel, and what to do if something goes wrong.
Warning: This is a work in progress. If you are not reasonably at ease with
the C programming language, GCC, installing Linux, and recovering from
system crashes, please use the 1.0 version, or wait for 1.2.
WHAT IS LINUX?
Linux is a Unix clone for 386/486-based PCs written from scratch by
...
...
@@ -24,20 +28,24 @@ INSTALLING the kernel:
- If you install the full sources, do a
cd /usr/src
tar xvf linux-1.0.tar
gzip -cd linux-1.1.XX.tar.gz | tar xfv -
to get it all put in place.
to get it all put in place. Replace "XX" with the version number of the
latest kernel.
- if you install by patching, you need a *clean* 0.99.15 source tree,
which presumably exists in /usr/src/linux. If so, to get the kernel
patched, just do a
- Installing by patching is not worth the effort because the full set of
patches is bigger than a new kernel distribution. Instead, get the
latest full source archive and install as above. Then, get all newer
patch files, and do
cd /usr/src
patch -p0 < linux-1.0.patch
gzip -cd patchXX.gz | patch -p0
and you should be ok. You may want to remove the backup files (xxx~
or xxx.orig), and make sure that there are no failed patches (xxx# or
xxx.rej).
(repeat xx for all versions bigger than the version of your current
source tree, _in_order_) and you should be ok. You may want to remove
the backup files (xxx~ or xxx.orig), and make sure that there are no
failed patches (xxx# or xxx.rej). If there are, either you or me has
made a mistake.
- make sure your /usr/include/linux and /usr/include/asm directories
are just symlinks to the kernel sources:
...
...
@@ -88,10 +96,11 @@ CONFIGURING the kernel:
COMPILING the kernel:
- make sure you have gcc-2.
4.5
or newer available. It seems older gcc
- make sure you have gcc-2.
5.8
or newer available. It seems older gcc
versions can have problems compiling newer versions of linux. If you
upgrade your compiler, remember to get the new binutils package too
(for as/ld/nm and company)
(for as/ld/nm and company). Do not use gcc-2.6.0; it has a few serious
bugs.
- do a "make zImage" to create a compressed kernel image. If you want
to make a bootdisk (without root filesystem or lilo), insert a floppy
...
...
@@ -148,7 +157,7 @@ IF SOMETHING GOES WRONG:
unable to handle kernel paging request at address C0000010
Oops: 0002
EIP: 0010:
xxxxxxxx
EIP: 0010:
XXXXXXXX
eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx
esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx
ds: xxxx es: xxxx fs: xxxx gs: xxxx
...
...
@@ -194,3 +203,16 @@ IF SOMETHING GOES WRONG:
kernel image or similar), telling me as much about your setup as
possible will help.
- alternately, you can use gdb on a running kernel. (read-only; i.e. you
cannot change values or set break points.) To do this, first compile the
kernel with -g; edit arch/i386/Makefile appropriately, then do a "make
clean". You'll also need to enable CONFIG_PROC_FS (via "make config").
After you've rebooted with the new kernel, do "gdb tools/zSystem
/proc/kcore". You can now use all the usual gdb commands. The command to
look up the point where your system crashed is "l *0xXXXXXXXX". (Replace
the XXXes with the EIP value.)
gdb'ing a non-running kernel currently fails because gdb (wrongly)
disregards the starting offset for which the kernel is compiled.
arch/i386/config.in
View file @
1b7a152c
...
...
@@ -107,6 +107,7 @@ if [ "$CONFIG_NET_ISA" = "y" ]; then
bool 'AT1500 and NE2100 (LANCE and PCnet-ISA) support' CONFIG_LANCE n
bool 'Cabletron E21xx support (not recommended)' CONFIG_E2100 n
bool 'DEPCA support' CONFIG_DEPCA n
bool 'EtherWorks 3 support' CONFIG_EWRK3 n
if [ "$CONFIG_NET_ALPHA" = "y" ]; then
bool 'EtherExpress support' CONFIG_EEXPRESS n
bool 'AT1700 support' CONFIG_AT1700 n
...
...
drivers/block/cdu31a.c
View file @
1b7a152c
...
...
@@ -2787,6 +2787,9 @@ cdu31a_init(unsigned long mem_start, unsigned long mem_end)
}
else
if
(
sony_cd_base_io
!=
0
)
{
tmp_irq
=
irq_used
;
/* Need IRQ 0 because we can't sleep here. */
irq_used
=
0
;
get_drive_configuration
(
sony_cd_base_io
,
drive_config
.
exec_status
,
&
res_size
);
...
...
@@ -2794,9 +2797,12 @@ cdu31a_init(unsigned long mem_start, unsigned long mem_end)
{
drive_found
=
1
;
}
irq_used
=
tmp_irq
;
}
else
{
irq_used
=
0
;
i
=
0
;
while
(
(
cdu31a_addresses
[
i
].
base
!=
0
)
&&
(
!
drive_found
))
...
...
@@ -2844,12 +2850,18 @@ cdu31a_init(unsigned long mem_start, unsigned long mem_end)
tmp_irq
=
autoirq_report
(
10
);
disable_interrupts
();
irq_used
=
0
;
set_drive_params
();
irq_used
=
tmp_irq
;
}
else
{
tmp_irq
=
irq_used
;
/* Need IRQ 0 because we can't sleep here. */
irq_used
=
0
;
set_drive_params
();
irq_used
=
tmp_irq
;
}
if
(
irq_used
>
0
)
...
...
drivers/block/floppy.c
View file @
1b7a152c
...
...
@@ -2628,7 +2628,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
case
FDCLRPRM
:
LOCK_FDC
(
drive
,
1
);
current_type
[
drive
]
=
NULL
;
floppy_sizes
[
drive
]
=
2
;
floppy_sizes
[
drive
]
=
MAX_DISK_SIZE
;
UDRS
->
keep_data
=
0
;
return
invalidate_drive
(
device
);
case
FDFMTEND
:
...
...
@@ -3159,7 +3159,6 @@ static int floppy_grab_irq_and_dma(void)
static
void
floppy_release_irq_and_dma
(
void
)
{
int
i
;
cli
();
if
(
--
usage_count
){
sti
();
...
...
@@ -3170,7 +3169,9 @@ static void floppy_release_irq_and_dma(void)
free_dma
(
FLOPPY_DMA
);
disable_irq
(
FLOPPY_IRQ
);
free_irq
(
FLOPPY_IRQ
);
/* switch off dma gates */
for
(
i
=
0
;
i
<
N_FDC
;
i
++
)
set_dor
(
i
,
~
8
,
0
);
set_dor
(
0
,
~
0
,
8
);
#if N_FDC > 1
if
(
fdc
.
address
!=
-
1
)
set_dor
(
1
,
~
8
,
0
);
#endif
}
drivers/char/ChangeLog
View file @
1b7a152c
Wed Nov 2 10:32:36 1994 Theodore Y. Ts'o (tytso@rt-11)
* n_tty.c (n_tty_receive_room): Only allow excess characters
through if we are in ICANON mode *and* there are other no
pending lines in the buffer. Otherwise cut and paste over
4k breaks.
Sat Oct 29 18:17:34 1994 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_ioctl, get_lsr_info): Added patch suggested by Arne
...
...
drivers/char/n_tty.c
View file @
1b7a152c
...
...
@@ -585,11 +585,12 @@ static int n_tty_receive_room(struct tty_struct *tty)
int
left
=
N_TTY_BUF_SIZE
-
tty
->
read_cnt
-
1
;
/*
* If we are doing input canonicalization, let as many
* characters through as possible, so that the excess
* characters can be "beeped".
* If we are doing input canonicalization, and there are no
* pending newlines, let characters through without limit, so
* that erase characters will be handled. Other excess
* characters will be beeped.
*/
if
(
L_ICANON
(
tty
)
)
if
(
tty
->
icanon
&&
!
tty
->
canon_data
)
return
N_TTY_BUF_SIZE
;
if
(
left
>
0
)
...
...
drivers/char/tty_io.c
View file @
1b7a152c
...
...
@@ -1009,6 +1009,12 @@ static void release_dev(struct file * filp)
(
tty
->
ldisc
.
close
)(
tty
);
tty
->
ldisc
=
ldiscs
[
N_TTY
];
tty
->
termios
->
c_line
=
N_TTY
;
if
(
o_tty
)
{
if
(
o_tty
->
ldisc
.
close
)
(
o_tty
->
ldisc
.
close
)(
o_tty
);
o_tty
->
ldisc
=
ldiscs
[
N_TTY
];
o_tty
->
termios
->
c_line
=
N_TTY
;
}
tty
->
driver
.
table
[
idx
]
=
NULL
;
if
(
tty
->
driver
.
flags
&
TTY_DRIVER_RESET_TERMIOS
)
{
...
...
drivers/scsi/README.st
View file @
1b7a152c
This
file
contains
brief
information
about
the
SCSI
tape
driver
.
Last
modified:
Wed
Jun
22
23
:
38
:
47
1994
by
root@
kai
.
home
Last
modified:
Sun
Oct
16
19
:
20
:
03
1994
by
root@
kai
.
home
BASICS
...
...
@@ -78,7 +78,10 @@ MTBSF Space backward over count filemarks. Tape positioned before
MTBSFM
As
above
but
ape
positioned
after
filemark
.
MTFSR
Space
forward
over
count
records
.
MTBSR
Space
backward
over
count
records
.
MTFSS
Space
forward
over
count
setmarks
.
MTBSS
Space
backward
over
coutn
setmarks
.
MTWEOF
Write
count
filemarks
.
MTWSM
Write
count
setmarks
.
MTREW
Rewind
tape
.
MTOFFL
Set
device
off
line
(
often
rewind
plus
eject
).
MTNOP
Do
nothing
except
flush
the
buffers
.
...
...
@@ -125,9 +128,8 @@ MTIOCGET Returns some status information.
The
current
block
size
and
the
density
code
are
stored
in
the
field
mt_dsreg
(
shifts
for
the
subfields
are
MT_ST_BLKSIZE_SHIFT
and
MT_ST_DENSITY_SHIFT
).
The
write
protect
bit
in
mt_gstat
is
set
if
the
tape
is
write
protected
.
The
other
fields
are
empty
.
The
WR_PROT,
BOT
,
EOF
,
EOT
,
EOD
,
and
D_
[
800
,
1600
,
6250
]
_
BPI
status
bits
reflect
the
tape
status
.
The
other
bits
are
not
used
.
MISCELLANEOUS
COMPILE
OPTIONS
...
...
drivers/scsi/fdomain.c
View file @
1b7a152c
/* fdomain.c -- Future Domain TMC-16x0 SCSI driver
* Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu
* Revised:
Sat Jul 30 22:06:37
1994 by faith@cs.unc.edu
* Revised:
Wed Nov 2 16:37:58
1994 by faith@cs.unc.edu
* Author: Rickard E. Faith, faith@cs.unc.edu
* Copyright 1992, 1993, 1994 Rickard E. Faith
*
* $Id: fdomain.c,v 5.
18 1994/07/31 03:09:15 faith
Exp $
* $Id: fdomain.c,v 5.
20 1994/11/02 21:38:33 root
Exp $
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
...
...
@@ -38,10 +38,20 @@
signature, then the driver may fail to function after the board is
detected.
The following BIOS versions are supported: 2.0, 3.0, 3.2,
and 3.4
.
The following BIOS versions are supported: 2.0, 3.0, 3.2,
3.4, and 3.5
.
The following chips are supported: TMC-1800, TMC-18C50, TMC-18C30.
Reports suggest that the driver will also work with the 36C70 chip.
Please note that the drive ordering that Future Domain implemented in BIOS
versions 3.4 and 3.5 is the opposite of the order (currently) used by the
rest of the SCSI industry. If you have BIOS version 3.4 or 3.5, and have
more then one drive, then the drive ordering will be the reverse of that
which you see under DOS. For example, under DOS SCSI ID 0 will be D: and
SCSI ID 1 will be C: (the boot device). Under Linux, SCSI ID 0 will be
/dev/sda and SCSI ID 1 will be /dev/sdb. The Linux ordering is consistent
with that provided by all the other SCSI drivers for Linux. If you want
this changed, send me patches that are protected by #ifdefs.
If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
your board. Please refer to the Seagate driver for more information and
possible support.
...
...
@@ -120,6 +130,9 @@
patches that support the TMC-3260, a PCI bus card with the 36C70 chip.
The 36C70 chip appears to be "completely compatible" with the 18C30 chip.
Thanks to Eric Kasten (tigger@petroglyph.cl.msu.edu) for providing the
patch for the version 3.5 BIOS.
All of the alpha testers deserve much thanks.
...
...
@@ -133,14 +146,14 @@
devices support parity, then you can probably get the driver to work by
turning this option off. I have no way of testing this, however.
FIFO_COUNT: The host adapter has an 8K cache
. When this many 512 byt
e
blocks are filled by the SCSI device, an interrupt will be raised.
Therefore, this could be as low as 0, or as high as 16. Note, however,
that values which are too high or too low seem to prevent any interrupts
from occuring, and thereby lock up the machine. I have found that 2 is a
good number, but throughput may be increased by changing this value to
values which are close to 2. Please let me know if you try any different
values.
FIFO_COUNT: The host adapter has an 8K cache
(host adapters based on th
e
18C30 chip have a 2k cache). When this many 512 byte blocks are filled by
the SCSI device, an interrupt will be raised. Therefore, this could be as
low as 0, or as high as 16. Note, however, that values which are too high
or too low seem to prevent any interrupts from occuring, and thereby lock
up the machine. I have found that 2 is a good number, but throughput may
be increased by changing this value to values which are close to 2.
Please let me know if you try any different
values.
DO_DETECT: This activates some old scan code which was needed before the
high level drivers got fixed. If you are having trouble with the driver,
...
...
@@ -150,11 +163,11 @@
RESELECTION: This is no longer an option, since I gave up trying to
implement it in version 4.x of this driver. It did not improve
performance at all and made the driver unstable (because I never found one
of the two race conditions which were introduced by
multiple outstanding
commands). The instability seems a very high price to pay just so that
you don't have to wait for the tape to rewind. When I have time, I will
work on this again. In the interim, if anyone wants to work on the code,
I can give them my latest version
.
of the two race conditions which were introduced by
the multiple
outstanding command code). The instability seems a very high price to pay
just so that you don't have to wait for the tape to rewind. If you want
this feature implemented, send me patches. I'll be happy to send a copy
of my (broken) driver to anyone who would like to see a copy
.
**************************************************************************/
...
...
@@ -169,7 +182,7 @@
#include <linux/string.h>
#include <linux/ioport.h>
#define VERSION "$Revision: 5.
18
$"
#define VERSION "$Revision: 5.
20
$"
/* START OF USER DEFINABLE OPTIONS */
...
...
@@ -292,7 +305,9 @@ static void *addresses[] = {
(
void
*
)
0xc8000
,
(
void
*
)
0xca000
,
(
void
*
)
0xce000
,
(
void
*
)
0xde000
};
(
void
*
)
0xde000
,
(
void
*
)
0xd0000
,
/* Extra addresses for PCI boards */
};
#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
static
unsigned
short
ports
[]
=
{
0x140
,
0x150
,
0x160
,
0x170
};
...
...
@@ -341,6 +356,7 @@ struct signature {
{
"FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92"
,
5
,
44
,
3
,
0
,
0
},
{
"FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93"
,
5
,
44
,
3
,
2
,
0
},
{
"Future Domain Corp. V1.0008/18/93"
,
5
,
33
,
3
,
4
,
0
},
{
"FUTURE DOMAIN CORP. V3.5008/18/93"
,
5
,
34
,
3
,
5
,
0
},
{
"Future Domain Corp. V1.0008/18/93"
,
26
,
33
,
3
,
4
,
1
},
{
"FUTURE DOMAIN TMC-18XX"
,
5
,
22
,
-
1
,
-
1
,
0
},
...
...
@@ -459,11 +475,15 @@ static int fdomain_is_valid_port( int port )
#endif
/* Check for board with lowest bios_base --
this isn't valid for the 18c30, so just
assume we have the right board. */
this isn't valid for the 18c30 or for
boards on the PCI bus, so just assume we
have the right board. */
if
(
chip
!=
tmc18c30
&&
addresses
[
(
options
&
0xc0
)
>>
6
]
!=
bios_base
)
return
0
;
if
(
chip
!=
tmc18c30
&&
!
PCI_bus
&&
addresses
[
(
options
&
0xc0
)
>>
6
]
!=
bios_base
)
return
0
;
/* Get the IRQ from the options. */
interrupt_level
=
ints
[
(
options
&
0x0e
)
>>
1
];
...
...
@@ -587,18 +607,15 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
}
}
else
{
/* The proper way of doing this is to use the PCI BIOS call
(interrupt 0x1a) to determine the device IRQ and interrupt
level. Then the port_base will be in configuration register
0x10 (and configuration register 0x30 will contain the value of
bios_base).
/* The proper way of doing this is to use ask the PCI bus for the
device IRQ and interrupt level.
Until the Linux kernel supports this sort of PCI bus query, we
scan down a bunch of addresses (Future Domain
folks say we
should find the address before we get to 0xf800). This works
fine on some systems -- other systems may have to scan more
addresses. If you have to modify this section for you
r
installation, please send mail to faith@cs.unc.edu. */
scan down a bunch of addresses (Future Domain
tech support says
we will probably find the address before we get to 0xf800).
This works fine on some systems -- other systems may have to
scan more addresses. If you have to modify this section fo
r
your
installation, please send mail to faith@cs.unc.edu. */
for
(
i
=
0xff00
;
!
flag
&&
i
>
0xf000
;
i
-=
8
)
{
port_base
=
i
;
...
...
@@ -798,6 +815,7 @@ static int fdomain_select( int target )
{
int
status
;
unsigned
long
timeout
;
static
int
flag
=
0
;
outb
(
0x82
,
SCSI_Cntl_port
);
/* Bus Enable + Select */
...
...
@@ -806,11 +824,9 @@ static int fdomain_select( int target )
/* Stop arbitration and enable parity */
outb
(
PARITY_MASK
,
TMC_Cntl_port
);
#if 0
timeout = jiffies + 25; /* 250mS */
#else
timeout
=
jiffies
+
35
;
/* 350mS -- because of timeouts */
#endif
timeout
=
jiffies
+
35
;
/* 350mS -- because of timeouts
(was 250mS) */
while
(
jiffies
<
timeout
)
{
status
=
inb
(
SCSI_Status_port
);
/* Read adapter status */
if
(
status
&
1
)
{
/* Busy asserted */
...
...
@@ -825,7 +841,12 @@ static int fdomain_select( int target )
if
(
!
target
)
printk
(
"Selection failed
\n
"
);
#endif
#if ERRORS_ONLY
if
(
!
target
)
printk
(
"Future Domain: Selection failed
\n
"
);
if
(
!
target
)
{
if
(
chip
==
tmc18c30
&&
!
flag
)
/* Skip first failure for 18C30 chips. */
++
flag
;
else
printk
(
"Future Domain: Selection failed
\n
"
);
}
#endif
return
1
;
}
...
...
drivers/scsi/scsi.c
View file @
1b7a152c
...
...
@@ -157,6 +157,7 @@ static struct blist blacklist[] =
* controller, which causes SCSI code to reset bus.*/
{
"QUANTUM"
,
"LPS525S"
,
"3110"
},
/* Locks sometimes if polled for lun != 0 */
{
"QUANTUM"
,
"PD1225S"
,
"3110"
},
/* Locks sometimes if polled for lun != 0 */
{
"MEDIAVIS"
,
"CDR-H93MV"
,
"1.31"
},
/* Locks up if polled for lun != 0 */
{
NULL
,
NULL
,
NULL
}};
static
int
blacklisted
(
unsigned
char
*
response_data
){
...
...
drivers/scsi/st.c
View file @
1b7a152c
...
...
@@ -11,7 +11,7 @@
Copyright 1992, 1993, 1994 Kai Makisara
email makisara@vtinsx.ins.vtt.fi or Kai.Makisara@vtt.fi
Last modified:
Wed Jun 22 23:37:10
1994 by root@kai.home
Last modified:
Tue Oct 25 19:37:33
1994 by root@kai.home
*/
#include <linux/fs.h>
...
...
@@ -415,6 +415,7 @@ scsi_tape_open(struct inode * inode, struct file * filp)
STp
->
dirty
=
0
;
STp
->
rw
=
ST_IDLE
;
if
(
STp
->
eof
!=
ST_EOD
)
/* Save EOD across opens */
STp
->
eof
=
ST_NOEOF
;
STp
->
eof_hit
=
0
;
STp
->
recover_count
=
0
;
...
...
@@ -450,6 +451,7 @@ scsi_tape_open(struct inode * inode, struct file * filp)
if
(
SCpnt
->
request
.
dev
==
dev
)
sleep_on
(
&
(
STp
->
waiting
)
);
(
STp
->
mt_status
)
->
mt_fileno
=
STp
->
drv_block
=
0
;
STp
->
eof
=
ST_NOEOF
;
}
if
((
STp
->
buffer
)
->
last_result_fatal
!=
0
)
{
...
...
@@ -601,7 +603,7 @@ scsi_tape_close(struct inode * inode, struct file * filp)
#ifdef DEBUG
if
(
debugging
)
printk
(
"st%d: File length %ld bytes.
\n
"
,
dev
,
filp
->
f_pos
);
printk
(
"st%d: File length %ld bytes.
\n
"
,
dev
,
(
long
)(
filp
->
f_pos
)
);
#endif
if
(
result
==
0
||
result
==
(
-
ENOSPC
))
{
...
...
@@ -1053,6 +1055,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count)
printk
(
"st%d: Zero returned for first BLANK CHECK after EOF.
\n
"
,
dev
);
#endif
STp
->
eof
=
ST_EOD
;
return
0
;
/* First BLANK_CHECK after EOF */
}
else
...
...
@@ -1098,7 +1101,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count)
STp
->
eof_hit
=
1
;
SCpnt
->
request
.
dev
=
-
1
;
/* Mark as not busy */
if
(
total
==
0
&&
STp
->
eof
==
ST_FM
)
{
STp
->
eof
=
0
;
STp
->
eof
=
ST_NOEOF
;
STp
->
drv_block
=
0
;
if
(
STp
->
moves_after_eof
>
1
)
STp
->
moves_after_eof
=
0
;
...
...
@@ -1253,18 +1256,58 @@ st_int_ioctl(struct inode * inode,struct file * file,
if
(
blkno
>=
0
)
blkno
-=
arg
;
break
;
case
MTFSS
:
cmd
[
0
]
=
SPACE
;
cmd
[
1
]
=
0x04
;
/* Space Setmarks */
cmd
[
2
]
=
(
arg
>>
16
);
cmd
[
3
]
=
(
arg
>>
8
);
cmd
[
4
]
=
arg
;
#ifdef DEBUG
if
(
debugging
)
printk
(
"st%d: Spacing tape forward %d setmarks.
\n
"
,
dev
,
cmd
[
2
]
*
65536
+
cmd
[
3
]
*
256
+
cmd
[
4
]);
#endif
if
(
arg
!=
0
)
blkno
=
fileno
=
(
-
1
);
break
;
case
MTBSS
:
cmd
[
0
]
=
SPACE
;
cmd
[
1
]
=
0x04
;
/* Space Setmarks */
ltmp
=
(
-
arg
);
cmd
[
2
]
=
(
ltmp
>>
16
);
cmd
[
3
]
=
(
ltmp
>>
8
);
cmd
[
4
]
=
ltmp
;
#ifdef DEBUG
if
(
debugging
)
{
if
(
cmd
[
2
]
&
0x80
)
ltmp
=
0xff000000
;
ltmp
=
ltmp
|
(
cmd
[
2
]
<<
16
)
|
(
cmd
[
3
]
<<
8
)
|
cmd
[
4
];
printk
(
"st%d: Spacing tape backward %ld setmarks.
\n
"
,
dev
,
(
-
ltmp
));
}
#endif
if
(
arg
!=
0
)
blkno
=
fileno
=
(
-
1
);
break
;
case
MTWEOF
:
case
MTWSM
:
if
(
STp
->
write_prot
)
return
(
-
EACCES
);
cmd
[
0
]
=
WRITE_FILEMARKS
;
if
(
cmd_in
==
MTWSM
)
cmd
[
1
]
=
2
;
cmd
[
2
]
=
(
arg
>>
16
);
cmd
[
3
]
=
(
arg
>>
8
);
cmd
[
4
]
=
arg
;
timeout
=
ST_TIMEOUT
;
#ifdef DEBUG
if
(
debugging
)
if
(
debugging
)
{
if
(
cmd_in
==
MTWEOF
)
printk
(
"st%d: Writing %d filemarks.
\n
"
,
dev
,
cmd
[
2
]
*
65536
+
cmd
[
3
]
*
256
+
cmd
[
4
]);
else
printk
(
"st%d: Writing %d setmarks.
\n
"
,
dev
,
cmd
[
2
]
*
65536
+
cmd
[
3
]
*
256
+
cmd
[
4
]);
}
#endif
fileno
+=
arg
;
blkno
=
0
;
...
...
@@ -1503,9 +1546,12 @@ st_int_ioctl(struct inode * inode,struct file * file,
else
STp
->
drv_block
=
(
-
1
);
}
if
(
STp
->
eof
==
ST_NOEOF
&&
(
SCpnt
->
sense_buffer
[
2
]
&
0x0f
)
==
BLANK_CHECK
)
STp
->
eof
=
ST_EOD
;
}
return
ioctl_result
;
return
ioctl_result
;
}
...
...
@@ -1576,9 +1622,26 @@ st_ioctl(struct inode * inode,struct file * file,
(
STp
->
mt_status
)
->
mt_blkno
-=
((
STp
->
buffer
)
->
buffer_bytes
+
STp
->
block_size
-
1
)
/
STp
->
block_size
;
}
(
STp
->
mt_status
)
->
mt_gstat
=
0
;
if
(
STp
->
drv_write_prot
)
(
STp
->
mt_status
)
->
mt_gstat
|=
GMT_WR_PROT
(
0xffffffff
);
if
((
STp
->
mt_status
)
->
mt_blkno
==
0
)
{
if
((
STp
->
mt_status
)
->
mt_fileno
==
0
)
(
STp
->
mt_status
)
->
mt_gstat
|=
GMT_BOT
(
0xffffffff
);
else
(
STp
->
mt_status
)
->
mt_gstat
|=
GMT_EOF
(
0xffffffff
);
}
if
(
STp
->
eof
==
ST_EOM_OK
||
STp
->
eof
==
ST_EOM_ERROR
)
(
STp
->
mt_status
)
->
mt_gstat
|=
GMT_EOT
(
0xffffffff
);
else
if
(
STp
->
eof
==
ST_EOD
)
(
STp
->
mt_status
)
->
mt_gstat
|=
GMT_EOD
(
0xffffffff
);
if
(
STp
->
density
==
1
)
(
STp
->
mt_status
)
->
mt_gstat
|=
GMT_D_800
(
0xffffffff
);
else
if
(
STp
->
density
==
2
)
(
STp
->
mt_status
)
->
mt_gstat
|=
GMT_D_1600
(
0xffffffff
);
else
if
(
STp
->
density
==
3
)
(
STp
->
mt_status
)
->
mt_gstat
|=
GMT_D_6250
(
0xffffffff
);
memcpy_tofs
((
char
*
)
arg
,
(
char
*
)(
STp
->
mt_status
),
sizeof
(
struct
mtget
));
...
...
drivers/scsi/st.h
View file @
1b7a152c
...
...
@@ -55,6 +55,7 @@ typedef struct {
#define ST_FM 1
#define ST_EOM_OK 2
#define ST_EOM_ERROR 3
#define ST_EOD 4
/* Values of rw */
#define ST_IDLE 0
...
...
drivers/sound/configure.c
View file @
1b7a152c
...
...
@@ -112,7 +112,7 @@ hw_entry hw_table[] =
{
B
(
OPT_SB
),
B
(
OPT_PAS
),
"SBPRO"
,
1
,
0
,
1
},
{
B
(
OPT_SB
)
|
B
(
OPT_SBPRO
),
B
(
OPT_PAS
),
"SB16"
,
1
,
0
,
1
},
{
B
(
OPT_PSS
)
|
B
(
OPT_SB
)
|
B
(
OPT_PAS
)
|
B
(
OPT_GUS
),
0
,
"AUDIO"
,
1
,
0
,
1
},
{
B
(
OPT_PSS
)
|
B
(
OPT_SB
)
|
B
(
OPT_PAS
)
|
B
(
OPT_GUS
)
|
B
(
OPT_MSS
)
,
0
,
"AUDIO"
,
1
,
0
,
1
},
{
B
(
OPT_MPU401
),
0
,
"MIDI_AUTO"
,
0
,
OPT_MIDI
,
0
},
{
B
(
OPT_PSS
)
|
B
(
OPT_SB
)
|
B
(
OPT_PAS
)
|
B
(
OPT_MPU401
)
|
B
(
OPT_GUS
),
0
,
"MIDI"
,
1
,
0
,
1
},
{
B
(
OPT_ADLIB
),
0
,
"YM3812_AUTO"
,
0
,
OPT_YM3812
,
0
},
...
...
drivers/sound/soundcard.c
View file @
1b7a152c
...
...
@@ -43,9 +43,15 @@ static struct fileinfo files[SND_NDEVS];
int
snd_ioctl_return
(
int
*
addr
,
int
value
)
{
int
error
;
if
(
value
<
0
)
return
value
;
error
=
verify_area
(
VERIFY_WRITE
,
addr
,
sizeof
(
int
));
if
(
error
)
return
error
;
PUT_WORD_TO_USER
(
addr
,
0
,
value
);
return
0
;
}
...
...
fs/block_dev.c
View file @
1b7a152c
...
...
@@ -31,6 +31,7 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
unsigned
int
dev
;
struct
buffer_head
*
bh
,
*
bufferlist
[
NBUF
];
register
char
*
p
;
int
excess
;
write_error
=
buffercount
=
0
;
dev
=
inode
->
i_rdev
;
...
...
@@ -86,8 +87,9 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
blocks
=
read_ahead
[
MAJOR
(
dev
)]
/
(
blocksize
>>
9
)
/
2
;
if
(
block
+
blocks
>
size
)
blocks
=
size
-
block
;
if
(
blocks
>
NBUF
)
blocks
=
NBUF
;
blocks
-=
(
block
%
blocks_per_cluster
);
if
(
!
blocks
)
blocks
=
1
;
excess
=
(
block
+
blocks
)
%
blocks_per_cluster
;
if
(
blocks
>
excess
)
blocks
-=
excess
;
bhlist
[
0
]
=
bh
;
for
(
i
=
1
;
i
<
blocks
;
i
++
){
if
(((
i
+
block
)
%
blocks_per_cluster
)
==
0
)
{
...
...
@@ -102,6 +104,7 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
};
ll_rw_block
(
READ
,
blocks
,
bhlist
);
for
(
i
=
1
;
i
<
blocks
;
i
++
)
brelse
(
bhlist
[
i
]);
wait_on_buffer
(
bh
);
};
};
...
...
@@ -168,6 +171,7 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count)
loff_t
size
;
unsigned
int
dev
;
int
read
;
int
excess
;
dev
=
inode
->
i_rdev
;
blocksize
=
BLOCK_SIZE
;
...
...
@@ -205,7 +209,9 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count)
if
(
filp
->
f_reada
)
{
if
(
blocks
<
read_ahead
[
MAJOR
(
dev
)]
/
(
blocksize
>>
9
))
blocks
=
read_ahead
[
MAJOR
(
dev
)]
/
(
blocksize
>>
9
);
blocks
-=
(
block
%
blocks_per_cluster
);
excess
=
(
block
+
blocks
)
%
blocks_per_cluster
;
if
(
blocks
>
excess
)
blocks
-=
excess
;
if
(
rblocks
>
blocks
)
blocks
=
rblocks
;
...
...
fs/exec.c
View file @
1b7a152c
...
...
@@ -50,8 +50,6 @@
asmlinkage
int
sys_exit
(
int
exit_code
);
asmlinkage
int
sys_brk
(
unsigned
long
);
extern
void
shm_exit
(
void
);
static
int
load_aout_binary
(
struct
linux_binprm
*
,
struct
pt_regs
*
regs
);
static
int
load_aout_library
(
int
fd
);
static
int
aout_core_dump
(
long
signr
,
struct
pt_regs
*
regs
);
...
...
@@ -197,6 +195,8 @@ static int aout_core_dump(long signr, struct pt_regs * regs)
goto
end_coredump
;
if
(
!
inode
->
i_op
||
!
inode
->
i_op
->
default_file_ops
)
goto
end_coredump
;
if
(
get_write_access
(
inode
))
goto
end_coredump
;
file
.
f_mode
=
3
;
file
.
f_flags
=
0
;
file
.
f_count
=
1
;
...
...
@@ -206,7 +206,7 @@ static int aout_core_dump(long signr, struct pt_regs * regs)
file
.
f_op
=
inode
->
i_op
->
default_file_ops
;
if
(
file
.
f_op
->
open
)
if
(
file
.
f_op
->
open
(
inode
,
&
file
))
goto
end
_coredump
;
goto
done
_coredump
;
if
(
!
file
.
f_op
->
write
)
goto
close_coredump
;
has_dumped
=
1
;
...
...
@@ -273,6 +273,8 @@ static int aout_core_dump(long signr, struct pt_regs * regs)
close_coredump:
if
(
file
.
f_op
->
release
)
file
.
f_op
->
release
(
inode
,
&
file
);
done_coredump:
put_write_access
(
inode
);
end_coredump:
set_fs
(
fs
);
iput
(
inode
);
...
...
@@ -529,8 +531,6 @@ void flush_old_exec(struct linux_binprm * bprm)
current
->
comm
[
i
++
]
=
ch
;
}
current
->
comm
[
i
]
=
'\0'
;
if
(
current
->
shm
)
shm_exit
();
/* Release all of the old mmap stuff. */
mpnt
=
current
->
mm
->
mmap
;
...
...
@@ -636,6 +636,11 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
retval
=
-
EACCES
;
goto
exec_error2
;
}
/* better not execute files which are being written to */
if
(
bprm
.
inode
->
i_wcount
>
0
)
{
retval
=
-
ETXTBSY
;
goto
exec_error2
;
}
memset
(
bprm
.
buf
,
0
,
sizeof
(
bprm
.
buf
));
old_fs
=
get_fs
();
set_fs
(
get_ds
());
...
...
@@ -844,17 +849,15 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
goto
beyond_if
;
}
if
(
ex
.
a_text
)
{
error
=
do_mmap
(
file
,
N_TXTADDR
(
ex
),
ex
.
a_text
,
PROT_READ
|
PROT_EXEC
,
MAP_FIXED
|
MAP_SHARED
|
MAP_DENYWRITE
|
MAP_EXECUTABLE
,
MAP_FIXED
|
MAP_PRIVATE
|
MAP_DENYWRITE
|
MAP_EXECUTABLE
,
fd_offset
);
if
(
error
!=
N_TXTADDR
(
ex
))
{
sys_close
(
fd
);
send_sig
(
SIGSEGV
,
current
,
0
);
return
-
EINVAL
;
}
send_sig
(
SIGKILL
,
current
,
0
);
return
error
;
}
error
=
do_mmap
(
file
,
N_TXTADDR
(
ex
)
+
ex
.
a_text
,
ex
.
a_data
,
...
...
@@ -863,8 +866,8 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
fd_offset
+
ex
.
a_text
);
sys_close
(
fd
);
if
(
error
!=
N_TXTADDR
(
ex
)
+
ex
.
a_text
)
{
send_sig
(
SIG
SEGV
,
current
,
0
);
return
-
EINVAL
;
send_sig
(
SIG
KILL
,
current
,
0
);
return
error
;
}
}
beyond_if:
...
...
fs/ext2/CHANGES
View file @
1b7a152c
...
...
@@ -6,6 +6,12 @@ Changes from version 0.5 to version 0.5a
- The famous readdir() bug has been fixed by Stephen Tweedie.
- Added a revision level in the superblock.
- Full support for O_SYNC flag of the open system call.
- New mount options: `resuid=#uid' and `resgid=#gid'. `resuid' causes
ext2fs to consider user #uid like root for the reserved blocks.
`resgid' acts the same way with group #gid. New fields in the
superblock contain default values for resuid and resgid and can
be modified by tune2fs.
Idea comes from Rene Cougnenc <cougnenc@renux.frmug.fr.net>.
- New mount options: `bsddf' and `minixdf'. `bsddf' causes ext2fs
to remove the blocks used for FS structures from the total block
count in statfs. With `minixdf', ext2fs mimics Minix behavior
...
...
fs/ext2/balloc.c
View file @
1b7a152c
...
...
@@ -270,7 +270,10 @@ int ext2_new_block (struct super_block * sb, unsigned long goal,
}
lock_super
(
sb
);
es
=
sb
->
u
.
ext2_sb
.
s_es
;
if
(
es
->
s_free_blocks_count
<=
es
->
s_r_blocks_count
&&
!
fsuser
())
{
if
(
es
->
s_free_blocks_count
<=
es
->
s_r_blocks_count
&&
(
!
fsuser
()
&&
(
sb
->
u
.
ext2_sb
.
s_resuid
!=
current
->
fsuid
)
&&
(
sb
->
u
.
ext2_sb
.
s_resgid
==
0
||
!
in_group_p
(
sb
->
u
.
ext2_sb
.
s_resgid
))))
{
unlock_super
(
sb
);
return
0
;
}
...
...
fs/ext2/super.c
View file @
1b7a152c
...
...
@@ -173,6 +173,7 @@ static int convert_pre_02b_fs (struct super_block * sb,
* This function has been shamelessly adapted from the msdos fs
*/
static
int
parse_options
(
char
*
options
,
unsigned
long
*
sb_block
,
unsigned
short
*
resuid
,
unsigned
short
*
resgid
,
unsigned
long
*
mount_options
)
{
char
*
this_char
;
...
...
@@ -247,6 +248,32 @@ static int parse_options (char * options, unsigned long * sb_block,
else
if
(
!
strcmp
(
this_char
,
"nogrpid"
)
||
!
strcmp
(
this_char
,
"sysvgroups"
))
clear_opt
(
*
mount_options
,
GRPID
);
else
if
(
!
strcmp
(
this_char
,
"resgid"
))
{
if
(
!
value
||
!*
value
)
{
printk
(
"EXT2-fs: the resgid option requires "
"an argument"
);
return
0
;
}
*
resgid
=
simple_strtoul
(
value
,
&
value
,
0
);
if
(
*
value
)
{
printk
(
"EXT2-fs: Invalid resgid option: %s
\n
"
,
value
);
return
0
;
}
}
else
if
(
!
strcmp
(
this_char
,
"resuid"
))
{
if
(
!
value
||
!*
value
)
{
printk
(
"EXT2-fs: the resuid option requires "
"an argument"
);
return
0
;
}
*
resuid
=
simple_strtoul
(
value
,
&
value
,
0
);
if
(
*
value
)
{
printk
(
"EXT2-fs: Invalid resuid option: %s
\n
"
,
value
);
return
0
;
}
}
else
if
(
!
strcmp
(
this_char
,
"sb"
))
{
if
(
!
value
||
!*
value
)
{
printk
(
"EXT2-fs: the sb option requires "
...
...
@@ -367,6 +394,8 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
struct
buffer_head
*
bh
;
struct
ext2_super_block
*
es
;
unsigned
long
sb_block
=
1
;
unsigned
short
resuid
=
EXT2_DEF_RESUID
;
unsigned
short
resgid
=
EXT2_DEF_RESGID
;
unsigned
long
logic_sb_block
=
1
;
int
dev
=
sb
->
s_dev
;
int
db_count
;
...
...
@@ -376,7 +405,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
#endif
set_opt
(
sb
->
u
.
ext2_sb
.
s_mount_opt
,
CHECK_NORMAL
);
if
(
!
parse_options
((
char
*
)
data
,
&
sb_block
,
if
(
!
parse_options
((
char
*
)
data
,
&
sb_block
,
&
resuid
,
&
resgid
,
&
sb
->
u
.
ext2_sb
.
s_mount_opt
))
{
sb
->
s_dev
=
0
;
return
NULL
;
...
...
@@ -452,6 +481,14 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
sizeof
(
struct
ext2_group_desc
);
sb
->
u
.
ext2_sb
.
s_sbh
=
bh
;
sb
->
u
.
ext2_sb
.
s_es
=
es
;
if
(
resuid
!=
EXT2_DEF_RESUID
)
sb
->
u
.
ext2_sb
.
s_resuid
=
resuid
;
else
sb
->
u
.
ext2_sb
.
s_resuid
=
es
->
s_def_resuid
;
if
(
resgid
!=
EXT2_DEF_RESGID
)
sb
->
u
.
ext2_sb
.
s_resgid
=
resgid
;
else
sb
->
u
.
ext2_sb
.
s_resgid
=
es
->
s_def_resgid
;
sb
->
u
.
ext2_sb
.
s_mount_state
=
es
->
s_state
;
sb
->
u
.
ext2_sb
.
s_rename_lock
=
0
;
sb
->
u
.
ext2_sb
.
s_rename_wait
=
NULL
;
...
...
@@ -633,14 +670,22 @@ void ext2_write_super (struct super_block * sb)
int
ext2_remount
(
struct
super_block
*
sb
,
int
*
flags
,
char
*
data
)
{
struct
ext2_super_block
*
es
;
unsigned
short
resuid
=
sb
->
u
.
ext2_sb
.
s_resuid
;
unsigned
short
resgid
=
sb
->
u
.
ext2_sb
.
s_resgid
;
unsigned
long
new_mount_opt
;
unsigned
long
tmp
;
/*
* Allow the "check" option to be passed as a remount option.
*/
set_opt
(
sb
->
u
.
ext2_sb
.
s_mount_opt
,
CHECK_NORMAL
);
parse_options
(
data
,
&
tmp
,
&
sb
->
u
.
ext2_sb
.
s_mount_opt
);
if
(
!
parse_options
(
data
,
&
tmp
,
&
resuid
,
&
resgid
,
&
new_mount_opt
))
return
-
EINVAL
;
sb
->
u
.
ext2_sb
.
s_mount_opt
=
new_mount_opt
;
sb
->
u
.
ext2_sb
.
s_resuid
=
resuid
;
sb
->
u
.
ext2_sb
.
s_resgid
=
resgid
;
es
=
sb
->
u
.
ext2_sb
.
s_es
;
if
((
*
flags
&
MS_RDONLY
)
==
(
sb
->
s_flags
&
MS_RDONLY
))
return
0
;
...
...
fs/msdos/file.c
View file @
1b7a152c
...
...
@@ -22,6 +22,7 @@
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define PRINTK(x)
#define Printk(x) printk x
static
struct
file_operations
msdos_file_operations
=
{
NULL
,
/* lseek - default */
...
...
@@ -66,13 +67,14 @@ int msdos_file_read(
{
char
*
start
;
int
left
,
offset
,
size
,
cnt
;
#define MSDOS_PREFETCH 48
struct
{
int
to_reada
;
/* How many block to read all at once */
struct
buffer_head
*
bhreq
[
64
];
/* Buffers not already read */
int
nbreq
;
/* Number of buffers to read */
struct
buffer_head
*
bhlist
[
64
];
/* All buffers needed */
int
file_sector
;
/* Next sector to read in the prefetch table */
/* This is relative to the file, not the disk */
struct
buffer_head
*
bhlist
[
MSDOS_PREFETCH
];
/* All buffers needed */
int
nblist
;
/* Number of buffers in bhlist */
int
nolist
;
int
nolist
;
/* index in bhlist */
int
fetched_max
;
/* End of pre fetch area */
}
pre
;
int
i
;
...
...
@@ -89,59 +91,83 @@ int msdos_file_read(
if
(
filp
->
f_pos
>=
inode
->
i_size
||
count
<=
0
)
return
0
;
/*
Tell the buffer cache which block we expect to read in advance
Since we are limited with the stack, we preread only
64
Since we are limited with the stack, we preread only
MSDOS_PREFETCH
because we have to keep the result into the local
arrays pre.bhlist and pre.bhreq.
arrays pre.bhlist and bhreq.
Each time we process one block in bhlist, we replace
it by a new prefetch block if needed.
*/
PRINTK
((
"#### ino %ld pos %ld size %ld count %d
\n
"
,
inode
->
i_ino
,
filp
->
f_pos
,
inode
->
i_size
,
count
));
{
int
file_sector
=
filp
->
f_pos
>>
SECTOR_BITS
;
pre
.
to_reada
=
count
/
SECTOR_SIZE
;
struct
buffer_head
*
bhreq
[
MSDOS_PREFETCH
];
/* Buffers not */
/* already read */
int
nbreq
;
/* Number of buffers in bhreq */
/*
We must prefetch complete block, so we must
take in account the offset in the first block.
*/
int
count_max
=
(
filp
->
f_pos
&
(
SECTOR_SIZE
-
1
))
+
count
;
int
to_reada
;
/* How many block to read all at once */
pre
.
file_sector
=
filp
->
f_pos
>>
SECTOR_BITS
;
to_reada
=
count_max
/
SECTOR_SIZE
;
if
(
count_max
&
(
SECTOR_SIZE
-
1
))
to_reada
++
;
if
(
filp
->
f_reada
){
int
min_read
=
read_ahead
[
MAJOR
(
inode
->
i_dev
)];
if
(
min_read
>
pre
.
to_reada
)
pre
.
to_reada
=
min_read
;
if
(
min_read
>
to_reada
)
to_reada
=
min_read
;
}
if
(
pre
.
to_reada
>
64
)
pre
.
to_reada
=
64
;
pre
.
nbreq
=
pre
.
nblist
=
0
;
for
(
i
=
0
;
i
<
pre
.
to_reada
;
i
++
){
if
(
to_reada
>
MSDOS_PREFETCH
)
to_reada
=
MSDOS_PREFETCH
;
nbreq
=
pre
.
nblist
=
0
;
for
(
i
=
0
;
i
<
to_reada
;
i
++
){
int
sector
;
struct
buffer_head
*
bh
;
if
(
!
(
sector
=
msdos_smap
(
inode
,
file_sector
++
)))
break
;
if
(
!
(
sector
=
msdos_smap
(
inode
,
pre
.
file_sector
++
)))
break
;
PRINTK
((
"fsector1 %d -> %d
\n
"
,
pre
.
file_sector
-
1
,
sector
));
bh
=
getblk
(
inode
->
i_dev
,
sector
,
SECTOR_SIZE
);
if
(
bh
==
NULL
)
break
;
pre
.
bhlist
[
pre
.
nblist
++
]
=
bh
;
if
(
!
bh
->
b_uptodate
){
pre
.
bhreq
[
pre
.
nbreq
++
]
=
bh
;
bhreq
[
nbreq
++
]
=
bh
;
}
}
if
(
pre
.
nbreq
>
0
)
ll_rw_block
(
READ
,
pre
.
nbreq
,
pre
.
bhreq
);
pre
.
fetched_max
=
pre
.
file_sector
*
SECTOR_SIZE
;
if
(
nbreq
>
0
)
ll_rw_block
(
READ
,
nbreq
,
bhreq
);
}
start
=
buf
;
pre
.
nolist
=
0
;
while
((
left
=
MIN
(
inode
->
i_size
-
filp
->
f_pos
,
count
-
(
buf
-
start
)))
>
0
){
struct
buffer_head
*
bh
;
void
*
data
;
PRINTK
((
"file_read pos %d
\n
"
,
filp
->
f_pos
))
;
if
(
pre
.
nolist
>=
pre
.
nblist
){
/* This code is executed when more than 64 sectors */
/* are request at once */
struct
buffer_head
*
bh
=
pre
.
bhlist
[
pre
.
nolist
]
;
char
*
data
;
if
(
bh
==
NULL
)
break
;
PRINTK
((
"file_read pos %ld nblist %d %d %d
\n
"
,
filp
->
f_pos
,
pre
.
nblist
,
pre
.
fetched
,
count
));
pre
.
bhlist
[
pre
.
nolist
]
=
NULL
;
if
(
left
+
filp
->
f_pos
>
pre
.
fetched_max
){
int
sector
;
if
(
!
(
sector
=
msdos_smap
(
inode
,
filp
->
f_pos
>>
SECTOR_BITS
)))
break
;
if
(
!
(
bh
=
msdos_sread
(
inode
->
i_dev
,
sector
)))
break
;
if
((
sector
=
msdos_smap
(
inode
,
pre
.
file_sector
++
))){
struct
buffer_head
*
bhreq
[
1
];
PRINTK
((
"fsector2 %d -> %d
\n
"
,
pre
.
file_sector
-
1
,
sector
));
bhreq
[
0
]
=
getblk
(
inode
->
i_dev
,
sector
,
SECTOR_SIZE
);
if
(
bhreq
[
0
]
==
NULL
)
break
;
pre
.
bhlist
[
pre
.
nolist
]
=
bhreq
[
0
];
if
(
!
bhreq
[
0
]
->
b_uptodate
)
ll_rw_block
(
READ
,
1
,
bhreq
);
pre
.
fetched_max
+=
SECTOR_SIZE
;
}
else
{
bh
=
pre
.
bhlist
[
pre
.
nolist
];
pre
.
bhlist
[
pre
.
nolist
++
]
=
NULL
;
/* Stop prefetching further, we have reached eof */
pre
.
fetched_max
=
2000000000l
;
}
}
pre
.
nolist
++
;
if
(
pre
.
nolist
>=
pre
.
nblist
)
pre
.
nolist
=
0
;
wait_on_buffer
(
bh
);
if
(
!
bh
->
b_uptodate
){
/* read error ? */
brelse
(
bh
);
break
;
}
}
data
=
bh
->
b_data
;
offset
=
filp
->
f_pos
&
(
SECTOR_SIZE
-
1
);
filp
->
f_pos
+=
(
size
=
MIN
(
SECTOR_SIZE
-
offset
,
left
));
data
=
bh
->
b_data
;
if
(
MSDOS_I
(
inode
)
->
i_binary
)
{
memcpy_tofs
(
buf
,
data
+
offset
,
size
);
buf
+=
size
;
...
...
@@ -161,6 +187,7 @@ int msdos_file_read(
}
brelse
(
bh
);
}
PRINTK
((
"--- %d -> %d
\n
"
,
count
,(
int
)(
buf
-
start
)));
for
(
i
=
0
;
i
<
pre
.
nblist
;
i
++
)
brelse
(
pre
.
bhlist
[
i
]);
if
(
start
==
buf
)
return
-
EIO
;
if
(
!
IS_RDONLY
(
inode
))
...
...
fs/namei.c
View file @
1b7a152c
...
...
@@ -117,6 +117,38 @@ int permission(struct inode * inode,int mask)
return
0
;
}
/*
* get_write_access() gets write permission for a file.
* put_write_access() releases this write permission.
* This is used for regular files.
* We cannot support write (and maybe mmap read-write shared) accesses and
* MAP_DENYWRITE mmapings simultaneously.
*/
int
get_write_access
(
struct
inode
*
inode
)
{
struct
task_struct
**
p
;
if
((
inode
->
i_count
>
1
)
&&
S_ISREG
(
inode
->
i_mode
))
/* shortcut */
for
(
p
=
&
LAST_TASK
;
p
>
&
FIRST_TASK
;
--
p
)
{
struct
vm_area_struct
*
mpnt
;
if
(
!*
p
)
continue
;
for
(
mpnt
=
(
*
p
)
->
mm
->
mmap
;
mpnt
;
mpnt
=
mpnt
->
vm_next
)
{
if
(
inode
!=
mpnt
->
vm_inode
)
continue
;
if
(
mpnt
->
vm_flags
&
VM_DENYWRITE
)
return
-
ETXTBSY
;
}
}
inode
->
i_wcount
++
;
return
0
;
}
void
put_write_access
(
struct
inode
*
inode
)
{
inode
->
i_wcount
--
;
}
/*
* lookup() looks up one part of a pathname, using the fs-dependent
* routines (currently minix_lookup) for it. It also checks for
...
...
@@ -308,7 +340,6 @@ int open_namei(const char * pathname, int flag, int mode,
const
char
*
basename
;
int
namelen
,
error
;
struct
inode
*
dir
,
*
inode
;
struct
task_struct
**
p
;
mode
&=
S_IALLUGO
&
~
current
->
fs
->
umask
;
mode
|=
S_IFREG
;
...
...
@@ -380,23 +411,6 @@ int open_namei(const char * pathname, int flag, int mode,
return
-
EROFS
;
}
}
if
((
inode
->
i_count
>
1
)
&&
(
flag
&
2
))
{
for
(
p
=
&
LAST_TASK
;
p
>
&
FIRST_TASK
;
--
p
)
{
struct
vm_area_struct
*
mpnt
;
if
(
!*
p
)
continue
;
for
(
mpnt
=
(
*
p
)
->
mm
->
mmap
;
mpnt
;
mpnt
=
mpnt
->
vm_next
)
{
if
(
inode
!=
mpnt
->
vm_inode
)
continue
;
if
(
mpnt
->
vm_page_prot
&
PAGE_RW
)
continue
;
if
(
mpnt
->
vm_flags
&
VM_DENYWRITE
)
{
iput
(
inode
);
return
-
ETXTBSY
;
}
}
}
}
/*
* An append-only file must be opened in append mode for writing
*/
...
...
@@ -407,9 +421,14 @@ int open_namei(const char * pathname, int flag, int mode,
if
(
flag
&
O_TRUNC
)
{
struct
iattr
newattrs
;
if
((
error
=
get_write_access
(
inode
)))
{
iput
(
inode
);
return
error
;
}
newattrs
.
ia_size
=
0
;
newattrs
.
ia_valid
=
ATTR_SIZE
;
if
((
error
=
notify_change
(
inode
,
&
newattrs
)))
{
put_write_access
(
inode
);
iput
(
inode
);
return
error
;
}
...
...
@@ -417,6 +436,7 @@ int open_namei(const char * pathname, int flag, int mode,
if
(
inode
->
i_op
&&
inode
->
i_op
->
truncate
)
inode
->
i_op
->
truncate
(
inode
);
inode
->
i_dirt
=
1
;
put_write_access
(
inode
);
}
*
res_inode
=
inode
;
return
0
;
...
...
fs/nfs/proc.c
View file @
1b7a152c
...
...
@@ -77,25 +77,12 @@ static int nfs_stat_to_errno(int stat);
static
inline
int
*
nfs_rpc_alloc
(
int
size
)
{
#if 0
/* Allow for the NFS crap as well as buffer */
return (int *)kmalloc(size+NFS_SLACK_SPACE,GFP_KERNEL);
#else
/* If kmalloc fails, then we will give an EIO to user level.
(Please correct me, I am wron here... ??) This is not
desirable, but it is also not desirable to execute the
following code: Just loop until we get memory, call schedule(),
so that other processes are run inbetween (and hopefully give
some memory back). Florian
*/
int
*
i
;
while
(
!
(
i
=
(
int
*
)
kmalloc
(
size
+
NFS_SLACK_SPACE
,
GFP_KERNEL
)))
{
/* printk("NFS: call schedule\n"); */
while
(
!
(
i
=
(
int
*
)
kmalloc
(
size
+
NFS_SLACK_SPACE
,
GFP_NFS
)))
{
schedule
();
}
return
i
;
#endif
}
static
inline
void
nfs_rpc_free
(
int
*
p
)
...
...
fs/nfs/symlink.c
View file @
1b7a152c
...
...
@@ -71,16 +71,9 @@ static int nfs_follow_link(struct inode *dir, struct inode *inode,
}
error
=
nfs_proc_readlink
(
NFS_SERVER
(
inode
),
NFS_FH
(
inode
),
&
mem
,
&
res
,
&
len
,
NFS_MAXPATHLEN
);
#if 0
if ((res2 = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_KERNEL)) == NULL) {
printk("NFS: no memory in nfs_follow_link\n");
error = -EIO;
}
#else
while
((
res2
=
(
char
*
)
kmalloc
(
NFS_MAXPATHLEN
+
1
,
GFP_KERNEL
))
==
NULL
)
{
while
((
res2
=
(
char
*
)
kmalloc
(
NFS_MAXPATHLEN
+
1
,
GFP_NFS
))
==
NULL
)
{
schedule
();
}
#endif
if
(
error
)
{
iput
(
inode
);
iput
(
dir
);
...
...
fs/open.c
View file @
1b7a152c
...
...
@@ -86,6 +86,11 @@ asmlinkage int sys_truncate(const char * path, unsigned int length)
iput
(
inode
);
return
-
EPERM
;
}
error
=
get_write_access
(
inode
);
if
(
error
)
{
iput
(
inode
);
return
error
;
}
inode
->
i_size
=
newattrs
.
ia_size
=
length
;
if
(
inode
->
i_op
&&
inode
->
i_op
->
truncate
)
inode
->
i_op
->
truncate
(
inode
);
...
...
@@ -93,6 +98,7 @@ asmlinkage int sys_truncate(const char * path, unsigned int length)
newattrs
.
ia_valid
=
ATTR_SIZE
|
ATTR_CTIME
|
ATTR_MTIME
;
inode
->
i_dirt
=
1
;
error
=
notify_change
(
inode
,
&
newattrs
);
put_write_access
(
inode
);
iput
(
inode
);
return
error
;
}
...
...
@@ -320,14 +326,14 @@ asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
/*
* If the owner has been changed, remove the setuid bit
*/
if
(
user
!=
inode
->
i_uid
&&
inode
->
i_mode
&
S_ISUID
)
{
if
(
user
!=
inode
->
i_uid
&&
(
inode
->
i_mode
&
S_ISUID
)
)
{
newattrs
.
ia_mode
&=
~
S_ISUID
;
newattrs
.
ia_valid
|=
ATTR_MODE
;
}
/*
* If the group has been changed, remove the setgid bit
*/
if
(
group
!=
inode
->
i_gid
&&
inode
->
i_mode
&
S_ISGID
)
{
if
(
group
!=
inode
->
i_gid
&&
(
inode
->
i_mode
&
S_ISGID
)
)
{
newattrs
.
ia_mode
&=
~
S_ISGID
;
newattrs
.
ia_valid
|=
ATTR_MODE
;
}
...
...
@@ -352,6 +358,7 @@ asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
user
=
inode
->
i_uid
;
if
(
group
==
(
gid_t
)
-
1
)
group
=
inode
->
i_gid
;
newattrs
.
ia_mode
=
inode
->
i_mode
;
newattrs
.
ia_uid
=
user
;
newattrs
.
ia_gid
=
group
;
newattrs
.
ia_ctime
=
CURRENT_TIME
;
...
...
@@ -359,15 +366,15 @@ asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
/*
* If the owner has been changed, remove the setuid bit
*/
if
(
user
!=
inode
->
i_uid
&&
inode
->
i_mode
&
S_ISUID
)
{
newattrs
.
ia_mode
=
inode
->
i_mode
&
~
S_ISUID
;
if
(
user
!=
inode
->
i_uid
&&
(
inode
->
i_mode
&
S_ISUID
)
)
{
newattrs
.
ia_mode
&=
~
S_ISUID
;
newattrs
.
ia_valid
|=
ATTR_MODE
;
}
/*
* If the group has been changed, remove the setgid bit
*/
if
(
group
!=
inode
->
i_gid
&&
inode
->
i_mode
&
S_ISGID
)
{
newattrs
.
ia_mode
=
inode
->
i_mode
&
~
S_ISGID
;
if
(
group
!=
inode
->
i_gid
&&
(
inode
->
i_mode
&
S_ISGID
)
)
{
newattrs
.
ia_mode
&=
~
S_ISGID
;
newattrs
.
ia_valid
|=
ATTR_MODE
;
}
inode
->
i_dirt
=
1
;
...
...
@@ -413,6 +420,8 @@ int do_open(const char * filename,int flags,int mode)
if
(
flag
&
(
O_TRUNC
|
O_CREAT
))
flag
|=
2
;
error
=
open_namei
(
filename
,
flag
,
mode
,
&
inode
,
NULL
);
if
(
!
error
&&
(
f
->
f_mode
&
2
))
error
=
get_write_access
(
inode
);
if
(
error
)
{
current
->
files
->
fd
[
fd
]
=
NULL
;
f
->
f_count
--
;
...
...
@@ -428,6 +437,7 @@ int do_open(const char * filename,int flags,int mode)
if
(
f
->
f_op
&&
f
->
f_op
->
open
)
{
error
=
f
->
f_op
->
open
(
inode
,
f
);
if
(
error
)
{
if
(
f
->
f_mode
&
2
)
put_write_access
(
inode
);
iput
(
inode
);
f
->
f_count
--
;
current
->
files
->
fd
[
fd
]
=
NULL
;
...
...
@@ -475,6 +485,7 @@ int close_fp(struct file *filp, unsigned int fd)
filp
->
f_op
->
release
(
inode
,
filp
);
filp
->
f_count
--
;
filp
->
f_inode
=
NULL
;
if
(
filp
->
f_mode
&
2
)
put_write_access
(
inode
);
iput
(
inode
);
return
0
;
}
...
...
fs/sysv/INTRO
View file @
1b7a152c
...
...
@@ -178,12 +178,6 @@ These filesystems are rather similar. Here is a comparison with Minix FS:
Notation: We often speak of a "block" but mean a zone (the allocation unit)
and not the disk driver's notion of "block".
Because the block size may be smaller than 1024 (which is the unit used by
the disk drivers and the buffer code), many functions must return a pointer
to the buffer data additionally to the buffer head pointer. One must not
assume that the entire buffer is occupied by this single block. This makes
the implementation of truncate() difficult.
Bruno Haible <haible@ma2s2.mathematik.uni-karlsruhe.de>
fs/sysv/Makefile
View file @
1b7a152c
...
...
@@ -15,7 +15,7 @@
$(AS)
-o
$*
.o
$<
OBJS
=
ialloc.o balloc.o inode.o file.o dir.o symlink.o namei.o
\
fsync.o truncate.o
mmap.o
fsync.o truncate.o
sysv.o
:
$(OBJS)
$(LD)
-r
-o
sysv.o
$(OBJS)
...
...
fs/sysv/README
View file @
1b7a152c
...
...
@@ -4,7 +4,7 @@ It implements all of
- SystemV/386 FS,
- Coherent FS.
This is version beta
3
.
This is version beta
4
.
To install:
* Answer the 'System V and Coherent filesystem support' question with 'y'
...
...
fs/sysv/balloc.c
View file @
1b7a152c
...
...
@@ -26,7 +26,7 @@
#include <linux/locks.h>
/* We don't trust the value of
sb->sv_sbd->s_tfree = *sb->sv_sb_total_free_blocks
sb->sv_sbd
2
->s_tfree = *sb->sv_sb_total_free_blocks
but we nevertheless keep it up to date. */
void
sysv_free_block
(
struct
super_block
*
sb
,
unsigned
int
block
)
...
...
@@ -55,16 +55,13 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
unsigned
short
*
flc_count
;
unsigned
long
*
flc_blocks
;
if
(
sb
->
sv_block_size_ratio_bits
>
0
)
/* block_size < BLOCK_SIZE ? */
bh
=
bread
(
sb
->
s_dev
,
(
block
>>
sb
->
sv_block_size_ratio_bits
)
+
sb
->
sv_block_base
,
BLOCK_SIZE
);
else
bh
=
getblk
(
sb
->
s_dev
,
(
block
>>
sb
->
sv_block_size_ratio_bits
)
+
sb
->
sv_block_base
,
BLOCK_SIZE
);
bh
=
sv_getblk
(
sb
,
sb
->
s_dev
,
block
);
if
(
!
bh
)
{
printk
(
"sysv_free_block: getblk()
or bread()
failed
\n
"
);
printk
(
"sysv_free_block: getblk() failed
\n
"
);
unlock_super
(
sb
);
return
;
}
bh_data
=
bh
->
b_data
+
((
block
&
sb
->
sv_block_size_ratio_1
)
<<
sb
->
sv_block_size_bits
)
;
bh_data
=
bh
->
b_data
;
switch
(
sb
->
sv_type
)
{
case
FSTYPE_XENIX
:
flc_count
=
&
((
struct
xenix_freelist_chunk
*
)
bh_data
)
->
fl_nfree
;
...
...
@@ -95,31 +92,25 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
* in this block being freed:
*/
if
(
*
sb
->
sv_sb_flc_count
==
0
)
{
/* Applies only to Coherent FS */
if
(
sb
->
sv_block_size_ratio_bits
>
0
)
/* block_size < BLOCK_SIZE ? */
bh
=
bread
(
sb
->
s_dev
,
(
block
>>
sb
->
sv_block_size_ratio_bits
)
+
sb
->
sv_block_base
,
BLOCK_SIZE
);
else
bh
=
getblk
(
sb
->
s_dev
,
(
block
>>
sb
->
sv_block_size_ratio_bits
)
+
sb
->
sv_block_base
,
BLOCK_SIZE
);
bh
=
sv_getblk
(
sb
,
sb
->
s_dev
,
block
);
if
(
!
bh
)
{
printk
(
"sysv_free_block: getblk()
or bread()
failed
\n
"
);
printk
(
"sysv_free_block: getblk() failed
\n
"
);
unlock_super
(
sb
);
return
;
}
bh_data
=
bh
->
b_data
+
((
block
&
sb
->
sv_block_size_ratio_1
)
<<
sb
->
sv_block_size_bits
);
memset
(
bh_data
,
0
,
sb
->
sv_block_size
);
/* this implies ((struct ..._freelist_chunk *) bh_data)->flc_count = 0; */
memset
(
bh
->
b_data
,
0
,
sb
->
sv_block_size
);
/* this implies ((struct ..._freelist_chunk *) bh->b_data)->flc_count = 0; */
mark_buffer_dirty
(
bh
,
1
);
bh
->
b_uptodate
=
1
;
brelse
(
bh
);
/* still *sb->sv_sb_flc_count = 0 */
}
else
{
if
(
sb
->
sv_block_size_ratio_bits
==
0
)
{
/* block_size == BLOCK_SIZE ? */
/* Throw away block's contents */
bh
=
get_hash_table
(
sb
->
s_dev
,
(
block
>>
sb
->
sv_block_size_ratio_bits
)
+
sb
->
sv_block_base
,
BLOCK_SIZE
);
bh
=
sv_get_hash_table
(
sb
,
sb
->
s_dev
,
block
);
if
(
bh
)
bh
->
b_dirt
=
0
;
brelse
(
bh
);
}
}
if
(
sb
->
sv_convert
)
block
=
to_coh_ulong
(
block
);
sb
->
sv_sb_flc_blocks
[(
*
sb
->
sv_sb_flc_count
)
++
]
=
block
;
...
...
@@ -128,7 +119,8 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
to_coh_ulong
(
from_coh_ulong
(
*
sb
->
sv_sb_total_free_blocks
)
+
1
);
else
*
sb
->
sv_sb_total_free_blocks
=
*
sb
->
sv_sb_total_free_blocks
+
1
;
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh1
,
1
);
/* super-block has been modified */
if
(
sb
->
sv_bh1
!=
sb
->
sv_bh2
)
mark_buffer_dirty
(
sb
->
sv_bh2
,
1
);
sb
->
s_dirt
=
1
;
/* and needs time stamp */
unlock_super
(
sb
);
}
...
...
@@ -165,13 +157,14 @@ int sysv_new_block(struct super_block * sb)
unsigned
short
*
flc_count
;
unsigned
long
*
flc_blocks
;
if
(
!
(
bh
=
s
ysv_bread
(
sb
,
sb
->
s_dev
,
block
,
&
bh_data
)))
{
if
(
!
(
bh
=
s
v_bread
(
sb
,
sb
->
s_dev
,
block
)))
{
printk
(
"sysv_new_block: cannot read free-list block
\n
"
);
/* retry this same block next time */
(
*
sb
->
sv_sb_flc_count
)
++
;
unlock_super
(
sb
);
return
0
;
}
bh_data
=
bh
->
b_data
;
switch
(
sb
->
sv_type
)
{
case
FSTYPE_XENIX
:
flc_count
=
&
((
struct
xenix_freelist_chunk
*
)
bh_data
)
->
fl_nfree
;
...
...
@@ -202,23 +195,18 @@ int sysv_new_block(struct super_block * sb)
brelse
(
bh
);
}
/* Now the free list head in the superblock is valid again. */
if
(
sb
->
sv_block_size_ratio_bits
>
0
)
/* block_size < BLOCK_SIZE ? */
bh
=
bread
(
sb
->
s_dev
,
(
block
>>
sb
->
sv_block_size_ratio_bits
)
+
sb
->
sv_block_base
,
BLOCK_SIZE
);
else
bh
=
getblk
(
sb
->
s_dev
,
(
block
>>
sb
->
sv_block_size_ratio_bits
)
+
sb
->
sv_block_base
,
BLOCK_SIZE
);
bh
=
sv_getblk
(
sb
,
sb
->
s_dev
,
block
);
if
(
!
bh
)
{
printk
(
"sysv_new_block: getblk()
or bread()
failed
\n
"
);
printk
(
"sysv_new_block: getblk() failed
\n
"
);
unlock_super
(
sb
);
return
0
;
}
bh_data
=
bh
->
b_data
+
((
block
&
sb
->
sv_block_size_ratio_1
)
<<
sb
->
sv_block_size_bits
);
if
(
sb
->
sv_block_size_ratio_bits
==
0
)
/* block_size == BLOCK_SIZE ? */
if
(
bh
->
b_count
!=
1
)
{
printk
(
"sysv_new_block: block already in use
\n
"
);
unlock_super
(
sb
);
return
0
;
}
memset
(
bh_data
,
0
,
sb
->
sv_block_size
);
memset
(
bh
->
b
_data
,
0
,
sb
->
sv_block_size
);
mark_buffer_dirty
(
bh
,
1
);
bh
->
b_uptodate
=
1
;
brelse
(
bh
);
...
...
@@ -227,7 +215,8 @@ int sysv_new_block(struct super_block * sb)
to_coh_ulong
(
from_coh_ulong
(
*
sb
->
sv_sb_total_free_blocks
)
-
1
);
else
*
sb
->
sv_sb_total_free_blocks
=
*
sb
->
sv_sb_total_free_blocks
-
1
;
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh1
,
1
);
/* super-block has been modified */
if
(
sb
->
sv_bh1
!=
sb
->
sv_bh2
)
mark_buffer_dirty
(
sb
->
sv_bh2
,
1
);
sb
->
s_dirt
=
1
;
/* and needs time stamp */
unlock_super
(
sb
);
return
block
;
...
...
@@ -265,10 +254,11 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
printk
(
"sysv_count_free_blocks: new block %d is not in data zone
\n
"
,
block
);
break
;
}
if
(
!
(
bh
=
s
ysv_bread
(
sb
,
sb
->
s_dev
,
block
,
&
bh_data
)))
{
if
(
!
(
bh
=
s
v_bread
(
sb
,
sb
->
s_dev
,
block
)))
{
printk
(
"sysv_count_free_blocks: cannot read free-list block
\n
"
);
break
;
}
bh_data
=
bh
->
b_data
;
switch
(
sb
->
sv_type
)
{
case
FSTYPE_XENIX
:
flc_count
=
&
((
struct
xenix_freelist_chunk
*
)
bh_data
)
->
fl_nfree
;
...
...
@@ -321,7 +311,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
printk
(
"sysv_count_free_blocks: free block count was %d, correcting to %d
\n
"
,
old_count
,
count
);
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
*
sb
->
sv_sb_total_free_blocks
=
(
sb
->
sv_convert
?
to_coh_ulong
(
count
)
:
count
);
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh
2
,
1
);
/* super-block has been modified */
sb
->
s_dirt
=
1
;
/* and needs time stamp */
}
}
...
...
fs/sysv/dir.c
View file @
1b7a152c
...
...
@@ -80,11 +80,12 @@ static int sysv_readdir1 (struct inode * inode, struct file * filp,
return
-
EBADF
;
while
(
filp
->
f_pos
<
inode
->
i_size
)
{
offset
=
filp
->
f_pos
&
sb
->
sv_block_size_1
;
bh
=
sysv_file_bread
(
inode
,
filp
->
f_pos
>>
sb
->
sv_block_size_bits
,
0
,
&
bh_data
);
bh
=
sysv_file_bread
(
inode
,
filp
->
f_pos
>>
sb
->
sv_block_size_bits
,
0
);
if
(
!
bh
)
{
filp
->
f_pos
+=
sb
->
sv_block_size
-
offset
;
continue
;
}
bh_data
=
bh
->
b_data
;
while
(
offset
<
sb
->
sv_block_size
&&
filp
->
f_pos
<
inode
->
i_size
)
{
de
=
(
struct
sysv_dir_entry
*
)
(
offset
+
bh_data
);
offset
+=
SYSV_DIRSIZE
;
...
...
@@ -128,10 +129,6 @@ static int sysv_readdir(struct inode * inode, struct file * filp,
if
(
count
==
1
)
return
sysv_readdir1
(
inode
,
filp
,
dirent
);
retval
=
verify_area
(
VERIFY_WRITE
,
dirent
,
count
);
if
(
retval
)
return
retval
;
stored
=
0
;
while
(
count
>=
sizeof
(
struct
dirent
))
{
retval
=
sysv_readdir1
(
inode
,
filp
,
dirent
);
...
...
fs/sysv/file.c
View file @
1b7a152c
...
...
@@ -39,19 +39,6 @@ static int sysv_file_write(struct inode *, struct file *, char *, int);
* the coh filesystem.
*/
static
struct
file_operations
sysv_file_operations
=
{
NULL
,
/* lseek - default */
sysv_file_read
,
/* read */
sysv_file_write
,
/* write */
NULL
,
/* readdir - bad */
NULL
,
/* select - default */
NULL
,
/* ioctl - default */
sysv_mmap
,
/* mmap */
NULL
,
/* no special open is needed */
NULL
,
/* release */
sysv_sync_file
/* fsync */
};
static
struct
file_operations
sysv_file_operations_with_bmap
=
{
NULL
,
/* lseek - default */
sysv_file_read
,
/* read */
sysv_file_write
,
/* write */
...
...
@@ -77,44 +64,21 @@ struct inode_operations sysv_file_inode_operations = {
NULL
,
/* rename */
NULL
,
/* readlink */
NULL
,
/* follow_link */
NULL
,
/* bmap */
sysv_truncate
,
/* truncate */
NULL
/* permission */
};
struct
inode_operations
sysv_file_inode_operations_with_bmap
=
{
&
sysv_file_operations_with_bmap
,
/* default file operations */
NULL
,
/* create */
NULL
,
/* lookup */
NULL
,
/* link */
NULL
,
/* unlink */
NULL
,
/* symlink */
NULL
,
/* mkdir */
NULL
,
/* rmdir */
NULL
,
/* mknod */
NULL
,
/* rename */
NULL
,
/* readlink */
NULL
,
/* follow_link */
sysv_bmap
,
/* bmap */
sysv_truncate
,
/* truncate */
NULL
/* permission */
};
struct
sysv_buffer
{
struct
buffer_head
*
bh
;
char
*
bh_data
;
};
int
sysv_file_read
(
struct
inode
*
inode
,
struct
file
*
filp
,
char
*
buf
,
int
count
)
{
struct
super_block
*
sb
=
inode
->
i_sb
;
int
read
,
left
,
chars
;
unsigned
int
block
;
int
blocks
,
offset
;
int
bhrequest
,
bhreqi
,
uptodate
;
struct
sysv_buffer
*
bhb
,
*
bhe
;
int
bhrequest
,
uptodate
;
struct
buffer_head
**
bhb
,
*
*
bhe
;
struct
buffer_head
*
bhreq
[
NBUF
];
struct
sysv_buffer
buflist
[
NBUF
];
struct
buffer_head
*
buflist
[
NBUF
];
unsigned
int
size
;
if
(
!
inode
)
{
...
...
@@ -156,9 +120,6 @@ int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int cou
This routine is optimized to make maximum use of the various
buffers and caches.
We must remove duplicates from the bhreq array as ll_rw_block
doesn't like duplicate requests (it hangs in wait_on_buffer...).
*/
do
{
...
...
@@ -166,15 +127,10 @@ int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int cou
uptodate
=
1
;
while
(
blocks
)
{
--
blocks
;
bhb
->
bh
=
sysv_getblk
(
inode
,
block
++
,
0
,
&
bhb
->
bh_data
);
if
(
bhb
->
bh
&&
!
bhb
->
bh
->
b_uptodate
)
{
*
bhb
=
sysv_getblk
(
inode
,
block
++
,
0
);
if
(
*
bhb
&&
!
(
*
bhb
)
->
b_uptodate
)
{
uptodate
=
0
;
if
(
sb
->
sv_block_size_ratio_bits
>
0
)
/* block_size < BLOCK_SIZE ? */
for
(
bhreqi
=
0
;
bhreqi
<
bhrequest
;
bhreqi
++
)
if
(
bhreq
[
bhreqi
]
==
bhb
->
bh
)
goto
notreq
;
bhreq
[
bhrequest
++
]
=
bhb
->
bh
;
notreq:
;
bhreq
[
bhrequest
++
]
=
*
bhb
;
}
if
(
++
bhb
==
&
buflist
[
NBUF
])
...
...
@@ -193,10 +149,10 @@ int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int cou
ll_rw_block
(
READ
,
bhrequest
,
bhreq
);
do
{
/* Finish off all I/O that has actually completed */
if
(
bhe
->
bh
)
{
wait_on_buffer
(
bhe
->
bh
);
if
(
!
bhe
->
bh
->
b_uptodate
)
{
/* read error? */
brelse
(
bhe
->
bh
);
if
(
*
bhe
)
{
wait_on_buffer
(
*
bhe
);
if
(
!
(
*
bhe
)
->
b_uptodate
)
{
/* read error? */
brelse
(
*
bhe
);
if
(
++
bhe
==
&
buflist
[
NBUF
])
bhe
=
buflist
;
left
=
0
;
...
...
@@ -210,9 +166,9 @@ int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int cou
filp
->
f_pos
+=
chars
;
left
-=
chars
;
read
+=
chars
;
if
(
bhe
->
bh
)
{
memcpy_tofs
(
buf
,
offset
+
bhe
->
bh
_data
,
chars
);
brelse
(
bhe
->
bh
);
if
(
*
bhe
)
{
memcpy_tofs
(
buf
,
offset
+
(
*
bhe
)
->
b
_data
,
chars
);
brelse
(
*
bhe
);
buf
+=
chars
;
}
else
{
while
(
chars
--
>
0
)
...
...
@@ -221,12 +177,12 @@ int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int cou
offset
=
0
;
if
(
++
bhe
==
&
buflist
[
NBUF
])
bhe
=
buflist
;
}
while
(
left
>
0
&&
bhe
!=
bhb
&&
(
!
bhe
->
bh
||
!
bhe
->
bh
->
b_lock
));
}
while
(
left
>
0
&&
bhe
!=
bhb
&&
(
!
*
bhe
||
!
(
*
bhe
)
->
b_lock
));
}
while
(
left
>
0
);
/* Release the read-ahead blocks */
while
(
bhe
!=
bhb
)
{
brelse
(
bhe
->
bh
);
brelse
(
*
bhe
);
if
(
++
bhe
==
&
buflist
[
NBUF
])
bhe
=
buflist
;
};
...
...
@@ -244,7 +200,6 @@ static int sysv_file_write(struct inode * inode, struct file * filp, char * buf,
off_t
pos
;
int
written
,
c
;
struct
buffer_head
*
bh
;
char
*
bh_data
;
char
*
p
;
if
(
!
inode
)
{
...
...
@@ -262,15 +217,13 @@ static int sysv_file_write(struct inode * inode, struct file * filp, char * buf,
* writing our data into blocks that have meanwhile been incorporated into
* the freelist, thereby trashing the freelist.
*/
if
(
sb
->
sv_block_size_ratio_bits
>
0
)
/* block_size < BLOCK_SIZE ? */
coh_lock_inode
(
inode
);
if
(
filp
->
f_flags
&
O_APPEND
)
pos
=
inode
->
i_size
;
else
pos
=
filp
->
f_pos
;
written
=
0
;
while
(
written
<
count
)
{
bh
=
sysv_getblk
(
inode
,
pos
>>
sb
->
sv_block_size_bits
,
1
,
&
bh_data
);
bh
=
sysv_getblk
(
inode
,
pos
>>
sb
->
sv_block_size_bits
,
1
);
if
(
!
bh
)
{
if
(
!
written
)
written
=
-
ENOSPC
;
...
...
@@ -279,7 +232,7 @@ static int sysv_file_write(struct inode * inode, struct file * filp, char * buf,
c
=
sb
->
sv_block_size
-
(
pos
&
sb
->
sv_block_size_1
);
if
(
c
>
count
-
written
)
c
=
count
-
written
;
if
(
c
!=
BLOCK_SIZE
&&
!
bh
->
b_uptodate
)
{
if
(
c
!=
sb
->
sv_block_size
&&
!
bh
->
b_uptodate
)
{
ll_rw_block
(
READ
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
if
(
!
bh
->
b_uptodate
)
{
...
...
@@ -289,8 +242,8 @@ static int sysv_file_write(struct inode * inode, struct file * filp, char * buf,
break
;
}
}
/* now either c==
BLOCK_SIZE
or bh->b_uptodate */
p
=
(
pos
&
sb
->
sv_block_size_1
)
+
bh_data
;
/* now either c==
sb->sv_block_size
or bh->b_uptodate */
p
=
(
pos
&
sb
->
sv_block_size_1
)
+
bh
->
b
_data
;
pos
+=
c
;
if
(
pos
>
inode
->
i_size
)
{
inode
->
i_size
=
pos
;
...
...
@@ -306,7 +259,5 @@ static int sysv_file_write(struct inode * inode, struct file * filp, char * buf,
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
filp
->
f_pos
=
pos
;
inode
->
i_dirt
=
1
;
if
(
sb
->
sv_block_size_ratio_bits
>
0
)
/* block_size < BLOCK_SIZE ? */
coh_unlock_inode
(
inode
);
return
written
;
}
fs/sysv/fsync.c
View file @
1b7a152c
...
...
@@ -38,7 +38,7 @@ static int sync_block (struct inode * inode, unsigned long * blockp, int convert
if
(
!
block
)
return
0
;
sb
=
inode
->
i_sb
;
bh
=
get_hash_table
(
inode
->
i_dev
,
(
block
>>
sb
->
sv_block_size_ratio_bits
)
+
sb
->
sv_block_base
,
BLOCK_SIZE
);
bh
=
sv_get_hash_table
(
sb
,
inode
->
i_dev
,
block
);
if
(
!
bh
)
return
0
;
if
(
*
blockp
!=
tmp
)
{
...
...
@@ -60,7 +60,7 @@ static int sync_block (struct inode * inode, unsigned long * blockp, int convert
/* Sync one block full of indirect pointers and read it because we'll need it. */
static
int
sync_iblock
(
struct
inode
*
inode
,
unsigned
long
*
iblockp
,
int
convert
,
struct
buffer_head
*
*
bh
,
char
*
*
bh_data
,
int
wait
)
struct
buffer_head
*
*
bh
,
int
wait
)
{
int
rc
;
unsigned
long
tmp
,
block
;
...
...
@@ -74,7 +74,7 @@ static int sync_iblock (struct inode * inode, unsigned long * iblockp, int conve
rc
=
sync_block
(
inode
,
iblockp
,
convert
,
wait
);
if
(
rc
)
return
rc
;
*
bh
=
s
ysv_bread
(
inode
->
i_sb
,
inode
->
i_dev
,
block
,
bh_data
);
*
bh
=
s
v_bread
(
inode
->
i_sb
,
inode
->
i_dev
,
block
);
if
(
tmp
!=
*
iblockp
)
{
brelse
(
*
bh
);
*
bh
=
NULL
;
...
...
@@ -105,18 +105,17 @@ static int sync_indirect(struct inode *inode, unsigned long *iblockp, int conver
{
int
i
;
struct
buffer_head
*
ind_bh
;
char
*
ind_bh_data
;
int
rc
,
err
=
0
;
struct
super_block
*
sb
;
rc
=
sync_iblock
(
inode
,
iblockp
,
convert
,
&
ind_bh
,
&
ind_bh_data
,
wait
);
rc
=
sync_iblock
(
inode
,
iblockp
,
convert
,
&
ind_bh
,
wait
);
if
(
rc
||
!
ind_bh
)
return
rc
;
sb
=
inode
->
i_sb
;
for
(
i
=
0
;
i
<
sb
->
sv_ind_per_block
;
i
++
)
{
rc
=
sync_block
(
inode
,
((
unsigned
long
*
)
ind_bh_data
)
+
i
,
sb
->
sv_convert
,
((
unsigned
long
*
)
ind_bh
->
b
_data
)
+
i
,
sb
->
sv_convert
,
wait
);
if
(
rc
>
0
)
break
;
...
...
@@ -132,18 +131,17 @@ static int sync_dindirect(struct inode *inode, unsigned long *diblockp, int conv
{
int
i
;
struct
buffer_head
*
dind_bh
;
char
*
dind_bh_data
;
int
rc
,
err
=
0
;
struct
super_block
*
sb
;
rc
=
sync_iblock
(
inode
,
diblockp
,
convert
,
&
dind_bh
,
&
dind_bh_data
,
wait
);
rc
=
sync_iblock
(
inode
,
diblockp
,
convert
,
&
dind_bh
,
wait
);
if
(
rc
||
!
dind_bh
)
return
rc
;
sb
=
inode
->
i_sb
;
for
(
i
=
0
;
i
<
sb
->
sv_ind_per_block
;
i
++
)
{
rc
=
sync_indirect
(
inode
,
((
unsigned
long
*
)
dind_bh_data
)
+
i
,
sb
->
sv_convert
,
((
unsigned
long
*
)
dind_bh
->
b
_data
)
+
i
,
sb
->
sv_convert
,
wait
);
if
(
rc
>
0
)
break
;
...
...
@@ -159,18 +157,17 @@ static int sync_tindirect(struct inode *inode, unsigned long *tiblockp, int conv
{
int
i
;
struct
buffer_head
*
tind_bh
;
char
*
tind_bh_data
;
int
rc
,
err
=
0
;
struct
super_block
*
sb
;
rc
=
sync_iblock
(
inode
,
tiblockp
,
convert
,
&
tind_bh
,
&
tind_bh_data
,
wait
);
rc
=
sync_iblock
(
inode
,
tiblockp
,
convert
,
&
tind_bh
,
wait
);
if
(
rc
||
!
tind_bh
)
return
rc
;
sb
=
inode
->
i_sb
;
for
(
i
=
0
;
i
<
sb
->
sv_ind_per_block
;
i
++
)
{
rc
=
sync_dindirect
(
inode
,
((
unsigned
long
*
)
tind_bh_data
)
+
i
,
sb
->
sv_convert
,
((
unsigned
long
*
)
tind_bh
->
b
_data
)
+
i
,
sb
->
sv_convert
,
wait
);
if
(
rc
>
0
)
break
;
...
...
fs/sysv/ialloc.c
View file @
1b7a152c
...
...
@@ -23,22 +23,37 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/stddef.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/locks.h>
/* We don't trust the value of
sb->sv_sbd->s_tinode = *sb->sv_sb_total_free_inodes
sb->sv_sbd
2
->s_tinode = *sb->sv_sb_total_free_inodes
but we nevertheless keep it up to date. */
/* An inode on disk is considered free if both i_mode == 0 and i_nlink == 0. */
/* return &sb->sv_sb_fic_inodes[i] = &sbd->s_inode[i]; */
static
inline
sysv_ino_t
*
sv_sb_fic_inode
(
struct
super_block
*
sb
,
unsigned
int
i
)
{
if
(
sb
->
sv_bh1
==
sb
->
sv_bh2
)
return
&
sb
->
sv_sb_fic_inodes
[
i
];
else
{
/* 512 byte Xenix FS */
unsigned
int
offset
=
offsetof
(
struct
xenix_super_block
,
s_inode
[
i
]);
if
(
offset
<
512
)
return
(
sysv_ino_t
*
)(
sb
->
sv_sbd1
+
offset
);
else
return
(
sysv_ino_t
*
)(
sb
->
sv_sbd2
+
offset
);
}
}
void
sysv_free_inode
(
struct
inode
*
inode
)
{
struct
super_block
*
sb
;
unsigned
int
ino
;
struct
buffer_head
*
bh
;
char
*
bh_data
;
struct
sysv_inode
*
raw_inode
;
if
(
!
inode
)
...
...
@@ -64,17 +79,18 @@ void sysv_free_inode(struct inode * inode)
printk
(
"sysv_free_inode: inode 0,1,2 or nonexistent inode
\n
"
);
return
;
}
if
(
!
(
bh
=
s
ysv_bread
(
sb
,
inode
->
i_dev
,
sb
->
sv_firstinodezone
+
((
ino
-
1
)
>>
sb
->
sv_inodes_per_block_bits
),
&
bh_data
)))
{
if
(
!
(
bh
=
s
v_bread
(
sb
,
inode
->
i_dev
,
sb
->
sv_firstinodezone
+
((
ino
-
1
)
>>
sb
->
sv_inodes_per_block_bits
)
)))
{
printk
(
"sysv_free_inode: unable to read inode block on device %d/%d
\n
"
,
MAJOR
(
inode
->
i_dev
),
MINOR
(
inode
->
i_dev
));
clear_inode
(
inode
);
return
;
}
raw_inode
=
(
struct
sysv_inode
*
)
bh_data
+
((
ino
-
1
)
&
sb
->
sv_inodes_per_block_1
);
raw_inode
=
(
struct
sysv_inode
*
)
bh
->
b
_data
+
((
ino
-
1
)
&
sb
->
sv_inodes_per_block_1
);
lock_super
(
sb
);
if
(
*
sb
->
sv_sb_fic_count
<
sb
->
sv_fic_size
)
sb
->
sv_sb_fic_inodes
[(
*
sb
->
sv_sb_fic_count
)
++
]
=
ino
;
*
sv_sb_fic_inode
(
sb
,(
*
sb
->
sv_sb_fic_count
)
++
)
=
ino
;
(
*
sb
->
sv_sb_total_free_inodes
)
++
;
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh1
,
1
);
/* super-block has been modified */
if
(
sb
->
sv_bh1
!=
sb
->
sv_bh2
)
mark_buffer_dirty
(
sb
->
sv_bh2
,
1
);
sb
->
s_dirt
=
1
;
/* and needs time stamp */
memset
(
raw_inode
,
0
,
sizeof
(
struct
sysv_inode
));
mark_buffer_dirty
(
bh
,
1
);
...
...
@@ -88,7 +104,6 @@ struct inode * sysv_new_inode(const struct inode * dir)
struct
inode
*
inode
;
struct
super_block
*
sb
;
struct
buffer_head
*
bh
;
char
*
bh_data
;
struct
sysv_inode
*
raw_inode
;
int
i
,
j
,
ino
,
block
;
...
...
@@ -99,7 +114,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
inode
->
i_flags
=
inode
->
i_sb
->
s_flags
;
lock_super
(
sb
);
/* protect against task switches */
if
((
*
sb
->
sv_sb_fic_count
==
0
)
||
(
sb
->
sv_sb_fic_inodes
[(
*
sb
->
sv_sb_fic_count
)
-
1
]
==
0
)
/* Applies only to SystemV2 FS */
||
(
*
sv_sb_fic_inode
(
sb
,(
*
sb
->
sv_sb_fic_count
)
-
1
)
==
0
)
/* Applies only to SystemV2 FS */
)
{
/* Rebuild cache of free inodes: */
/* i : index into cache slot being filled */
...
...
@@ -109,15 +124,15 @@ struct inode * sysv_new_inode(const struct inode * dir)
/* bh : buffer for block */
/* raw_inode : pointer to inode ino in the block */
for
(
i
=
0
,
ino
=
SYSV_ROOT_INO
+
1
,
block
=
sb
->
sv_firstinodezone
,
j
=
SYSV_ROOT_INO
;
i
<
sb
->
sv_fic_size
&&
block
<
sb
->
sv_firstdatazone
;
block
++
,
j
=
0
)
{
if
(
!
(
bh
=
s
ysv_bread
(
sb
,
sb
->
s_dev
,
block
,
&
bh_data
)))
{
if
(
!
(
bh
=
s
v_bread
(
sb
,
sb
->
s_dev
,
block
)))
{
printk
(
"sysv_new_inode: unable to read inode table
\n
"
);
break
;
/* go with what we've got */
/* FIXME: Perhaps try the next block? */
}
raw_inode
=
(
struct
sysv_inode
*
)
bh_data
+
j
;
raw_inode
=
(
struct
sysv_inode
*
)
bh
->
b
_data
+
j
;
for
(;
j
<
sb
->
sv_inodes_per_block
&&
i
<
sb
->
sv_fic_size
;
ino
++
,
j
++
,
raw_inode
++
)
{
if
(
raw_inode
->
i_mode
==
0
&&
raw_inode
->
i_nlink
==
0
)
sb
->
sv_sb_fic_inodes
[
i
++
]
=
ino
;
*
sv_sb_fic_inode
(
sb
,
i
++
)
=
ino
;
}
brelse
(
bh
);
}
...
...
@@ -129,8 +144,9 @@ struct inode * sysv_new_inode(const struct inode * dir)
*
sb
->
sv_sb_fic_count
=
i
;
}
/* Now *sb->sv_sb_fic_count > 0. */
ino
=
sb
->
sv_sb_fic_inodes
[
--
(
*
sb
->
sv_sb_fic_count
)];
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
ino
=
*
sv_sb_fic_inode
(
sb
,
--
(
*
sb
->
sv_sb_fic_count
));
mark_buffer_dirty
(
sb
->
sv_bh1
,
1
);
/* super-block has been modified */
if
(
sb
->
sv_bh1
!=
sb
->
sv_bh2
)
mark_buffer_dirty
(
sb
->
sv_bh2
,
1
);
sb
->
s_dirt
=
1
;
/* and needs time stamp */
inode
->
i_count
=
1
;
inode
->
i_nlink
=
1
;
...
...
@@ -142,7 +158,6 @@ struct inode * sysv_new_inode(const struct inode * dir)
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_op
=
NULL
;
inode
->
i_blocks
=
inode
->
i_blksize
=
0
;
inode
->
u
.
sysv_i
.
i_lock
=
0
;
inode
->
u
.
sysv_i
.
i_wait
=
NULL
;
insert_inode_hash
(
inode
);
/* Change directory entry: */
inode
->
i_mode
=
0
;
/* for sysv_write_inode() */
...
...
@@ -152,7 +167,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
inode
->
i_dirt
=
1
;
/* cleared by sysv_write_inode() */
/* That's it. */
(
*
sb
->
sv_sb_total_free_inodes
)
--
;
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified again */
mark_buffer_dirty
(
sb
->
sv_bh
2
,
1
);
/* super-block has been modified again */
sb
->
s_dirt
=
1
;
/* and needs time stamp again */
unlock_super
(
sb
);
return
inode
;
...
...
@@ -162,7 +177,6 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
{
#if 1
/* test */
struct
buffer_head
*
bh
;
char
*
bh_data
;
struct
sysv_inode
*
raw_inode
;
int
j
,
block
,
count
;
...
...
@@ -176,12 +190,12 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
/* bh : buffer for block */
/* raw_inode : pointer to inode ino in the block */
for
(
block
=
sb
->
sv_firstinodezone
,
j
=
SYSV_ROOT_INO
;
block
<
sb
->
sv_firstdatazone
;
block
++
,
j
=
0
)
{
if
(
!
(
bh
=
s
ysv_bread
(
sb
,
sb
->
s_dev
,
block
,
&
bh_data
)))
{
if
(
!
(
bh
=
s
v_bread
(
sb
,
sb
->
s_dev
,
block
)))
{
printk
(
"sysv_count_free_inodes: unable to read inode table
\n
"
);
break
;
/* go with what we've got */
/* FIXME: Perhaps try the next block? */
}
raw_inode
=
(
struct
sysv_inode
*
)
bh_data
+
j
;
raw_inode
=
(
struct
sysv_inode
*
)
bh
->
b
_data
+
j
;
for
(;
j
<
sb
->
sv_inodes_per_block
;
j
++
,
raw_inode
++
)
if
(
raw_inode
->
i_mode
==
0
&&
raw_inode
->
i_nlink
==
0
)
count
++
;
...
...
@@ -191,7 +205,7 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
printk
(
"sysv_count_free_inodes: free inode count was %d, correcting to %d
\n
"
,(
short
)(
*
sb
->
sv_sb_total_free_inodes
),
count
);
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
*
sb
->
sv_sb_total_free_inodes
=
count
;
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh
2
,
1
);
/* super-block has been modified */
sb
->
s_dirt
=
1
;
/* and needs time stamp */
}
}
...
...
fs/sysv/inode.c
View file @
1b7a152c
This diff is collapsed.
Click to expand it.
fs/sysv/namei.c
View file @
1b7a152c
...
...
@@ -63,7 +63,6 @@ static struct buffer_head * sysv_find_entry(struct inode * dir,
struct
super_block
*
sb
;
unsigned
long
pos
,
block
,
offset
;
/* pos = block * block_size + offset */
struct
buffer_head
*
bh
;
char
*
bh_data
;
*
res_dir
=
NULL
;
if
(
!
dir
)
...
...
@@ -78,7 +77,7 @@ static struct buffer_head * sysv_find_entry(struct inode * dir,
pos
=
block
=
offset
=
0
;
while
(
pos
<
dir
->
i_size
)
{
if
(
!
bh
)
{
bh
=
sysv_file_bread
(
dir
,
block
,
0
,
&
bh_data
);
bh
=
sysv_file_bread
(
dir
,
block
,
0
);
if
(
!
bh
)
{
/* offset = 0; */
block
++
;
pos
+=
sb
->
sv_block_size
;
...
...
@@ -86,7 +85,7 @@ static struct buffer_head * sysv_find_entry(struct inode * dir,
}
}
if
(
sysv_match
(
namelen
,
name
,
*
res_dir
=
(
struct
sysv_dir_entry
*
)
(
bh_data
+
offset
)
))
*
res_dir
=
(
struct
sysv_dir_entry
*
)
(
bh
->
b
_data
+
offset
)
))
return
bh
;
pos
+=
SYSV_DIRSIZE
;
offset
+=
SYSV_DIRSIZE
;
...
...
@@ -148,7 +147,6 @@ static int sysv_add_entry(struct inode * dir,
int
i
;
unsigned
long
pos
,
block
,
offset
;
/* pos = block * block_size + offset */
struct
buffer_head
*
bh
;
char
*
bh_data
;
struct
sysv_dir_entry
*
de
;
*
res_buf
=
NULL
;
...
...
@@ -167,11 +165,11 @@ static int sysv_add_entry(struct inode * dir,
pos
=
block
=
offset
=
0
;
while
(
1
)
{
if
(
!
bh
)
{
bh
=
sysv_file_bread
(
dir
,
block
,
1
,
&
bh_data
);
bh
=
sysv_file_bread
(
dir
,
block
,
1
);
if
(
!
bh
)
return
-
ENOSPC
;
}
de
=
(
struct
sysv_dir_entry
*
)
(
bh_data
+
offset
);
de
=
(
struct
sysv_dir_entry
*
)
(
bh
->
b
_data
+
offset
);
pos
+=
SYSV_DIRSIZE
;
offset
+=
SYSV_DIRSIZE
;
if
(
pos
>
dir
->
i_size
)
{
...
...
@@ -218,9 +216,6 @@ int sysv_create(struct inode * dir,const char * name, int len, int mode,
iput
(
dir
);
return
-
ENOSPC
;
}
if
(
inode
->
i_sb
->
sv_block_size_ratio_bits
==
0
)
/* block_size == BLOCK_SIZE ? */
inode
->
i_op
=
&
sysv_file_inode_operations_with_bmap
;
else
inode
->
i_op
=
&
sysv_file_inode_operations
;
inode
->
i_mode
=
mode
;
inode
->
i_dirt
=
1
;
...
...
@@ -264,9 +259,6 @@ int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rde
inode
->
i_mode
=
mode
;
inode
->
i_op
=
NULL
;
if
(
S_ISREG
(
inode
->
i_mode
))
if
(
inode
->
i_sb
->
sv_block_size_ratio_bits
==
0
)
/* block_size == BLOCK_SIZE ? */
inode
->
i_op
=
&
sysv_file_inode_operations_with_bmap
;
else
inode
->
i_op
=
&
sysv_file_inode_operations
;
else
if
(
S_ISDIR
(
inode
->
i_mode
))
{
inode
->
i_op
=
&
sysv_dir_inode_operations
;
...
...
@@ -305,7 +297,6 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
int
error
;
struct
inode
*
inode
;
struct
buffer_head
*
bh
,
*
dir_block
;
char
*
bh_data
;
struct
sysv_dir_entry
*
de
;
if
(
!
dir
)
{
...
...
@@ -329,7 +320,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
}
inode
->
i_op
=
&
sysv_dir_inode_operations
;
inode
->
i_size
=
2
*
SYSV_DIRSIZE
;
dir_block
=
sysv_file_bread
(
inode
,
0
,
1
,
&
bh_data
);
dir_block
=
sysv_file_bread
(
inode
,
0
,
1
);
if
(
!
dir_block
)
{
iput
(
dir
);
inode
->
i_nlink
--
;
...
...
@@ -337,10 +328,10 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
iput
(
inode
);
return
-
ENOSPC
;
}
de
=
(
struct
sysv_dir_entry
*
)
(
bh
_data
+
0
*
SYSV_DIRSIZE
);
de
=
(
struct
sysv_dir_entry
*
)
(
dir_block
->
b
_data
+
0
*
SYSV_DIRSIZE
);
de
->
inode
=
inode
->
i_ino
;
strcpy
(
de
->
name
,
"."
);
/* rest of de->name is zero, see sysv_new_block */
de
=
(
struct
sysv_dir_entry
*
)
(
bh
_data
+
1
*
SYSV_DIRSIZE
);
de
=
(
struct
sysv_dir_entry
*
)
(
dir_block
->
b
_data
+
1
*
SYSV_DIRSIZE
);
de
->
inode
=
dir
->
i_ino
;
strcpy
(
de
->
name
,
".."
);
/* rest of de->name is zero, see sysv_new_block */
inode
->
i_nlink
=
2
;
...
...
@@ -375,7 +366,6 @@ static int empty_dir(struct inode * inode)
struct
super_block
*
sb
;
unsigned
long
pos
,
block
,
offset
;
/* pos = block * block_size + offset */
struct
buffer_head
*
bh
;
char
*
bh_data
;
struct
sysv_dir_entry
*
de
;
if
(
!
inode
)
...
...
@@ -387,26 +377,26 @@ static int empty_dir(struct inode * inode)
goto
bad_dir
;
if
(
inode
->
i_size
<
pos
)
goto
bad_dir
;
bh
=
sysv_file_bread
(
inode
,
0
,
0
,
&
bh_data
);
bh
=
sysv_file_bread
(
inode
,
0
,
0
);
if
(
!
bh
)
goto
bad_dir
;
de
=
(
struct
sysv_dir_entry
*
)
(
bh_data
+
0
*
SYSV_DIRSIZE
);
de
=
(
struct
sysv_dir_entry
*
)
(
bh
->
b
_data
+
0
*
SYSV_DIRSIZE
);
if
(
!
de
->
inode
||
strcmp
(
de
->
name
,
"."
))
goto
bad_dir
;
de
=
(
struct
sysv_dir_entry
*
)
(
bh_data
+
1
*
SYSV_DIRSIZE
);
de
=
(
struct
sysv_dir_entry
*
)
(
bh
->
b
_data
+
1
*
SYSV_DIRSIZE
);
if
(
!
de
->
inode
||
strcmp
(
de
->
name
,
".."
))
goto
bad_dir
;
sb
=
inode
->
i_sb
;
while
(
pos
<
inode
->
i_size
)
{
if
(
!
bh
)
{
bh
=
sysv_file_bread
(
inode
,
block
,
0
,
&
bh_data
);
bh
=
sysv_file_bread
(
inode
,
block
,
0
);
if
(
!
bh
)
{
/* offset = 0; */
block
++
;
pos
+=
sb
->
sv_block_size
;
continue
;
}
}
de
=
(
struct
sysv_dir_entry
*
)
(
bh_data
+
offset
);
de
=
(
struct
sysv_dir_entry
*
)
(
bh
->
b
_data
+
offset
);
pos
+=
SYSV_DIRSIZE
;
offset
+=
SYSV_DIRSIZE
;
if
(
de
->
inode
)
{
...
...
@@ -553,7 +543,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
}
inode
->
i_mode
=
S_IFLNK
|
0777
;
inode
->
i_op
=
&
sysv_symlink_inode_operations
;
name_block
=
sysv_file_bread
(
inode
,
0
,
1
,
&
name_block_data
);
name_block
=
sysv_file_bread
(
inode
,
0
,
1
);
if
(
!
name_block
)
{
iput
(
dir
);
inode
->
i_nlink
--
;
...
...
@@ -562,6 +552,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
return
-
ENOSPC
;
}
sb
=
inode
->
i_sb
;
name_block_data
=
name_block
->
b_data
;
i
=
0
;
while
(
i
<
sb
->
sv_block_size_1
&&
(
c
=
*
(
symname
++
)))
name_block_data
[
i
++
]
=
c
;
...
...
@@ -678,7 +669,6 @@ static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old
{
struct
inode
*
old_inode
,
*
new_inode
;
struct
buffer_head
*
old_bh
,
*
new_bh
,
*
dir_bh
;
char
*
dir_bh_data
;
struct
sysv_dir_entry
*
old_de
,
*
new_de
;
int
retval
;
...
...
@@ -745,10 +735,10 @@ static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old
if
(
subdir
(
new_dir
,
old_inode
))
goto
end_rename
;
retval
=
-
EIO
;
dir_bh
=
sysv_file_bread
(
old_inode
,
0
,
0
,
&
dir_bh_data
);
dir_bh
=
sysv_file_bread
(
old_inode
,
0
,
0
);
if
(
!
dir_bh
)
goto
end_rename
;
if
(
PARENT_INO
(
dir_bh_data
)
!=
old_dir
->
i_ino
)
if
(
PARENT_INO
(
dir_bh
->
b
_data
)
!=
old_dir
->
i_ino
)
goto
end_rename
;
retval
=
-
EMLINK
;
if
(
!
new_inode
&&
new_dir
->
i_nlink
>=
new_dir
->
i_sb
->
sv_link_max
)
...
...
@@ -781,7 +771,7 @@ static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old
mark_buffer_dirty
(
old_bh
,
1
);
mark_buffer_dirty
(
new_bh
,
1
);
if
(
dir_bh
)
{
PARENT_INO
(
dir_bh_data
)
=
new_dir
->
i_ino
;
PARENT_INO
(
dir_bh
->
b
_data
)
=
new_dir
->
i_ino
;
mark_buffer_dirty
(
dir_bh
,
1
);
old_dir
->
i_nlink
--
;
old_dir
->
i_dirt
=
1
;
...
...
fs/sysv/symlink.c
View file @
1b7a152c
...
...
@@ -49,7 +49,6 @@ static int sysv_follow_link(struct inode * dir, struct inode * inode,
{
int
error
;
struct
buffer_head
*
bh
;
char
*
bh_data
;
*
res_inode
=
NULL
;
if
(
!
dir
)
{
...
...
@@ -70,14 +69,14 @@ static int sysv_follow_link(struct inode * dir, struct inode * inode,
iput
(
dir
);
return
-
ELOOP
;
}
if
(
!
(
bh
=
sysv_file_bread
(
inode
,
0
,
0
,
&
bh_data
)))
{
/* is reading 1 block enough ?? */
if
(
!
(
bh
=
sysv_file_bread
(
inode
,
0
,
0
)))
{
/* is reading 1 block enough ?? */
iput
(
inode
);
iput
(
dir
);
return
-
EIO
;
}
iput
(
inode
);
current
->
link_count
++
;
error
=
open_namei
(
bh_data
,
flag
,
mode
,
res_inode
,
dir
);
error
=
open_namei
(
bh
->
b
_data
,
flag
,
mode
,
res_inode
,
dir
);
current
->
link_count
--
;
brelse
(
bh
);
return
error
;
...
...
@@ -96,10 +95,11 @@ static int sysv_readlink(struct inode * inode, char * buffer, int buflen)
}
if
(
buflen
>
inode
->
i_sb
->
sv_block_size_1
)
buflen
=
inode
->
i_sb
->
sv_block_size_1
;
bh
=
sysv_file_bread
(
inode
,
0
,
0
,
&
bh_data
);
bh
=
sysv_file_bread
(
inode
,
0
,
0
);
iput
(
inode
);
if
(
!
bh
)
return
0
;
bh_data
=
bh
->
b_data
;
i
=
0
;
while
(
i
<
buflen
&&
(
c
=
bh_data
[
i
]))
{
i
++
;
...
...
fs/sysv/truncate.c
View file @
1b7a152c
This diff is collapsed.
Click to expand it.
include/linux/ext2_fs.h
View file @
1b7a152c
...
...
@@ -349,7 +349,9 @@ struct ext2_super_block {
unsigned
long
s_checkinterval
;
/* max. time between checks */
unsigned
long
s_creator_os
;
/* OS */
unsigned
long
s_rev_level
;
/* Revision level */
unsigned
long
s_reserved
[
236
];
/* Padding to the end of the block */
unsigned
short
s_def_resuid
;
/* Default uid for reserved blocks */
unsigned
short
s_def_resgid
;
/* Default gid for reserved blocks */
unsigned
long
s_reserved
[
235
];
/* Padding to the end of the block */
};
#define EXT2_OS_LINUX 0
...
...
@@ -358,6 +360,9 @@ struct ext2_super_block {
#define EXT2_CURRENT_REV 0
#define EXT2_DEF_RESUID 0
#define EXT2_DEF_RESGID 0
/*
* Structure of a directory entry
*/
...
...
include/linux/ext2_fs_sb.h
View file @
1b7a152c
...
...
@@ -49,6 +49,8 @@ struct ext2_sb_info {
int
s_rename_lock
;
struct
wait_queue
*
s_rename_wait
;
unsigned
long
s_mount_opt
;
unsigned
short
s_resuid
;
unsigned
short
s_resgid
;
unsigned
short
s_mount_state
;
};
...
...
include/linux/fs.h
View file @
1b7a152c
...
...
@@ -226,6 +226,7 @@ struct inode {
struct
inode
*
i_mount
;
struct
socket
*
i_socket
;
unsigned
short
i_count
;
unsigned
short
i_wcount
;
unsigned
short
i_flags
;
unsigned
char
i_lock
;
unsigned
char
i_dirt
;
...
...
@@ -464,6 +465,8 @@ extern int notify_change(struct inode *, struct iattr *);
extern
int
namei
(
const
char
*
pathname
,
struct
inode
**
res_inode
);
extern
int
lnamei
(
const
char
*
pathname
,
struct
inode
**
res_inode
);
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
inode
*
base
);
extern
int
do_mknod
(
const
char
*
filename
,
int
mode
,
dev_t
dev
);
...
...
include/linux/interrupt.h
View file @
1b7a152c
...
...
@@ -20,6 +20,7 @@ enum {
TQUEUE_BH
,
SERIAL_BH
,
NET_BH
,
IMMEDIATE_BH
,
KEYBOARD_BH
};
...
...
include/linux/mm.h
View file @
1b7a152c
...
...
@@ -196,6 +196,7 @@ extern int do_mmap(struct file * file, unsigned long addr, unsigned long len,
extern
void
merge_segments
(
struct
vm_area_struct
*
);
extern
void
insert_vm_struct
(
struct
task_struct
*
,
struct
vm_area_struct
*
);
extern
int
do_munmap
(
unsigned
long
,
size_t
);
extern
unsigned
long
get_unmapped_area
(
unsigned
long
);
#define read_swap_page(nr,buf) \
rw_swap_page(READ,(nr),(buf))
...
...
@@ -232,7 +233,7 @@ extern unsigned short * mem_map;
#define GFP_USER 0x02
#define GFP_KERNEL 0x03
#define GFP_NOBUFFER 0x04
#define GFP_NFS 0x05
/*
* vm_ops not present page codes for shared memory.
...
...
include/linux/mtio.h
View file @
1b7a152c
...
...
@@ -50,7 +50,9 @@ struct mtop {
#define MTTELL 23
/* tell block (Tandberg, etc.) */
#define MTSETDRVBUFFER 24
/* set the drive buffering according to SCSI-2 */
/* ordinary buffered operation with code 1 */
#define MTFSS 25
/* space forward over setmarks */
#define MTBSS 26
/* space backward over setmarks */
#define MTWSM 27
/* write setmarks */
/* structure for MTIOCGET - mag tape get status command */
...
...
include/linux/sched.h
View file @
1b7a152c
...
...
@@ -288,8 +288,7 @@ struct task_struct {
/* file system info */
int
link_count
;
struct
tty_struct
*
tty
;
/* NULL if no tty */
/* shm stuff */
struct
shm_desc
*
shm
;
/* ipc stuff */
struct
sem_undo
*
semundo
;
/* ldt for this task - used by Wine. If NULL, default_ldt is used */
struct
desc_struct
*
ldt
;
...
...
@@ -343,7 +342,7 @@ struct task_struct {
/* comm */
"swapper", \
/* vm86_info */
NULL, 0, 0, 0, 0, \
/* fs info */
0,NULL, \
/* ipc */
NULL,
NULL,
\
/* ipc */
NULL, \
/* ldt */
NULL, \
/* tss */
INIT_TSS, \
/* fs */
{ INIT_FS }, \
...
...
include/linux/shm.h
View file @
1b7a152c
...
...
@@ -14,9 +14,13 @@ struct shmid_ds {
/* the following are private */
unsigned
short
shm_npages
;
/* size of segment (pages) */
unsigned
long
*
shm_pages
;
/* array of ptrs to frames -> SHMMAX */
struct
shm_desc
*
attaches
;
/* descriptors for attaches */
struct
vm_area_struct
*
attaches
;
/* descriptors for attaches */
};
/* permission flag for shmget */
#define SHM_R 0400
/* or S_IRUGO from <linux/stat.h> */
#define SHM_W 0200
/* or S_IWUGO from <linux/stat.h> */
/* mode for attach */
#define SHM_RDONLY 010000
/* read-only access */
#define SHM_RND 020000
/* round attach address to SHMLBA boundary */
...
...
@@ -35,7 +39,7 @@ struct shminfo {
};
/* address range for shared memory attaches if no address passed to shmat() */
#define SHM_RANGE_START 0x
4
0000000
#define SHM_RANGE_START 0x
5
0000000
#define SHM_RANGE_END 0x60000000
/* format of page table entries that correspond to shared memory pages
...
...
@@ -89,20 +93,6 @@ struct shm_info {
ulong
swap_successes
;
};
/*
* Per process internal structure for managing segments.
* A shmat will add to and shmdt will remove from the list.
*/
struct
shm_desc
{
struct
task_struct
*
task
;
/* attacher */
unsigned
long
shm_sgn
;
/* signature for this attach */
unsigned
long
start
;
/* virt addr of attach, multiple of SHMLBA */
unsigned
long
end
;
/* multiple of SHMLBA */
struct
shm_desc
*
task_next
;
/* next attach for task */
struct
shm_desc
*
seg_next
;
/* next attach for segment */
};
#endif
/* __KERNEL__ */
#endif
/* _LINUX_SHM_H_ */
...
...
include/linux/sysv_fs.h
View file @
1b7a152c
...
...
@@ -335,54 +335,25 @@ struct sysv_dir_entry {
#define SYSV2_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_SYSV2)
#define COH_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_COH)
/* Because the block size may be smaller than 1024 (which is the unit used by
the disk drivers and the buffer code), many functions must return a pointer
to the buffer data additionally to the buffer head pointer.
*/
#if 0
struct bh_data {
struct buffer_head * bh;
char * bh_data;
};
#endif
/* sysv_bread(sb,dev,block,...) would be equivalent to
bread(dev,block,BLOCK_SIZE)
if the block size were always 1024, which is the only one bread() supports.
*/
/* sv_get_hash_table(sb,dev,block) is equivalent to get_hash_table(dev,block,block_size) */
static
inline
struct
buffer_head
*
sysv_bread
(
struct
super_block
*
sb
,
int
dev
,
unsigned
int
block
,
char
*
*
data
)
{
struct
buffer_head
*
bh
;
if
(
!
(
bh
=
bread
(
dev
,
(
block
>>
sb
->
sv_block_size_ratio_bits
)
+
sb
->
sv_block_base
,
BLOCK_SIZE
)))
return
NULL
;
*
data
=
bh
->
b_data
+
((
block
&
sb
->
sv_block_size_ratio_1
)
<<
sb
->
sv_block_size_bits
);
return
bh
;
}
/* locks - protect against simultaneous write and truncate */
extern
void
_coh_wait_on_inode
(
struct
inode
*
inode
);
extern
inline
void
coh_wait_on_inode
(
struct
inode
*
inode
)
sv_get_hash_table
(
struct
super_block
*
sb
,
int
dev
,
unsigned
int
block
)
{
if
(
inode
->
u
.
sysv_i
.
i_lock
)
_coh_wait_on_inode
(
inode
);
return
get_hash_table
(
dev
,
block
+
sb
->
sv_block_base
,
sb
->
sv_block_size
);
}
extern
inline
void
coh_lock_inode
(
struct
inode
*
inode
)
/* sv_getblk(sb,dev,block) is equivalent to getblk(dev,block,block_size) */
static
inline
struct
buffer_head
*
sv_getblk
(
struct
super_block
*
sb
,
int
dev
,
unsigned
int
block
)
{
if
(
inode
->
u
.
sysv_i
.
i_lock
)
_coh_wait_on_inode
(
inode
);
inode
->
u
.
sysv_i
.
i_lock
=
1
;
return
getblk
(
dev
,
block
+
sb
->
sv_block_base
,
sb
->
sv_block_size
);
}
extern
inline
void
coh_unlock_inode
(
struct
inode
*
inode
)
/* sv_bread(sb,dev,block) is equivalent to bread(dev,block,block_size) */
static
inline
struct
buffer_head
*
sv_bread
(
struct
super_block
*
sb
,
int
dev
,
unsigned
int
block
)
{
inode
->
u
.
sysv_i
.
i_lock
=
0
;
wake_up
(
&
inode
->
u
.
sysv_i
.
i_wait
);
return
bread
(
dev
,
block
+
sb
->
sv_block_base
,
sb
->
sv_block_size
);
}
...
...
@@ -412,8 +383,8 @@ extern unsigned long sysv_count_free_blocks(struct super_block *sb);
extern
int
sysv_bmap
(
struct
inode
*
,
int
);
extern
struct
buffer_head
*
sysv_getblk
(
struct
inode
*
,
unsigned
int
,
int
,
char
*
*
);
extern
struct
buffer_head
*
sysv_file_bread
(
struct
inode
*
,
int
,
int
,
char
*
*
);
extern
struct
buffer_head
*
sysv_getblk
(
struct
inode
*
,
unsigned
int
,
int
);
extern
struct
buffer_head
*
sysv_file_bread
(
struct
inode
*
,
int
,
int
);
extern
int
sysv_file_read
(
struct
inode
*
,
struct
file
*
,
char
*
,
int
);
extern
void
sysv_truncate
(
struct
inode
*
);
...
...
include/linux/sysv_fs_i.h
View file @
1b7a152c
...
...
@@ -10,10 +10,6 @@ struct sysv_inode_info {
* then 1 double indirection block,
* then 1 triple indirection block.
*/
/* the following are only used if block_size < BLOCK_SIZE */
int
i_lock
;
/* lock to protect against simultaneous */
struct
wait_queue
*
i_wait
;
/* write and truncate */
/* */
};
#endif
...
...
include/linux/sysv_fs_sb.h
View file @
1b7a152c
...
...
@@ -16,7 +16,6 @@ struct sysv_sb_info {
unsigned
int
s_block_size_1
;
/* block_size - 1 */
unsigned
int
s_block_size_bits
;
/* log2(block_size) */
unsigned
int
s_block_size_ratio
;
/* BLOCK_SIZE / block_size */
unsigned
int
s_block_size_ratio_1
;
/* block_size_ratio - 1 */
unsigned
int
s_block_size_ratio_bits
;
/* log2(block_size_ratio) */
char
s_convert
;
/* flag whether byte ordering requires conversion */
char
s_kludge_symlinks
;
/* flag whether symlinks have a kludgey mode */
...
...
@@ -33,15 +32,24 @@ struct sysv_sb_info {
unsigned
int
s_ind_per_block_2_1
;
/* ind_per_block ^ 2 - 1 */
unsigned
int
s_ind_per_block_2_bits
;
/* log2(ind_per_block^2) */
unsigned
int
s_ind_per_block_3
;
/* ind_per_block ^ 3 */
unsigned
int
s_ind_per_block_block_size_1
;
/* ind_per_block*block_size - 1 */
unsigned
int
s_ind_per_block_block_size_bits
;
/* log2(ind_per_block*block_size) */
unsigned
int
s_ind_per_block_2_block_size_1
;
/* ind_per_block^2 * block_size - 1 */
unsigned
int
s_ind_per_block_2_block_size_bits
;
/* log2(ind_per_block^2 * block_size) */
unsigned
int
s_ind0_size
;
/* 10 * block_size */
unsigned
int
s_ind1_size
;
/* (10 + ipb) * block_size */
unsigned
int
s_ind2_size
;
/* (10 + ipb + ipb^2) * block_size */
unsigned
int
s_toobig_block
;
/* 10 + ipb + ipb^2 + ipb^3 */
unsigned
int
s_block_base
;
/* physical block number of block 0 */
unsigned
short
s_fic_size
;
/* free inode cache size, NICINOD */
unsigned
short
s_flc_size
;
/* free block list chunk size, NICFREE */
/* The superblock is kept in a disk buffer: */
struct
buffer_head
*
s_bh
;
/* The superblock is kept in one or two disk buffers: */
struct
buffer_head
*
s_bh1
;
struct
buffer_head
*
s_bh2
;
/* These are pointers into the disk buffer, to compensate for
different superblock layout. */
char
*
s_sbd
;
/* entire superblock data */
char
*
s_sbd1
;
/* entire superblock data, for part 1 */
char
*
s_sbd2
;
/* entire superblock data, for part 2 */
unsigned
short
*
s_sb_fic_count
;
/* pointer to s_sbd->s_ninode */
unsigned
short
*
s_sb_fic_inodes
;
/* pointer to s_sbd->s_inode */
unsigned
short
*
s_sb_total_free_inodes
;
/* pointer to s_sbd->s_tinode */
...
...
@@ -57,7 +65,7 @@ struct sysv_sb_info {
unsigned
long
s_ndatazones
;
/* total number of data zones */
unsigned
long
s_nzones
;
/* same as s_sbd->s_fsize */
};
/* The fields s_block_size_ratio, s_
toobig_block, s_sbd
are currently unused. */
/* The fields s_block_size_ratio, s_
ind_per_block_2_1, s_toobig_block
are currently unused. */
/* sv_ == u.sysv_sb.s_ */
#define sv_type u.sysv_sb.s_type
...
...
@@ -65,7 +73,6 @@ struct sysv_sb_info {
#define sv_block_size_1 u.sysv_sb.s_block_size_1
#define sv_block_size_bits u.sysv_sb.s_block_size_bits
#define sv_block_size_ratio u.sysv_sb.s_block_size_ratio
#define sv_block_size_ratio_1 u.sysv_sb.s_block_size_ratio_1
#define sv_block_size_ratio_bits u.sysv_sb.s_block_size_ratio_bits
#define sv_convert u.sysv_sb.s_convert
#define sv_kludge_symlinks u.sysv_sb.s_kludge_symlinks
...
...
@@ -81,12 +88,21 @@ struct sysv_sb_info {
#define sv_ind_per_block_2_1 u.sysv_sb.s_ind_per_block_2_1
#define sv_ind_per_block_2_bits u.sysv_sb.s_ind_per_block_2_bits
#define sv_ind_per_block_3 u.sysv_sb.s_ind_per_block_3
#define sv_ind_per_block_block_size_1 u.sysv_sb.s_ind_per_block_block_size_1
#define sv_ind_per_block_block_size_bits u.sysv_sb.s_ind_per_block_block_size_bits
#define sv_ind_per_block_2_block_size_1 u.sysv_sb.s_ind_per_block_2_block_size_1
#define sv_ind_per_block_2_block_size_bits u.sysv_sb.s_ind_per_block_2_block_size_bits
#define sv_ind0_size u.sysv_sb.s_ind0_size
#define sv_ind1_size u.sysv_sb.s_ind1_size
#define sv_ind2_size u.sysv_sb.s_ind2_size
#define sv_toobig_block u.sysv_sb.s_toobig_block
#define sv_block_base u.sysv_sb.s_block_base
#define sv_fic_size u.sysv_sb.s_fic_size
#define sv_flc_size u.sysv_sb.s_flc_size
#define sv_bh u.sysv_sb.s_bh
#define sv_sbd u.sysv_sb.s_sbd
#define sv_bh1 u.sysv_sb.s_bh1
#define sv_bh2 u.sysv_sb.s_bh2
#define sv_sbd1 u.sysv_sb.s_sbd1
#define sv_sbd2 u.sysv_sb.s_sbd2
#define sv_sb_fic_count u.sysv_sb.s_sb_fic_count
#define sv_sb_fic_inodes u.sysv_sb.s_sb_fic_inodes
#define sv_sb_total_free_inodes u.sysv_sb.s_sb_total_free_inodes
...
...
include/linux/tqueue.h
View file @
1b7a152c
...
...
@@ -57,7 +57,7 @@ typedef struct tq_struct * task_queue;
#define DECLARE_TASK_QUEUE(q) task_queue q = &tq_last
extern
struct
tq_struct
tq_last
;
extern
task_queue
tq_timer
;
extern
task_queue
tq_timer
,
tq_immediate
;
#ifdef INCLUDE_INLINE_FUNCS
struct
tq_struct
tq_last
=
{
...
...
ipc/shm.c
View file @
1b7a152c
This diff is collapsed.
Click to expand it.
ipc/util.c
View file @
1b7a152c
...
...
@@ -132,21 +132,11 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr)
return
-
ENOSYS
;
}
int
shm_fork
(
struct
task_struct
*
p1
,
struct
task_struct
*
p2
)
{
return
0
;
}
void
sem_exit
(
void
)
{
return
;
}
void
shm_exit
(
void
)
{
return
;
}
int
shm_swap
(
int
prio
)
{
return
0
;
...
...
kernel/exit.c
View file @
1b7a152c
...
...
@@ -17,7 +17,6 @@
#include <linux/malloc.h>
#include <asm/segment.h>
extern
void
shm_exit
(
void
);
extern
void
sem_exit
(
void
);
int
getrusage
(
struct
task_struct
*
,
int
,
struct
rusage
*
);
...
...
@@ -413,8 +412,6 @@ NORET_TYPE void do_exit(long code)
fake_volatile:
if
(
current
->
semundo
)
sem_exit
();
if
(
current
->
shm
)
shm_exit
();
exit_mm
();
exit_files
();
exit_fs
();
...
...
kernel/fork.c
View file @
1b7a152c
...
...
@@ -32,7 +32,6 @@ asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
#define MAX_TASKS_PER_USER (NR_TASKS/2)
#define MIN_TASKS_LEFT_FOR_ROOT 4
extern
int
shm_fork
(
struct
task_struct
*
,
struct
task_struct
*
);
long
last_pid
=
0
;
static
int
find_empty_process
(
void
)
...
...
@@ -104,6 +103,8 @@ static int dup_mmap(struct task_struct * tsk)
tmp
->
vm_next
=
NULL
;
if
(
tmp
->
vm_inode
)
tmp
->
vm_inode
->
i_count
++
;
if
(
tmp
->
vm_ops
&&
tmp
->
vm_ops
->
open
)
tmp
->
vm_ops
->
open
(
tmp
);
*
p
=
tmp
;
p
=
&
tmp
->
vm_next
;
}
...
...
@@ -141,13 +142,12 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * p)
p
->
mm
->
cmin_flt
=
p
->
mm
->
cmaj_flt
=
0
;
if
(
copy_page_tables
(
p
))
return
1
;
dup_mmap
(
p
);
return
dup_mmap
(
p
);
}
else
{
if
(
clone_page_tables
(
p
))
return
1
;
dup_mmap
(
p
);
/* wrong.. */
return
dup_mmap
(
p
);
/* wrong.. */
}
return
shm_fork
(
current
,
p
);
}
static
void
copy_fs
(
unsigned
long
clone_flags
,
struct
task_struct
*
p
)
...
...
@@ -243,6 +243,7 @@ asmlinkage int sys_fork(struct pt_regs regs)
__asm__
(
"clts ; fnsave %0 ; frstor %0"
:
"=m"
(
p
->
tss
.
i387
));
if
(
copy_mm
(
clone_flags
,
p
))
goto
bad_fork_cleanup
;
p
->
semundo
=
NULL
;
copy_files
(
clone_flags
,
p
);
copy_fs
(
clone_flags
,
p
);
set_tss_desc
(
gdt
+
(
nr
<<
1
)
+
FIRST_TSS_ENTRY
,
&
(
p
->
tss
));
...
...
kernel/ksyms.c
View file @
1b7a152c
...
...
@@ -29,6 +29,7 @@
#include <linux/serial.h>
#include <linux/locks.h>
#include <linux/string.h>
#include <linux/delay.h>
#ifdef CONFIG_INET
#include <linux/net.h>
#include <linux/netdevice.h>
...
...
@@ -143,6 +144,7 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
X
(
bh_mask
),
X
(
add_timer
),
X
(
del_timer
),
X
(
tq_immediate
),
/* dma handling */
X
(
request_dma
),
...
...
@@ -157,6 +159,10 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
X
(
current
),
X
(
jiffies
),
X
(
xtime
),
X
(
loops_per_sec
),
X
(
kill_proc
),
X
(
kill_pg
),
X
(
kill_sl
),
/* misc */
X
(
panic
),
...
...
kernel/sched.c
View file @
1b7a152c
...
...
@@ -43,6 +43,7 @@ volatile struct timeval xtime; /* The current time */
int
tickadj
=
500
/
HZ
;
/* microsecs */
DECLARE_TASK_QUEUE
(
tq_timer
);
DECLARE_TASK_QUEUE
(
tq_immediate
);
/*
* phase-lock loop variables
...
...
@@ -589,6 +590,11 @@ void tqueue_bh(void * unused)
run_task_queue
(
&
tq_timer
);
}
void
immediate_bh
(
void
*
unused
)
{
run_task_queue
(
&
tq_immediate
);
}
/*
* The int argument is really a (struct pt_regs *), in case the
* interrupt wants to know from where it was called. The timer
...
...
@@ -830,6 +836,7 @@ void sched_init(void)
bh_base
[
TIMER_BH
].
routine
=
timer_bh
;
bh_base
[
TQUEUE_BH
].
routine
=
tqueue_bh
;
bh_base
[
IMMEDIATE_BH
].
routine
=
immediate_bh
;
if
(
sizeof
(
struct
sigaction
)
!=
16
)
panic
(
"Struct sigaction MUST be 16 bytes"
);
set_tss_desc
(
gdt
+
FIRST_TSS_ENTRY
,
&
init_task
.
tss
);
...
...
mm/mmap.c
View file @
1b7a152c
...
...
@@ -71,6 +71,8 @@ int do_mmap(struct file * file, unsigned long addr, unsigned long len,
default:
return
-
EINVAL
;
}
if
((
flags
&
MAP_DENYWRITE
)
&&
(
file
->
f_inode
->
i_wcount
>
0
))
return
-
ETXTBSY
;
}
else
if
((
flags
&
MAP_TYPE
)
==
MAP_SHARED
)
return
-
EINVAL
;
...
...
@@ -85,23 +87,8 @@ int do_mmap(struct file * file, unsigned long addr, unsigned long len,
if
(
len
>
TASK_SIZE
||
addr
>
TASK_SIZE
-
len
)
return
-
EINVAL
;
}
else
{
struct
vm_area_struct
*
vmm
;
/* Maybe this works.. Ugly it is. */
addr
=
SHM_RANGE_START
;
while
(
addr
+
len
<
SHM_RANGE_END
)
{
for
(
vmm
=
current
->
mm
->
mmap
;
vmm
;
vmm
=
vmm
->
vm_next
)
{
if
(
addr
>=
vmm
->
vm_end
)
continue
;
if
(
addr
+
len
<=
vmm
->
vm_start
)
continue
;
addr
=
PAGE_ALIGN
(
vmm
->
vm_end
);
break
;
}
if
(
!
vmm
)
break
;
}
if
(
addr
+
len
>=
SHM_RANGE_END
)
addr
=
get_unmapped_area
(
len
);
if
(
!
addr
)
return
-
ENOMEM
;
}
...
...
@@ -157,22 +144,45 @@ int do_mmap(struct file * file, unsigned long addr, unsigned long len,
if
(
error
)
{
kfree
(
vma
);
if
(
!
current
->
errno
)
current
->
errno
=
-
error
;
return
-
1
;
return
error
;
}
insert_vm_struct
(
current
,
vma
);
merge_segments
(
current
->
mm
->
mmap
);
return
addr
;
}
/*
* Get an address range which is currently unmapped.
* For mmap() without MAP_FIXED and shmat() with addr=0.
* Return value 0 means ENOMEM.
*/
unsigned
long
get_unmapped_area
(
unsigned
long
len
)
{
struct
vm_area_struct
*
vmm
;
unsigned
long
gap_start
=
0
,
gap_end
;
for
(
vmm
=
current
->
mm
->
mmap
;
;
vmm
=
vmm
->
vm_next
)
{
if
(
gap_start
<
SHM_RANGE_START
)
gap_start
=
SHM_RANGE_START
;
if
(
!
vmm
||
((
gap_end
=
vmm
->
vm_start
)
>
SHM_RANGE_END
))
gap_end
=
SHM_RANGE_END
;
gap_start
=
PAGE_ALIGN
(
gap_start
);
gap_end
&=
PAGE_MASK
;
if
((
gap_start
<=
gap_end
)
&&
(
gap_end
-
gap_start
>=
len
))
return
gap_start
;
if
(
!
vmm
)
return
0
;
gap_start
=
vmm
->
vm_end
;
}
}
asmlinkage
int
sys_mmap
(
unsigned
long
*
buffer
)
{
int
error
;
unsigned
long
flags
;
struct
file
*
file
=
NULL
;
error
=
verify_area
(
VERIFY_READ
,
buffer
,
6
*
4
);
error
=
verify_area
(
VERIFY_READ
,
buffer
,
6
*
sizeof
(
long
)
);
if
(
error
)
return
error
;
flags
=
get_fs_long
(
buffer
+
3
);
...
...
@@ -252,6 +262,8 @@ void unmap_fixup(struct vm_area_struct *area,
mpnt
->
vm_start
=
end
;
if
(
mpnt
->
vm_inode
)
mpnt
->
vm_inode
->
i_count
++
;
if
(
mpnt
->
vm_ops
&&
mpnt
->
vm_ops
->
open
)
mpnt
->
vm_ops
->
open
(
mpnt
);
area
->
vm_end
=
addr
;
/* Truncate area */
insert_vm_struct
(
current
,
mpnt
);
}
...
...
@@ -261,6 +273,12 @@ void unmap_fixup(struct vm_area_struct *area,
if
(
!
mpnt
)
return
;
*
mpnt
=
*
area
;
if
(
mpnt
->
vm_ops
&&
mpnt
->
vm_ops
->
open
)
mpnt
->
vm_ops
->
open
(
mpnt
);
if
(
area
->
vm_ops
&&
area
->
vm_ops
->
close
)
{
area
->
vm_end
=
area
->
vm_start
;
area
->
vm_ops
->
close
(
area
);
}
insert_vm_struct
(
current
,
mpnt
);
}
...
...
@@ -416,7 +434,7 @@ void merge_segments(struct vm_area_struct *mpnt)
/*
* and if we have an inode, the offsets must be contiguous..
*/
if
(
mpnt
->
vm_inode
!=
NULL
)
{
if
(
(
mpnt
->
vm_inode
!=
NULL
)
||
(
mpnt
->
vm_flags
&
VM_SHM
)
)
{
if
(
prev
->
vm_offset
+
prev
->
vm_end
-
prev
->
vm_start
!=
mpnt
->
vm_offset
)
continue
;
}
...
...
mm/mprotect.c
View file @
1b7a152c
...
...
@@ -76,6 +76,8 @@ static inline int mprotect_fixup_start(struct vm_area_struct * vma,
n
->
vm_page_prot
=
prot
;
if
(
n
->
vm_inode
)
n
->
vm_inode
->
i_count
++
;
if
(
n
->
vm_ops
&&
n
->
vm_ops
->
open
)
n
->
vm_ops
->
open
(
n
);
insert_vm_struct
(
current
,
n
);
merge_segments
(
current
->
mm
->
mmap
);
return
0
;
...
...
@@ -98,6 +100,8 @@ static inline int mprotect_fixup_end(struct vm_area_struct * vma,
n
->
vm_page_prot
=
prot
;
if
(
n
->
vm_inode
)
n
->
vm_inode
->
i_count
++
;
if
(
n
->
vm_ops
&&
n
->
vm_ops
->
open
)
n
->
vm_ops
->
open
(
n
);
insert_vm_struct
(
current
,
n
);
merge_segments
(
current
->
mm
->
mmap
);
return
0
;
...
...
@@ -129,6 +133,10 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma,
vma
->
vm_page_prot
=
prot
;
if
(
vma
->
vm_inode
)
vma
->
vm_inode
->
i_count
+=
2
;
if
(
vma
->
vm_ops
&&
vma
->
vm_ops
->
open
)
{
vma
->
vm_ops
->
open
(
left
);
vma
->
vm_ops
->
open
(
right
);
}
insert_vm_struct
(
current
,
left
);
insert_vm_struct
(
current
,
right
);
merge_segments
(
current
->
mm
->
mmap
);
...
...
@@ -210,6 +218,8 @@ asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot)
start
=
tmp
;
if
(
vma
->
vm_end
<=
start
)
{
vma
=
vma
->
vm_next
;
if
(
vma
&&
vma
->
vm_start
<
start
)
vma
=
vma
->
vm_next
;
if
(
!
vma
||
vma
->
vm_start
!=
start
)
return
-
EFAULT
;
}
...
...
mm/swap.c
View file @
1b7a152c
...
...
@@ -616,6 +616,7 @@ do { unsigned long size = PAGE_SIZE << high; \
unsigned
long
__get_free_pages
(
int
priority
,
unsigned
long
order
)
{
unsigned
long
flags
;
int
reserved_pages
;
if
(
intr_count
&&
priority
!=
GFP_ATOMIC
)
{
static
int
count
=
0
;
...
...
@@ -625,10 +626,13 @@ unsigned long __get_free_pages(int priority, unsigned long order)
priority
=
GFP_ATOMIC
;
}
}
reserved_pages
=
5
;
if
(
priority
!=
GFP_NFS
)
reserved_pages
=
min_free_pages
;
save_flags
(
flags
);
repeat:
cli
();
if
((
priority
==
GFP_ATOMIC
)
||
nr_free_pages
>
min_free
_pages
)
{
if
((
priority
==
GFP_ATOMIC
)
||
nr_free_pages
>
reserved
_pages
)
{
RMQUEUE
(
order
);
restore_flags
(
flags
);
return
0
;
...
...
net/inet/devinet.c
View file @
1b7a152c
...
...
@@ -67,42 +67,6 @@ unsigned long ip_get_mask(unsigned long addr)
return
(
0
);
}
/*
* Perform an IP address matching operation
*/
int
ip_addr_match
(
unsigned
long
me
,
unsigned
long
him
)
{
int
i
;
unsigned
long
mask
=
0xFFFFFFFF
;
/*
* Simple case
*/
if
(
me
==
him
)
return
(
1
);
/*
* Look for a match ending in all 1's
*/
for
(
i
=
0
;
i
<
4
;
i
++
,
me
>>=
8
,
him
>>=
8
,
mask
>>=
8
)
{
if
((
me
&
0xFF
)
!=
(
him
&
0xFF
))
{
/*
* The only way this could be a match is for
* the rest of addr1 to be 0 or 255.
*/
if
(
me
!=
0
&&
me
!=
mask
)
return
(
0
);
return
(
1
);
}
}
return
(
1
);
}
/*
* Check the address for our address, broadcasts, etc.
*
...
...
net/inet/icmp.c
View file @
1b7a152c
...
...
@@ -176,8 +176,13 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
* Build Layer 2-3 headers for message back to source.
*/
offset
=
ip_build_header
(
skb
,
dev
->
pa_addr
,
iph
->
saddr
,
&
ndev
,
IPPROTO_ICMP
,
NULL
,
len
,
skb_in
->
ip_hdr
->
tos
,
255
);
{
unsigned
long
our_addr
=
dev
->
pa_addr
;
if
(
iph
->
daddr
!=
our_addr
&&
ip_chk_addr
(
iph
->
daddr
)
==
IS_MYADDR
)
our_addr
=
iph
->
daddr
;
offset
=
ip_build_header
(
skb
,
our_addr
,
iph
->
saddr
,
&
ndev
,
IPPROTO_ICMP
,
NULL
,
len
,
skb_in
->
ip_hdr
->
tos
,
255
);
}
if
(
offset
<
0
)
{
...
...
net/inet/udp.c
View file @
1b7a152c
...
...
@@ -276,7 +276,7 @@ static int udp_send(struct sock *sk, struct sockaddr_in *sin,
*/
buff
=
skb
->
data
;
saddr
=
0
;
saddr
=
sk
->
saddr
;
dev
=
NULL
;
tmp
=
sk
->
prot
->
build_header
(
skb
,
saddr
,
sin
->
sin_addr
.
s_addr
,
&
dev
,
IPPROTO_UDP
,
sk
->
opt
,
skb
->
mem_len
,
sk
->
ip_tos
,
sk
->
ip_ttl
);
...
...
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