Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
13a96bae
提交
13a96bae
7月 27, 2011
创建
作者:
Frans Kaashoek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Dirt simple logging
Passes usertests and stressfs Seems to recover correctly in a number of simple cases
上级
97657d70
显示空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
242 行增加
和
45 行删除
+242
-45
Makefile
Makefile
+1
-0
defs.h
defs.h
+8
-0
fs.c
fs.c
+6
-6
fs.h
fs.h
+1
-0
initcode.S
initcode.S
+3
-0
log.c
log.c
+164
-0
main.c
main.c
+0
-0
mkfs.c
mkfs.c
+8
-5
param.h
param.h
+2
-0
syscall.c
syscall.c
+30
-17
syscall.h
syscall.h
+19
-17
没有找到文件。
Makefile
浏览文件 @
13a96bae
...
@@ -26,6 +26,7 @@ OBJS = \
...
@@ -26,6 +26,7 @@ OBJS = \
uart.o
\
uart.o
\
vectors.o
\
vectors.o
\
vm.o
\
vm.o
\
log.o
\
# Cross-compiling (e.g., on Mac OS X)
# Cross-compiling (e.g., on Mac OS X)
#TOOLPREFIX = i386-jos-elf-
#TOOLPREFIX = i386-jos-elf-
...
...
defs.h
浏览文件 @
13a96bae
...
@@ -6,6 +6,7 @@ struct pipe;
...
@@ -6,6 +6,7 @@ struct pipe;
struct
proc
;
struct
proc
;
struct
spinlock
;
struct
spinlock
;
struct
stat
;
struct
stat
;
struct
superblock
;
// bio.c
// bio.c
void
binit
(
void
);
void
binit
(
void
);
...
@@ -32,6 +33,7 @@ int filestat(struct file*, struct stat*);
...
@@ -32,6 +33,7 @@ int filestat(struct file*, struct stat*);
int
filewrite
(
struct
file
*
,
char
*
,
int
n
);
int
filewrite
(
struct
file
*
,
char
*
,
int
n
);
// fs.c
// fs.c
void
readsb
(
int
dev
,
struct
superblock
*
sb
);
int
dirlink
(
struct
inode
*
,
char
*
,
uint
);
int
dirlink
(
struct
inode
*
,
char
*
,
uint
);
struct
inode
*
dirlookup
(
struct
inode
*
,
char
*
,
uint
*
);
struct
inode
*
dirlookup
(
struct
inode
*
,
char
*
,
uint
*
);
struct
inode
*
ialloc
(
uint
,
short
);
struct
inode
*
ialloc
(
uint
,
short
);
...
@@ -75,6 +77,12 @@ void lapicinit(int);
...
@@ -75,6 +77,12 @@ void lapicinit(int);
void
lapicstartap
(
uchar
,
uint
);
void
lapicstartap
(
uchar
,
uint
);
void
microdelay
(
int
);
void
microdelay
(
int
);
// log.c
void
initlog
(
void
);
void
log_write
(
struct
buf
*
);
void
begin_trans
();
void
commit_trans
();
// mp.c
// mp.c
extern
int
ismp
;
extern
int
ismp
;
int
mpbcpu
(
void
);
int
mpbcpu
(
void
);
...
...
fs.c
浏览文件 @
13a96bae
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
static
void
itrunc
(
struct
inode
*
);
static
void
itrunc
(
struct
inode
*
);
// Read the super block.
// Read the super block.
static
void
void
readsb
(
int
dev
,
struct
superblock
*
sb
)
readsb
(
int
dev
,
struct
superblock
*
sb
)
{
{
struct
buf
*
bp
;
struct
buf
*
bp
;
...
@@ -65,7 +65,7 @@ balloc(uint dev)
...
@@ -65,7 +65,7 @@ balloc(uint dev)
m
=
1
<<
(
bi
%
8
);
m
=
1
<<
(
bi
%
8
);
if
((
bp
->
data
[
bi
/
8
]
&
m
)
==
0
){
// Is block free?
if
((
bp
->
data
[
bi
/
8
]
&
m
)
==
0
){
// Is block free?
bp
->
data
[
bi
/
8
]
|=
m
;
// Mark block in use on disk.
bp
->
data
[
bi
/
8
]
|=
m
;
// Mark block in use on disk.
b
write
(
bp
);
log_
write
(
bp
);
brelse
(
bp
);
brelse
(
bp
);
return
b
+
bi
;
return
b
+
bi
;
}
}
...
@@ -92,7 +92,7 @@ bfree(int dev, uint b)
...
@@ -92,7 +92,7 @@ bfree(int dev, uint b)
if
((
bp
->
data
[
bi
/
8
]
&
m
)
==
0
)
if
((
bp
->
data
[
bi
/
8
]
&
m
)
==
0
)
panic
(
"freeing free block"
);
panic
(
"freeing free block"
);
bp
->
data
[
bi
/
8
]
&=
~
m
;
// Mark block free on disk.
bp
->
data
[
bi
/
8
]
&=
~
m
;
// Mark block free on disk.
b
write
(
bp
);
log_
write
(
bp
);
brelse
(
bp
);
brelse
(
bp
);
}
}
...
@@ -159,7 +159,7 @@ ialloc(uint dev, short type)
...
@@ -159,7 +159,7 @@ ialloc(uint dev, short type)
if
(
dip
->
type
==
0
){
// a free inode
if
(
dip
->
type
==
0
){
// a free inode
memset
(
dip
,
0
,
sizeof
(
*
dip
));
memset
(
dip
,
0
,
sizeof
(
*
dip
));
dip
->
type
=
type
;
dip
->
type
=
type
;
b
write
(
bp
);
// mark it allocated on the disk
log_
write
(
bp
);
// mark it allocated on the disk
brelse
(
bp
);
brelse
(
bp
);
return
iget
(
dev
,
inum
);
return
iget
(
dev
,
inum
);
}
}
...
@@ -183,7 +183,7 @@ iupdate(struct inode *ip)
...
@@ -183,7 +183,7 @@ iupdate(struct inode *ip)
dip
->
nlink
=
ip
->
nlink
;
dip
->
nlink
=
ip
->
nlink
;
dip
->
size
=
ip
->
size
;
dip
->
size
=
ip
->
size
;
memmove
(
dip
->
addrs
,
ip
->
addrs
,
sizeof
(
ip
->
addrs
));
memmove
(
dip
->
addrs
,
ip
->
addrs
,
sizeof
(
ip
->
addrs
));
b
write
(
bp
);
log_
write
(
bp
);
brelse
(
bp
);
brelse
(
bp
);
}
}
...
@@ -339,7 +339,7 @@ bmap(struct inode *ip, uint bn)
...
@@ -339,7 +339,7 @@ bmap(struct inode *ip, uint bn)
a
=
(
uint
*
)
bp
->
data
;
a
=
(
uint
*
)
bp
->
data
;
if
((
addr
=
a
[
bn
])
==
0
){
if
((
addr
=
a
[
bn
])
==
0
){
a
[
bn
]
=
addr
=
balloc
(
ip
->
dev
);
a
[
bn
]
=
addr
=
balloc
(
ip
->
dev
);
b
write
(
bp
);
log_
write
(
bp
);
}
}
brelse
(
bp
);
brelse
(
bp
);
return
addr
;
return
addr
;
...
...
fs.h
浏览文件 @
13a96bae
...
@@ -13,6 +13,7 @@ struct superblock {
...
@@ -13,6 +13,7 @@ struct superblock {
uint
size
;
// Size of file system image (blocks)
uint
size
;
// Size of file system image (blocks)
uint
nblocks
;
// Number of data blocks
uint
nblocks
;
// Number of data blocks
uint
ninodes
;
// Number of inodes.
uint
ninodes
;
// Number of inodes.
uint
nlog
;
// Number of log blocks
};
};
#define NDIRECT 12
#define NDIRECT 12
...
...
initcode.S
浏览文件 @
13a96bae
...
@@ -3,9 +3,12 @@
...
@@ -3,9 +3,12 @@
#include "syscall.h"
#include "syscall.h"
#include "traps.h"
#include "traps.h"
# exec(init, argv)
# exec(init, argv)
.globl start
.globl start
start:
start:
movl $SYS_init, %eax
int $T_SYSCALL
pushl $argv
pushl $argv
pushl $init
pushl $init
pushl $0 // where caller pc would be
pushl $0 // where caller pc would be
...
...
log.c
0 → 100644
浏览文件 @
13a96bae
#include "types.h"
#include "defs.h"
#include "param.h"
#include "mmu.h"
#include "proc.h"
#include "x86.h"
#include "spinlock.h"
#include "fs.h"
#include "buf.h"
// Dirt simple "logging" supporting only one transaction. All file system calls
// that potentially write a block should be wrapped in begin_trans and commit_trans,
// so that there is never more than one transaction. This serializes all file system
// operations that potentially write, but simplifies recovery (only the last
// one transaction to recover) and concurrency (don't have to worry about reading a modified
// block from a transaction that hasn't committed yet).
// The header of the log. If head == 0, there are no log entries. All entries till head
// are committed. sector[] records the home sector for each block in the log
// (i.e., physical logging).
struct
logheader
{
int
head
;
int
sector
[
LOGSIZE
];
};
struct
{
struct
spinlock
lock
;
int
start
;
int
size
;
int
intrans
;
int
dev
;
struct
logheader
lh
;
}
log
;
static
void
recover_from_log
(
void
);
void
initlog
(
void
)
{
if
(
sizeof
(
struct
logheader
)
>=
BSIZE
)
panic
(
"initlog: too big logheader"
);
struct
superblock
sb
;
initlock
(
&
log
.
lock
,
"log"
);
readsb
(
ROOTDEV
,
&
sb
);
log
.
start
=
sb
.
size
-
sb
.
nlog
;
log
.
size
=
sb
.
nlog
;
log
.
dev
=
ROOTDEV
;
recover_from_log
();
}
// Copy committed blocks from log to their home location
static
void
install_trans
(
void
)
{
int
tail
;
if
(
log
.
lh
.
head
>
0
)
cprintf
(
"install_trans %d
\n
"
,
log
.
lh
.
head
);
for
(
tail
=
0
;
tail
<
log
.
lh
.
head
;
tail
++
)
{
cprintf
(
"put entry %d to disk block %d
\n
"
,
tail
,
log
.
lh
.
sector
[
tail
]);
struct
buf
*
lbuf
=
bread
(
log
.
dev
,
log
.
start
+
tail
+
1
);
// read i'th block from log
struct
buf
*
dbuf
=
bread
(
log
.
dev
,
log
.
lh
.
sector
[
tail
]);
// read dst block
memmove
(
dbuf
->
data
,
lbuf
->
data
,
BSIZE
);
bwrite
(
dbuf
);
brelse
(
lbuf
);
brelse
(
dbuf
);
}
}
// Read the log header from disk into the in-memory log header
static
void
read_head
(
void
)
{
struct
buf
*
buf
=
bread
(
log
.
dev
,
log
.
start
);
struct
logheader
*
lh
=
(
struct
logheader
*
)
(
buf
->
data
);
int
i
;
log
.
lh
.
head
=
lh
->
head
;
for
(
i
=
0
;
i
<
log
.
lh
.
head
;
i
++
)
{
log
.
lh
.
sector
[
i
]
=
lh
->
sector
[
i
];
}
brelse
(
buf
);
if
(
log
.
lh
.
head
>
0
)
cprintf
(
"read_head: %d
\n
"
,
log
.
lh
.
head
);
}
// Write the in-memory log header to disk, committing log entries till head
static
void
write_head
(
void
)
{
if
(
log
.
lh
.
head
>
0
)
cprintf
(
"write_head: %d
\n
"
,
log
.
lh
.
head
);
struct
buf
*
buf
=
bread
(
log
.
dev
,
log
.
start
);
struct
logheader
*
hb
=
(
struct
logheader
*
)
(
buf
->
data
);
int
i
;
hb
->
head
=
log
.
lh
.
head
;
for
(
i
=
0
;
i
<
log
.
lh
.
head
;
i
++
)
{
hb
->
sector
[
i
]
=
log
.
lh
.
sector
[
i
];
}
bwrite
(
buf
);
brelse
(
buf
);
}
static
void
recover_from_log
(
void
)
{
read_head
();
install_trans
();
// Install all transactions till head
log
.
lh
.
head
=
0
;
write_head
();
// Reclaim log
}
void
begin_trans
(
void
)
{
acquire
(
&
log
.
lock
);
while
(
log
.
intrans
)
{
sleep
(
&
log
,
&
log
.
lock
);
}
log
.
intrans
=
1
;
release
(
&
log
.
lock
);
}
void
commit_trans
(
void
)
{
write_head
();
// This causes all blocks till log.head to be commited
install_trans
();
// Install all the transactions till head
log
.
lh
.
head
=
0
;
write_head
();
// Reclaim log
acquire
(
&
log
.
lock
);
log
.
intrans
=
0
;
wakeup
(
&
log
);
release
(
&
log
.
lock
);
}
// Write buffer into the log at log.head and record the block number log.lh.entry, but
// don't write the log header (which would commit the write).
void
log_write
(
struct
buf
*
b
)
{
int
i
;
if
(
log
.
lh
.
head
>=
LOGSIZE
)
panic
(
"too big a transaction"
);
if
(
!
log
.
intrans
)
panic
(
"write outside of trans"
);
cprintf
(
"log_write: %d %d
\n
"
,
b
->
sector
,
log
.
lh
.
head
);
for
(
i
=
0
;
i
<
log
.
lh
.
head
;
i
++
)
{
if
(
log
.
lh
.
sector
[
i
]
==
b
->
sector
)
// log absorbtion?
break
;
}
log
.
lh
.
sector
[
i
]
=
b
->
sector
;
struct
buf
*
lbuf
=
bread
(
b
->
dev
,
log
.
start
+
i
+
1
);
memmove
(
lbuf
->
data
,
b
->
data
,
BSIZE
);
bwrite
(
lbuf
);
brelse
(
lbuf
);
if
(
i
==
log
.
lh
.
head
)
log
.
lh
.
head
++
;
}
main.c
浏览文件 @
13a96bae
mkfs.c
浏览文件 @
13a96bae
...
@@ -9,8 +9,10 @@
...
@@ -9,8 +9,10 @@
#include "types.h"
#include "types.h"
#include "fs.h"
#include "fs.h"
#include "stat.h"
#include "stat.h"
#include "param.h"
int
nblocks
=
995
;
int
nblocks
=
985
;
int
nlog
=
LOGSIZE
;
int
ninodes
=
200
;
int
ninodes
=
200
;
int
size
=
1024
;
int
size
=
1024
;
...
@@ -79,17 +81,18 @@ main(int argc, char *argv[])
...
@@ -79,17 +81,18 @@ main(int argc, char *argv[])
sb
.
size
=
xint
(
size
);
sb
.
size
=
xint
(
size
);
sb
.
nblocks
=
xint
(
nblocks
);
// so whole disk is size sectors
sb
.
nblocks
=
xint
(
nblocks
);
// so whole disk is size sectors
sb
.
ninodes
=
xint
(
ninodes
);
sb
.
ninodes
=
xint
(
ninodes
);
sb
.
nlog
=
xint
(
nlog
);
bitblocks
=
size
/
(
512
*
8
)
+
1
;
bitblocks
=
size
/
(
512
*
8
)
+
1
;
usedblocks
=
ninodes
/
IPB
+
3
+
bitblocks
;
usedblocks
=
ninodes
/
IPB
+
3
+
bitblocks
;
freeblock
=
usedblocks
;
freeblock
=
usedblocks
;
printf
(
"used %d (bit %d ninode %zu) free %u total %d
\n
"
,
usedblocks
,
printf
(
"used %d (bit %d ninode %zu) free %u
log %u
total %d
\n
"
,
usedblocks
,
bitblocks
,
ninodes
/
IPB
+
1
,
freeblock
,
n
blocks
+
usedblocks
);
bitblocks
,
ninodes
/
IPB
+
1
,
freeblock
,
n
log
,
nblocks
+
usedblocks
+
nlog
);
assert
(
nblocks
+
usedblocks
==
size
);
assert
(
nblocks
+
usedblocks
+
nlog
==
size
);
for
(
i
=
0
;
i
<
nblocks
+
usedblocks
;
i
++
)
for
(
i
=
0
;
i
<
nblocks
+
usedblocks
+
nlog
;
i
++
)
wsect
(
i
,
zeroes
);
wsect
(
i
,
zeroes
);
memset
(
buf
,
0
,
sizeof
(
buf
));
memset
(
buf
,
0
,
sizeof
(
buf
));
...
...
param.h
浏览文件 @
13a96bae
...
@@ -10,3 +10,5 @@
...
@@ -10,3 +10,5 @@
#define USERTOP 0xA0000 // end of user address space
#define USERTOP 0xA0000 // end of user address space
#define PHYSTOP 0x1000000 // use phys mem up to here as free pool
#define PHYSTOP 0x1000000 // use phys mem up to here as free pool
#define MAXARG 32 // max exec arguments
#define MAXARG 32 // max exec arguments
#define LOGSIZE 10 // size of log
syscall.c
浏览文件 @
13a96bae
...
@@ -98,28 +98,37 @@ extern int sys_wait(void);
...
@@ -98,28 +98,37 @@ extern int sys_wait(void);
extern
int
sys_write
(
void
);
extern
int
sys_write
(
void
);
extern
int
sys_uptime
(
void
);
extern
int
sys_uptime
(
void
);
int
sys_init
(
void
)
{
initlog
();
return
0
;
}
static
int
(
*
syscalls
[])(
void
)
=
{
static
int
(
*
syscalls
[])(
void
)
=
{
[
SYS_chdir
]
sys_chdir
,
[
SYS_init
]
sys_init
,
[
SYS_close
]
sys_close
,
[
SYS_dup
]
sys_dup
,
[
SYS_exec
]
sys_exec
,
[
SYS_exit
]
sys_exit
,
[
SYS_fork
]
sys_fork
,
[
SYS_fork
]
sys_fork
,
[
SYS_fstat
]
sys_fstat
,
[
SYS_exit
]
sys_exit
,
[
SYS_getpid
]
sys_getpid
,
[
SYS_wait
]
sys_wait
,
[
SYS_kill
]
sys_kill
,
[
SYS_link
]
sys_link
,
[
SYS_mkdir
]
sys_mkdir
,
[
SYS_mknod
]
sys_mknod
,
[
SYS_open
]
sys_open
,
[
SYS_pipe
]
sys_pipe
,
[
SYS_pipe
]
sys_pipe
,
[
SYS_read
]
sys_read
,
[
SYS_read
]
sys_read
,
[
SYS_kill
]
sys_kill
,
[
SYS_exec
]
sys_exec
,
[
SYS_fstat
]
sys_fstat
,
[
SYS_chdir
]
sys_chdir
,
[
SYS_dup
]
sys_dup
,
[
SYS_getpid
]
sys_getpid
,
[
SYS_sbrk
]
sys_sbrk
,
[
SYS_sbrk
]
sys_sbrk
,
[
SYS_sleep
]
sys_sleep
,
[
SYS_sleep
]
sys_sleep
,
[
SYS_unlink
]
sys_unlink
,
[
SYS_wait
]
sys_wait
,
[
SYS_write
]
sys_write
,
[
SYS_uptime
]
sys_uptime
,
[
SYS_uptime
]
sys_uptime
,
// File system calls that are run in a transaction:
[
SYS_open
]
sys_open
,
[
SYS_write
]
sys_write
,
[
SYS_mknod
]
sys_mknod
,
[
SYS_unlink
]
sys_unlink
,
[
SYS_link
]
sys_link
,
[
SYS_mkdir
]
sys_mkdir
,
[
SYS_close
]
sys_close
,
};
};
void
void
...
@@ -128,9 +137,13 @@ syscall(void)
...
@@ -128,9 +137,13 @@ syscall(void)
int
num
;
int
num
;
num
=
proc
->
tf
->
eax
;
num
=
proc
->
tf
->
eax
;
if
(
num
>=
0
&&
num
<
NELEM
(
syscalls
)
&&
syscalls
[
num
])
if
(
num
>=
0
&&
num
<
SYS_open
&&
syscalls
[
num
])
{
proc
->
tf
->
eax
=
syscalls
[
num
]();
}
else
if
(
num
>=
SYS_open
&&
num
<
NELEM
(
syscalls
)
&&
syscalls
[
num
])
{
begin_trans
();
proc
->
tf
->
eax
=
syscalls
[
num
]();
proc
->
tf
->
eax
=
syscalls
[
num
]();
else
{
commit_trans
();
}
else
{
cprintf
(
"%d %s: unknown sys call %d
\n
"
,
cprintf
(
"%d %s: unknown sys call %d
\n
"
,
proc
->
pid
,
proc
->
name
,
num
);
proc
->
pid
,
proc
->
name
,
num
);
proc
->
tf
->
eax
=
-
1
;
proc
->
tf
->
eax
=
-
1
;
...
...
syscall.h
浏览文件 @
13a96bae
// System call numbers
// System call numbers
#define SYS_init 0
#define SYS_fork 1
#define SYS_fork 1
#define SYS_exit 2
#define SYS_exit 2
#define SYS_wait 3
#define SYS_wait 3
#define SYS_pipe 4
#define SYS_pipe 4
#define SYS_write 5
#define SYS_read 5
#define SYS_read 6
#define SYS_kill 6
#define SYS_close 7
#define SYS_exec 7
#define SYS_kill 8
#define SYS_fstat 8
#define SYS_exec 9
#define SYS_chdir 9
#define SYS_open 10
#define SYS_dup 10
#define SYS_mknod 11
#define SYS_getpid 11
#define SYS_unlink 12
#define SYS_sbrk 12
#define SYS_fstat 13
#define SYS_sleep 13
#define SYS_link 14
#define SYS_uptime 14
#define SYS_mkdir 15
#define SYS_chdir 16
#define SYS_open 15
#define SYS_dup 17
#define SYS_write 16
#define SYS_getpid 18
#define SYS_mknod 17
#define SYS_sbrk 19
#define SYS_unlink 18
#define SYS_sleep 20
#define SYS_link 19
#define SYS_uptime 21
#define SYS_mkdir 20
#define SYS_close 21
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论