Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
948078f5
提交
948078f5
6月 15, 2011
创建
作者:
Nickolai Zeldovich
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
read-write locks for buffer cache
上级
9f969fb4
显示空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
35 行增加
和
29 行删除
+35
-29
bio.c
bio.c
+16
-12
buf.h
buf.h
+5
-3
defs.h
defs.h
+1
-1
fs.c
fs.c
+12
-12
ide.c
ide.c
+1
-1
没有找到文件。
bio.c
浏览文件 @
948078f5
...
...
@@ -54,7 +54,7 @@ evict(uint key, void *bp)
{
struct
buf
*
b
=
bp
;
acquire
(
&
b
->
lock
);
if
((
b
->
flags
&
(
B_BUSY
|
B_VALID
))
==
0
)
if
((
b
->
flags
&
(
B_BUSY
R
|
B_BUSYW
|
B_VALID
))
==
0
)
return
b
;
release
(
&
b
->
lock
);
return
0
;
...
...
@@ -65,7 +65,7 @@ evict_valid(uint key, void *bp)
{
struct
buf
*
b
=
bp
;
acquire
(
&
b
->
lock
);
if
((
b
->
flags
&
B_BUSY
)
==
0
)
if
((
b
->
flags
&
(
B_BUSYR
|
B_BUSYW
)
)
==
0
)
return
b
;
release
(
&
b
->
lock
);
return
0
;
...
...
@@ -75,7 +75,7 @@ evict_valid(uint key, void *bp)
// If not found, allocate fresh block.
// In either case, return locked buffer.
static
struct
buf
*
bget
(
uint
dev
,
uint
sector
)
bget
(
uint
dev
,
uint
sector
,
int
writer
)
{
struct
buf
*
b
;
...
...
@@ -88,8 +88,9 @@ bget(uint dev, uint sector)
acquire
(
&
b
->
lock
);
if
(
b
->
dev
!=
dev
)
panic
(
"dev mismatch"
);
if
(
!
(
b
->
flags
&
B_BUSY
))
{
b
->
flags
|=
B_BUSY
;
if
(
!
(
b
->
flags
&
(
B_BUSYW
|
(
writer
?
B_BUSYR
:
0
))))
{
b
->
flags
|=
B_BUSYR
|
(
writer
?
B_BUSYW
:
0
);
__sync_fetch_and_add
(
&
b
->
readbusy
,
1
);
release
(
&
b
->
lock
);
rcu_end_read
();
return
b
;
...
...
@@ -108,7 +109,8 @@ bget(uint dev, uint sector)
victim
=
ns_enumerate
(
bufns
,
evict_valid
);
if
(
victim
==
0
)
panic
(
"bget all busy"
);
victim
->
flags
|=
B_BUSY
;
victim
->
flags
|=
B_BUSYR
|
B_BUSYW
;
__sync_fetch_and_add
(
&
victim
->
readbusy
,
1
);
ns_remove
(
bufns
,
victim
->
sector
,
victim
);
release
(
&
victim
->
lock
);
rcu_delayed
(
victim
,
kmfree
);
...
...
@@ -116,7 +118,8 @@ bget(uint dev, uint sector)
b
=
kmalloc
(
sizeof
(
*
b
));
b
->
dev
=
dev
;
b
->
sector
=
sector
;
b
->
flags
=
B_BUSY
;
b
->
flags
=
B_BUSYR
|
B_BUSYW
;
b
->
readbusy
=
1
;
initlock
(
&
b
->
lock
,
"bcache-lock"
);
initcondvar
(
&
b
->
cv
,
"bcache-cv"
);
if
(
ns_insert
(
bufns
,
b
->
sector
,
b
)
<
0
)
{
...
...
@@ -128,11 +131,11 @@ bget(uint dev, uint sector)
// Return a B_BUSY buf with the contents of the indicated disk sector.
struct
buf
*
bread
(
uint
dev
,
uint
sector
)
bread
(
uint
dev
,
uint
sector
,
int
writer
)
{
struct
buf
*
b
;
b
=
bget
(
dev
,
sector
);
b
=
bget
(
dev
,
sector
,
writer
);
if
(
!
(
b
->
flags
&
B_VALID
))
iderw
(
b
);
return
b
;
...
...
@@ -142,7 +145,7 @@ bread(uint dev, uint sector)
void
bwrite
(
struct
buf
*
b
)
{
if
((
b
->
flags
&
B_BUSY
)
==
0
)
if
((
b
->
flags
&
B_BUSY
W
)
==
0
)
panic
(
"bwrite"
);
b
->
flags
|=
B_DIRTY
;
if
(
writeback
)
...
...
@@ -154,9 +157,10 @@ void
brelse
(
struct
buf
*
b
)
{
acquire
(
&
b
->
lock
);
if
((
b
->
flags
&
B_BUSY
)
==
0
)
if
((
b
->
flags
&
(
B_BUSYR
|
B_BUSYW
)
)
==
0
)
panic
(
"brelse"
);
b
->
flags
&=
~
B_BUSY
;
int
lastreader
=
__sync_sub_and_fetch
(
&
b
->
readbusy
,
1
);
b
->
flags
&=
~
(
B_BUSYW
|
((
lastreader
==
0
)
?
B_BUSYR
:
0
));
release
(
&
b
->
lock
);
cv_wakeup
(
&
b
->
cv
);
}
...
...
buf.h
浏览文件 @
948078f5
...
...
@@ -2,6 +2,7 @@ struct buf {
int
flags
;
uint
dev
;
uint
sector
;
int
readbusy
;
struct
buf
*
prev
;
// LRU cache list
struct
buf
*
next
;
struct
buf
*
qnext
;
// disk queue
...
...
@@ -9,7 +10,8 @@ struct buf {
struct
spinlock
lock
;
uchar
data
[
512
];
};
#define B_BUSY 0x1 // buffer is locked by some process
#define B_VALID 0x2 // buffer has been read from disk
#define B_DIRTY 0x4 // buffer needs to be written to disk
#define B_BUSYR 0x1 // buffer is locked by some process
#define B_BUSYW 0x2 // buffer is locked by some process
#define B_VALID 0x4 // buffer has been read from disk
#define B_DIRTY 0x8 // buffer needs to be written to disk
defs.h
浏览文件 @
948078f5
...
...
@@ -14,7 +14,7 @@ struct ns;
// bio.c
void
binit
(
void
);
struct
buf
*
bread
(
uint
,
uint
);
struct
buf
*
bread
(
uint
,
uint
,
int
writer
);
void
brelse
(
struct
buf
*
);
void
bwrite
(
struct
buf
*
);
...
...
fs.c
浏览文件 @
948078f5
...
...
@@ -32,7 +32,7 @@ readsb(int dev, struct superblock *sb)
{
struct
buf
*
bp
;
bp
=
bread
(
dev
,
1
);
bp
=
bread
(
dev
,
1
,
0
);
memmove
(
sb
,
bp
->
data
,
sizeof
(
*
sb
));
brelse
(
bp
);
}
...
...
@@ -43,7 +43,7 @@ bzero(int dev, int bno)
{
struct
buf
*
bp
;
bp
=
bread
(
dev
,
bno
);
bp
=
bread
(
dev
,
bno
,
1
);
memset
(
bp
->
data
,
0
,
BSIZE
);
bwrite
(
bp
);
brelse
(
bp
);
...
...
@@ -62,7 +62,7 @@ balloc(uint dev)
bp
=
0
;
readsb
(
dev
,
&
sb
);
for
(
b
=
0
;
b
<
sb
.
size
;
b
+=
BPB
){
bp
=
bread
(
dev
,
BBLOCK
(
b
,
sb
.
ninodes
));
bp
=
bread
(
dev
,
BBLOCK
(
b
,
sb
.
ninodes
)
,
1
);
for
(
bi
=
0
;
bi
<
BPB
;
bi
++
){
m
=
1
<<
(
bi
%
8
);
if
((
bp
->
data
[
bi
/
8
]
&
m
)
==
0
){
// Is block free?
...
...
@@ -88,7 +88,7 @@ bfree(int dev, uint b)
bzero
(
dev
,
b
);
readsb
(
dev
,
&
sb
);
bp
=
bread
(
dev
,
BBLOCK
(
b
,
sb
.
ninodes
));
bp
=
bread
(
dev
,
BBLOCK
(
b
,
sb
.
ninodes
)
,
1
);
bi
=
b
%
BPB
;
m
=
1
<<
(
bi
%
8
);
if
((
bp
->
data
[
bi
/
8
]
&
m
)
==
0
)
...
...
@@ -160,7 +160,7 @@ ialloc(uint dev, short type)
readsb
(
dev
,
&
sb
);
for
(
inum
=
1
;
inum
<
sb
.
ninodes
;
inum
++
){
// loop over inode blocks
bp
=
bread
(
dev
,
IBLOCK
(
inum
));
bp
=
bread
(
dev
,
IBLOCK
(
inum
)
,
1
);
dip
=
(
struct
dinode
*
)
bp
->
data
+
inum
%
IPB
;
int
seemsfree
=
(
dip
->
type
==
0
);
brelse
(
bp
);
...
...
@@ -191,7 +191,7 @@ iupdate(struct inode *ip)
struct
buf
*
bp
;
struct
dinode
*
dip
;
bp
=
bread
(
ip
->
dev
,
IBLOCK
(
ip
->
inum
));
bp
=
bread
(
ip
->
dev
,
IBLOCK
(
ip
->
inum
)
,
1
);
dip
=
(
struct
dinode
*
)
bp
->
data
+
ip
->
inum
%
IPB
;
dip
->
type
=
ip
->
type
;
dip
->
major
=
ip
->
major
;
...
...
@@ -268,7 +268,7 @@ iget(uint dev, uint inum)
goto
retry
;
}
struct
buf
*
bp
=
bread
(
ip
->
dev
,
IBLOCK
(
ip
->
inum
));
struct
buf
*
bp
=
bread
(
ip
->
dev
,
IBLOCK
(
ip
->
inum
)
,
0
);
struct
dinode
*
dip
=
(
struct
dinode
*
)
bp
->
data
+
ip
->
inum
%
IPB
;
ip
->
type
=
dip
->
type
;
ip
->
major
=
dip
->
major
;
...
...
@@ -394,7 +394,7 @@ bmap(struct inode *ip, uint bn)
// Load indirect block, allocating if necessary.
if
((
addr
=
ip
->
addrs
[
NDIRECT
])
==
0
)
ip
->
addrs
[
NDIRECT
]
=
addr
=
balloc
(
ip
->
dev
);
bp
=
bread
(
ip
->
dev
,
addr
);
bp
=
bread
(
ip
->
dev
,
addr
,
1
);
a
=
(
uint
*
)
bp
->
data
;
if
((
addr
=
a
[
bn
])
==
0
){
a
[
bn
]
=
addr
=
balloc
(
ip
->
dev
);
...
...
@@ -425,7 +425,7 @@ itrunc(struct inode *ip)
}
if
(
ip
->
addrs
[
NDIRECT
]){
bp
=
bread
(
ip
->
dev
,
ip
->
addrs
[
NDIRECT
]);
bp
=
bread
(
ip
->
dev
,
ip
->
addrs
[
NDIRECT
]
,
0
);
a
=
(
uint
*
)
bp
->
data
;
for
(
j
=
0
;
j
<
NINDIRECT
;
j
++
){
if
(
a
[
j
])
...
...
@@ -471,7 +471,7 @@ readi(struct inode *ip, char *dst, uint off, uint n)
n
=
ip
->
size
-
off
;
for
(
tot
=
0
;
tot
<
n
;
tot
+=
m
,
off
+=
m
,
dst
+=
m
){
bp
=
bread
(
ip
->
dev
,
bmap
(
ip
,
off
/
BSIZE
));
bp
=
bread
(
ip
->
dev
,
bmap
(
ip
,
off
/
BSIZE
)
,
0
);
m
=
min
(
n
-
tot
,
BSIZE
-
off
%
BSIZE
);
memmove
(
dst
,
bp
->
data
+
off
%
BSIZE
,
m
);
brelse
(
bp
);
...
...
@@ -499,7 +499,7 @@ writei(struct inode *ip, char *src, uint off, uint n)
n
=
MAXFILE
*
BSIZE
-
off
;
for
(
tot
=
0
;
tot
<
n
;
tot
+=
m
,
off
+=
m
,
src
+=
m
){
bp
=
bread
(
ip
->
dev
,
bmap
(
ip
,
off
/
BSIZE
));
bp
=
bread
(
ip
->
dev
,
bmap
(
ip
,
off
/
BSIZE
)
,
1
);
m
=
min
(
n
-
tot
,
BSIZE
-
off
%
BSIZE
);
memmove
(
bp
->
data
+
off
%
BSIZE
,
src
,
m
);
bwrite
(
bp
);
...
...
@@ -536,7 +536,7 @@ dirlookup(struct inode *dp, char *name, uint *poff)
panic
(
"dirlookup not DIR"
);
for
(
off
=
0
;
off
<
dp
->
size
;
off
+=
BSIZE
){
bp
=
bread
(
dp
->
dev
,
bmap
(
dp
,
off
/
BSIZE
));
bp
=
bread
(
dp
->
dev
,
bmap
(
dp
,
off
/
BSIZE
)
,
0
);
for
(
de
=
(
struct
dirent
*
)
bp
->
data
;
de
<
(
struct
dirent
*
)(
bp
->
data
+
BSIZE
);
de
++
){
...
...
ide.c
浏览文件 @
948078f5
...
...
@@ -130,7 +130,7 @@ iderw(struct buf *b)
{
struct
buf
**
pp
;
if
(
!
(
b
->
flags
&
B_BUSY
))
if
(
!
(
b
->
flags
&
(
B_BUSYR
|
B_BUSYW
)
))
panic
(
"iderw: buf not busy"
);
if
((
b
->
flags
&
(
B_VALID
|
B_DIRTY
))
==
B_VALID
)
panic
(
"iderw: nothing to do"
);
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论