Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
2c565472
提交
2c565472
8月 04, 2014
创建
作者:
Robert Morris
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
every iput() and namei() must be inside a transaction
上级
020c8e23
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
145 行增加
和
17 行删除
+145
-17
exec.c
exec.c
+8
-2
fs.c
fs.c
+3
-0
log.c
log.c
+1
-5
proc.c
proc.c
+2
-0
sysfile.c
sysfile.c
+26
-9
usertests.c
usertests.c
+105
-1
没有找到文件。
exec.c
浏览文件 @
2c565472
...
...
@@ -18,8 +18,11 @@ exec(char *path, char **argv)
struct
proghdr
ph
;
pde_t
*
pgdir
,
*
oldpgdir
;
if
((
ip
=
namei
(
path
))
==
0
)
begin_trans
();
if
((
ip
=
namei
(
path
))
==
0
){
commit_trans
();
return
-
1
;
}
ilock
(
ip
);
pgdir
=
0
;
...
...
@@ -47,6 +50,7 @@ exec(char *path, char **argv)
goto
bad
;
}
iunlockput
(
ip
);
commit_trans
();
ip
=
0
;
// Allocate two pages at the next page boundary.
...
...
@@ -95,7 +99,9 @@ exec(char *path, char **argv)
bad:
if
(
pgdir
)
freevm
(
pgdir
);
if
(
ip
)
if
(
ip
)
{
iunlockput
(
ip
);
commit_trans
();
}
return
-
1
;
}
fs.c
浏览文件 @
2c565472
...
...
@@ -314,6 +314,8 @@ iunlock(struct inode *ip)
// be recycled.
// If that was the last reference and the inode has no links
// to it, free the inode (and its content) on disk.
// All calls to iput() must be inside a transaction in
// case it has to free the inode.
void
iput
(
struct
inode
*
ip
)
{
...
...
@@ -601,6 +603,7 @@ skipelem(char *path, char *name)
// Look up and return the inode for a path name.
// If parent != 0, return the inode for the parent and copy the final
// path element into name, which must have room for DIRSIZ bytes.
// Must be called inside a transaction since it calls iput().
static
struct
inode
*
namex
(
char
*
path
,
int
nameiparent
,
char
*
name
)
{
...
...
log.c
浏览文件 @
2c565472
...
...
@@ -5,7 +5,7 @@
#include "fs.h"
#include "buf.h"
// Simple logging. Each
system call that might write the file system
// Simple logging. Each
file system system call
// should be surrounded with begin_trans() and commit_trans() calls.
//
// The log holds at most one transaction at a time. Commit forces
...
...
@@ -18,10 +18,6 @@
// one transaction reading a block that another one has modified,
// for example an i-node block.
//
// Read-only system calls don't need to use transactions, though
// this means that they may observe uncommitted data. I-node and
// buffer locks prevent read-only calls from seeing inconsistent data.
//
// The log is a physical re-do log containing disk blocks.
// The on-disk log format:
// header block, containing sector #s for block A, B, C, ...
...
...
proc.c
浏览文件 @
2c565472
...
...
@@ -186,7 +186,9 @@ exit(void)
}
}
begin_trans
();
iput
(
proc
->
cwd
);
commit_trans
();
proc
->
cwd
=
0
;
acquire
(
&
ptable
.
lock
);
...
...
sysfile.c
浏览文件 @
2c565472
...
...
@@ -120,10 +120,12 @@ sys_link(void)
if
(
argstr
(
0
,
&
old
)
<
0
||
argstr
(
1
,
&
new
)
<
0
)
return
-
1
;
if
((
ip
=
namei
(
old
))
==
0
)
return
-
1
;
begin_trans
();
if
((
ip
=
namei
(
old
))
==
0
){
commit_trans
();
return
-
1
;
}
ilock
(
ip
);
if
(
ip
->
type
==
T_DIR
){
...
...
@@ -186,10 +188,12 @@ sys_unlink(void)
if
(
argstr
(
0
,
&
path
)
<
0
)
return
-
1
;
if
((
dp
=
nameiparent
(
path
,
name
))
==
0
)
return
-
1
;
begin_trans
();
if
((
dp
=
nameiparent
(
path
,
name
))
==
0
){
commit_trans
();
return
-
1
;
}
ilock
(
dp
);
...
...
@@ -286,18 +290,24 @@ sys_open(void)
if
(
argstr
(
0
,
&
path
)
<
0
||
argint
(
1
,
&
omode
)
<
0
)
return
-
1
;
begin_trans
();
if
(
omode
&
O_CREATE
){
begin_trans
();
ip
=
create
(
path
,
T_FILE
,
0
,
0
);
commit_trans
();
if
(
ip
==
0
)
if
(
ip
==
0
){
commit_trans
();
return
-
1
;
}
}
else
{
if
((
ip
=
namei
(
path
))
==
0
)
if
((
ip
=
namei
(
path
))
==
0
){
commit_trans
();
return
-
1
;
}
ilock
(
ip
);
if
(
ip
->
type
==
T_DIR
&&
omode
!=
O_RDONLY
){
iunlockput
(
ip
);
commit_trans
();
return
-
1
;
}
}
...
...
@@ -306,9 +316,11 @@ sys_open(void)
if
(
f
)
fileclose
(
f
);
iunlockput
(
ip
);
commit_trans
();
return
-
1
;
}
iunlock
(
ip
);
commit_trans
();
f
->
type
=
FD_INODE
;
f
->
ip
=
ip
;
...
...
@@ -361,15 +373,20 @@ sys_chdir(void)
char
*
path
;
struct
inode
*
ip
;
if
(
argstr
(
0
,
&
path
)
<
0
||
(
ip
=
namei
(
path
))
==
0
)
begin_trans
();
if
(
argstr
(
0
,
&
path
)
<
0
||
(
ip
=
namei
(
path
))
==
0
){
commit_trans
();
return
-
1
;
}
ilock
(
ip
);
if
(
ip
->
type
!=
T_DIR
){
iunlockput
(
ip
);
commit_trans
();
return
-
1
;
}
iunlock
(
ip
);
iput
(
proc
->
cwd
);
commit_trans
();
proc
->
cwd
=
ip
;
return
0
;
}
...
...
usertests.c
浏览文件 @
2c565472
...
...
@@ -13,6 +13,106 @@ char name[3];
char
*
echoargv
[]
=
{
"echo"
,
"ALL"
,
"TESTS"
,
"PASSED"
,
0
};
int
stdout
=
1
;
// does chdir() call iput(p->cwd) in a transaction?
void
iputtest
(
void
)
{
printf
(
stdout
,
"iput test
\n
"
);
if
(
mkdir
(
"iputdir"
)
<
0
){
printf
(
stdout
,
"mkdir failed
\n
"
);
exit
();
}
if
(
chdir
(
"iputdir"
)
<
0
){
printf
(
stdout
,
"chdir iputdir failed
\n
"
);
exit
();
}
if
(
unlink
(
"../iputdir"
)
<
0
){
printf
(
stdout
,
"unlink ../iputdir failed
\n
"
);
exit
();
}
if
(
chdir
(
"/"
)
<
0
){
printf
(
stdout
,
"chdir / failed
\n
"
);
exit
();
}
printf
(
stdout
,
"iput test ok
\n
"
);
}
// does exit() call iput(p->cwd) in a transaction?
void
exitiputtest
(
void
)
{
int
pid
;
printf
(
stdout
,
"exitiput test
\n
"
);
pid
=
fork
();
if
(
pid
<
0
){
printf
(
stdout
,
"fork failed
\n
"
);
exit
();
}
if
(
pid
==
0
){
if
(
mkdir
(
"iputdir"
)
<
0
){
printf
(
stdout
,
"mkdir failed
\n
"
);
exit
();
}
if
(
chdir
(
"iputdir"
)
<
0
){
printf
(
stdout
,
"child chdir failed
\n
"
);
exit
();
}
if
(
unlink
(
"../iputdir"
)
<
0
){
printf
(
stdout
,
"unlink ../iputdir failed
\n
"
);
exit
();
}
exit
();
}
wait
();
printf
(
stdout
,
"exitiput test ok
\n
"
);
}
// does the error path in open() for attempt to write a
// directory call iput() in a transaction?
// needs a hacked kernel that pauses just after the namei()
// call in sys_open():
// if((ip = namei(path)) == 0)
// return -1;
// {
// int i;
// for(i = 0; i < 10000; i++)
// yield();
// }
void
openiputtest
(
void
)
{
int
pid
;
printf
(
stdout
,
"openiput test
\n
"
);
if
(
mkdir
(
"oidir"
)
<
0
){
printf
(
stdout
,
"mkdir oidir failed
\n
"
);
exit
();
}
pid
=
fork
();
if
(
pid
<
0
){
printf
(
stdout
,
"fork failed
\n
"
);
exit
();
}
if
(
pid
==
0
){
int
fd
=
open
(
"oidir"
,
O_RDWR
);
if
(
fd
>=
0
){
printf
(
stdout
,
"open directory for write succeeded
\n
"
);
exit
();
}
exit
();
}
sleep
(
1
);
if
(
unlink
(
"oidir"
)
!=
0
){
printf
(
stdout
,
"unlink failed
\n
"
);
exit
();
}
wait
();
printf
(
stdout
,
"openiput test ok
\n
"
);
}
// simple file system tests
void
...
...
@@ -187,7 +287,7 @@ void dirtest(void)
printf
(
stdout
,
"unlink dir0 failed
\n
"
);
exit
();
}
printf
(
stdout
,
"mkdir test
\n
"
);
printf
(
stdout
,
"mkdir test
ok
\n
"
);
}
void
...
...
@@ -1628,6 +1728,10 @@ main(int argc, char *argv[])
writetest1
();
createtest
();
openiputtest
();
exitiputtest
();
iputtest
();
mem
();
pipe1
();
preempt
();
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论