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
7450aa7e
Commit
7450aa7e
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 1.1.3
parent
a92264df
Changes
48
Show whitespace changes
Inline
Side-by-side
Showing
48 changed files
with
1614 additions
and
604 deletions
+1614
-604
Configure
Configure
+51
-151
Makefile
Makefile
+5
-6
config.in
config.in
+61
-63
drivers/block/ll_rw_blk.c
drivers/block/ll_rw_blk.c
+5
-5
drivers/scsi/fdomain.c
drivers/scsi/fdomain.c
+15
-6
fs/block_dev.c
fs/block_dev.c
+72
-12
fs/buffer.c
fs/buffer.c
+1071
-187
fs/devices.c
fs/devices.c
+20
-0
fs/ext/file.c
fs/ext/file.c
+1
-1
fs/ext/freelists.c
fs/ext/freelists.c
+5
-5
fs/ext/inode.c
fs/ext/inode.c
+3
-3
fs/ext/namei.c
fs/ext/namei.c
+14
-14
fs/ext/truncate.c
fs/ext/truncate.c
+3
-3
fs/ext2/balloc.c
fs/ext2/balloc.c
+7
-7
fs/ext2/file.c
fs/ext2/file.c
+9
-1
fs/ext2/ialloc.c
fs/ext2/ialloc.c
+8
-8
fs/ext2/inode.c
fs/ext2/inode.c
+87
-3
fs/ext2/namei.c
fs/ext2/namei.c
+13
-13
fs/ext2/super.c
fs/ext2/super.c
+9
-9
fs/ext2/truncate.c
fs/ext2/truncate.c
+5
-5
fs/minix/bitmap.c
fs/minix/bitmap.c
+5
-5
fs/minix/file.c
fs/minix/file.c
+1
-1
fs/minix/inode.c
fs/minix/inode.c
+7
-7
fs/minix/namei.c
fs/minix/namei.c
+13
-13
fs/minix/truncate.c
fs/minix/truncate.c
+2
-2
fs/msdos/fat.c
fs/msdos/fat.c
+3
-3
fs/msdos/file.c
fs/msdos/file.c
+1
-1
fs/msdos/inode.c
fs/msdos/inode.c
+1
-1
fs/msdos/misc.c
fs/msdos/misc.c
+1
-1
fs/msdos/namei.c
fs/msdos/namei.c
+9
-9
fs/proc/array.c
fs/proc/array.c
+4
-0
fs/proc/root.c
fs/proc/root.c
+1
-0
fs/sysv/balloc.c
fs/sysv/balloc.c
+6
-6
fs/sysv/file.c
fs/sysv/file.c
+1
-1
fs/sysv/ialloc.c
fs/sysv/ialloc.c
+5
-5
fs/sysv/inode.c
fs/sysv/inode.c
+2
-2
fs/sysv/namei.c
fs/sysv/namei.c
+13
-13
fs/sysv/truncate.c
fs/sysv/truncate.c
+2
-2
fs/xiafs/bitmap.c
fs/xiafs/bitmap.c
+4
-4
fs/xiafs/file.c
fs/xiafs/file.c
+1
-1
fs/xiafs/inode.c
fs/xiafs/inode.c
+2
-2
fs/xiafs/namei.c
fs/xiafs/namei.c
+13
-13
fs/xiafs/truncate.c
fs/xiafs/truncate.c
+2
-2
include/linux/ext2_fs.h
include/linux/ext2_fs.h
+1
-0
include/linux/fs.h
include/linux/fs.h
+34
-4
include/linux/mm.h
include/linux/mm.h
+1
-0
include/linux/sys.h
include/linux/sys.h
+1
-1
mm/swap.c
mm/swap.c
+14
-3
No files found.
Configure
View file @
7450aa7e
...
...
@@ -11,87 +11,6 @@
#
# Each line in the config file is a command.
#
# # internal comment
#
# Lines beginning with a `#' are ignored.
#
# : message
#
# `:' causes the line to be echoed to the screen.
#
# * external comment
#
# `*' causes the line to be placed in the output
# configuration file as a comment as well as being
# echoed to the screen.
#
# if condition
# ... commands ...
# else
# ... commands ...
# fi
#
# This does the obvious thing. The `else' clause is
# optional. Conditionals can be nested.
#
# The `condition' can be any valid bash expression.
# They typically involve tests against environment
# variables set by configuration options. For example,
#
# if [ "$CONFIG_SCSI" = "y" ]
# ...More stuff...
# fi
#
# Note! That there is no `then' keyword.
#
# bool 'prompt' CONFIG_VARIABLE default
#
# This prompts the user for a boolean value.
# The prompt may not contain an apostrophe.
# `default' should be either `y' or `n'.
# The user's response is recorded in four places.
#
# In .config, if `y'
# CONFIG_VARIABLE = CONFIG_VARIABLE
# In .config, if `n'
# # CONFIG_VARIABLE is not set
#
# In autoconf.h, if `y'
# #define CONFIG_VARIABLE 1
# In autoconf.h, if `n'
# #undef CONFIG_VARIABLE
#
# In config.in, if `y'
# bool 'prompt' CONFIG_VARIABLE y
# In config.in, if `n'
# bool 'prompt' CONFIG_VARIABLE n
#
# In the environment of the Configure script, if `y'
# CONFIG_VARIABLE = y
# In the environment of the Configure script, if `n'
# CONFIG_VARIABLE = n
#
# The value is placed into the environment of the Configure
# script so that later parts of config.in can use the `if'
# command to inspect the results of previous queries.
#
# int 'prompt' CONFIG_VARIABLE default
#
# This prompts the user for an integer value.
# The prompt may not contain an apostrophe.
# `default' should be an integer.
#
# The response is recorded as follows.
#
# In .config
# CONFIG_VARIABLE = response
# In autoconf.h
# #define CONFIG_VARIABLE (response)
# In config.in
# int 'prompt' CONFIG_VARIABLE response
# In the environment of the Configure script
# CONFIG_VARIABLE = response
#
# 050793 - use IFS='@' to get around a bug in a pre-version of bash-1.13
# with an empty IFS.
...
...
@@ -114,58 +33,85 @@ set -f -h
# readln prompt default
#
function
readln
()
{
if
[
"
$DEFAULT
"
=
"-d"
]
;
then
echo
"
$1
"
ans
=
$2
else
echo
-n
"
$1
"
IFS
=
'@'
read
ans </dev/tty
||
exit
1
[
-z
"
$ans
"
]
&&
ans
=
$2
fi
}
#
# change updates the "config.new" file according to the answer
#
# change define old new
#
function
change
()
{
if
[
"
$2
"
!=
"
$3
"
]
;
then
sed
"s/
$1
$2$/$1
$3
/"
<
$CONFIG_NEW
>
.tmpc
mv
.tmpc
$CONFIG_NEW
fi
}
#
# comment does some pretty-printing
#
# comment 'xxx'
#
function
comment
()
{
echo
"*"
;
echo
"*
$1
"
;
echo
"*"
(
echo
""
;
echo
"#"
;
echo
"#
$1
"
;
echo
"#"
)
>>
$CONFIG
(
echo
""
;
echo
"/*"
;
echo
" *
$1
"
;
echo
" */"
)
>>
$CONFIG_H
}
#
# bool processes a boolean argument
#
# bool
tail
# bool
question define default
#
function
bool
()
{
# Slimier hack to get bash to rescan a line.
eval
"set --
$1
"
ans
=
""
while
[
"
$ans
"
!=
"y"
-a
"
$ans
"
!=
"n"
]
;
do
readln
"
$1
(
$2
) [
$3
] "
"
$3
"
done
if
[
"
$ans
"
=
"y"
]
;
then
echo
"
$2
=
$2
"
>>
$CONFIG
echo
"
$2
=
$2
"
>>
$CONFIG
echo
"#define
$2
1"
>>
$CONFIG_H
else
echo
"#
$2
is not set"
>>
$CONFIG
echo
"#undef
$2
"
>>
$CONFIG_H
fi
raw_input_line
=
"bool '
$1
'
$2
$ans
"
change
$2
$3
$ans
eval
"
$2
=
$ans
"
}
#
# int processes an integer argument
#
# int
tail
# int
question define default
#
function
int
()
{
# Slimier hack to get bash to rescan a line.
eval
"set --
$1
"
ans
=
"x"
while
[
$[$ans
+0]
!=
"
$ans
"
]
;
do
readln
"
$1
(
$2
) [
$3
] "
"
$3
"
done
echo
"
$2
=
$ans
"
>>
$CONFIG
echo
"
$2
=
$ans
"
>>
$CONFIG
echo
"#define
$2
(
$ans
)"
>>
$CONFIG_H
raw_input_line
=
"int '
$1
'
$2
$ans
"
eval
"
$2
=
$ans
"
}
CONFIG
=
.tmpconfig
CONFIG_H
=
include/linux/autoconf.h
trap
"rm -f
$CONFIG
$CONFIG_H
config.new ; exit 1"
1 2
CONFIG_H
=
.tmpconfig.h
CONFIG_NEW
=
config.new
trap
"rm -f
$CONFIG
$CONFIG_H
$CONFIG_NEW
; exit 1"
1 2
#
# Make sure we start out with a clean slate.
#
>
config.new
cp
config.in
$CONFIG_NEW
echo
"#"
>
$CONFIG
echo
"# Automatically generated make config: don't edit"
>>
$CONFIG
echo
"#"
>>
$CONFIG
...
...
@@ -174,62 +120,16 @@ echo "/*" > $CONFIG_H
echo
" * Automatically generated C config: don't edit"
>>
$CONFIG_H
echo
" */"
>>
$CONFIG_H
stack
=
''
branch
=
't'
while
IFS
=
'@'
read
raw_input_line
do
# Slimy hack to get bash to rescan a line.
read
cmd rest
<<-
END_OF_COMMAND
$raw_input_line
END_OF_COMMAND
if
[
"
$cmd
"
=
"*"
]
;
then
if
[
"
$branch
"
=
"t"
]
;
then
echo
"
$raw_input_line
"
echo
"#
$rest
"
>>
$CONFIG
if
[
"
$prevcmd
"
!=
"*"
]
;
then
echo
>>
$CONFIG_H
echo
"/*
$rest
"
>>
$CONFIG_H
else
echo
" *
$rest
"
>>
$CONFIG_H
fi
prevcmd
=
"*"
fi
else
[
"
$prevcmd
"
=
"*"
]
&&
echo
" */"
>>
$CONFIG_H
prevcmd
=
""
case
"
$cmd
"
in
:
)
[
"
$branch
"
=
"t"
]
&&
echo
"
$raw_input_line
"
;;
int
)
[
"
$branch
"
=
"t"
]
&&
int
"
$rest
"
;;
bool
)
[
"
$branch
"
=
"t"
]
&&
bool
"
$rest
"
;;
exec
)
[
"
$branch
"
=
"t"
]
&&
(
sh
-c
"
$rest
"
)
;;
if
)
stack
=
"
$branch
$stack
"
if
[
"
$branch
"
=
"t"
]
&&
eval
"
$rest
"
;
then
branch
=
t
else
branch
=
f
fi
;;
else
)
if
[
"
$branch
"
=
"t"
]
;
then
branch
=
f
else
read
branch rest
<<-
END_OF_STACK
$stack
END_OF_STACK
fi
;;
fi
)
[
-z
"
$stack
"
]
&&
echo
"Error! Extra fi."
1>&2
read
branch stack
<<-
END_OF_STACK
$stack
END_OF_STACK
;;
esac
fi
echo
"
$raw_input_line
"
>>
config.new
done
[
"
$prevcmd
"
=
"*"
]
&&
echo
" */"
>>
$CONFIG_H
DEFAULT
=
$1
.
./config.in
[
-z
"
$stack
"
]
||
echo
"Error! Untermiated if."
1>&2
if
[
"
$CONFIG_SOUND
"
=
"y"
]
;
then
$MAKE
-C
drivers/sound config
||
exit
1
fi
mv
.tmpconfig .config
mv
.tmpconfig.h include/linux/autoconf.h
mv
config.in config.old
mv
config.new config.in
...
...
Makefile
View file @
7450aa7e
VERSION
=
1
PATCHLEVEL
=
1
SUBLEVEL
=
2
SUBLEVEL
=
3
all
:
Version zImage
...
...
@@ -116,12 +116,11 @@ endif
Version
:
dummy
rm
-f
tools/version.h
oldconfig
:
$(CONFIG_SHELL)
Configure
-d
$(OPTS)
config
:
$(CONFIG_SHELL)
Configure
$(OPTS)
< config.in
@
if
grep
-s
'^CONFIG_SOUND'
.tmpconfig
;
then
\
$(MAKE)
-C
drivers/sound config
;
\
else
:
;
fi
mv
.tmpconfig .config
$(CONFIG_SHELL)
Configure
$(OPTS)
linuxsubdirs
:
dummy
set
-e
;
for
i
in
$(SUBDIRS)
;
do
$(MAKE)
-C
$$
i
;
done
...
...
config.in
View file @
7450aa7e
...
...
@@ -2,9 +2,9 @@
# For a description of the syntax of this configuration file,
# see the Configure script.
#
*
* General setup
*
comment 'General setup'
bool 'Kernel math emulation' CONFIG_MATH_EMULATION y
bool 'Normal harddisk support' CONFIG_BLK_DEV_HD y
bool 'XT harddisk support' CONFIG_BLK_DEV_XD n
...
...
@@ -12,59 +12,60 @@ bool 'TCP/IP networking' CONFIG_INET y
bool 'Limit memory to low 16MB' CONFIG_MAX_16M n
bool 'System V IPC' CONFIG_SYSVIPC y
bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y
*
* Program binary formats
*
comment 'Program binary formats'
bool 'Elf executables' CONFIG_BINFMT_ELF y
bool 'COFF executables' CONFIG_BINFMT_COFF y
*
* SCSI support
*
comment 'SCSI support'
bool 'SCSI support?' CONFIG_SCSI n
if [ "$CONFIG_SCSI" = "n" ]
:
: Skipping SCSI configuration options...
:
if [ "$CONFIG_SCSI" = "n" ]; then
comment 'Skipping SCSI configuration options...'
else
*
* SCSI support type (disk, tape, CDrom)
*
comment 'SCSI support type (disk, tape, CDrom)'
bool 'Scsi disk support' CONFIG_BLK_DEV_SD y
bool 'Scsi tape support' CONFIG_CHR_DEV_ST
y
bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR
y
bool 'Scsi generic support' CONFIG_CHR_DEV_SG
y
*
* SCSI low-level drivers
*
bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X
y
bool 'Scsi tape support' CONFIG_CHR_DEV_ST
n
bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR
n
bool 'Scsi generic support' CONFIG_CHR_DEV_SG
n
comment 'SCSI low-level drivers'
bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X
n
bool 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 y
bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740
y
bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN
y
bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380
y
bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16
y
bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE
y
bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128
y
bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR
y
bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST
y
bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740
n
bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN
n
bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380
n
bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16
n
bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE
n
bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128
n
bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR
n
bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST
n
fi
*
* Network device support
*
comment 'Network device support'
bool 'Network device support?' CONFIG_ETHERCARDS y
if [ "$CONFIG_ETHERCARDS" = "n" ]
:
: Skipping ethercard configuration options...
:
if [ "$CONFIG_ETHERCARDS" = "n" ]
; then
comment 'Skipping ethercard configuration options...'
else
bool 'SLIP (serial line) support' CONFIG_SLIP n
if [ "$CONFIG_SLIP" = "y" ]
if [ "$CONFIG_SLIP" = "y" ]
; then
bool ' CSLIP compressed headers' SL_COMPRESSED y
# bool ' SLIP debugging on' SL_DUMP y
fi
#bool 'PPP (point-to-point) support' CONFIG_PPP n
bool 'PLIP (parallel port) support' CONFIG_PLIP n
bool 'NE2000/NE1000 support' CONFIG_NE2000 n
bool 'WD80
*
3 support' CONFIG_WD80x3 y
bool 'WD80
E
3 support' CONFIG_WD80x3 y
bool 'SMC Ultra support' CONFIG_ULTRA n
bool '3c501 support' CONFIG_EL1 n
bool '3c503 support' CONFIG_EL2 n
...
...
@@ -77,20 +78,22 @@ bool 'AT1700 support' CONFIG_AT1700 n
#bool 'Zenith Z-Note support' CONFIG_ZNET n
#bool 'EtherExpress support' CONFIG_EEXPRESS n
bool 'DEPCA support' CONFIG_DEPCA n
#bool 'NI52
**
support' CONFIG_NI52 n
#bool 'NI65
**
support' CONFIG_NI65 n
#bool 'NI52
EE
support' CONFIG_NI52 n
#bool 'NI65
EE
support' CONFIG_NI65 n
#bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
#bool 'Cabletron E21xx support (not recommended)' CONFIG_E21 n
bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n
fi
*
comment 'CD-ROM drivers'
bool 'Sony CDU31A CDROM driver support' CONFIG_CDU31A n
bool 'Mitsumi CDROM driver support' CONFIG_MCD n
bool 'Matsushita/Panasonic CDROM driver support' CONFIG_SBPCD n
*
* Filesystems
*
comment 'Filesystems'
bool 'Standard (minix) fs support' CONFIG_MINIX_FS y
bool 'Extended fs support' CONFIG_EXT_FS n
bool 'Second extended fs support' CONFIG_EXT2_FS y
...
...
@@ -101,13 +104,13 @@ bool 'NFS filesystem support' CONFIG_NFS_FS y
bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS n
bool 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS n
bool 'System V and Coherent filesystem support' CONFIG_SYSV_FS n
*
* character devices
*
comment 'character devices'
bool 'Parallel printer support' CONFIG_PRINTER n
bool 'Logitech busmouse support' CONFIG_BUSMOUSE n
bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE y
if [ "$CONFIG_PSMOUSE" = "y" ]
if [ "$CONFIG_PSMOUSE" = "y" ]
; then
bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE y
fi
bool 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n
...
...
@@ -115,23 +118,18 @@ bool 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n
bool 'Selection (cut and paste for virtual consoles)' CONFIG_SELECTION n
bool 'QIC-02 tape support' CONFIG_TAPE_QIC02 n
bool 'QIC-117 tape support' CONFIG_FTAPE n
if [ "$CONFIG_FTAPE" = "y" ]
if [ "$CONFIG_FTAPE" = "y" ]
; then
int ' number of ftape buffers' NR_FTAPE_BUFFERS 3
fi
*
* Sound
*
comment 'Sound'
bool 'Sound card support' CONFIG_SOUND n
*
* Kernel hacking
*
comment 'Kernel hacking'
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC n
bool 'Kernel profiling support' CONFIG_PROFILE n
if [ "$CONFIG_SCSI" = "y" ]
if [ "$CONFIG_SCSI" = "y" ]
; then
bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS y
fi
if [ "$CONFIG_SOUND" = "y" ]
exec touch .makesound
else
exec rm -f .makesound
fi
drivers/block/ll_rw_blk.c
View file @
7450aa7e
...
...
@@ -156,7 +156,7 @@ static void add_request(struct blk_dev_struct * dev, struct request * req)
req
->
next
=
NULL
;
cli
();
if
(
req
->
bh
)
req
->
bh
->
b_dirt
=
0
;
mark_buffer_clean
(
req
->
bh
)
;
if
(
!
(
tmp
=
dev
->
current_request
))
{
dev
->
current_request
=
req
;
(
dev
->
request_fn
)();
...
...
@@ -240,12 +240,12 @@ static void make_request(int major,int rw, struct buffer_head * bh)
!
req
->
waiting
&&
req
->
cmd
==
rw
&&
req
->
sector
+
req
->
nr_sectors
==
sector
&&
req
->
nr_sectors
<
2
5
4
)
req
->
nr_sectors
<
2
4
4
)
{
req
->
bhtail
->
b_reqnext
=
bh
;
req
->
bhtail
=
bh
;
req
->
nr_sectors
+=
count
;
bh
->
b_dirt
=
0
;
mark_buffer_clean
(
bh
)
;
sti
();
return
;
}
...
...
@@ -254,14 +254,14 @@ static void make_request(int major,int rw, struct buffer_head * bh)
!
req
->
waiting
&&
req
->
cmd
==
rw
&&
req
->
sector
-
count
==
sector
&&
req
->
nr_sectors
<
2
5
4
)
req
->
nr_sectors
<
2
4
4
)
{
req
->
nr_sectors
+=
count
;
bh
->
b_reqnext
=
req
->
bh
;
req
->
buffer
=
bh
->
b_data
;
req
->
current_nr_sectors
=
count
;
req
->
sector
=
sector
;
bh
->
b_dirt
=
0
;
mark_buffer_clean
(
bh
)
;
req
->
bh
=
bh
;
sti
();
return
;
...
...
drivers/scsi/fdomain.c
View file @
7450aa7e
/* fdomain.c -- Future Domain TMC-16x0 SCSI driver
* Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu
* Revised:
Fri Apr 1 23:47:55
1994 by faith@cs.unc.edu
* Revised:
Thu Apr 7 20:30:09
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.1
5 1994/04/02 04:48:04
root Exp $
* $Id: fdomain.c,v 5.1
6 1994/04/08 00:30:15
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
...
...
@@ -168,7 +168,7 @@
#include <linux/string.h>
#include <linux/ioport.h>
#define VERSION "$Revision: 5.1
5
$"
#define VERSION "$Revision: 5.1
6
$"
/* START OF USER DEFINABLE OPTIONS */
...
...
@@ -282,6 +282,9 @@ static int TMC_Status_port;
static
int
Write_FIFO_port
;
static
int
Write_SCSI_Data_port
;
static
int
FIFO_Size
=
0x2000
;
/* 8k FIFO for
pre-tmc18c30 chips */
extern
void
fdomain_16x0_intr
(
int
unused
);
static
void
*
addresses
[]
=
{
...
...
@@ -421,7 +424,10 @@ static int fdomain_is_valid_port( int port )
outb( 0x80, port + IO_Control );
if (inb( port + Configuration2 ) & 0x80 == 0x80) {
outb( 0x00, port + IO_Control );
if (inb( port + Configuration2 ) & 0x80 == 0x00) chip = tmc18c30;
if (inb( port + Configuration2 ) & 0x80 == 0x00) {
chip = tmc18c30;
FIFO_Size = 0x800; /* 2k FIFO */
}
}
#else
...
...
@@ -429,7 +435,10 @@ static int fdomain_is_valid_port( int port )
have problems. Lets assume it is an
18c30 if the RAM is disabled. */
if
(
inb
(
port
+
Configuration2
)
&
0x02
)
chip
=
tmc18c30
;
if
(
inb
(
port
+
Configuration2
)
&
0x02
)
{
chip
=
tmc18c30
;
FIFO_Size
=
0x800
;
/* 2k FIFO */
}
#endif
/* If that failed, we are an 18c50. */
}
...
...
@@ -1127,7 +1136,7 @@ void fdomain_16x0_intr( int unused )
}
if
(
current_SC
->
SCp
.
have_data_in
==
-
1
)
{
/* DATA OUT */
while
(
(
data_count
=
0x2000
-
inw
(
FIFO_Data_Count_port
))
>
512
)
{
while
(
(
data_count
=
FIFO_Size
-
inw
(
FIFO_Data_Count_port
))
>
512
)
{
#if EVERY_ACCESS
printk
(
"DC=%d, "
,
data_count
)
;
#endif
...
...
fs/block_dev.c
View file @
7450aa7e
...
...
@@ -14,13 +14,18 @@
extern
int
*
blk_size
[];
extern
int
*
blksize_size
[];
#define NBUF 64
int
block_write
(
struct
inode
*
inode
,
struct
file
*
filp
,
char
*
buf
,
int
count
)
{
int
blocksize
,
blocksize_bits
,
i
;
int
block
;
int
blocksize
,
blocksize_bits
,
i
,
j
;
int
block
,
blocks
;
int
offset
;
int
chars
;
int
written
=
0
;
int
cluster_list
[
4
];
struct
buffer_head
*
bhlist
[
NBUF
];
int
blocks_per_cluster
;
unsigned
int
size
;
unsigned
int
dev
;
struct
buffer_head
*
bh
;
...
...
@@ -38,6 +43,8 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
i
>>=
1
;
}
blocks_per_cluster
=
PAGE_SIZE
/
blocksize
;
block
=
filp
->
f_pos
>>
blocksize_bits
;
offset
=
filp
->
f_pos
&
(
blocksize
-
1
);
...
...
@@ -51,11 +58,50 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
chars
=
blocksize
-
offset
;
if
(
chars
>
count
)
chars
=
count
;
#if 0
if (chars == blocksize)
bh = getblk(dev, block, blocksize);
else
bh
=
breada
(
dev
,
block
,
blocksize
,
offset
,
size
<<
blocksize_bits
);
bh = breada(dev,block,block+1,block+2,-1);
#else
for
(
i
=
0
;
i
<
blocks_per_cluster
;
i
++
)
cluster_list
[
i
]
=
block
+
i
;
if
((
block
%
blocks_per_cluster
)
==
0
)
generate_cluster
(
dev
,
cluster_list
,
blocksize
);
bh
=
getblk
(
dev
,
block
,
blocksize
);
if
(
chars
!=
blocksize
&&
!
bh
->
b_uptodate
)
{
if
(
!
filp
->
f_reada
||
!
read_ahead
[
MAJOR
(
dev
)])
{
/* We do this to force the read of a single buffer */
brelse
(
bh
);
bh
=
bread
(
dev
,
block
,
blocksize
);
}
else
{
/* Read-ahead before write */
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
;
bhlist
[
0
]
=
bh
;
for
(
i
=
1
;
i
<
blocks
;
i
++
){
if
(((
i
+
block
)
%
blocks_per_cluster
)
==
0
)
{
for
(
j
=
0
;
j
<
blocks_per_cluster
;
j
++
)
cluster_list
[
j
]
=
block
+
i
+
j
;
generate_cluster
(
dev
,
cluster_list
,
blocksize
);
};
bhlist
[
i
]
=
getblk
(
dev
,
block
+
i
,
blocksize
);
if
(
!
bhlist
[
i
]){
while
(
i
>=
0
)
brelse
(
bhlist
[
i
--
]);
return
written
?
written
:
-
EIO
;
};
};
ll_rw_block
(
READ
,
blocks
,
bhlist
);
for
(
i
=
1
;
i
<
blocks
;
i
++
)
brelse
(
bhlist
[
i
]);
};
};
#endif
block
++
;
if
(
!
bh
)
return
written
?
written
:-
EIO
;
...
...
@@ -68,23 +114,23 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
p
+=
chars
;
buf
+=
chars
;
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
0
);
mark_buffer_dirty
(
bh
,
0
);
brelse
(
bh
);
}
filp
->
f_reada
=
1
;
return
written
;
}
#define NBUF 32
int
block_read
(
struct
inode
*
inode
,
struct
file
*
filp
,
char
*
buf
,
int
count
)
{
unsigned
int
block
;
unsigned
int
offset
;
int
blocksize
;
int
blocksize_bits
,
i
;
unsigned
int
left
;
unsigned
int
blocks
;
unsigned
int
blocks
,
rblocks
,
left
;
int
bhrequest
,
uptodate
;
int
cluster_list
[
4
];
int
blocks_per_cluster
;
struct
buffer_head
**
bhb
,
**
bhe
;
struct
buffer_head
*
buflist
[
NBUF
];
struct
buffer_head
*
bhreq
[
NBUF
];
...
...
@@ -110,6 +156,8 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count)
else
size
=
INT_MAX
;
blocks_per_cluster
=
PAGE_SIZE
/
blocksize
;
if
(
offset
>
size
)
left
=
0
;
else
...
...
@@ -122,12 +170,16 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count)
block
=
offset
>>
blocksize_bits
;
offset
&=
blocksize
-
1
;
size
>>=
blocksize_bits
;
blocks
=
(
left
+
offset
+
blocksize
-
1
)
>>
blocksize_bits
;
rblocks
=
blocks
=
(
left
+
offset
+
blocksize
-
1
)
>>
blocksize_bits
;
bhb
=
bhe
=
buflist
;
if
(
filp
->
f_reada
)
{
blocks
+=
read_ahead
[
MAJOR
(
dev
)]
/
(
blocksize
>>
9
);
if
(
blocks
<
read_ahead
[
MAJOR
(
dev
)]
/
(
blocksize
>>
9
))
blocks
=
read_ahead
[
MAJOR
(
dev
)]
/
(
blocksize
>>
9
);
if
(
block
+
blocks
>
size
)
blocks
=
size
-
block
;
blocks
-=
(
block
%
blocks_per_cluster
);
if
(
rblocks
>
blocks
)
blocks
=
rblocks
;
}
/* We do this in a two stage process. We first try and request
...
...
@@ -145,6 +197,12 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count)
uptodate
=
1
;
while
(
blocks
)
{
--
blocks
;
#if 1
if
((
block
%
blocks_per_cluster
)
==
0
)
{
for
(
i
=
0
;
i
<
blocks_per_cluster
;
i
++
)
cluster_list
[
i
]
=
block
+
i
;
generate_cluster
(
dev
,
cluster_list
,
blocksize
);
}
#endif
*
bhb
=
getblk
(
dev
,
block
++
,
blocksize
);
if
(
*
bhb
&&
!
(
*
bhb
)
->
b_uptodate
)
{
uptodate
=
0
;
...
...
@@ -163,8 +221,10 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count)
}
/* Now request them all */
if
(
bhrequest
)
if
(
bhrequest
)
{
ll_rw_block
(
READ
,
bhrequest
,
bhreq
);
refill_freelist
(
blocksize
);
}
do
{
/* Finish off all I/O that has actually completed */
if
(
*
bhe
)
{
...
...
fs/buffer.c
View file @
7450aa7e
...
...
@@ -26,8 +26,10 @@
#include <linux/string.h>
#include <linux/locks.h>
#include <linux/errno.h>
#include <linux/malloc.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/io.h>
#ifdef CONFIG_SCSI
...
...
@@ -46,23 +48,76 @@ extern int check_cdu31a_media_change(int, int);
extern
int
check_mcd_media_change
(
int
,
int
);
#endif
#define NR_SIZES 4
static
char
buffersize_index
[
9
]
=
{
-
1
,
0
,
1
,
-
1
,
2
,
-
1
,
-
1
,
-
1
,
3
};
static
short
int
bufferindex_size
[
NR_SIZES
]
=
{
512
,
1024
,
2048
,
4096
};
#define BUFSIZE_INDEX(X) (buffersize_index[(X)>>9])
static
int
grow_buffers
(
int
pri
,
int
size
);
static
struct
buffer_head
*
hash_table
[
NR_HASH
];
static
struct
buffer_head
*
free_list
=
NULL
;
static
int
shrink_specific_buffers
(
unsigned
int
priority
,
int
size
);
static
int
maybe_shrink_lav_buffers
(
int
);
static
int
nr_hash
=
0
;
/* Size of hash table */
static
struct
buffer_head
**
hash_table
;
struct
buffer_head
**
buffer_pages
;
static
struct
buffer_head
*
lru_list
[
NR_LIST
]
=
{
NULL
,
};
static
struct
buffer_head
*
free_list
[
NR_SIZES
]
=
{
NULL
,
};
static
struct
buffer_head
*
unused_list
=
NULL
;
static
struct
wait_queue
*
buffer_wait
=
NULL
;
int
nr_buffers
=
0
;
int
nr_buffers_type
[
NR_LIST
]
=
{
0
,};
int
nr_buffers_size
[
NR_SIZES
]
=
{
0
,};
int
nr_buffers_st
[
NR_SIZES
][
NR_LIST
]
=
{{
0
,},};
int
buffer_usage
[
NR_SIZES
]
=
{
0
,};
/* Usage counts used to determine load average */
int
buffers_lav
[
NR_SIZES
]
=
{
0
,};
/* Load average of buffer usage */
int
nr_free
[
NR_SIZES
]
=
{
0
,};
int
buffermem
=
0
;
int
nr_buffer_heads
=
0
;
static
int
min_free_pages
=
20
;
/* nr free pages needed before buffer grows */
extern
int
*
blksize_size
[];
/* Here is the parameter block for the bdflush process. */
static
void
wakeup_bdflush
(
int
);
#define N_PARAM 9
#define LAV
static
union
bdflush_param
{
struct
{
int
nfract
;
/* Percentage of buffer cache dirty to
activate bdflush */
int
ndirty
;
/* Maximum number of dirty blocks to write out per
wake-cycle */
int
nrefill
;
/* Number of clean buffers to try and obtain
each time we call refill */
int
nref_dirt
;
/* Dirty buffer threshold for activating bdflush
when trying to refill buffers. */
int
clu_nfract
;
/* Percentage of buffer cache to scan to
search for free clusters */
int
age_buffer
;
/* Time for normal buffer to age before
we flush it */
int
age_super
;
/* Time for superblock to age before we
flush it */
int
lav_const
;
/* Constant used for load average (time
constant */
int
lav_ratio
;
/* Used to determine how low a lav for a
particular size can go before we start to
trim back the buffers */
}
b_un
;
unsigned
int
data
[
N_PARAM
];
}
bdf_prm
=
{{
25
,
500
,
64
,
256
,
15
,
3000
,
500
,
1884
,
2
}};
/* The lav constant is set for 1 minute, as long as the update process runs
every 5 seconds. If you change the frequency of update, the time
constant will also change. */
/* These are the min and max parameter values that we will allow to be assigned */
static
int
bdflush_min
[
N_PARAM
]
=
{
0
,
10
,
5
,
25
,
0
,
100
,
100
,
1
,
1
};
static
int
bdflush_max
[
N_PARAM
]
=
{
100
,
5000
,
2000
,
2000
,
100
,
60000
,
60000
,
2047
,
5
};
/*
* Rewrote the wait-routines to use the "new" wait-queue functionality,
* and getting rid of the cli-sti pairs. The wait-queue routines still
...
...
@@ -93,28 +148,38 @@ void __wait_on_buffer(struct buffer_head * bh)
return until all buffer writes have completed. Sync() may return
before the writes have finished; fsync() may not. */
/* Godamity-damn. Some buffers (bitmaps for filesystems)
spontaneously dirty themselves without ever brelse being called.
We will ultimately want to put these in a separate list, but for
now we search all of the lists for dirty buffers */
static
int
sync_buffers
(
dev_t
dev
,
int
wait
)
{
int
i
,
retry
,
pass
=
0
,
err
=
0
;
struct
buffer_head
*
bh
;
int
nlist
,
ncount
;
struct
buffer_head
*
bh
,
*
next
;
/* One pass for no-wait, three for wait:
0) write out all dirty, unlocked buffers;
1) write out all dirty buffers, waiting if locked;
2) wait for completion by waiting for all buffers to unlock.
*/
repeat:
2) wait for completion by waiting for all buffers to unlock. */
repeat:
retry
=
0
;
bh
=
free_list
;
for
(
i
=
nr_buffers
*
2
;
i
--
>
0
;
bh
=
bh
->
b_next_free
)
{
ncount
=
0
;
/* We search all lists as a failsafe mechanism, not because we expect
there to be dirty buffers on any of the other lists. */
for
(
nlist
=
0
;
nlist
<
NR_LIST
;
nlist
++
)
{
repeat1:
bh
=
lru_list
[
nlist
];
if
(
!
bh
)
continue
;
for
(
i
=
nr_buffers_type
[
nlist
]
*
2
;
i
--
>
0
;
bh
=
next
)
{
if
(
bh
->
b_list
!=
nlist
)
goto
repeat1
;
next
=
bh
->
b_next_free
;
if
(
!
lru_list
[
nlist
])
break
;
if
(
dev
&&
bh
->
b_dev
!=
dev
)
continue
;
#ifdef 0
/* Disable bad-block debugging code */
if
(
bh
->
b_req
&&
!
bh
->
b_lock
&&
!
bh
->
b_dirt
&&
!
bh
->
b_uptodate
)
printk
(
"Warning (IO error) - orphaned block %08x on %04x
\n
"
,
bh
->
b_blocknr
,
bh
->
b_dev
);
#endif
if
(
bh
->
b_lock
)
{
/* Buffer is locked; skip it unless wait is
...
...
@@ -125,12 +190,13 @@ static int sync_buffers(dev_t dev, int wait)
}
wait_on_buffer
(
bh
);
}
/* If an unlocked buffer is not uptodate, there has been
an IO error. Skip it. */
/* If an unlocked buffer is not uptodate, there has
been
an IO error. Skip it. */
if
(
wait
&&
bh
->
b_req
&&
!
bh
->
b_lock
&&
!
bh
->
b_dirt
&&
!
bh
->
b_uptodate
)
{
err
=
1
;
printk
(
"Weird - unlocked, clean and not uptodate buffer on %d list %d
\n
"
,
nlist
);
continue
;
}
/* Don't write clean buffers. Don't write ANY buffers
...
...
@@ -138,10 +204,19 @@ static int sync_buffers(dev_t dev, int wait)
if
(
!
bh
->
b_dirt
||
pass
>=
2
)
continue
;
bh
->
b_count
++
;
bh
->
b_flushtime
=
0
;
ll_rw_block
(
WRITE
,
1
,
&
bh
);
if
(
nlist
!=
BUF_DIRTY
)
{
printk
(
"[%d %x %d] "
,
nlist
,
bh
->
b_dev
,
bh
->
b_blocknr
);
ncount
++
;
};
bh
->
b_count
--
;
retry
=
1
;
}
}
if
(
ncount
)
printk
(
"sys_sync: %d dirty buffers not on dirty list
\n
"
,
ncount
);
/* If we are waiting for the sync to succeed, and if any dirty
blocks were written, then repeat; on the second pass, only
wait for buffers being written (do not pass to write any
...
...
@@ -195,15 +270,20 @@ asmlinkage int sys_fsync(unsigned int fd)
void
invalidate_buffers
(
dev_t
dev
)
{
int
i
;
int
nlist
;
struct
buffer_head
*
bh
;
bh
=
free_list
;
for
(
i
=
nr_buffers
*
2
;
--
i
>
0
;
bh
=
bh
->
b_next_free
)
{
for
(
nlist
=
0
;
nlist
<
NR_LIST
;
nlist
++
)
{
bh
=
lru_list
[
nlist
];
for
(
i
=
nr_buffers_type
[
nlist
]
*
2
;
--
i
>
0
;
bh
=
bh
->
b_next_free
)
{
if
(
bh
->
b_dev
!=
dev
)
continue
;
wait_on_buffer
(
bh
);
if
(
bh
->
b_dev
==
dev
)
bh
->
b_uptodate
=
bh
->
b_dirt
=
bh
->
b_req
=
0
;
bh
->
b_flushtime
=
bh
->
b_uptodate
=
bh
->
b_dirt
=
bh
->
b_req
=
0
;
}
}
}
...
...
@@ -280,7 +360,7 @@ void check_disk_change(dev_t dev)
#endif
}
#define _hashfn(dev,block) (((unsigned)(dev^block))%
NR_HASH
)
#define _hashfn(dev,block) (((unsigned)(dev^block))%
nr_hash
)
#define hash(dev,block) hash_table[_hashfn(dev,block)]
static
inline
void
remove_from_hash_queue
(
struct
buffer_head
*
bh
)
...
...
@@ -294,59 +374,118 @@ static inline void remove_from_hash_queue(struct buffer_head * bh)
bh
->
b_next
=
bh
->
b_prev
=
NULL
;
}
static
inline
void
remove_from_lru_list
(
struct
buffer_head
*
bh
)
{
if
(
!
(
bh
->
b_prev_free
)
||
!
(
bh
->
b_next_free
))
panic
(
"VFS: LRU block list corrupted"
);
if
(
bh
->
b_dev
==
0xffff
)
panic
(
"LRU list corrupted"
);
bh
->
b_prev_free
->
b_next_free
=
bh
->
b_next_free
;
bh
->
b_next_free
->
b_prev_free
=
bh
->
b_prev_free
;
if
(
lru_list
[
bh
->
b_list
]
==
bh
)
lru_list
[
bh
->
b_list
]
=
bh
->
b_next_free
;
if
(
lru_list
[
bh
->
b_list
]
==
bh
)
lru_list
[
bh
->
b_list
]
=
NULL
;
bh
->
b_next_free
=
bh
->
b_prev_free
=
NULL
;
}
static
inline
void
remove_from_free_list
(
struct
buffer_head
*
bh
)
{
int
isize
=
BUFSIZE_INDEX
(
bh
->
b_size
);
if
(
!
(
bh
->
b_prev_free
)
||
!
(
bh
->
b_next_free
))
panic
(
"VFS: Free block list corrupted"
);
if
(
bh
->
b_dev
!=
0xffff
)
panic
(
"Free list corrupted"
);
if
(
!
free_list
[
isize
])
panic
(
"Free list empty"
);
nr_free
[
isize
]
--
;
if
(
bh
->
b_next_free
==
bh
)
free_list
[
isize
]
=
NULL
;
else
{
bh
->
b_prev_free
->
b_next_free
=
bh
->
b_next_free
;
bh
->
b_next_free
->
b_prev_free
=
bh
->
b_prev_free
;
if
(
free_list
==
bh
)
free_list
=
bh
->
b_next_free
;
if
(
free_list
[
isize
]
==
bh
)
free_list
[
isize
]
=
bh
->
b_next_free
;
};
bh
->
b_next_free
=
bh
->
b_prev_free
=
NULL
;
}
static
inline
void
remove_from_queues
(
struct
buffer_head
*
bh
)
{
if
(
bh
->
b_dev
==
0xffff
)
{
remove_from_free_list
(
bh
);
/* Free list entries should not be
in the hash queue */
return
;
};
nr_buffers_type
[
bh
->
b_list
]
--
;
nr_buffers_st
[
BUFSIZE_INDEX
(
bh
->
b_size
)][
bh
->
b_list
]
--
;
remove_from_hash_queue
(
bh
);
remove_from_
free
_list
(
bh
);
remove_from_
lru
_list
(
bh
);
}
static
inline
void
put_
first_free
(
struct
buffer_head
*
bh
)
static
inline
void
put_
last_lru
(
struct
buffer_head
*
bh
)
{
if
(
!
bh
||
(
bh
==
free_list
)
)
if
(
!
bh
)
return
;
remove_from_free_list
(
bh
);
/* add to front of free list */
bh
->
b_next_free
=
free_list
;
bh
->
b_prev_free
=
free_list
->
b_prev_free
;
free_list
->
b_prev_free
->
b_next_free
=
bh
;
free_list
->
b_prev_free
=
bh
;
free_list
=
bh
;
if
(
bh
==
lru_list
[
bh
->
b_list
])
{
lru_list
[
bh
->
b_list
]
=
bh
->
b_next_free
;
return
;
}
if
(
bh
->
b_dev
==
0xffff
)
panic
(
"Wrong block for lru list"
);
remove_from_lru_list
(
bh
);
/* add to back of free list */
if
(
!
lru_list
[
bh
->
b_list
])
{
lru_list
[
bh
->
b_list
]
=
bh
;
lru_list
[
bh
->
b_list
]
->
b_prev_free
=
bh
;
};
bh
->
b_next_free
=
lru_list
[
bh
->
b_list
];
bh
->
b_prev_free
=
lru_list
[
bh
->
b_list
]
->
b_prev_free
;
lru_list
[
bh
->
b_list
]
->
b_prev_free
->
b_next_free
=
bh
;
lru_list
[
bh
->
b_list
]
->
b_prev_free
=
bh
;
}
static
inline
void
put_last_free
(
struct
buffer_head
*
bh
)
{
int
isize
;
if
(
!
bh
)
return
;
if
(
bh
==
free_list
)
{
free_list
=
bh
->
b_next_free
;
return
;
}
remove_from_free_list
(
bh
);
isize
=
BUFSIZE_INDEX
(
bh
->
b_size
);
bh
->
b_dev
=
0xffff
;
/* So it is obvious we are on the free list */
/* add to back of free list */
bh
->
b_next_free
=
free_list
;
bh
->
b_prev_free
=
free_list
->
b_prev_free
;
free_list
->
b_prev_free
->
b_next_free
=
bh
;
free_list
->
b_prev_free
=
bh
;
if
(
!
free_list
[
isize
])
{
free_list
[
isize
]
=
bh
;
bh
->
b_prev_free
=
bh
;
};
nr_free
[
isize
]
++
;
bh
->
b_next_free
=
free_list
[
isize
];
bh
->
b_prev_free
=
free_list
[
isize
]
->
b_prev_free
;
free_list
[
isize
]
->
b_prev_free
->
b_next_free
=
bh
;
free_list
[
isize
]
->
b_prev_free
=
bh
;
}
static
inline
void
insert_into_queues
(
struct
buffer_head
*
bh
)
{
/* put at end of free list */
bh
->
b_next_free
=
free_list
;
bh
->
b_prev_free
=
free_list
->
b_prev_free
;
free_list
->
b_prev_free
->
b_next_free
=
bh
;
free_list
->
b_prev_free
=
bh
;
if
(
bh
->
b_dev
==
0xffff
)
{
put_last_free
(
bh
);
return
;
};
if
(
!
lru_list
[
bh
->
b_list
])
{
lru_list
[
bh
->
b_list
]
=
bh
;
bh
->
b_prev_free
=
bh
;
};
if
(
bh
->
b_next_free
)
panic
(
"VFS: buffer LRU pointers corrupted"
);
bh
->
b_next_free
=
lru_list
[
bh
->
b_list
];
bh
->
b_prev_free
=
lru_list
[
bh
->
b_list
]
->
b_prev_free
;
lru_list
[
bh
->
b_list
]
->
b_prev_free
->
b_next_free
=
bh
;
lru_list
[
bh
->
b_list
]
->
b_prev_free
=
bh
;
nr_buffers_type
[
bh
->
b_list
]
++
;
nr_buffers_st
[
BUFSIZE_INDEX
(
bh
->
b_size
)][
bh
->
b_list
]
++
;
/* put the buffer in new hash-queue if it has a device */
bh
->
b_prev
=
NULL
;
bh
->
b_next
=
NULL
;
...
...
@@ -398,7 +537,7 @@ struct buffer_head * get_hash_table(dev_t dev, int block, int size)
void
set_blocksize
(
dev_t
dev
,
int
size
)
{
int
i
;
int
i
,
nlist
;
struct
buffer_head
*
bh
,
*
bhnext
;
if
(
!
blksize_size
[
MAJOR
(
dev
)])
...
...
@@ -421,8 +560,10 @@ void set_blocksize(dev_t dev, int size)
/* We need to be quite careful how we do this - we are moving entries
around on the free list, and we can get in a loop if we are not careful.*/
bh
=
free_list
;
for
(
i
=
nr_buffers
*
2
;
--
i
>
0
;
bh
=
bhnext
)
{
for
(
nlist
=
0
;
nlist
<
NR_LIST
;
nlist
++
)
{
bh
=
lru_list
[
nlist
];
for
(
i
=
nr_buffers_type
[
nlist
]
*
2
;
--
i
>
0
;
bh
=
bhnext
)
{
if
(
!
bh
)
break
;
bhnext
=
bh
->
b_next_free
;
if
(
bh
->
b_dev
!=
dev
)
continue
;
...
...
@@ -430,11 +571,195 @@ void set_blocksize(dev_t dev, int size)
continue
;
wait_on_buffer
(
bh
);
if
(
bh
->
b_dev
==
dev
&&
bh
->
b_size
!=
size
)
bh
->
b_uptodate
=
bh
->
b_dirt
=
0
;
if
(
bh
->
b_dev
==
dev
&&
bh
->
b_size
!=
size
)
{
bh
->
b_uptodate
=
bh
->
b_dirt
=
bh
->
b_flushtime
=
0
;
};
remove_from_hash_queue
(
bh
);
/* put_first_free(bh); */
}
}
}
#define BADNESS(bh) (((bh)->b_dirt<<1)+(bh)->b_lock)
void
refill_freelist
(
int
size
)
{
struct
buffer_head
*
bh
,
*
tmp
;
struct
buffer_head
*
candidate
[
NR_LIST
];
unsigned
int
best_time
,
winner
;
int
isize
=
BUFSIZE_INDEX
(
size
);
int
buffers
[
NR_LIST
];
int
i
;
int
needed
;
/* First see if we even need this. Sometimes it is advantageous
to request some blocks in a filesystem that we know that we will
be needing ahead of time. */
if
(
nr_free
[
isize
]
>
100
)
return
0
;
/* If there are too many dirty buffers, we wake up the update process
now so as to ensure that there are still clean buffers available
for user processes to use (and dirty) */
/* We are going to try and locate this much memory */
needed
=
bdf_prm
.
b_un
.
nrefill
*
size
;
while
(
nr_free_pages
>
min_free_pages
&&
needed
>
0
&&
grow_buffers
(
GFP_BUFFER
,
size
))
{
needed
-=
PAGE_SIZE
;
}
if
(
needed
<=
0
)
return
;
/* See if there are too many buffers of a different size.
If so, victimize them */
while
(
maybe_shrink_lav_buffers
(
size
))
{
if
(
!
grow_buffers
(
GFP_BUFFER
,
size
))
break
;
needed
-=
PAGE_SIZE
;
if
(
needed
<=
0
)
return
;
};
/* OK, we cannot grow the buffer cache, now try and get some
from the lru list */
/* First set the candidate pointers to usable buffers. This
should be quick nearly all of the time. */
repeat0:
for
(
i
=
0
;
i
<
NR_LIST
;
i
++
){
if
(
i
==
BUF_DIRTY
||
i
==
BUF_SHARED
||
nr_buffers_type
[
i
]
==
0
)
{
candidate
[
i
]
=
NULL
;
buffers
[
i
]
=
0
;
continue
;
}
buffers
[
i
]
=
nr_buffers_type
[
i
];
for
(
bh
=
lru_list
[
i
];
buffers
[
i
]
>
0
;
bh
=
tmp
,
buffers
[
i
]
--
)
{
if
(
buffers
[
i
]
<
0
)
panic
(
"Here is the problem"
);
tmp
=
bh
->
b_next_free
;
if
(
!
bh
)
break
;
if
(
mem_map
[
MAP_NR
((
unsigned
long
)
bh
->
b_data
)]
!=
1
||
bh
->
b_dirt
)
{
refile_buffer
(
bh
);
continue
;
};
if
(
bh
->
b_count
||
bh
->
b_size
!=
size
)
continue
;
/* Buffers are written in the order they are placed
on the locked list. If we encounter a locked
buffer here, this means that the rest of them
are also locked */
if
(
bh
->
b_lock
&&
(
i
==
BUF_LOCKED
||
i
==
BUF_LOCKED1
))
{
buffers
[
i
]
=
0
;
break
;
}
if
(
BADNESS
(
bh
))
continue
;
break
;
};
if
(
!
buffers
[
i
])
candidate
[
i
]
=
NULL
;
/* Nothing on this list */
else
candidate
[
i
]
=
bh
;
if
(
candidate
[
i
]
&&
candidate
[
i
]
->
b_count
)
panic
(
"Here is the problem"
);
}
repeat:
if
(
needed
<=
0
)
return
;
/* Now see which candidate wins the election */
winner
=
best_time
=
UINT_MAX
;
for
(
i
=
0
;
i
<
NR_LIST
;
i
++
){
if
(
!
candidate
[
i
])
continue
;
if
(
candidate
[
i
]
->
b_lru_time
<
best_time
){
best_time
=
candidate
[
i
]
->
b_lru_time
;
winner
=
i
;
}
}
/* If we have a winner, use it, and then get a new candidate from that list */
if
(
winner
!=
UINT_MAX
)
{
i
=
winner
;
bh
=
candidate
[
i
];
candidate
[
i
]
=
bh
->
b_next_free
;
if
(
candidate
[
i
]
==
bh
)
candidate
[
i
]
=
NULL
;
/* Got last one */
if
(
bh
->
b_count
||
bh
->
b_size
!=
size
)
panic
(
"Busy buffer in candidate list
\n
"
);
if
(
mem_map
[
MAP_NR
((
unsigned
long
)
bh
->
b_data
)]
!=
1
)
panic
(
"Shared buffer in candidate list
\n
"
);
if
(
BADNESS
(
bh
))
panic
(
"Buffer in candidate list with BADNESS != 0
\n
"
);
if
(
bh
->
b_dev
==
0xffff
)
panic
(
"Wrong list"
);
remove_from_queues
(
bh
);
bh
->
b_dev
=
0xffff
;
put_last_free
(
bh
);
needed
-=
bh
->
b_size
;
buffers
[
i
]
--
;
if
(
buffers
[
i
]
<
0
)
panic
(
"Here is the problem"
);
if
(
buffers
[
i
]
==
0
)
candidate
[
i
]
=
NULL
;
/* Now all we need to do is advance the candidate pointer
from the winner list to the next usable buffer */
if
(
candidate
[
i
]
&&
buffers
[
i
]
>
0
){
if
(
buffers
[
i
]
<=
0
)
panic
(
"Here is another problem"
);
for
(
bh
=
candidate
[
i
];
buffers
[
i
]
>
0
;
bh
=
tmp
,
buffers
[
i
]
--
)
{
if
(
buffers
[
i
]
<
0
)
panic
(
"Here is the problem"
);
tmp
=
bh
->
b_next_free
;
if
(
!
bh
)
break
;
if
(
mem_map
[
MAP_NR
((
unsigned
long
)
bh
->
b_data
)]
!=
1
||
bh
->
b_dirt
)
{
refile_buffer
(
bh
);
continue
;
};
if
(
bh
->
b_count
||
bh
->
b_size
!=
size
)
continue
;
/* Buffers are written in the order they are
placed on the locked list. If we encounter
a locked buffer here, this means that the
rest of them are also locked */
if
(
bh
->
b_lock
&&
(
i
==
BUF_LOCKED
||
i
==
BUF_LOCKED1
))
{
buffers
[
i
]
=
0
;
break
;
}
if
(
BADNESS
(
bh
))
continue
;
break
;
};
if
(
!
buffers
[
i
])
candidate
[
i
]
=
NULL
;
/* Nothing here */
else
candidate
[
i
]
=
bh
;
if
(
candidate
[
i
]
&&
candidate
[
i
]
->
b_count
)
panic
(
"Here is the problem"
);
}
goto
repeat
;
}
if
(
needed
<=
0
)
return
;
/* Too bad, that was not enough. Try a little harder to grow some. */
if
(
nr_free_pages
>
5
)
{
if
(
grow_buffers
(
GFP_BUFFER
,
size
))
{
needed
-=
PAGE_SIZE
;
goto
repeat0
;
};
}
/* and repeat until we find something good */
if
(
!
grow_buffers
(
GFP_ATOMIC
,
size
))
wakeup_bdflush
(
1
);
needed
-=
PAGE_SIZE
;
goto
repeat0
;
}
/*
...
...
@@ -447,85 +772,105 @@ void set_blocksize(dev_t dev, int size)
* 14.02.92: changed it to sync dirty buffers a bit: better performance
* when the filesystem starts to get full of dirty blocks (I hope).
*/
#define BADNESS(bh) (((bh)->b_dirt<<1)+(bh)->b_lock)
struct
buffer_head
*
getblk
(
dev_t
dev
,
int
block
,
int
size
)
{
struct
buffer_head
*
bh
,
*
tmp
;
int
buffers
;
static
int
grow_size
=
0
;
struct
buffer_head
*
bh
;
int
isize
=
BUFSIZE_INDEX
(
size
);
/* Update this for the buffer size lav. */
buffer_usage
[
isize
]
++
;
/* If there are too many dirty buffers, we wake up the update process
now so as to ensure that there are still clean buffers available
for user processes to use (and dirty) */
repeat:
bh
=
get_hash_table
(
dev
,
block
,
size
);
if
(
bh
)
{
if
(
bh
->
b_uptodate
&&
!
bh
->
b_dirt
)
put_last_free
(
bh
);
put_last_lru
(
bh
);
if
(
!
bh
->
b_dirt
)
bh
->
b_flushtime
=
0
;
return
bh
;
}
grow_size
-=
size
;
if
(
nr_free_pages
>
min_free_pages
&&
grow_size
<=
0
)
{
if
(
grow_buffers
(
GFP_BUFFER
,
size
))
grow_size
=
PAGE_SIZE
;
}
buffers
=
nr_buffers
;
bh
=
NULL
;
for
(
tmp
=
free_list
;
buffers
--
>
0
;
tmp
=
tmp
->
b_next_free
)
{
if
(
tmp
->
b_count
||
tmp
->
b_size
!=
size
)
continue
;
if
(
mem_map
[
MAP_NR
((
unsigned
long
)
tmp
->
b_data
)]
!=
1
)
continue
;
if
(
!
bh
||
BADNESS
(
tmp
)
<
BADNESS
(
bh
))
{
bh
=
tmp
;
if
(
!
BADNESS
(
tmp
))
break
;
}
#if 0
if (tmp->b_dirt) {
tmp->b_count++;
ll_rw_block(WRITEA, 1, &tmp);
tmp->b_count--;
}
#endif
}
if
(
!
bh
)
{
if
(
nr_free_pages
>
5
)
if
(
grow_buffers
(
GFP_BUFFER
,
size
))
goto
repeat
;
if
(
!
grow_buffers
(
GFP_ATOMIC
,
size
))
sleep_on
(
&
buffer_wait
);
goto
repeat
;
}
while
(
!
free_list
[
isize
])
refill_freelist
(
size
);
wait_on_buffer
(
bh
);
if
(
bh
->
b_count
||
bh
->
b_size
!=
size
)
goto
repeat
;
if
(
bh
->
b_dirt
)
{
sync_buffers
(
0
,
0
);
goto
repeat
;
}
/* NOTE!! While we slept waiting for this block, somebody else might */
/* already have added "this" block to the cache. check it */
if
(
find_buffer
(
dev
,
block
,
size
))
goto
repeat
;
/* OK, FINALLY we know that this buffer is the only one of its kind, */
bh
=
free_list
[
isize
];
remove_from_free_list
(
bh
);
/* OK, FINALLY we know that this buffer is the only one of it's kind, */
/* and that it's unused (b_count=0), unlocked (b_lock=0), and clean */
bh
->
b_count
=
1
;
bh
->
b_dirt
=
0
;
bh
->
b_lock
=
0
;
bh
->
b_uptodate
=
0
;
bh
->
b_flushtime
=
0
;
bh
->
b_req
=
0
;
remove_from_queues
(
bh
);
bh
->
b_dev
=
dev
;
bh
->
b_blocknr
=
block
;
insert_into_queues
(
bh
);
return
bh
;
}
void
set_writetime
(
struct
buffer_head
*
buf
,
int
flag
)
{
int
newtime
;
if
(
buf
->
b_dirt
){
/* Move buffer to dirty list if jiffies is clear */
newtime
=
jiffies
+
(
flag
?
bdf_prm
.
b_un
.
age_super
:
bdf_prm
.
b_un
.
age_buffer
);
if
(
!
buf
->
b_flushtime
||
buf
->
b_flushtime
>
newtime
)
buf
->
b_flushtime
=
newtime
;
}
else
{
buf
->
b_flushtime
=
0
;
}
}
static
char
buffer_disposition
[]
=
{
BUF_CLEAN
,
BUF_SHARED
,
BUF_LOCKED
,
BUF_SHARED
,
BUF_DIRTY
,
BUF_DIRTY
,
BUF_DIRTY
,
BUF_DIRTY
};
void
refile_buffer
(
struct
buffer_head
*
buf
){
int
i
,
dispose
;
i
=
0
;
if
(
buf
->
b_dev
==
0xffff
)
panic
(
"Attempt to refile free buffer
\n
"
);
if
(
mem_map
[
MAP_NR
((
unsigned
long
)
buf
->
b_data
)]
!=
1
)
i
=
1
;
if
(
buf
->
b_lock
)
i
|=
2
;
if
(
buf
->
b_dirt
)
i
|=
4
;
dispose
=
buffer_disposition
[
i
];
if
(
buf
->
b_list
==
BUF_SHARED
&&
dispose
==
BUF_CLEAN
)
dispose
=
BUF_UNSHARED
;
if
(
dispose
==
-
1
)
panic
(
"Bad buffer settings (%d)
\n
"
,
i
);
if
(
dispose
==
BUF_CLEAN
)
buf
->
b_lru_time
=
jiffies
;
if
(
dispose
!=
buf
->
b_list
)
{
if
(
dispose
==
BUF_DIRTY
||
dispose
==
BUF_UNSHARED
)
buf
->
b_lru_time
=
jiffies
;
if
(
dispose
==
BUF_LOCKED
&&
(
buf
->
b_flushtime
-
buf
->
b_lru_time
)
<=
bdf_prm
.
b_un
.
age_super
)
dispose
=
BUF_LOCKED1
;
remove_from_queues
(
buf
);
buf
->
b_list
=
dispose
;
insert_into_queues
(
buf
);
if
(
dispose
==
BUF_DIRTY
&&
nr_buffers_type
[
BUF_DIRTY
]
>
(
nr_buffers
-
nr_buffers_type
[
BUF_SHARED
])
*
bdf_prm
.
b_un
.
nfract
/
100
)
wakeup_bdflush
(
0
);
}
}
void
brelse
(
struct
buffer_head
*
buf
)
{
if
(
!
buf
)
return
;
wait_on_buffer
(
buf
);
/* If dirty, mark the time this buffer should be written back */
set_writetime
(
buf
,
0
);
refile_buffer
(
buf
);
if
(
buf
->
b_count
)
{
if
(
--
buf
->
b_count
)
return
;
...
...
@@ -560,7 +905,8 @@ struct buffer_head * bread(dev_t dev, int block, int size)
/*
* Ok, breada can be used as bread, but additionally to mark other
* blocks for reading as well.
* blocks for reading as well. End the argument list with a negative
* number.
*/
#define NBUF 16
...
...
@@ -686,6 +1032,7 @@ static struct buffer_head * create_buffers(unsigned long page, unsigned long siz
head
=
bh
;
bh
->
b_data
=
(
char
*
)
(
page
+
offset
);
bh
->
b_size
=
size
;
bh
->
b_dev
=
0xffff
;
/* Flag as unused */
}
return
head
;
/*
...
...
@@ -766,6 +1113,7 @@ static unsigned long try_to_load_aligned(unsigned long address,
{
struct
buffer_head
*
bh
,
*
tmp
,
*
arr
[
8
];
unsigned
long
offset
;
int
isize
=
BUFSIZE_INDEX
(
size
);
int
*
p
;
int
block
;
...
...
@@ -788,10 +1136,14 @@ static unsigned long try_to_load_aligned(unsigned long address,
arr
[
block
++
]
=
bh
;
bh
->
b_count
=
1
;
bh
->
b_dirt
=
0
;
bh
->
b_flushtime
=
0
;
bh
->
b_uptodate
=
0
;
bh
->
b_req
=
0
;
bh
->
b_dev
=
dev
;
bh
->
b_blocknr
=
*
(
p
++
);
bh
->
b_list
=
BUF_CLEAN
;
nr_buffers
++
;
nr_buffers_size
[
isize
]
++
;
insert_into_queues
(
bh
);
if
(
bh
->
b_this_page
)
bh
=
bh
->
b_this_page
;
...
...
@@ -801,6 +1153,7 @@ static unsigned long try_to_load_aligned(unsigned long address,
buffermem
+=
PAGE_SIZE
;
bh
->
b_this_page
=
tmp
;
mem_map
[
MAP_NR
(
address
)]
++
;
buffer_pages
[
address
>>
PAGE_SHIFT
]
=
bh
;
read_buffers
(
arr
,
block
);
while
(
block
--
>
0
)
brelse
(
arr
[
block
]);
...
...
@@ -889,11 +1242,16 @@ static int grow_buffers(int pri, int size)
{
unsigned
long
page
;
struct
buffer_head
*
bh
,
*
tmp
;
struct
buffer_head
*
insert_point
;
int
isize
;
if
((
size
&
511
)
||
(
size
>
PAGE_SIZE
))
{
printk
(
"VFS: grow_buffers: size = %d
\n
"
,
size
);
return
0
;
}
isize
=
BUFSIZE_INDEX
(
size
);
if
(
!
(
page
=
__get_free_page
(
pri
)))
return
0
;
bh
=
create_buffers
(
page
,
size
);
...
...
@@ -901,25 +1259,32 @@ static int grow_buffers(int pri, int size)
free_page
(
page
);
return
0
;
}
insert_point
=
free_list
[
isize
];
tmp
=
bh
;
while
(
1
)
{
if
(
free_list
)
{
tmp
->
b_next_free
=
free_list
;
tmp
->
b_prev_free
=
free_list
->
b_prev_free
;
free_list
->
b_prev_free
->
b_next_free
=
tmp
;
free_list
->
b_prev_free
=
tmp
;
nr_free
[
isize
]
++
;
if
(
insert_point
)
{
tmp
->
b_next_free
=
insert_point
->
b_next_free
;
tmp
->
b_prev_free
=
insert_point
;
insert_point
->
b_next_free
->
b_prev_free
=
tmp
;
insert_point
->
b_next_free
=
tmp
;
}
else
{
tmp
->
b_prev_free
=
tmp
;
tmp
->
b_next_free
=
tmp
;
}
free_lis
t
=
tmp
;
insert_poin
t
=
tmp
;
++
nr_buffers
;
if
(
tmp
->
b_this_page
)
tmp
=
tmp
->
b_this_page
;
else
break
;
}
free_list
[
isize
]
=
bh
;
buffer_pages
[
page
>>
PAGE_SHIFT
]
=
bh
;
tmp
->
b_this_page
=
bh
;
wake_up
(
&
buffer_wait
);
buffermem
+=
PAGE_SIZE
;
return
1
;
}
...
...
@@ -932,6 +1297,7 @@ static int try_to_free(struct buffer_head * bh, struct buffer_head ** bhp)
{
unsigned
long
page
;
struct
buffer_head
*
tmp
,
*
p
;
int
isize
=
BUFSIZE_INDEX
(
bh
->
b_size
);
*
bhp
=
bh
;
page
=
(
unsigned
long
)
bh
->
b_data
;
...
...
@@ -949,16 +1315,72 @@ static int try_to_free(struct buffer_head * bh, struct buffer_head ** bhp)
p
=
tmp
;
tmp
=
tmp
->
b_this_page
;
nr_buffers
--
;
nr_buffers_size
[
isize
]
--
;
if
(
p
==
*
bhp
)
{
*
bhp
=
p
->
b_prev_free
;
if
(
p
==
*
bhp
)
/* Was this the last in the list? */
*
bhp
=
NULL
;
}
remove_from_queues
(
p
);
put_unused_buffer_head
(
p
);
}
while
(
tmp
!=
bh
);
buffermem
-=
PAGE_SIZE
;
buffer_pages
[
page
>>
PAGE_SHIFT
]
=
NULL
;
free_page
(
page
);
return
!
mem_map
[
MAP_NR
(
page
)];
}
/*
* Consult the load average for buffers and decide whether or not
* we should shrink the buffers of one size or not. If we decide yes,
* do it and return 1. Else return 0. Do not attempt to shrink size
* that is specified.
*
* I would prefer not to use a load average, but the way things are now it
* seems unavoidable. The way to get rid of it would be to force clustering
* universally, so that when we reclaim buffers we always reclaim an entire
* page. Doing this would mean that we all need to move towards QMAGIC.
*/
static
int
maybe_shrink_lav_buffers
(
int
size
)
{
int
nlist
;
int
isize
;
int
total_lav
,
total_n_buffers
,
n_sizes
;
/* Do not consider the shared buffers since they would not tend
to have getblk called very often, and this would throw off
the lav. They are not easily reclaimable anyway (let the swapper
make the first move). */
total_lav
=
total_n_buffers
=
n_sizes
=
0
;
for
(
nlist
=
0
;
nlist
<
NR_SIZES
;
nlist
++
)
{
total_lav
+=
buffers_lav
[
nlist
];
if
(
nr_buffers_size
[
nlist
])
n_sizes
++
;
total_n_buffers
+=
nr_buffers_size
[
nlist
];
total_n_buffers
-=
nr_buffers_st
[
nlist
][
BUF_SHARED
];
}
/* See if we have an excessive number of buffers of a particular
size - if so, victimize that bunch. */
isize
=
(
size
?
BUFSIZE_INDEX
(
size
)
:
-
1
);
if
(
n_sizes
>
1
)
for
(
nlist
=
0
;
nlist
<
NR_SIZES
;
nlist
++
)
{
if
(
nlist
==
isize
)
continue
;
if
(
nr_buffers_size
[
nlist
]
&&
bdf_prm
.
b_un
.
lav_const
*
buffers_lav
[
nlist
]
*
total_n_buffers
<
total_lav
*
(
nr_buffers_size
[
nlist
]
-
nr_buffers_st
[
nlist
][
BUF_SHARED
]))
if
(
shrink_specific_buffers
(
6
,
bufferindex_size
[
nlist
]))
return
1
;
}
return
0
;
}
/*
* Try to free up some pages by shrinking the buffer-cache
*
...
...
@@ -967,23 +1389,60 @@ static int try_to_free(struct buffer_head * bh, struct buffer_head ** bhp)
* of 0 means "we'd better get some free pages now".
*/
int
shrink_buffers
(
unsigned
int
priority
)
{
if
(
priority
<
2
)
{
sync_buffers
(
0
,
0
);
}
if
(
priority
==
2
)
wakeup_bdflush
(
1
);
if
(
maybe_shrink_lav_buffers
(
0
))
return
1
;
/* No good candidate size - take any size we can find */
return
shrink_specific_buffers
(
priority
,
0
);
}
static
int
shrink_specific_buffers
(
unsigned
int
priority
,
int
size
)
{
struct
buffer_head
*
bh
;
int
i
;
int
nlist
;
int
i
,
isize
,
isize1
;
if
(
priority
<
2
)
sync_buffers
(
0
,
0
);
bh
=
free_list
;
i
=
nr_buffers
>>
priority
;
for
(
;
i
--
>
0
;
bh
=
bh
->
b_next_free
)
{
if
(
bh
->
b_count
||
(
priority
>=
5
&&
mem_map
[
MAP_NR
((
unsigned
long
)
bh
->
b_data
)]
>
1
))
{
put_last_free
(
bh
);
#ifdef DEBUG
if
(
size
)
printk
(
"Shrinking buffers of size %d
\n
"
,
size
);
#endif
/* First try the free lists, and see if we can get a complete page
from here */
isize1
=
(
size
?
BUFSIZE_INDEX
(
size
)
:
-
1
);
for
(
isize
=
0
;
isize
<
NR_SIZES
;
isize
++
){
if
(
isize1
!=
-
1
&&
isize1
!=
isize
)
continue
;
bh
=
free_list
[
isize
];
if
(
!
bh
)
continue
;
for
(
i
=
0
;
!
i
||
bh
!=
free_list
[
isize
];
bh
=
bh
->
b_next_free
,
i
++
)
{
if
(
bh
->
b_count
||
!
bh
->
b_this_page
)
continue
;
if
(
try_to_free
(
bh
,
&
bh
))
return
1
;
if
(
!
bh
)
break
;
/* Some interrupt must have used it after we
freed the page. No big deal - keep looking */
}
}
if
(
!
bh
->
b_this_page
)
/* Not enough in the free lists, now try the lru list */
for
(
nlist
=
0
;
nlist
<
NR_LIST
;
nlist
++
)
{
repeat1:
if
(
priority
>
3
&&
nlist
==
BUF_SHARED
)
continue
;
bh
=
lru_list
[
nlist
];
if
(
!
bh
)
continue
;
i
=
nr_buffers_type
[
nlist
]
>>
priority
;
for
(
;
i
--
>
0
;
bh
=
bh
->
b_next_free
)
{
/* We may have stalled while waiting for I/O to complete. */
if
(
bh
->
b_list
!=
nlist
)
goto
repeat1
;
if
(
bh
->
b_count
||
!
bh
->
b_this_page
)
continue
;
if
(
size
&&
bh
->
b_size
!=
size
)
continue
;
if
(
bh
->
b_lock
)
if
(
priority
)
continue
;
...
...
@@ -991,41 +1450,228 @@ int shrink_buffers(unsigned int priority)
wait_on_buffer
(
bh
);
if
(
bh
->
b_dirt
)
{
bh
->
b_count
++
;
bh
->
b_flushtime
=
0
;
ll_rw_block
(
WRITEA
,
1
,
&
bh
);
bh
->
b_count
--
;
continue
;
}
if
(
try_to_free
(
bh
,
&
bh
))
return
1
;
if
(
!
bh
)
break
;
}
}
return
0
;
}
void
show_buffers
(
void
)
{
struct
buffer_head
*
bh
;
int
found
=
0
,
locked
=
0
,
dirty
=
0
,
used
=
0
,
lastused
=
0
;
int
shared
;
int
nlist
,
isize
;
printk
(
"Buffer memory: %6dkB
\n
"
,
buffermem
>>
10
);
printk
(
"Buffer heads: %6d
\n
"
,
nr_buffer_heads
);
printk
(
"Buffer blocks: %6d
\n
"
,
nr_buffers
);
bh
=
free_list
;
for
(
nlist
=
0
;
nlist
<
NR_LIST
;
nlist
++
)
{
shared
=
found
=
locked
=
dirty
=
used
=
lastused
=
0
;
bh
=
lru_list
[
nlist
];
if
(
!
bh
)
continue
;
do
{
found
++
;
if
(
bh
->
b_lock
)
locked
++
;
if
(
bh
->
b_dirt
)
dirty
++
;
if
(
mem_map
[
MAP_NR
(((
unsigned
long
)
bh
->
b_data
))]
!=
1
)
shared
++
;
if
(
bh
->
b_count
)
used
++
,
lastused
=
found
;
bh
=
bh
->
b_next_free
;
}
while
(
bh
!=
free_list
);
printk
(
"Buffer mem: %d buffers, %d used (last=%d), %d locked, %d dirty
\n
"
,
found
,
used
,
lastused
,
locked
,
dirty
);
}
while
(
bh
!=
lru_list
[
nlist
]);
printk
(
"Buffer[%d] mem: %d buffers, %d used (last=%d), %d locked, %d dirty %d shrd
\n
"
,
nlist
,
found
,
used
,
lastused
,
locked
,
dirty
,
shared
);
};
printk
(
"Size [LAV] Free Clean Unshar Lck Lck1 Dirty Shared
\n
"
);
for
(
isize
=
0
;
isize
<
NR_SIZES
;
isize
++
){
printk
(
"%5d [%5d]: %7d "
,
bufferindex_size
[
isize
],
buffers_lav
[
isize
],
nr_free
[
isize
]);
for
(
nlist
=
0
;
nlist
<
NR_LIST
;
nlist
++
)
printk
(
"%7d "
,
nr_buffers_st
[
isize
][
nlist
]);
printk
(
"
\n
"
);
}
}
/*
* try_to_reassign() checks if all the buffers on this particular page
* are unused, and reassign to a new cluster them if this is true.
*/
static
inline
int
try_to_reassign
(
struct
buffer_head
*
bh
,
struct
buffer_head
**
bhp
,
dev_t
dev
,
unsigned
int
starting_block
)
{
unsigned
long
page
;
struct
buffer_head
*
tmp
,
*
p
;
*
bhp
=
bh
;
page
=
(
unsigned
long
)
bh
->
b_data
;
page
&=
PAGE_MASK
;
if
(
mem_map
[
MAP_NR
(
page
)]
!=
1
)
return
0
;
tmp
=
bh
;
do
{
if
(
!
tmp
)
return
0
;
if
(
tmp
->
b_count
||
tmp
->
b_dirt
||
tmp
->
b_lock
)
return
0
;
tmp
=
tmp
->
b_this_page
;
}
while
(
tmp
!=
bh
);
tmp
=
bh
;
while
((
unsigned
int
)
tmp
->
b_data
&
(
PAGE_SIZE
-
1
))
tmp
=
tmp
->
b_this_page
;
/* This is the buffer at the head of the page */
bh
=
tmp
;
do
{
p
=
tmp
;
tmp
=
tmp
->
b_this_page
;
remove_from_queues
(
p
);
p
->
b_dev
=
dev
;
p
->
b_uptodate
=
0
;
p
->
b_req
=
0
;
p
->
b_blocknr
=
starting_block
++
;
insert_into_queues
(
p
);
}
while
(
tmp
!=
bh
);
return
1
;
}
/*
* Try to find a free cluster by locating a page where
* all of the buffers are unused. We would like this function
* to be atomic, so we do not call anything that might cause
* the process to sleep. The priority is somewhat similar to
* the priority used in shrink_buffers.
*
* My thinking is that the kernel should end up using whole
* pages for the buffer cache as much of the time as possible.
* This way the other buffers on a particular page are likely
* to be very near each other on the free list, and we will not
* be expiring data prematurely. For now we only canibalize buffers
* of the same size to keep the code simpler.
*/
static
int
reassign_cluster
(
dev_t
dev
,
unsigned
int
starting_block
,
int
size
)
{
struct
buffer_head
*
bh
;
int
isize
=
BUFSIZE_INDEX
(
size
);
int
i
;
/* We want to give ourselves a really good shot at generating
a cluster, and since we only take buffers from the free
list, we "overfill" it a little. */
while
(
nr_free
[
isize
]
<
32
)
refill_freelist
(
size
);
bh
=
free_list
[
isize
];
if
(
bh
)
for
(
i
=
0
;
!
i
||
bh
!=
free_list
[
isize
]
;
bh
=
bh
->
b_next_free
,
i
++
)
{
if
(
!
bh
->
b_this_page
)
continue
;
if
(
try_to_reassign
(
bh
,
&
bh
,
dev
,
starting_block
))
return
4
;
}
return
0
;
}
/* This function tries to generate a new cluster of buffers
* from a new page in memory. We should only do this if we have
* not expanded the buffer cache to the maximum size that we allow.
*/
static
unsigned
long
try_to_generate_cluster
(
dev_t
dev
,
int
block
,
int
size
)
{
struct
buffer_head
*
bh
,
*
tmp
,
*
arr
[
8
];
int
isize
=
BUFSIZE_INDEX
(
size
);
unsigned
long
offset
;
unsigned
long
page
;
int
nblock
;
page
=
get_free_page
(
GFP_NOBUFFER
);
if
(
!
page
)
return
0
;
bh
=
create_buffers
(
page
,
size
);
if
(
!
bh
)
{
free_page
(
page
);
return
0
;
};
nblock
=
block
;
for
(
offset
=
0
;
offset
<
PAGE_SIZE
;
offset
+=
size
)
{
if
(
find_buffer
(
dev
,
nblock
++
,
size
))
goto
not_aligned
;
}
tmp
=
bh
;
nblock
=
0
;
while
(
1
)
{
arr
[
nblock
++
]
=
bh
;
bh
->
b_count
=
1
;
bh
->
b_dirt
=
0
;
bh
->
b_flushtime
=
0
;
bh
->
b_lock
=
0
;
bh
->
b_uptodate
=
0
;
bh
->
b_req
=
0
;
bh
->
b_dev
=
dev
;
bh
->
b_list
=
BUF_CLEAN
;
bh
->
b_blocknr
=
block
++
;
nr_buffers
++
;
nr_buffers_size
[
isize
]
++
;
insert_into_queues
(
bh
);
if
(
bh
->
b_this_page
)
bh
=
bh
->
b_this_page
;
else
break
;
}
buffermem
+=
PAGE_SIZE
;
buffer_pages
[
page
>>
PAGE_SHIFT
]
=
bh
;
bh
->
b_this_page
=
tmp
;
while
(
nblock
--
>
0
)
brelse
(
arr
[
nblock
]);
return
4
;
not_aligned:
while
((
tmp
=
bh
)
!=
NULL
)
{
bh
=
bh
->
b_this_page
;
put_unused_buffer_head
(
tmp
);
}
free_page
(
page
);
return
0
;
}
unsigned
long
generate_cluster
(
dev_t
dev
,
int
b
[],
int
size
)
{
int
i
,
offset
;
for
(
i
=
0
,
offset
=
0
;
offset
<
PAGE_SIZE
;
i
++
,
offset
+=
size
)
{
if
(
i
&&
b
[
i
]
-
1
!=
b
[
i
-
1
])
return
0
;
/* No need to cluster */
if
(
find_buffer
(
dev
,
b
[
i
],
size
))
return
0
;
};
/* OK, we have a candidate for a new cluster */
/* See if one size of buffer is over-represented in the buffer cache,
if so reduce the numbers of buffers */
if
(
maybe_shrink_lav_buffers
(
size
))
{
int
retval
;
retval
=
try_to_generate_cluster
(
dev
,
b
[
0
],
size
);
if
(
retval
)
return
retval
;
};
if
(
nr_free_pages
>
min_free_pages
)
return
try_to_generate_cluster
(
dev
,
b
[
0
],
size
);
else
return
reassign_cluster
(
dev
,
b
[
0
],
size
);
}
/*
* This initializes the initial buffer free list. nr_buffers is set
* This initializes the initial buffer free list. nr_buffers
_type
is set
* to one less the actual number of buffers, as a sop to backwards
* compatibility --- the old code did this (I think unintentionally,
* but I'm not sure), and programs in the ps package expect it.
...
...
@@ -1034,16 +1680,254 @@ void show_buffers(void)
void
buffer_init
(
void
)
{
int
i
;
int
isize
=
BUFSIZE_INDEX
(
BLOCK_SIZE
);
if
(
high_memory
>=
4
*
1024
*
1024
)
if
(
high_memory
>=
4
*
1024
*
1024
)
{
min_free_pages
=
200
;
if
(
high_memory
>=
16
*
1024
*
1024
)
nr_hash
=
16381
;
else
nr_hash
=
4093
;
}
else
{
min_free_pages
=
20
;
for
(
i
=
0
;
i
<
NR_HASH
;
i
++
)
nr_hash
=
997
;
};
hash_table
=
(
struct
buffer_head
**
)
vmalloc
(
nr_hash
*
sizeof
(
struct
buffer_head
*
));
buffer_pages
=
(
struct
buffer_head
**
)
vmalloc
((
high_memory
>>
PAGE_SHIFT
)
*
sizeof
(
struct
buffer_head
*
));
for
(
i
=
0
;
i
<
high_memory
>>
PAGE_SHIFT
;
i
++
)
buffer_pages
[
i
]
=
NULL
;
for
(
i
=
0
;
i
<
nr_hash
;
i
++
)
hash_table
[
i
]
=
NULL
;
free_list
=
0
;
lru_list
[
BUF_CLEAN
]
=
0
;
grow_buffers
(
GFP_KERNEL
,
BLOCK_SIZE
);
if
(
!
free_list
)
if
(
!
free_list
[
isize
]
)
panic
(
"VFS: Unable to initialize buffer free list!"
);
return
;
}
/* This is a simple kernel daemon, whose job it is to provide a dynamicly
* response to dirty buffers. Once this process is activated, we write back
* a limited number of buffers to the disks and then go back to sleep again.
* In effect this is a process which never leaves kernel mode, and does not have
* any user memory associated with it except for the stack. There is also
* a kernel stack page, which obviously must be separate from the user stack.
*/
struct
wait_queue
*
bdflush_wait
=
NULL
;
struct
wait_queue
*
bdflush_done
=
NULL
;
static
int
bdflush_running
=
0
;
static
void
wakeup_bdflush
(
int
wait
)
{
if
(
!
bdflush_running
){
printk
(
"Warning - bdflush not running
\n
"
);
sync_buffers
(
0
,
0
);
return
;
};
wake_up
(
&
bdflush_wait
);
if
(
wait
)
sleep_on
(
&
bdflush_done
);
}
/*
* Here we attempt to write back old buffers. We also try and flush indoes
* and supers as well, since this function is essentially "update", and
* otherwise there would be no way of ensuring that these quantities ever
* get written back. Ideally, we would have a timestamp on the inodes
* and superblocks so that we could write back only the old ones as well
*/
asmlinkage
int
sync_old_buffers
(
void
)
{
int
i
,
isize
;
int
ndirty
,
nwritten
;
int
nlist
;
int
ncount
;
struct
buffer_head
*
bh
,
*
next
;
sync_supers
(
0
);
sync_inodes
(
0
);
ncount
=
0
;
#ifdef DEBUG
for
(
nlist
=
0
;
nlist
<
NR_LIST
;
nlist
++
)
#else
for
(
nlist
=
BUF_DIRTY
;
nlist
<=
BUF_DIRTY
;
nlist
++
)
#endif
{
ndirty
=
0
;
nwritten
=
0
;
repeat:
bh
=
lru_list
[
nlist
];
if
(
bh
)
for
(
i
=
nr_buffers_type
[
nlist
];
--
i
>
0
;
bh
=
next
)
{
/* We may have stalled while waiting for I/O to complete. */
if
(
bh
->
b_list
!=
nlist
)
goto
repeat
;
next
=
bh
->
b_next_free
;
if
(
!
lru_list
[
nlist
])
{
printk
(
"Dirty list empty %d
\n
"
,
i
);
break
;
}
/* Clean buffer on dirty list? Refile it */
if
(
nlist
==
BUF_DIRTY
&&
!
bh
->
b_dirt
&&
!
bh
->
b_lock
)
{
refile_buffer
(
bh
);
continue
;
}
if
(
bh
->
b_lock
||
!
bh
->
b_dirt
)
continue
;
ndirty
++
;
if
(
bh
->
b_flushtime
>
jiffies
)
continue
;
nwritten
++
;
bh
->
b_count
++
;
bh
->
b_flushtime
=
0
;
#ifdef DEBUG
if
(
nlist
!=
BUF_DIRTY
)
ncount
++
;
#endif
ll_rw_block
(
WRITE
,
1
,
&
bh
);
bh
->
b_count
--
;
}
}
#ifdef DEBUG
if
(
ncount
)
printk
(
"sync_old_buffers: %d dirty buffers not on dirty list
\n
"
,
ncount
);
printk
(
"Wrote %d/%d buffers
\n
"
,
nwritten
,
ndirty
);
#endif
/* We assume that we only come through here on a regular
schedule, like every 5 seconds. Now update load averages.
Shift usage counts to prevent overflow. */
for
(
isize
=
0
;
isize
<
NR_SIZES
;
isize
++
){
CALC_LOAD
(
buffers_lav
[
isize
],
bdf_prm
.
b_un
.
lav_const
,
buffer_usage
[
isize
]);
buffer_usage
[
isize
]
=
0
;
};
return
0
;
}
/* This is the interface to bdflush. As we get more sophisticated, we can
* pass tuning parameters to this "process", to adjust how it behaves. If you
* invoke this again after you have done this once, you would simply modify
* the tuning parameters. We would want to verify each parameter, however,
* to make sure that it is reasonable. */
asmlinkage
int
sys_bdflush
(
int
func
,
int
data
)
{
int
i
,
error
;
int
ndirty
;
int
nlist
;
int
ncount
;
struct
buffer_head
*
bh
,
*
next
;
if
(
!
suser
())
return
-
EPERM
;
if
(
func
==
1
)
return
sync_old_buffers
();
/* Basically func 0 means start, 1 means read param 1, 2 means write param 1, etc */
if
(
func
>=
2
){
i
=
(
func
-
2
)
>>
1
;
if
(
i
<
0
||
i
>=
N_PARAM
)
return
-
EINVAL
;
if
((
func
&
1
)
==
0
)
{
error
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
data
,
sizeof
(
int
));
if
(
error
)
return
error
;
put_fs_long
(
bdf_prm
.
data
[
i
],
data
);
return
0
;
};
if
(
data
<
bdflush_min
[
i
]
||
data
>
bdflush_max
[
i
])
return
-
EINVAL
;
bdf_prm
.
data
[
i
]
=
data
;
return
0
;
};
if
(
bdflush_running
++
)
return
-
EBUSY
;
/* Only one copy of this running at one time */
/* OK, from here on is the daemon */
while
(
1
==
1
){
#ifdef DEBUG
printk
(
"bdflush() activated..."
);
#endif
ncount
=
0
;
#ifdef DEBUG
for
(
nlist
=
0
;
nlist
<
NR_LIST
;
nlist
++
)
#else
for
(
nlist
=
BUF_DIRTY
;
nlist
<=
BUF_DIRTY
;
nlist
++
)
#endif
{
ndirty
=
0
;
repeat:
bh
=
lru_list
[
nlist
];
if
(
bh
)
for
(
i
=
nr_buffers_type
[
nlist
];
--
i
>
0
&&
ndirty
<
bdf_prm
.
b_un
.
ndirty
;
bh
=
next
)
{
/* We may have stalled while waiting for I/O to complete. */
if
(
bh
->
b_list
!=
nlist
)
goto
repeat
;
next
=
bh
->
b_next_free
;
if
(
!
lru_list
[
nlist
])
{
printk
(
"Dirty list empty %d
\n
"
,
i
);
break
;
}
/* Clean buffer on dirty list? Refile it */
if
(
nlist
==
BUF_DIRTY
&&
!
bh
->
b_dirt
&&
!
bh
->
b_lock
)
{
refile_buffer
(
bh
);
continue
;
}
if
(
bh
->
b_lock
||
!
bh
->
b_dirt
)
continue
;
/* Should we write back buffers that are shared or not??
currently dirty buffers are not shared, so it does not matter */
bh
->
b_count
++
;
ndirty
++
;
bh
->
b_flushtime
=
0
;
ll_rw_block
(
WRITE
,
1
,
&
bh
);
#ifdef DEBUG
if
(
nlist
!=
BUF_DIRTY
)
ncount
++
;
#endif
bh
->
b_count
--
;
}
}
#ifdef DEBUG
if
(
ncount
)
printk
(
"sys_bdflush: %d dirty buffers not on dirty list
\n
"
,
ncount
);
printk
(
"sleeping again.
\n
"
);
#endif
wake_up
(
&
bdflush_done
);
/* If there are still a lot of dirty buffers around, skip the sleep
and flush some more */
if
(
nr_buffers_type
[
BUF_DIRTY
]
<
(
nr_buffers
-
nr_buffers_type
[
BUF_SHARED
])
*
bdf_prm
.
b_un
.
nfract
/
100
)
{
interruptible_sleep_on
(
&
bdflush_wait
);
}
}
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 8
* c-brace-imaginary-offset: 0
* c-brace-offset: -8
* c-argdecl-indent: 8
* c-label-offset: -8
* c-continued-statement-offset: 8
* c-continued-brace-offset: 0
* End:
*/
fs/devices.c
View file @
7450aa7e
...
...
@@ -28,6 +28,26 @@ static struct device_struct blkdevs[MAX_BLKDEV] = {
{
NULL
,
NULL
},
};
int
get_device_list
(
char
*
page
)
{
int
i
;
int
len
;
len
=
sprintf
(
page
,
"Character devices:
\n
"
);
for
(
i
=
0
;
i
<
MAX_CHRDEV
;
i
++
)
{
if
(
chrdevs
[
i
].
fops
)
{
len
+=
sprintf
(
page
+
len
,
"%2d %s
\n
"
,
i
,
chrdevs
[
i
].
name
);
}
}
len
+=
sprintf
(
page
+
len
,
"
\n
Block devices:
\n
"
);
for
(
i
=
0
;
i
<
MAX_BLKDEV
;
i
++
)
{
if
(
blkdevs
[
i
].
fops
)
{
len
+=
sprintf
(
page
+
len
,
"%2d %s
\n
"
,
i
,
blkdevs
[
i
].
name
);
}
}
return
len
;
}
struct
file_operations
*
get_blkfops
(
unsigned
int
major
)
{
if
(
major
>=
MAX_BLKDEV
)
...
...
fs/ext/file.c
View file @
7450aa7e
...
...
@@ -248,7 +248,7 @@ static int ext_file_write(struct inode * inode, struct file * filp, char * buf,
memcpy_fromfs
(
p
,
buf
,
c
);
buf
+=
c
;
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
0
);
mark_buffer_dirty
(
bh
,
0
);
brelse
(
bh
);
}
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
...
...
fs/ext/freelists.c
View file @
7450aa7e
...
...
@@ -83,7 +83,7 @@ printk("ext_free_block: block full, skipping to %d\n", block);
}
sb
->
u
.
ext_sb
.
s_freeblockscount
++
;
sb
->
s_dirt
=
1
;
dirtify_buffer
(
sb
->
u
.
ext_sb
.
s_firstfreeblock
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext_sb
.
s_firstfreeblock
,
1
);
unlock_super
(
sb
);
return
;
}
...
...
@@ -104,7 +104,7 @@ int ext_new_block(struct super_block * sb)
efb
=
(
struct
ext_free_block
*
)
sb
->
u
.
ext_sb
.
s_firstfreeblock
->
b_data
;
if
(
efb
->
count
)
{
j
=
efb
->
free
[
--
efb
->
count
];
dirtify_buffer
(
sb
->
u
.
ext_sb
.
s_firstfreeblock
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext_sb
.
s_firstfreeblock
,
1
);
}
else
{
#ifdef EXTFS_DEBUG
printk
(
"ext_new_block: block empty, skipping to %d
\n
"
,
efb
->
next
);
...
...
@@ -135,7 +135,7 @@ printk("ext_new_block: block empty, skipping to %d\n", efb->next);
}
clear_block
(
bh
->
b_data
);
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
#ifdef EXTFS_DEBUG
printk
(
"ext_new_block: allocating block %d
\n
"
,
j
);
...
...
@@ -239,7 +239,7 @@ printk("ext_free_inode: inode full, skipping to %d\n", ino);
}
sb
->
u
.
ext_sb
.
s_freeinodescount
++
;
sb
->
s_dirt
=
1
;
dirtify_buffer
(
sb
->
u
.
ext_sb
.
s_firstfreeinodeblock
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext_sb
.
s_firstfreeinodeblock
,
1
);
unlock_super
(
sb
);
}
...
...
@@ -263,7 +263,7 @@ struct inode * ext_new_inode(const struct inode * dir)
(
sb
->
u
.
ext_sb
.
s_firstfreeinodenumber
-
1
)
%
EXT_INODES_PER_BLOCK
;
if
(
efi
->
count
)
{
j
=
efi
->
free
[
--
efi
->
count
];
dirtify_buffer
(
sb
->
u
.
ext_sb
.
s_firstfreeinodeblock
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext_sb
.
s_firstfreeinodeblock
,
1
);
}
else
{
#ifdef EXTFS_DEBUG
printk
(
"ext_free_inode: inode empty, skipping to %d
\n
"
,
efi
->
next
);
...
...
fs/ext/inode.c
View file @
7450aa7e
...
...
@@ -139,7 +139,7 @@ void ext_write_super (struct super_block *sb)
es
->
s_freeblockscount
=
sb
->
u
.
ext_sb
.
s_freeblockscount
;
es
->
s_firstfreeinode
=
sb
->
u
.
ext_sb
.
s_firstfreeinodenumber
;
es
->
s_freeinodescount
=
sb
->
u
.
ext_sb
.
s_freeinodescount
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
sb
->
s_dirt
=
0
;
}
...
...
@@ -296,7 +296,7 @@ static struct buffer_head * block_getblk(struct inode * inode,
goto
repeat
;
}
*
p
=
tmp
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
return
result
;
}
...
...
@@ -407,7 +407,7 @@ static struct buffer_head * ext_update_inode(struct inode * inode)
raw_inode
->
i_zone
[
0
]
=
inode
->
i_rdev
;
else
for
(
block
=
0
;
block
<
12
;
block
++
)
raw_inode
->
i_zone
[
block
]
=
inode
->
u
.
ext_i
.
i_data
[
block
];
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_dirt
=
0
;
return
bh
;
}
...
...
fs/ext/namei.c
View file @
7450aa7e
...
...
@@ -249,7 +249,7 @@ printk ("ext_add_entry: skipping to next block\n");
#if 0
dir->i_ctime = CURRENT_TIME;
#endif
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
}
brelse
(
bh
);
bh
=
NULL
;
...
...
@@ -296,7 +296,7 @@ printk ("ext_add_entry : creating next block\n");
de
->
name_len
=
namelen
;
for
(
i
=
0
;
i
<
namelen
;
i
++
)
de
->
name
[
i
]
=
name
[
i
];
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
*
res_dir
=
de
;
return
bh
;
}
...
...
@@ -334,7 +334,7 @@ int ext_create(struct inode * dir,const char * name, int len, int mode,
return
-
ENOSPC
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
*
result
=
inode
;
...
...
@@ -393,7 +393,7 @@ int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev
return
-
ENOSPC
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
iput
(
inode
);
...
...
@@ -445,7 +445,7 @@ int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
de
->
name_len
=
2
;
strcpy
(
de
->
name
,
".."
);
inode
->
i_nlink
=
2
;
dirtify_buffer
(
dir_block
,
1
);
mark_buffer_dirty
(
dir_block
,
1
);
brelse
(
dir_block
);
inode
->
i_mode
=
S_IFDIR
|
(
mode
&
0777
&
~
current
->
umask
);
if
(
dir
->
i_mode
&
S_ISGID
)
...
...
@@ -459,7 +459,7 @@ int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
return
-
ENOSPC
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_nlink
++
;
dir
->
i_dirt
=
1
;
iput
(
dir
);
...
...
@@ -567,7 +567,7 @@ int ext_rmdir(struct inode * dir, const char * name, int len)
de
->
inode
=
0
;
de
->
name_len
=
0
;
ext_merge_entries
(
de
,
pde
,
nde
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_nlink
=
0
;
inode
->
i_dirt
=
1
;
dir
->
i_nlink
--
;
...
...
@@ -610,7 +610,7 @@ int ext_unlink(struct inode * dir, const char * name, int len)
de
->
inode
=
0
;
de
->
name_len
=
0
;
ext_merge_entries
(
de
,
pde
,
nde
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
inode
->
i_ctime
=
CURRENT_TIME
;
...
...
@@ -650,7 +650,7 @@ int ext_symlink(struct inode * dir, const char * name, int len, const char * sym
while
(
i
<
1023
&&
(
c
=
*
(
symname
++
)))
name_block
->
b_data
[
i
++
]
=
c
;
name_block
->
b_data
[
i
]
=
0
;
dirtify_buffer
(
name_block
,
1
);
mark_buffer_dirty
(
name_block
,
1
);
brelse
(
name_block
);
inode
->
i_size
=
i
;
inode
->
i_dirt
=
1
;
...
...
@@ -672,7 +672,7 @@ int ext_symlink(struct inode * dir, const char * name, int len, const char * sym
return
-
ENOSPC
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
iput
(
inode
);
...
...
@@ -708,7 +708,7 @@ int ext_link(struct inode * oldinode, struct inode * dir, const char * name, int
return
-
ENOSPC
;
}
de
->
inode
=
oldinode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
oldinode
->
i_nlink
++
;
...
...
@@ -851,11 +851,11 @@ static int do_ext_rename(struct inode * old_dir, const char * old_name, int old_
new_inode
->
i_nlink
--
;
new_inode
->
i_dirt
=
1
;
}
dirtify_buffer
(
old_bh
,
1
);
dirtify_buffer
(
new_bh
,
1
);
mark_buffer_dirty
(
old_bh
,
1
);
mark_buffer_dirty
(
new_bh
,
1
);
if
(
dir_bh
)
{
PARENT_INO
(
dir_bh
->
b_data
)
=
new_dir
->
i_ino
;
dirtify_buffer
(
dir_bh
,
1
);
mark_buffer_dirty
(
dir_bh
,
1
);
old_dir
->
i_nlink
--
;
new_dir
->
i_nlink
++
;
old_dir
->
i_dirt
=
1
;
...
...
fs/ext/truncate.c
View file @
7450aa7e
...
...
@@ -102,7 +102,7 @@ static int trunc_indirect(struct inode * inode, int offset, unsigned long * p)
continue
;
}
*
ind
=
0
;
dirtify_buffer
(
ind_bh
,
1
);
mark_buffer_dirty
(
ind_bh
,
1
);
brelse
(
bh
);
ext_free_block
(
inode
->
i_sb
,
tmp
);
}
...
...
@@ -154,7 +154,7 @@ static int trunc_dindirect(struct inode * inode, int offset, unsigned long * p)
if
(
!
tmp
)
continue
;
retry
|=
trunc_indirect
(
inode
,
offset
+
(
i
<<
8
),
dind
);
dirtify_buffer
(
dind_bh
,
1
);
mark_buffer_dirty
(
dind_bh
,
1
);
}
dind
=
(
unsigned
long
*
)
dind_bh
->
b_data
;
for
(
i
=
0
;
i
<
256
;
i
++
)
...
...
@@ -201,7 +201,7 @@ static int trunc_tindirect(struct inode * inode)
goto
repeat
;
tind
=
i
+
(
unsigned
long
*
)
tind_bh
->
b_data
;
retry
|=
trunc_dindirect
(
inode
,
9
+
256
+
256
*
256
+
(
i
<<
16
),
tind
);
dirtify_buffer
(
tind_bh
,
1
);
mark_buffer_dirty
(
tind_bh
,
1
);
}
tind
=
(
unsigned
long
*
)
tind_bh
->
b_data
;
for
(
i
=
0
;
i
<
256
;
i
++
)
...
...
fs/ext2/balloc.c
View file @
7450aa7e
...
...
@@ -310,10 +310,10 @@ void ext2_free_blocks (struct super_block * sb, unsigned long block,
}
}
dirtify_buffer
(
bh2
,
1
);
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
bh2
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
sb
->
s_flags
&
MS_SYNC
)
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -524,7 +524,7 @@ int ext2_new_block (struct super_block * sb, unsigned long goal,
j
=
tmp
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
sb
->
s_flags
&
MS_SYNC
)
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -544,16 +544,16 @@ int ext2_new_block (struct super_block * sb, unsigned long goal,
}
clear_block
(
bh
->
b_data
,
sb
->
s_blocksize
);
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
ext2_debug
(
"allocating block %d. "
"Goal hits %d of %d.
\n
"
,
j
,
goal_hits
,
goal_attempts
);
gdp
->
bg_free_blocks_count
--
;
dirtify_buffer
(
bh2
,
1
);
mark_buffer_dirty
(
bh2
,
1
);
es
->
s_free_blocks_count
--
;
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
sb
->
s_dirt
=
1
;
unlock_super
(
sb
);
return
j
;
...
...
fs/ext2/file.c
View file @
7450aa7e
...
...
@@ -78,6 +78,7 @@ static int ext2_file_read (struct inode * inode, struct file * filp,
int
read
,
left
,
chars
;
int
block
,
blocks
,
offset
;
int
bhrequest
,
uptodate
;
int
clusterblocks
;
struct
buffer_head
**
bhb
,
**
bhe
;
struct
buffer_head
*
bhreq
[
NBUF
];
struct
buffer_head
*
buflist
[
NBUF
];
...
...
@@ -130,11 +131,18 @@ static int ext2_file_read (struct inode * inode, struct file * filp,
* buffers and caches.
*/
clusterblocks
=
0
;
do
{
bhrequest
=
0
;
uptodate
=
1
;
while
(
blocks
)
{
--
blocks
;
#if 1
if
(
!
clusterblocks
)
clusterblocks
=
ext2_getcluster
(
inode
,
block
);
if
(
clusterblocks
)
clusterblocks
--
;
#endif
*
bhb
=
ext2_getblk
(
inode
,
block
++
,
0
,
&
err
);
if
(
*
bhb
&&
!
(
*
bhb
)
->
b_uptodate
)
{
uptodate
=
0
;
...
...
@@ -277,7 +285,7 @@ static int ext2_file_write (struct inode * inode, struct file * filp,
memcpy_fromfs
(
p
,
buf
,
c
);
buf
+=
c
;
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
0
);
mark_buffer_dirty
(
bh
,
0
);
brelse
(
bh
);
}
up
(
&
inode
->
i_sem
);
...
...
fs/ext2/ialloc.c
View file @
7450aa7e
...
...
@@ -202,7 +202,7 @@ static void set_inode_dtime (struct inode * inode,
EXT2_INODES_PER_BLOCK
(
inode
->
i_sb
));
raw_inode
->
i_links_count
=
0
;
raw_inode
->
i_dtime
=
CURRENT_TIME
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
inode
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -266,12 +266,12 @@ void ext2_free_inode (struct inode * inode)
gdp
->
bg_free_inodes_count
++
;
if
(
S_ISDIR
(
inode
->
i_mode
))
gdp
->
bg_used_dirs_count
--
;
dirtify_buffer
(
bh2
,
1
);
mark_buffer_dirty
(
bh2
,
1
);
es
->
s_free_inodes_count
++
;
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
set_inode_dtime
(
inode
,
gdp
);
}
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
sb
->
s_flags
&
MS_SYNC
)
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -313,7 +313,7 @@ static void inc_inode_version (struct inode * inode,
EXT2_INODES_PER_BLOCK
(
inode
->
i_sb
));
raw_inode
->
i_version
++
;
inode
->
u
.
ext2_i
.
i_version
=
raw_inode
->
i_version
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
}
...
...
@@ -438,7 +438,7 @@ struct inode * ext2_new_inode (const struct inode * dir, int mode)
"bit already set for inode %d"
,
j
);
goto
repeat
;
}
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
sb
->
s_flags
&
MS_SYNC
)
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -466,9 +466,9 @@ struct inode * ext2_new_inode (const struct inode * dir, int mode)
gdp
->
bg_free_inodes_count
--
;
if
(
S_ISDIR
(
mode
))
gdp
->
bg_used_dirs_count
++
;
dirtify_buffer
(
bh2
,
1
);
mark_buffer_dirty
(
bh2
,
1
);
es
->
s_free_inodes_count
--
;
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
sb
->
s_dirt
=
1
;
inode
->
i_mode
=
mode
;
inode
->
i_sb
=
sb
;
...
...
fs/ext2/inode.c
View file @
7450aa7e
...
...
@@ -109,7 +109,7 @@ static int ext2_alloc_block (struct inode * inode, unsigned long goal)
}
clear_block
(
bh
->
b_data
,
inode
->
i_sb
->
s_blocksize
);
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
}
else
{
ext2_discard_prealloc
(
inode
);
...
...
@@ -314,7 +314,7 @@ static struct buffer_head * block_getblk (struct inode * inode,
goto
repeat
;
}
*
p
=
tmp
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
inode
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -328,6 +328,41 @@ static struct buffer_head * block_getblk (struct inode * inode,
return
result
;
}
static
int
block_getcluster
(
struct
inode
*
inode
,
struct
buffer_head
*
bh
,
int
nr
,
int
blocksize
)
{
unsigned
long
*
p
;
int
firstblock
=
0
;
int
result
=
0
;
int
i
;
/* Check to see if clustering possible here. */
if
(
!
bh
)
return
0
;
if
(
nr
%
(
PAGE_SIZE
/
inode
->
i_sb
->
s_blocksize
)
!=
0
)
goto
out
;
if
(
nr
+
3
>
EXT2_ADDR_PER_BLOCK
(
inode
->
i_sb
))
goto
out
;
for
(
i
=
0
;
i
<
(
PAGE_SIZE
/
inode
->
i_sb
->
s_blocksize
);
i
++
)
{
p
=
(
unsigned
long
*
)
bh
->
b_data
+
nr
+
i
;
/* All blocks in cluster must already be allocated */
if
(
*
p
==
0
)
goto
out
;
/* See if aligned correctly */
if
(
i
==
0
)
firstblock
=
*
p
;
else
if
(
*
p
!=
firstblock
+
i
)
goto
out
;
};
p
=
(
unsigned
long
*
)
bh
->
b_data
+
nr
;
result
=
generate_cluster
(
bh
->
b_dev
,
(
int
*
)
p
,
blocksize
);
out:
brelse
(
bh
);
return
result
;
}
struct
buffer_head
*
ext2_getblk
(
struct
inode
*
inode
,
long
block
,
int
create
,
int
*
err
)
{
...
...
@@ -389,6 +424,55 @@ struct buffer_head * ext2_getblk (struct inode * inode, long block,
inode
->
i_sb
->
s_blocksize
,
b
,
err
);
}
int
ext2_getcluster
(
struct
inode
*
inode
,
long
block
)
{
struct
buffer_head
*
bh
;
int
err
,
create
;
unsigned
long
b
;
unsigned
long
addr_per_block
=
EXT2_ADDR_PER_BLOCK
(
inode
->
i_sb
);
create
=
0
;
err
=
-
EIO
;
if
(
block
<
0
)
{
ext2_warning
(
inode
->
i_sb
,
"ext2_getblk"
,
"block < 0"
);
return
0
;
}
if
(
block
>
EXT2_NDIR_BLOCKS
+
addr_per_block
+
addr_per_block
*
addr_per_block
+
addr_per_block
*
addr_per_block
*
addr_per_block
)
{
ext2_warning
(
inode
->
i_sb
,
"ext2_getblk"
,
"block > big"
);
return
0
;
}
err
=
-
ENOSPC
;
b
=
block
;
if
(
block
<
EXT2_NDIR_BLOCKS
)
return
0
;
block
-=
EXT2_NDIR_BLOCKS
;
if
(
block
<
addr_per_block
)
{
bh
=
inode_getblk
(
inode
,
EXT2_IND_BLOCK
,
create
,
b
,
&
err
);
return
block_getcluster
(
inode
,
bh
,
block
,
inode
->
i_sb
->
s_blocksize
);
}
block
-=
addr_per_block
;
if
(
block
<
addr_per_block
*
addr_per_block
)
{
bh
=
inode_getblk
(
inode
,
EXT2_DIND_BLOCK
,
create
,
b
,
&
err
);
bh
=
block_getblk
(
inode
,
bh
,
block
/
addr_per_block
,
create
,
inode
->
i_sb
->
s_blocksize
,
b
,
&
err
);
return
block_getcluster
(
inode
,
bh
,
block
&
(
addr_per_block
-
1
),
inode
->
i_sb
->
s_blocksize
);
}
block
-=
addr_per_block
*
addr_per_block
;
bh
=
inode_getblk
(
inode
,
EXT2_TIND_BLOCK
,
create
,
b
,
&
err
);
bh
=
block_getblk
(
inode
,
bh
,
block
/
(
addr_per_block
*
addr_per_block
),
create
,
inode
->
i_sb
->
s_blocksize
,
b
,
&
err
);
bh
=
block_getblk
(
inode
,
bh
,
(
block
/
addr_per_block
)
&
(
addr_per_block
-
1
),
create
,
inode
->
i_sb
->
s_blocksize
,
b
,
&
err
);
return
block_getcluster
(
inode
,
bh
,
block
&
(
addr_per_block
-
1
),
inode
->
i_sb
->
s_blocksize
);
}
struct
buffer_head
*
ext2_bread
(
struct
inode
*
inode
,
int
block
,
int
create
,
int
*
err
)
{
...
...
@@ -549,7 +633,7 @@ static struct buffer_head * ext2_update_inode (struct inode * inode)
raw_inode
->
i_block
[
0
]
=
inode
->
i_rdev
;
else
for
(
block
=
0
;
block
<
EXT2_N_BLOCKS
;
block
++
)
raw_inode
->
i_block
[
block
]
=
inode
->
u
.
ext2_i
.
i_data
[
block
];
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_dirt
=
0
;
return
bh
;
}
...
...
fs/ext2/namei.c
View file @
7450aa7e
...
...
@@ -320,7 +320,7 @@ static struct buffer_head * ext2_add_entry (struct inode * dir,
*/
dir
->
i_mtime
=
dir
->
i_ctime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
*
res_dir
=
de
;
*
err
=
0
;
return
bh
;
...
...
@@ -394,7 +394,7 @@ int ext2_create (struct inode * dir,const char * name, int len, int mode,
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
#endif
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -460,7 +460,7 @@ int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
#endif
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -517,7 +517,7 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
de
->
name_len
=
2
;
strcpy
(
de
->
name
,
".."
);
inode
->
i_nlink
=
2
;
dirtify_buffer
(
dir_block
,
1
);
mark_buffer_dirty
(
dir_block
,
1
);
brelse
(
dir_block
);
inode
->
i_mode
=
S_IFDIR
|
(
mode
&
S_IRWXUGO
&
~
current
->
umask
);
if
(
dir
->
i_mode
&
S_ISGID
)
...
...
@@ -536,7 +536,7 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
#endif
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -660,7 +660,7 @@ int ext2_rmdir (struct inode * dir, const char * name, int len)
up
(
&
inode
->
i_sem
);
if
(
retval
)
goto
end_rmdir
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -728,7 +728,7 @@ int ext2_unlink (struct inode * dir, const char * name, int len)
retval
=
ext2_delete_entry
(
de
,
bh
);
if
(
retval
)
goto
end_unlink
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -793,7 +793,7 @@ int ext2_symlink (struct inode * dir, const char * name, int len,
link
[
i
++
]
=
c
;
link
[
i
]
=
0
;
if
(
name_block
)
{
dirtify_buffer
(
name_block
,
1
);
mark_buffer_dirty
(
name_block
,
1
);
brelse
(
name_block
);
}
inode
->
i_size
=
i
;
...
...
@@ -820,7 +820,7 @@ int ext2_symlink (struct inode * dir, const char * name, int len,
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
#endif
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -866,7 +866,7 @@ int ext2_link (struct inode * oldinode, struct inode * dir,
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
#endif
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
...
...
@@ -1042,19 +1042,19 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name,
}
old_dir
->
i_ctime
=
old_dir
->
i_mtime
=
CURRENT_TIME
;
old_dir
->
i_dirt
=
1
;
dirtify_buffer
(
old_bh
,
1
);
mark_buffer_dirty
(
old_bh
,
1
);
if
(
IS_SYNC
(
old_dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
old_bh
);
wait_on_buffer
(
old_bh
);
}
dirtify_buffer
(
new_bh
,
1
);
mark_buffer_dirty
(
new_bh
,
1
);
if
(
IS_SYNC
(
new_dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
new_bh
);
wait_on_buffer
(
new_bh
);
}
if
(
dir_bh
)
{
PARENT_INO
(
dir_bh
->
b_data
)
=
new_dir
->
i_ino
;
dirtify_buffer
(
dir_bh
,
1
);
mark_buffer_dirty
(
dir_bh
,
1
);
old_dir
->
i_nlink
--
;
old_dir
->
i_dirt
=
1
;
if
(
new_inode
)
{
...
...
fs/ext2/super.c
View file @
7450aa7e
...
...
@@ -36,7 +36,7 @@ void ext2_error (struct super_block * sb, const char * function,
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
sb
->
u
.
ext2_sb
.
s_mount_state
|=
EXT2_ERROR_FS
;
sb
->
u
.
ext2_sb
.
s_es
->
s_state
|=
EXT2_ERROR_FS
;
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
sb
->
s_dirt
=
1
;
}
va_start
(
args
,
fmt
);
...
...
@@ -66,7 +66,7 @@ NORET_TYPE void ext2_panic (struct super_block * sb, const char * function,
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
sb
->
u
.
ext2_sb
.
s_mount_state
|=
EXT2_ERROR_FS
;
sb
->
u
.
ext2_sb
.
s_es
->
s_state
|=
EXT2_ERROR_FS
;
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
sb
->
s_dirt
=
1
;
}
va_start
(
args
,
fmt
);
...
...
@@ -96,7 +96,7 @@ void ext2_put_super (struct super_block * sb)
lock_super
(
sb
);
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
sb
->
u
.
ext2_sb
.
s_es
->
s_state
=
sb
->
u
.
ext2_sb
.
s_mount_state
;
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
}
#ifndef DONT_USE_DCACHE
ext2_dcache_invalidate
(
sb
->
s_dev
);
...
...
@@ -159,10 +159,10 @@ static int convert_pre_02b_fs (struct super_block * sb,
gdp
[
i
].
bg_free_blocks_count
=
old_group_desc
[
i
].
bg_free_blocks_count
;
gdp
[
i
].
bg_free_inodes_count
=
old_group_desc
[
i
].
bg_free_inodes_count
;
}
dirtify_buffer
(
bh2
,
1
);
mark_buffer_dirty
(
bh2
,
1
);
brelse
(
bh2
);
es
->
s_magic
=
EXT2_SUPER_MAGIC
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
sb
->
s_magic
=
EXT2_SUPER_MAGIC
;
return
1
;
}
...
...
@@ -287,7 +287,7 @@ static void ext2_setup_super (struct super_block * sb,
es
->
s_max_mnt_count
=
EXT2_DFL_MAX_MNT_COUNT
;
es
->
s_mnt_count
++
;
es
->
s_mtime
=
CURRENT_TIME
;
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
sb
->
s_dirt
=
1
;
if
(
test_opt
(
sb
,
DEBUG
))
printk
(
"[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "
...
...
@@ -570,7 +570,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
#ifdef EXT2FS_PRE_02B_COMPAT
if
(
fs_converted
)
{
for
(
i
=
0
;
i
<
bh_count
;
i
++
)
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_group_desc
[
i
],
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_group_desc
[
i
],
1
);
sb
->
s_dirt
=
1
;
}
#endif
...
...
@@ -582,7 +582,7 @@ static void ext2_commit_super (struct super_block * sb,
struct
ext2_super_block
*
es
)
{
es
->
s_wtime
=
CURRENT_TIME
;
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
sb
->
s_dirt
=
0
;
}
...
...
@@ -639,7 +639,7 @@ int ext2_remount (struct super_block * sb, int * flags, char * data)
*/
es
->
s_state
=
sb
->
u
.
ext2_sb
.
s_mount_state
;
es
->
s_mtime
=
CURRENT_TIME
;
dirtify_buffer
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
sb
->
s_dirt
=
1
;
ext2_commit_super
(
sb
,
es
);
}
...
...
fs/ext2/truncate.c
View file @
7450aa7e
...
...
@@ -90,7 +90,7 @@ static int trunc_direct (struct inode * inode)
if
(
inode
->
u
.
ext2_i
.
i_flags
&
EXT2_SECRM_FL
)
{
clear_block
(
bh
->
b_data
,
inode
->
i_sb
->
s_blocksize
,
RANDOM_INT
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
}
brelse
(
bh
);
if
(
free_count
==
0
)
{
...
...
@@ -162,11 +162,11 @@ static int trunc_indirect (struct inode * inode, int offset, unsigned long * p)
continue
;
}
*
ind
=
0
;
dirtify_buffer
(
ind_bh
,
1
);
mark_buffer_dirty
(
ind_bh
,
1
);
if
(
inode
->
u
.
ext2_i
.
i_flags
&
EXT2_SECRM_FL
)
{
clear_block
(
bh
->
b_data
,
inode
->
i_sb
->
s_blocksize
,
RANDOM_INT
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
}
brelse
(
bh
);
if
(
free_count
==
0
)
{
...
...
@@ -243,7 +243,7 @@ static int trunc_dindirect (struct inode * inode, int offset,
continue
;
retry
|=
trunc_indirect
(
inode
,
offset
+
(
i
*
addr_per_block
),
dind
);
dirtify_buffer
(
dind_bh
,
1
);
mark_buffer_dirty
(
dind_bh
,
1
);
}
dind
=
(
unsigned
long
*
)
dind_bh
->
b_data
;
for
(
i
=
0
;
i
<
addr_per_block
;
i
++
)
...
...
@@ -302,7 +302,7 @@ static int trunc_tindirect (struct inode * inode)
retry
|=
trunc_dindirect
(
inode
,
EXT2_NDIR_BLOCKS
+
addr_per_block
+
(
i
+
1
)
*
addr_per_block
*
addr_per_block
,
tind
);
dirtify_buffer
(
tind_bh
,
1
);
mark_buffer_dirty
(
tind_bh
,
1
);
}
tind
=
(
unsigned
long
*
)
tind_bh
->
b_data
;
for
(
i
=
0
;
i
<
addr_per_block
;
i
++
)
...
...
fs/minix/bitmap.c
View file @
7450aa7e
...
...
@@ -93,7 +93,7 @@ void minix_free_block(struct super_block * sb, int block)
}
if
(
!
clear_bit
(
bit
,
bh
->
b_data
))
printk
(
"free_block (%04x:%d): bit already cleared
\n
"
,
sb
->
s_dev
,
block
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
return
;
}
...
...
@@ -118,7 +118,7 @@ int minix_new_block(struct super_block * sb)
printk
(
"new_block: bit already set"
);
goto
repeat
;
}
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
j
+=
i
*
8192
+
sb
->
u
.
minix_sb
.
s_firstdatazone
-
1
;
if
(
j
<
sb
->
u
.
minix_sb
.
s_firstdatazone
||
j
>=
sb
->
u
.
minix_sb
.
s_nzones
)
...
...
@@ -129,7 +129,7 @@ int minix_new_block(struct super_block * sb)
}
clear_block
(
bh
->
b_data
);
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
return
j
;
}
...
...
@@ -175,7 +175,7 @@ void minix_free_inode(struct inode * inode)
clear_inode
(
inode
);
if
(
!
clear_bit
(
ino
&
8191
,
bh
->
b_data
))
printk
(
"free_inode: bit %lu already cleared.
\n
"
,
ino
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
}
struct
inode
*
minix_new_inode
(
const
struct
inode
*
dir
)
...
...
@@ -204,7 +204,7 @@ struct inode * minix_new_inode(const struct inode * dir)
iput
(
inode
);
return
NULL
;
}
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
j
+=
i
*
8192
;
if
(
!
j
||
j
>=
inode
->
i_sb
->
u
.
minix_sb
.
s_ninodes
)
{
iput
(
inode
);
...
...
fs/minix/file.c
View file @
7450aa7e
...
...
@@ -240,7 +240,7 @@ static int minix_file_write(struct inode * inode, struct file * filp, char * buf
memcpy_fromfs
(
p
,
buf
,
c
);
buf
+=
c
;
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
0
);
mark_buffer_dirty
(
bh
,
0
);
brelse
(
bh
);
}
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
...
...
fs/minix/inode.c
View file @
7450aa7e
...
...
@@ -28,7 +28,7 @@ void minix_put_inode(struct inode *inode)
static
void
minix_commit_super
(
struct
super_block
*
sb
,
struct
minix_super_block
*
ms
)
{
dirtify_buffer
(
sb
->
u
.
minix_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
minix_sb
.
s_sbh
,
1
);
sb
->
s_dirt
=
0
;
}
...
...
@@ -54,7 +54,7 @@ void minix_put_super(struct super_block *sb)
lock_super
(
sb
);
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
sb
->
u
.
minix_sb
.
s_ms
->
s_state
=
sb
->
u
.
minix_sb
.
s_mount_state
;
dirtify_buffer
(
sb
->
u
.
minix_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
minix_sb
.
s_sbh
,
1
);
}
sb
->
s_dev
=
0
;
for
(
i
=
0
;
i
<
MINIX_I_MAP_SLOTS
;
i
++
)
...
...
@@ -90,7 +90,7 @@ int minix_remount (struct super_block * sb, int * flags, char * data)
return
0
;
/* Mounting a rw partition read-only. */
ms
->
s_state
=
sb
->
u
.
minix_sb
.
s_mount_state
;
dirtify_buffer
(
sb
->
u
.
minix_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
minix_sb
.
s_sbh
,
1
);
sb
->
s_dirt
=
1
;
minix_commit_super
(
sb
,
ms
);
}
...
...
@@ -98,7 +98,7 @@ int minix_remount (struct super_block * sb, int * flags, char * data)
/* Mount a partition which is read-only, read-write. */
sb
->
u
.
minix_sb
.
s_mount_state
=
ms
->
s_state
;
ms
->
s_state
&=
~
MINIX_VALID_FS
;
dirtify_buffer
(
sb
->
u
.
minix_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
minix_sb
.
s_sbh
,
1
);
sb
->
s_dirt
=
1
;
if
(
!
(
sb
->
u
.
minix_sb
.
s_mount_state
&
MINIX_VALID_FS
))
...
...
@@ -197,7 +197,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data,
}
if
(
!
(
s
->
s_flags
&
MS_RDONLY
))
{
ms
->
s_state
&=
~
MINIX_VALID_FS
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
s
->
s_dirt
=
1
;
}
if
(
!
(
s
->
u
.
minix_sb
.
s_mount_state
&
MINIX_VALID_FS
))
...
...
@@ -349,7 +349,7 @@ static struct buffer_head * block_getblk(struct inode * inode,
goto
repeat
;
}
*
p
=
tmp
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
return
result
;
}
...
...
@@ -477,7 +477,7 @@ static struct buffer_head * minix_update_inode(struct inode * inode)
else
for
(
block
=
0
;
block
<
9
;
block
++
)
raw_inode
->
i_zone
[
block
]
=
inode
->
u
.
minix_i
.
i_data
[
block
];
inode
->
i_dirt
=
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
return
bh
;
}
...
...
fs/minix/namei.c
View file @
7450aa7e
...
...
@@ -195,7 +195,7 @@ static int minix_add_entry(struct inode * dir,
dir
->
i_mtime
=
dir
->
i_ctime
=
CURRENT_TIME
;
for
(
i
=
0
;
i
<
info
->
s_namelen
;
i
++
)
de
->
name
[
i
]
=
(
i
<
namelen
)
?
name
[
i
]
:
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
*
res_dir
=
de
;
break
;
}
...
...
@@ -238,7 +238,7 @@ int minix_create(struct inode * dir,const char * name, int len, int mode,
return
error
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
*
result
=
inode
;
...
...
@@ -295,7 +295,7 @@ int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rd
return
error
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
iput
(
inode
);
...
...
@@ -347,7 +347,7 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
de
->
inode
=
dir
->
i_ino
;
strcpy
(
de
->
name
,
".."
);
inode
->
i_nlink
=
2
;
dirtify_buffer
(
dir_block
,
1
);
mark_buffer_dirty
(
dir_block
,
1
);
brelse
(
dir_block
);
inode
->
i_mode
=
S_IFDIR
|
(
mode
&
0777
&
~
current
->
umask
);
if
(
dir
->
i_mode
&
S_ISGID
)
...
...
@@ -361,7 +361,7 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
return
error
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_nlink
++
;
dir
->
i_dirt
=
1
;
iput
(
dir
);
...
...
@@ -469,7 +469,7 @@ int minix_rmdir(struct inode * dir, const char * name, int len)
if
(
inode
->
i_nlink
!=
2
)
printk
(
"empty directory has nlink!=2 (%d)
\n
"
,
inode
->
i_nlink
);
de
->
inode
=
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_nlink
=
0
;
inode
->
i_dirt
=
1
;
dir
->
i_nlink
--
;
...
...
@@ -522,7 +522,7 @@ int minix_unlink(struct inode * dir, const char * name, int len)
inode
->
i_nlink
=
1
;
}
de
->
inode
=
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
inode
->
i_nlink
--
;
...
...
@@ -562,7 +562,7 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s
while
(
i
<
1023
&&
(
c
=*
(
symname
++
)))
name_block
->
b_data
[
i
++
]
=
c
;
name_block
->
b_data
[
i
]
=
0
;
dirtify_buffer
(
name_block
,
1
);
mark_buffer_dirty
(
name_block
,
1
);
brelse
(
name_block
);
inode
->
i_size
=
i
;
inode
->
i_dirt
=
1
;
...
...
@@ -584,7 +584,7 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s
return
i
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
iput
(
inode
);
...
...
@@ -621,7 +621,7 @@ int minix_link(struct inode * oldinode, struct inode * dir, const char * name, i
return
error
;
}
de
->
inode
=
oldinode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
oldinode
->
i_nlink
++
;
...
...
@@ -774,11 +774,11 @@ static int do_minix_rename(struct inode * old_dir, const char * old_name, int ol
new_inode
->
i_ctime
=
CURRENT_TIME
;
new_inode
->
i_dirt
=
1
;
}
dirtify_buffer
(
old_bh
,
1
);
dirtify_buffer
(
new_bh
,
1
);
mark_buffer_dirty
(
old_bh
,
1
);
mark_buffer_dirty
(
new_bh
,
1
);
if
(
dir_bh
)
{
PARENT_INO
(
dir_bh
->
b_data
)
=
new_dir
->
i_ino
;
dirtify_buffer
(
dir_bh
,
1
);
mark_buffer_dirty
(
dir_bh
,
1
);
old_dir
->
i_nlink
--
;
old_dir
->
i_dirt
=
1
;
if
(
new_inode
)
{
...
...
fs/minix/truncate.c
View file @
7450aa7e
...
...
@@ -96,7 +96,7 @@ static int trunc_indirect(struct inode * inode, int offset, unsigned short * p)
continue
;
}
*
ind
=
0
;
dirtify_buffer
(
ind_bh
,
1
);
mark_buffer_dirty
(
ind_bh
,
1
);
brelse
(
bh
);
minix_free_block
(
inode
->
i_sb
,
tmp
);
}
...
...
@@ -144,7 +144,7 @@ static int trunc_dindirect(struct inode * inode)
goto
repeat
;
dind
=
i
+
(
unsigned
short
*
)
dind_bh
->
b_data
;
retry
|=
trunc_indirect
(
inode
,
7
+
512
+
(
i
<<
9
),
dind
);
dirtify_buffer
(
dind_bh
,
1
);
mark_buffer_dirty
(
dind_bh
,
1
);
}
dind
=
(
unsigned
short
*
)
dind_bh
->
b_data
;
for
(
i
=
0
;
i
<
512
;
i
++
)
...
...
fs/msdos/fat.c
View file @
7450aa7e
...
...
@@ -72,15 +72,15 @@ int fat_access(struct super_block *sb,int nr,int new_value)
*
p_first
=
new_value
&
0xff
;
*
p_last
=
(
*
p_last
&
0xf0
)
|
(
new_value
>>
8
);
}
dirtify_buffer
(
bh2
,
1
);
mark_buffer_dirty
(
bh2
,
1
);
}
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
for
(
copy
=
1
;
copy
<
MSDOS_SB
(
sb
)
->
fats
;
copy
++
)
{
if
(
!
(
c_bh
=
msdos_sread
(
sb
->
s_dev
,
MSDOS_SB
(
sb
)
->
fat_start
+
(
first
>>
SECTOR_BITS
)
+
MSDOS_SB
(
sb
)
->
fat_length
*
copy
,
&
c_data
)))
break
;
memcpy
(
c_data
,
data
,
SECTOR_SIZE
);
dirtify_buffer
(
c_bh
,
1
);
mark_buffer_dirty
(
c_bh
,
1
);
if
(
data
!=
data2
||
bh
!=
bh2
)
{
if
(
!
(
c_bh2
=
msdos_sread
(
sb
->
s_dev
,
MSDOS_SB
(
sb
)
->
fat_start
+
(
first
>>
...
...
fs/msdos/file.c
View file @
7450aa7e
...
...
@@ -200,7 +200,7 @@ static int msdos_file_write(struct inode *inode,struct file *filp,char *buf,
inode
->
i_size
=
filp
->
f_pos
;
inode
->
i_dirt
=
1
;
}
dirtify_buffer
(
bh
,
0
);
mark_buffer_dirty
(
bh
,
0
);
brelse
(
bh
);
}
if
(
start
==
buf
)
...
...
fs/msdos/inode.c
View file @
7450aa7e
...
...
@@ -415,7 +415,7 @@ void msdos_write_inode(struct inode *inode)
date_unix2dos
(
inode
->
i_mtime
,
&
raw_entry
->
time
,
&
raw_entry
->
date
);
raw_entry
->
time
=
CT_LE_W
(
raw_entry
->
time
);
raw_entry
->
date
=
CT_LE_W
(
raw_entry
->
date
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
}
...
...
fs/msdos/misc.c
View file @
7450aa7e
...
...
@@ -185,7 +185,7 @@ printk("zeroing sector %d\n",sector);
else
memset
(
data
,
0
,
SECTOR_SIZE
);
}
if
(
bh
)
{
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
}
}
...
...
fs/msdos/namei.c
View file @
7450aa7e
...
...
@@ -181,7 +181,7 @@ static int msdos_create_entry(struct inode *dir,char *name,int is_dir,
de
->
start
=
0
;
date_unix2dos
(
dir
->
i_mtime
,
&
de
->
time
,
&
de
->
date
);
de
->
size
=
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
((
*
result
=
iget
(
dir
->
i_sb
,
ino
))
!=
NULL
)
msdos_read_inode
(
*
result
);
brelse
(
bh
);
...
...
@@ -350,7 +350,7 @@ int msdos_rmdir(struct inode *dir,const char *name,int len)
dir
->
i_nlink
--
;
inode
->
i_dirt
=
dir
->
i_dirt
=
1
;
de
->
name
[
0
]
=
DELETED_FLAG
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
res
=
0
;
rmdir_done:
brelse
(
bh
);
...
...
@@ -384,7 +384,7 @@ int msdos_unlink(struct inode *dir,const char *name,int len)
MSDOS_I
(
inode
)
->
i_busy
=
1
;
inode
->
i_dirt
=
dir
->
i_dirt
=
1
;
de
->
name
[
0
]
=
DELETED_FLAG
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
unlink_done:
brelse
(
bh
);
iput
(
inode
);
...
...
@@ -429,12 +429,12 @@ static int rename_same_dir(struct inode *old_dir,char *old_name,
MSDOS_I
(
new_inode
)
->
i_busy
=
1
;
new_inode
->
i_dirt
=
1
;
new_de
->
name
[
0
]
=
DELETED_FLAG
;
dirtify_buffer
(
new_bh
,
1
);
mark_buffer_dirty
(
new_bh
,
1
);
iput
(
new_inode
);
brelse
(
new_bh
);
}
memcpy
(
old_de
->
name
,
new_name
,
MSDOS_NAME
);
dirtify_buffer
(
old_bh
,
1
);
mark_buffer_dirty
(
old_bh
,
1
);
if
(
MSDOS_SB
(
old_dir
->
i_sb
)
->
conversion
==
'a'
)
/* update binary info */
if
((
old_inode
=
iget
(
old_dir
->
i_sb
,
old_ino
))
!=
NULL
)
{
msdos_read_inode
(
old_inode
);
...
...
@@ -503,7 +503,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
MSDOS_I
(
new_inode
)
->
i_busy
=
1
;
new_inode
->
i_dirt
=
1
;
new_de
->
name
[
0
]
=
DELETED_FLAG
;
dirtify_buffer
(
new_bh
,
1
);
mark_buffer_dirty
(
new_bh
,
1
);
}
memcpy
(
free_de
,
old_de
,
sizeof
(
struct
msdos_dir_entry
));
memcpy
(
free_de
->
name
,
new_name
,
MSDOS_NAME
);
...
...
@@ -526,8 +526,8 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
cache_inval_inode
(
old_inode
);
old_inode
->
i_dirt
=
1
;
old_de
->
name
[
0
]
=
DELETED_FLAG
;
dirtify_buffer
(
old_bh
,
1
);
dirtify_buffer
(
free_bh
,
1
);
mark_buffer_dirty
(
old_bh
,
1
);
mark_buffer_dirty
(
free_bh
,
1
);
if
(
!
exists
)
iput
(
free_inode
);
else
{
MSDOS_I
(
new_inode
)
->
i_depend
=
free_inode
;
...
...
@@ -547,7 +547,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
dotdot_de
->
start
=
MSDOS_I
(
dotdot_inode
)
->
i_start
=
MSDOS_I
(
new_dir
)
->
i_start
;
dotdot_inode
->
i_dirt
=
1
;
dirtify_buffer
(
dotdot_bh
,
1
);
mark_buffer_dirty
(
dotdot_bh
,
1
);
old_dir
->
i_nlink
--
;
new_dir
->
i_nlink
++
;
/* no need to mark them dirty */
...
...
fs/proc/array.c
View file @
7450aa7e
...
...
@@ -465,6 +465,7 @@ static int get_maps(int pid, char *buf)
}
extern
int
get_module_list
(
char
*
);
extern
int
get_device_list
(
char
*
);
static
int
array_read
(
struct
inode
*
inode
,
struct
file
*
file
,
char
*
buf
,
int
count
)
{
...
...
@@ -522,6 +523,9 @@ static int array_read(struct inode * inode, struct file * file,char * buf, int c
case
17
:
length
=
get_kstat
(
page
);
break
;
case
18
:
length
=
get_device_list
(
page
);
break
;
default:
free_page
((
unsigned
long
)
page
);
return
-
EBADF
;
...
...
fs/proc/root.c
View file @
7450aa7e
...
...
@@ -67,6 +67,7 @@ static struct proc_dir_entry root_dir[] = {
{
14
,
5
,
"kcore"
},
{
16
,
7
,
"modules"
},
{
17
,
4
,
"stat"
},
{
18
,
7
,
"devices"
},
};
#define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
...
...
fs/sysv/balloc.c
View file @
7450aa7e
...
...
@@ -96,7 +96,7 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
}
*
flc_count
=
*
sb
->
sv_sb_flc_count
;
/* = sb->sv_flc_size */
memcpy
(
flc_blocks
,
sb
->
sv_sb_flc_blocks
,
*
flc_count
*
sizeof
(
sysv_zone_t
));
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
bh
->
b_uptodate
=
1
;
brelse
(
bh
);
*
sb
->
sv_sb_flc_count
=
0
;
...
...
@@ -117,7 +117,7 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
bh_data
=
bh
->
b_data
+
((
block
&
sb
->
sv_block_size_ratio_1
)
<<
sb
->
sv_block_size_bits
);
memzero
(
bh_data
,
sb
->
sv_block_size
);
/* this implies ((struct ..._freelist_chunk *) bh_data)->flc_count = 0; */
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
bh
->
b_uptodate
=
1
;
brelse
(
bh
);
/* still *sb->sv_sb_flc_count = 0 */
...
...
@@ -138,7 +138,7 @@ 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
;
dirtify_buffer
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
sb
->
s_dirt
=
1
;
/* and needs time stamp */
unlock_super
(
sb
);
}
...
...
@@ -229,7 +229,7 @@ int sysv_new_block(struct super_block * sb)
return
0
;
}
memzero
(
bh_data
,
sb
->
sv_block_size
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
bh
->
b_uptodate
=
1
;
brelse
(
bh
);
if
(
sb
->
sv_convert
)
...
...
@@ -237,7 +237,7 @@ 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
;
dirtify_buffer
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
sb
->
s_dirt
=
1
;
/* and needs time stamp */
unlock_super
(
sb
);
return
block
;
...
...
@@ -331,7 +331,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
);
dirtify_buffer
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
sb
->
s_dirt
=
1
;
/* and needs time stamp */
}
}
...
...
fs/sysv/file.c
View file @
7450aa7e
...
...
@@ -301,7 +301,7 @@ static int sysv_file_write(struct inode * inode, struct file * filp, char * buf,
memcpy_fromfs
(
p
,
buf
,
c
);
buf
+=
c
;
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
0
);
mark_buffer_dirty
(
bh
,
0
);
brelse
(
bh
);
}
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
...
...
fs/sysv/ialloc.c
View file @
7450aa7e
...
...
@@ -74,10 +74,10 @@ void sysv_free_inode(struct inode * inode)
if
(
*
sb
->
sv_sb_fic_count
<
sb
->
sv_fic_size
)
sb
->
sv_sb_fic_inodes
[(
*
sb
->
sv_sb_fic_count
)
++
]
=
ino
;
(
*
sb
->
sv_sb_total_free_inodes
)
++
;
dirtify_buffer
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
sb
->
s_dirt
=
1
;
/* and needs time stamp */
memset
(
raw_inode
,
0
,
sizeof
(
struct
sysv_inode
));
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
unlock_super
(
sb
);
brelse
(
bh
);
clear_inode
(
inode
);
...
...
@@ -130,7 +130,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
}
/* Now *sb->sv_sb_fic_count > 0. */
ino
=
sb
->
sv_sb_fic_inodes
[
--
(
*
sb
->
sv_sb_fic_count
)];
dirtify_buffer
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
sb
->
s_dirt
=
1
;
/* and needs time stamp */
inode
->
i_count
=
1
;
inode
->
i_nlink
=
1
;
...
...
@@ -152,7 +152,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
)
--
;
dirtify_buffer
(
sb
->
sv_bh
,
1
);
/* super-block has been modified again */
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified again */
sb
->
s_dirt
=
1
;
/* and needs time stamp again */
unlock_super
(
sb
);
return
inode
;
...
...
@@ -191,7 +191,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
;
dirtify_buffer
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
mark_buffer_dirty
(
sb
->
sv_bh
,
1
);
/* super-block has been modified */
sb
->
s_dirt
=
1
;
/* and needs time stamp */
}
}
...
...
fs/sysv/inode.c
View file @
7450aa7e
...
...
@@ -557,7 +557,7 @@ static struct buffer_head * block_getblk(struct inode * inode,
goto
repeat
;
}
*
p
=
(
sb
->
sv_convert
?
to_coh_ulong
(
block
)
:
block
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
*
start
=
result
->
b_data
+
((
block
&
sb
->
sv_block_size_ratio_1
)
<<
sb
->
sv_block_size_bits
);
return
result
;
...
...
@@ -773,7 +773,7 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
for
(
block
=
0
;
block
<
10
+
1
+
1
+
1
;
block
++
)
write3byte
(
&
raw_inode
->
i_a
.
i_addb
[
3
*
block
],
inode
->
u
.
sysv_i
.
i_data
[
block
]);
inode
->
i_dirt
=
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
return
bh
;
}
...
...
fs/sysv/namei.c
View file @
7450aa7e
...
...
@@ -193,7 +193,7 @@ static int sysv_add_entry(struct inode * dir,
dir
->
i_mtime
=
dir
->
i_ctime
=
CURRENT_TIME
;
for
(
i
=
0
;
i
<
SYSV_NAMELEN
;
i
++
)
de
->
name
[
i
]
=
(
i
<
namelen
)
?
name
[
i
]
:
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
*
res_dir
=
de
;
break
;
}
...
...
@@ -238,7 +238,7 @@ int sysv_create(struct inode * dir,const char * name, int len, int mode,
return
error
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
*
result
=
inode
;
...
...
@@ -298,7 +298,7 @@ int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rde
return
error
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
iput
(
inode
);
...
...
@@ -349,7 +349,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
de
->
inode
=
dir
->
i_ino
;
strcpy
(
de
->
name
,
".."
);
/* rest of de->name is zero, see sysv_new_block */
inode
->
i_nlink
=
2
;
dirtify_buffer
(
dir_block
,
1
);
mark_buffer_dirty
(
dir_block
,
1
);
brelse
(
dir_block
);
inode
->
i_mode
=
S_IFDIR
|
(
mode
&
0777
&
~
current
->
umask
);
if
(
dir
->
i_mode
&
S_ISGID
)
...
...
@@ -363,7 +363,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
return
error
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_nlink
++
;
dir
->
i_dirt
=
1
;
iput
(
dir
);
...
...
@@ -473,7 +473,7 @@ int sysv_rmdir(struct inode * dir, const char * name, int len)
if
(
inode
->
i_nlink
!=
2
)
printk
(
"empty directory has nlink!=2 (%d)
\n
"
,
inode
->
i_nlink
);
de
->
inode
=
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_nlink
=
0
;
inode
->
i_dirt
=
1
;
dir
->
i_nlink
--
;
...
...
@@ -526,7 +526,7 @@ int sysv_unlink(struct inode * dir, const char * name, int len)
inode
->
i_nlink
=
1
;
}
de
->
inode
=
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
inode
->
i_nlink
--
;
...
...
@@ -570,7 +570,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
while
(
i
<
sb
->
sv_block_size_1
&&
(
c
=
*
(
symname
++
)))
name_block_data
[
i
++
]
=
c
;
name_block_data
[
i
]
=
0
;
dirtify_buffer
(
name_block
,
1
);
mark_buffer_dirty
(
name_block
,
1
);
brelse
(
name_block
);
inode
->
i_size
=
i
;
inode
->
i_dirt
=
1
;
...
...
@@ -592,7 +592,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
return
i
;
}
de
->
inode
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
iput
(
inode
);
...
...
@@ -629,7 +629,7 @@ int sysv_link(struct inode * oldinode, struct inode * dir, const char * name, in
return
error
;
}
de
->
inode
=
oldinode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
oldinode
->
i_nlink
++
;
...
...
@@ -782,11 +782,11 @@ static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old
new_inode
->
i_ctime
=
CURRENT_TIME
;
new_inode
->
i_dirt
=
1
;
}
dirtify_buffer
(
old_bh
,
1
);
dirtify_buffer
(
new_bh
,
1
);
mark_buffer_dirty
(
old_bh
,
1
);
mark_buffer_dirty
(
new_bh
,
1
);
if
(
dir_bh
)
{
PARENT_INO
(
dir_bh_data
)
=
new_dir
->
i_ino
;
dirtify_buffer
(
dir_bh
,
1
);
mark_buffer_dirty
(
dir_bh
,
1
);
old_dir
->
i_nlink
--
;
old_dir
->
i_dirt
=
1
;
if
(
new_inode
)
{
...
...
fs/sysv/truncate.c
View file @
7450aa7e
...
...
@@ -84,7 +84,7 @@ static int coh_trunc_indirect (struct inode * inode, unsigned long blocks, unsig
if
(
!
indblock
)
continue
;
*
ind
=
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
sysv_free_block
(
sb
,
indblock
);
}
for
(
i
=
0
;
i
<
sb
->
sv_ind_per_block
;
i
++
)
...
...
@@ -338,7 +338,7 @@ static int trunc_indirect(struct inode * inode, unsigned long offset, unsigned l
continue
;
}
*
ind
=
0
;
dirtify_buffer
(
indbh
,
1
);
mark_buffer_dirty
(
indbh
,
1
);
brelse
(
bh
);
sysv_free_block
(
sb
,
block
);
}
...
...
fs/xiafs/bitmap.c
View file @
7450aa7e
...
...
@@ -65,7 +65,7 @@ static int find_first_zero(struct buffer_head *bh, int start_bit, int end_bit)
start_bit
=
j
+
(
i
<<
5
)
+
1
;
goto
repeat
;
}
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
return
j
+
(
i
<<
5
);
}
...
...
@@ -245,7 +245,7 @@ void xiafs_free_zone(struct super_block * sb, int d_addr)
printk
(
"XIA-FS: dev %04x"
" block bit %u (0x%x) already cleared (%s %d)
\n
"
,
sb
->
s_dev
,
bit
,
bit
,
WHERE_ERR
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
xiafs_unlock_super
(
sb
,
sb
->
u
.
xiafs_sb
.
s_zmap_cached
);
}
...
...
@@ -277,7 +277,7 @@ int xiafs_new_zone(struct super_block * sb, u_long prev_addr)
}
clear_buf
(
bh
);
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
return
tmp
;
}
...
...
@@ -305,7 +305,7 @@ void xiafs_free_inode(struct inode * inode)
printk
(
"XIA-FS: dev %04x"
"inode bit %ld (0x%lx) already cleared (%s %d)
\n
"
,
inode
->
i_dev
,
ino
,
ino
,
WHERE_ERR
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
xiafs_unlock_super
(
sb
,
sb
->
u
.
xiafs_sb
.
s_imap_cached
);
}
...
...
fs/xiafs/file.c
View file @
7450aa7e
...
...
@@ -241,7 +241,7 @@ xiafs_file_write(struct inode * inode, struct file * filp, char * buf, int count
memcpy_fromfs
(
cp
,
buf
,
c
);
buf
+=
c
;
bh
->
b_uptodate
=
1
;
dirtify_buffer
(
bh
,
0
);
mark_buffer_dirty
(
bh
,
0
);
brelse
(
bh
);
}
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
...
...
fs/xiafs/inode.c
View file @
7450aa7e
...
...
@@ -306,7 +306,7 @@ indt_getblk(struct inode * inode, struct buffer_head * bh,
}
*
lp
=
tmp
;
inode
->
i_blocks
+=
2
<<
XIAFS_ZSHIFT
(
inode
->
i_sb
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
return
result
;
}
...
...
@@ -466,7 +466,7 @@ static struct buffer_head * xiafs_update_inode(struct inode * inode)
|
(
inode
->
u
.
xiafs_i
.
i_dind_zone
&
0xffffff
);
}
inode
->
i_dirt
=
0
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
return
bh
;
}
...
...
fs/xiafs/namei.c
View file @
7450aa7e
...
...
@@ -221,7 +221,7 @@ static struct buffer_head * xiafs_add_entry(struct inode * dir,
memcpy
(
de
->
d_name
,
name
,
namelen
);
de
->
d_name
[
namelen
]
=
0
;
de
->
d_name_len
=
namelen
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
*
res_dir
=
de
;
if
(
res_pre
)
*
res_pre
=
de_pre
;
...
...
@@ -268,7 +268,7 @@ int xiafs_create(struct inode * dir, const char * name, int len, int mode,
return
-
ENOSPC
;
}
de
->
d_ino
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
*
result
=
inode
;
...
...
@@ -325,7 +325,7 @@ int xiafs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev
return
-
ENOSPC
;
}
de
->
d_ino
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
iput
(
inode
);
...
...
@@ -375,7 +375,7 @@ int xiafs_mkdir(struct inode * dir, const char * name, int len, int mode)
de
->
d_name_len
=
2
;
de
->
d_rec_len
=
XIAFS_ZSIZE
(
dir
->
i_sb
)
-
12
;
inode
->
i_nlink
=
2
;
dirtify_buffer
(
dir_block
,
1
);
mark_buffer_dirty
(
dir_block
,
1
);
brelse
(
dir_block
);
inode
->
i_mode
=
S_IFDIR
|
(
mode
&
S_IRWXUGO
&
~
current
->
umask
);
if
(
dir
->
i_mode
&
S_ISGID
)
...
...
@@ -389,7 +389,7 @@ int xiafs_mkdir(struct inode * dir, const char * name, int len, int mode)
return
-
ENOSPC
;
}
de
->
d_ino
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_nlink
++
;
dir
->
i_dirt
=
1
;
iput
(
dir
);
...
...
@@ -518,7 +518,7 @@ int xiafs_rmdir(struct inode * dir, const char * name, int len)
if
(
inode
->
i_nlink
!=
2
)
printk
(
"XIA-FS: empty directory has nlink!=2 (%s %d)
\n
"
,
WHERE_ERR
);
xiafs_rm_entry
(
de
,
de_pre
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_nlink
=
0
;
inode
->
i_dirt
=
1
;
dir
->
i_nlink
--
;
...
...
@@ -566,7 +566,7 @@ int xiafs_unlink(struct inode * dir, const char * name, int len)
inode
->
i_nlink
=
1
;
}
xiafs_rm_entry
(
de
,
de_pre
);
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_ctime
=
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
inode
->
i_nlink
--
;
...
...
@@ -611,7 +611,7 @@ int xiafs_symlink(struct inode * dir, const char * name,
for
(
i
=
0
;
i
<
BLOCK_SIZE
-
1
&&
(
c
=*
symname
++
);
i
++
)
name_block
->
b_data
[
i
]
=
c
;
name_block
->
b_data
[
i
]
=
0
;
dirtify_buffer
(
name_block
,
1
);
mark_buffer_dirty
(
name_block
,
1
);
brelse
(
name_block
);
inode
->
i_size
=
i
;
inode
->
i_dirt
=
1
;
...
...
@@ -624,7 +624,7 @@ int xiafs_symlink(struct inode * dir, const char * name,
return
-
ENOSPC
;
}
de
->
d_ino
=
inode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
iput
(
inode
);
...
...
@@ -661,7 +661,7 @@ int xiafs_link(struct inode * oldinode, struct inode * dir,
return
-
ENOSPC
;
}
de
->
d_ino
=
oldinode
->
i_ino
;
dirtify_buffer
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
brelse
(
bh
);
iput
(
dir
);
oldinode
->
i_nlink
++
;
...
...
@@ -798,11 +798,11 @@ static int do_xiafs_rename(struct inode * old_dir, const char * old_name,
new_inode
->
i_nlink
--
;
new_inode
->
i_dirt
=
1
;
}
dirtify_buffer
(
old_bh
,
1
);
dirtify_buffer
(
new_bh
,
1
);
mark_buffer_dirty
(
old_bh
,
1
);
mark_buffer_dirty
(
new_bh
,
1
);
if
(
dir_bh
)
{
PARENT_INO
(
dir_bh
->
b_data
)
=
new_dir
->
i_ino
;
dirtify_buffer
(
dir_bh
,
1
);
mark_buffer_dirty
(
dir_bh
,
1
);
old_dir
->
i_nlink
--
;
new_dir
->
i_nlink
++
;
old_dir
->
i_dirt
=
1
;
...
...
fs/xiafs/truncate.c
View file @
7450aa7e
...
...
@@ -104,7 +104,7 @@ static int trunc_indirect(struct inode * inode, int addr_off, u_long * lp)
retry
=
1
;
else
{
*
indp
=
0
;
dirtify_buffer
(
ind_bh
,
1
);
mark_buffer_dirty
(
ind_bh
,
1
);
inode
->
i_blocks
-=
2
<<
XIAFS_ZSHIFT
(
inode
->
i_sb
);
xiafs_free_zone
(
inode
->
i_sb
,
tmp
);
}
...
...
@@ -157,7 +157,7 @@ static int trunc_dindirect(struct inode * inode)
retry
|=
trunc_indirect
(
inode
,
8
+
((
1
+
i
)
<<
XIAFS_ADDRS_PER_Z_BITS
(
inode
->
i_sb
)),
dindp
);
dirtify_buffer
(
dind_bh
,
1
);
mark_buffer_dirty
(
dind_bh
,
1
);
}
dindp
=
(
u_long
*
)
dind_bh
->
b_data
;
for
(
i
=
0
;
i
<
XIAFS_ADDRS_PER_Z
(
inode
->
i_sb
)
&&
!
(
*
dindp
++
);
i
++
);
...
...
include/linux/ext2_fs.h
View file @
7450aa7e
...
...
@@ -390,6 +390,7 @@ extern int ext2_bmap (struct inode *, int);
extern
struct
buffer_head
*
ext2_getblk
(
struct
inode
*
,
long
,
int
,
int
*
);
extern
struct
buffer_head
*
ext2_bread
(
struct
inode
*
,
int
,
int
,
int
*
);
extern
int
ext2_getcluster
(
struct
inode
*
inode
,
long
block
);
extern
void
ext2_read_inode
(
struct
inode
*
);
extern
void
ext2_write_inode
(
struct
inode
*
);
extern
void
ext2_put_inode
(
struct
inode
*
);
...
...
include/linux/fs.h
View file @
7450aa7e
...
...
@@ -28,7 +28,6 @@
#define NR_INODE 2048
/* this should be bigger than NR_FILE */
#define NR_FILE 1024
/* this can well be larger on a larger system */
#define NR_SUPER 32
#define NR_HASH 997
#define NR_IHASH 131
#define NR_FILE_LOCKS 64
#define BLOCK_SIZE 1024
...
...
@@ -138,6 +137,11 @@ struct buffer_head {
unsigned
char
b_dirt
;
/* 0-clean,1-dirty */
unsigned
char
b_lock
;
/* 0 - ok, 1 -locked */
unsigned
char
b_req
;
/* 0 if the buffer has been invalidated */
unsigned
char
b_list
;
/* List that this buffer appears */
unsigned
char
b_retain
;
/* Expected number of times this will
be used. Put on freelist when 0 */
unsigned
long
b_flushtime
;
/* Time when this (dirty) buffer should be written */
unsigned
long
b_lru_time
;
/* Time when this buffer was last used. */
struct
wait_queue
*
b_wait
;
struct
buffer_head
*
b_prev
;
/* doubly linked list of hash-queue */
struct
buffer_head
*
b_next
;
...
...
@@ -356,16 +360,41 @@ extern struct super_block super_blocks[NR_SUPER];
extern
int
shrink_buffers
(
unsigned
int
priority
);
extern
void
refile_buffer
(
struct
buffer_head
*
buf
);
void
set_writetime
(
struct
buffer_head
*
buf
,
int
flag
);
struct
buffer_head
**
buffer_pages
;
extern
int
nr_buffers
;
extern
int
buffermem
;
extern
int
nr_buffer_heads
;
/* Once the full cluster diffs are in place, this will be filled out a bit. */
extern
inline
void
dirtify_buffer
(
struct
buffer_head
*
bh
,
int
flag
)
#define BUF_CLEAN 0
#define BUF_UNSHARED 1
/* Buffers that were shared but are not any more */
#define BUF_LOCKED 2
/* Buffers scheduled for write */
#define BUF_LOCKED1 3
/* Supers, inodes */
#define BUF_DIRTY 4
/* Dirty buffers, not yet scheduled for write */
#define BUF_SHARED 5
/* Buffers shared */
#define NR_LIST 6
extern
inline
void
mark_buffer_clean
(
struct
buffer_head
*
bh
)
{
if
(
bh
->
b_dirt
)
{
bh
->
b_dirt
=
0
;
if
(
bh
->
b_list
==
BUF_DIRTY
)
refile_buffer
(
bh
);
}
}
extern
inline
void
mark_buffer_dirty
(
struct
buffer_head
*
bh
,
int
flag
)
{
if
(
!
bh
->
b_dirt
)
{
bh
->
b_dirt
=
1
;
set_writetime
(
bh
,
flag
);
if
(
bh
->
b_list
!=
BUF_DIRTY
)
refile_buffer
(
bh
);
}
}
extern
void
check_disk_change
(
dev_t
dev
);
extern
void
invalidate_inodes
(
dev_t
dev
);
extern
void
invalidate_buffers
(
dev_t
dev
);
...
...
@@ -402,6 +431,7 @@ extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,in
extern
struct
buffer_head
*
breada
(
dev_t
dev
,
int
block
,
int
size
,
unsigned
int
pos
,
unsigned
int
filesize
);
extern
void
put_super
(
dev_t
dev
);
unsigned
long
generate_cluster
(
dev_t
dev
,
int
b
[],
int
size
);
extern
dev_t
ROOT_DEV
;
extern
void
show_buffers
(
void
);
...
...
include/linux/mm.h
View file @
7450aa7e
...
...
@@ -217,6 +217,7 @@ extern unsigned short * mem_map;
#define GFP_ATOMIC 0x01
#define GFP_USER 0x02
#define GFP_KERNEL 0x03
#define GFP_NOBUFFER 0x04
/* vm_ops not present page codes */
...
...
include/linux/sys.h
View file @
7450aa7e
...
...
@@ -14,6 +14,7 @@
/*
* These are system calls that will be removed at some time
* due to newer versions existing..
* (please be careful - ibcs2 may need some of these).
*/
#ifdef notdef
#define _sys_waitpid _sys_old_syscall
/* _sys_wait4 */
...
...
@@ -32,6 +33,5 @@
* but have an entry in the table for future expansion..
*/
#define _sys_quotactl _sys_ni_syscall
#define _sys_bdflush _sys_ni_syscall
#endif
mm/swap.c
View file @
7450aa7e
...
...
@@ -470,12 +470,12 @@ static int swap_out(unsigned int priority)
#endif
static
int
try_to_free_page
(
void
)
static
int
try_to_free_page
(
int
priority
)
{
int
i
=
6
;
while
(
i
--
)
{
if
(
shrink_buffers
(
i
))
if
(
priority
!=
GFP_NOBUFFER
&&
shrink_buffers
(
i
))
return
1
;
if
(
shm_swap
(
i
))
return
1
;
...
...
@@ -545,6 +545,17 @@ void free_pages(unsigned long addr, unsigned long order)
if
(
!--*
map
)
free_pages_ok
(
addr
,
order
);
restore_flags
(
flag
);
if
(
*
map
==
1
)
{
int
j
;
struct
buffer_head
*
bh
,
*
tmp
;
bh
=
buffer_pages
[
MAP_NR
(
addr
)];
if
(
bh
)
for
(
j
=
0
,
tmp
=
bh
;
tmp
&&
(
!
j
||
tmp
!=
bh
);
tmp
=
tmp
->
b_this_page
,
j
++
)
if
(
tmp
->
b_list
==
BUF_SHARED
&&
tmp
->
b_dev
!=
0xffff
)
refile_buffer
(
tmp
);
}
}
return
;
}
...
...
@@ -610,7 +621,7 @@ unsigned long __get_free_pages(int priority, unsigned long order)
return
0
;
}
restore_flags
(
flags
);
if
(
priority
!=
GFP_BUFFER
&&
try_to_free_page
())
if
(
priority
!=
GFP_BUFFER
&&
try_to_free_page
(
priority
))
goto
repeat
;
return
0
;
}
...
...
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