Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
3029f0e8
提交
3029f0e8
5月 25, 2011
创建
作者:
Robert Morris
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
inode generation #s to avoid race in namecache lookup
fix some races by having ialloc go thru inode cache
上级
cd61c6de
隐藏空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
85 行增加
和
22 行删除
+85
-22
Makefile
Makefile
+1
-1
exec.c
exec.c
+5
-0
file.c
file.c
+4
-0
file.h
file.h
+1
-0
fs.c
fs.c
+28
-9
fs.h
fs.h
+3
-1
mkfs.c
mkfs.c
+1
-0
namecache.c
namecache.c
+34
-9
sysfile.c
sysfile.c
+7
-1
usertests.c
usertests.c
+1
-1
没有找到文件。
Makefile
浏览文件 @
3029f0e8
...
...
@@ -222,7 +222,7 @@ ifndef CPUS
CPUS
:=
2
endif
QEMUOPTS
=
-hdb
fs.img xv6.img
-smp
$(CPUS)
MTRACEOPTS
=
-mtrace-enable
-mtrace-file
mtrace.out
-mtrace-quantum
1000
0
MTRACEOPTS
=
-mtrace-enable
-mtrace-file
mtrace.out
-mtrace-quantum
1000
qemu
:
fs.img xv6.img
$(QEMU)
-serial
mon:stdio
$(QEMUOPTS)
...
...
exec.c
浏览文件 @
3029f0e8
...
...
@@ -8,6 +8,9 @@
#include "defs.h"
#include "x86.h"
#include "elf.h"
#include "stat.h"
#include "fs.h"
#include "file.h"
int
exec
(
char
*
path
,
char
**
argv
)
...
...
@@ -27,6 +30,8 @@ exec(char *path, char **argv)
ilock
(
ip
);
// Check ELF header
if
(
ip
->
type
!=
T_FILE
)
goto
bad
;
if
(
readi
(
ip
,
(
char
*
)
&
elf
,
0
,
sizeof
(
elf
))
<
sizeof
(
elf
))
goto
bad
;
if
(
elf
.
magic
!=
ELF_MAGIC
)
...
...
file.c
浏览文件 @
3029f0e8
...
...
@@ -79,6 +79,8 @@ filestat(struct file *f, struct stat *st)
{
if
(
f
->
type
==
FD_INODE
){
ilock
(
f
->
ip
);
if
(
f
->
ip
->
type
==
0
)
panic
(
"filestat"
);
stati
(
f
->
ip
,
st
);
iunlock
(
f
->
ip
);
return
0
;
...
...
@@ -98,6 +100,8 @@ fileread(struct file *f, char *addr, int n)
return
piperead
(
f
->
pipe
,
addr
,
n
);
if
(
f
->
type
==
FD_INODE
){
ilock
(
f
->
ip
);
if
(
f
->
ip
->
type
==
0
)
panic
(
"fileread"
);
if
((
r
=
readi
(
f
->
ip
,
addr
,
f
->
off
,
n
))
>
0
)
f
->
off
+=
r
;
iunlock
(
f
->
ip
);
...
...
file.h
浏览文件 @
3029f0e8
...
...
@@ -14,6 +14,7 @@ struct file {
struct
inode
{
uint
dev
;
// Device number
uint
inum
;
// Inode number
uint
gen
;
// Generation number
int
ref
;
// Reference count
int
flags
;
// I_BUSY, I_VALID
struct
condvar
cv
;
...
...
fs.c
浏览文件 @
3029f0e8
...
...
@@ -148,6 +148,7 @@ iinit(void)
//PAGEBREAK!
// Allocate a new inode with the given type on device dev.
// Returns a locked inode.
struct
inode
*
ialloc
(
uint
dev
,
short
type
)
{
...
...
@@ -160,14 +161,24 @@ ialloc(uint dev, short type)
for
(
inum
=
1
;
inum
<
sb
.
ninodes
;
inum
++
){
// loop over inode blocks
bp
=
bread
(
dev
,
IBLOCK
(
inum
));
dip
=
(
struct
dinode
*
)
bp
->
data
+
inum
%
IPB
;
if
(
dip
->
type
==
0
){
// a free inode
memset
(
dip
,
0
,
sizeof
(
*
dip
));
dip
->
type
=
type
;
bwrite
(
bp
);
// mark it allocated on the disk
brelse
(
bp
);
return
iget
(
dev
,
inum
);
}
int
seemsfree
=
(
dip
->
type
==
0
);
brelse
(
bp
);
if
(
seemsfree
){
// maybe this inode is free. look at it via the
// inode cache to make sure.
struct
inode
*
ip
=
iget
(
dev
,
inum
);
ilock
(
ip
);
if
(
ip
->
type
==
0
){
ip
->
type
=
type
;
ip
->
gen
+=
1
;
if
(
ip
->
nlink
||
ip
->
size
||
ip
->
addrs
[
0
])
panic
(
"ialloc not zeroed"
);
iupdate
(
ip
);
return
ip
;
}
iunlockput
(
ip
);
cprintf
(
"ialloc oops %d
\n
"
,
inum
);
// XXX harmless
}
}
panic
(
"ialloc: no inodes"
);
}
...
...
@@ -186,6 +197,7 @@ iupdate(struct inode *ip)
dip
->
minor
=
ip
->
minor
;
dip
->
nlink
=
ip
->
nlink
;
dip
->
size
=
ip
->
size
;
dip
->
gen
=
ip
->
gen
;
memmove
(
dip
->
addrs
,
ip
->
addrs
,
sizeof
(
ip
->
addrs
));
bwrite
(
bp
);
brelse
(
bp
);
...
...
@@ -238,6 +250,9 @@ idup(struct inode *ip)
}
// Lock the given inode.
// XXX why does ilock() read the inode from disk?
// why doesn't the iget() that allocated the inode cache entry
// read the inode from disk?
void
ilock
(
struct
inode
*
ip
)
{
...
...
@@ -261,11 +276,10 @@ ilock(struct inode *ip)
ip
->
minor
=
dip
->
minor
;
ip
->
nlink
=
dip
->
nlink
;
ip
->
size
=
dip
->
size
;
ip
->
gen
=
dip
->
gen
;
memmove
(
ip
->
addrs
,
dip
->
addrs
,
sizeof
(
ip
->
addrs
));
brelse
(
bp
);
ip
->
flags
|=
I_VALID
;
if
(
ip
->
type
==
0
)
panic
(
"ilock: no type"
);
}
}
...
...
@@ -295,6 +309,9 @@ iput(struct inode *ip)
release
(
&
icache
.
lock
);
itrunc
(
ip
);
ip
->
type
=
0
;
ip
->
major
=
0
;
ip
->
minor
=
0
;
ip
->
gen
+=
1
;
iupdate
(
ip
);
acquire
(
&
icache
.
lock
);
ip
->
flags
=
0
;
...
...
@@ -590,6 +607,8 @@ namex(char *path, int nameiparent, char *name)
next
=
nc_lookup
(
ip
,
name
);
if
(
next
==
0
){
ilock
(
ip
);
if
(
ip
->
type
==
0
)
panic
(
"namex"
);
if
(
ip
->
type
!=
T_DIR
){
iunlockput
(
ip
);
return
0
;
...
...
fs.h
浏览文件 @
3029f0e8
...
...
@@ -15,17 +15,19 @@ struct superblock {
uint
ninodes
;
// Number of inodes.
};
#define NDIRECT 1
2
#define NDIRECT 1
1
#define NINDIRECT (BSIZE / sizeof(uint))
#define MAXFILE (NDIRECT + NINDIRECT)
// On-disk inode structure
// (512 % sizeof(dinode)) == 0
struct
dinode
{
short
type
;
// File type
short
major
;
// Major device number (T_DEV only)
short
minor
;
// Minor device number (T_DEV only)
short
nlink
;
// Number of links to inode in file system
uint
size
;
// Size of file (bytes)
uint
gen
;
// Generation # (to check name cache)
uint
addrs
[
NDIRECT
+
1
];
// Data block addresses
};
...
...
mkfs.c
浏览文件 @
3029f0e8
...
...
@@ -218,6 +218,7 @@ ialloc(ushort type)
din
.
type
=
xshort
(
type
);
din
.
nlink
=
xshort
(
1
);
din
.
size
=
xint
(
0
);
din
.
gen
=
1
;
winode
(
inum
,
&
din
);
return
inum
;
}
...
...
namecache.c
浏览文件 @
3029f0e8
...
...
@@ -4,11 +4,11 @@
// to do:
// use ns.c namespaces
// does directory inum need to be locked around ns_lookup?
// need a lock to make table lookup and iget atomic?
// unlink/lookup race?
// better: inode generation #
// maybe generation #s don't need to be in on-disk inode
// if namecache only referred to cached inodes
// insert when file created, not just looked up
// eviction
// verify that it hits when it is supposed to
//
#include "types.h"
...
...
@@ -33,6 +33,7 @@ struct nce {
uint
dinum
;
// directory inumber
char
name
[
DIRSIZ
];
uint
cinum
;
// child inumber
uint
gen
;
// child ip->gen
};
#define NCE 128
struct
nce
nce
[
NCE
];
...
...
@@ -61,28 +62,51 @@ struct inode *
nc_lookup
(
struct
inode
*
dir
,
char
*
name
)
{
uint
inum
=
0
;
uint
gen
=
0
;
acquire
(
&
nc_lock
);
struct
nce
*
e
=
nc_lookup1
(
dir
,
name
);
if
(
e
)
if
(
e
)
{
inum
=
e
->
cinum
;
gen
=
e
->
gen
;
}
release
(
&
nc_lock
);
if
(
inum
)
return
iget
(
dir
->
dev
,
inum
);
else
if
(
inum
){
struct
inode
*
ip
=
iget
(
dir
->
dev
,
inum
);
// this is a bit ugly
// maybe there should be a real inode cache and
// the namecache should contain direct refs.
ilock
(
ip
);
int
ok
=
(
ip
->
gen
==
gen
);
iunlock
(
ip
);
if
(
ok
){
return
ip
;
}
else
{
iput
(
ip
);
return
0
;
}
}
else
return
0
;
}
// dir is locked, but ip is not.
void
nc_insert
(
struct
inode
*
dir
,
char
*
name
,
struct
inode
*
ip
)
{
ilock
(
ip
);
uint
inum
=
ip
->
inum
;
uint
gen
=
ip
->
gen
;
iunlock
(
ip
);
acquire
(
&
nc_lock
);
struct
nce
*
e
=
nc_lookup1
(
dir
,
name
);
if
(
e
){
if
(
e
->
cinum
!=
ip
->
inum
)
if
(
e
->
cinum
!=
inum
||
e
->
gen
!=
gen
){
// someone forgot to call nc_invalidate()
panic
(
"nc_insert change"
);
}
release
(
&
nc_lock
);
return
;
}
...
...
@@ -95,7 +119,8 @@ nc_insert(struct inode *dir, char *name, struct inode *ip)
e
->
dev
=
dir
->
dev
;
e
->
dinum
=
dir
->
inum
;
strncpy
(
e
->
name
,
name
,
DIRSIZ
);
e
->
cinum
=
ip
->
inum
;
e
->
cinum
=
inum
;
e
->
gen
=
gen
;
break
;
}
}
...
...
sysfile.c
浏览文件 @
3029f0e8
...
...
@@ -177,6 +177,8 @@ sys_unlink(void)
if
((
dp
=
nameiparent
(
path
,
name
))
==
0
)
return
-
1
;
ilock
(
dp
);
if
(
dp
->
type
!=
T_DIR
)
panic
(
"sys_unlink"
);
// Cannot unlink "." or "..".
if
(
namecmp
(
name
,
"."
)
==
0
||
namecmp
(
name
,
".."
)
==
0
){
...
...
@@ -205,6 +207,7 @@ sys_unlink(void)
dp
->
nlink
--
;
iupdate
(
dp
);
}
nc_invalidate
(
dp
,
name
);
iunlockput
(
dp
);
...
...
@@ -224,6 +227,8 @@ create(char *path, short type, short major, short minor)
if
((
dp
=
nameiparent
(
path
,
name
))
==
0
)
return
0
;
ilock
(
dp
);
if
(
dp
->
type
!=
T_DIR
)
panic
(
"create"
);
if
((
ip
=
dirlookup
(
dp
,
name
,
&
off
))
!=
0
){
iunlockput
(
dp
);
...
...
@@ -237,7 +242,6 @@ create(char *path, short type, short major, short minor)
if
((
ip
=
ialloc
(
dp
->
dev
,
type
))
==
0
)
panic
(
"create: ialloc"
);
ilock
(
ip
);
ip
->
major
=
major
;
ip
->
minor
=
minor
;
ip
->
nlink
=
1
;
...
...
@@ -275,6 +279,8 @@ sys_open(void)
if
((
ip
=
namei
(
path
))
==
0
)
return
-
1
;
ilock
(
ip
);
if
(
ip
->
type
==
0
)
panic
(
"open"
);
if
(
ip
->
type
==
T_DIR
&&
omode
!=
O_RDONLY
){
iunlockput
(
ip
);
return
-
1
;
...
...
usertests.c
浏览文件 @
3029f0e8
...
...
@@ -1567,7 +1567,7 @@ main(int argc, char *argv[])
}
close
(
open
(
"usertests.ran"
,
O_CREATE
));
//
unopentest();
unopentest
();
bigargtest
();
bsstest
();
sbrktest
();
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论