Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
bb207a1d
提交
bb207a1d
9月 07, 2006
创建
作者:
rsc
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
comments
上级
52253dce
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
109 行增加
和
16 行删除
+109
-16
bio.c
bio.c
+37
-4
file.c
file.c
+5
-6
fs.c
fs.c
+60
-6
ide.c
ide.c
+7
-0
没有找到文件。
bio.c
浏览文件 @
bb207a1d
// Buffer cache.
//
// The buffer cache is a linked list of buf structures
// holding cached copies of disk block contents.
// Each buf has two state bits B_BUSY and B_VALID.
// If B_BUSY is set, it means that some code is currently
// editing buf, so other code is not allowed to look at it.
// To wait for a buffer that is B_BUSY, sleep on buf.
// (See bget below.)
//
// If B_VALID is set, it means that the memory contents
// have been initialized by reading them off the disk.
// (Conversely, if B_VALID is not set, the memory contents
// of buf must be initialized, often by calling bread,
// before being used.)
//
// After making changes to a buf's memory, call bwrite to flush
// the changes out to disk, to keep the disk and memory copies
// in sync.
//
// When finished with a buffer, call brelse to release the buffer
// (i.e., clear B_BUSY), so that others can access it.
//
// Bufs that are not B_BUSY are fair game for reuse for other
// disk blocks. It is not allowed to use a buf after calling brelse.
#include "types.h"
#include "param.h"
#include "x86.h"
...
...
@@ -10,7 +36,7 @@
struct
buf
buf
[
NBUF
];
struct
spinlock
buf_table_lock
;
//
l
inked list of all buffers, through prev/next.
//
L
inked list of all buffers, through prev/next.
// bufhead->next is most recently used.
// bufhead->tail is least recently used.
struct
buf
bufhead
;
...
...
@@ -22,6 +48,7 @@ binit(void)
initlock
(
&
buf_table_lock
,
"buf_table"
);
// Create linked list of buffers
bufhead
.
prev
=
&
bufhead
;
bufhead
.
next
=
&
bufhead
;
for
(
b
=
buf
;
b
<
buf
+
NBUF
;
b
++
){
...
...
@@ -32,7 +59,10 @@ binit(void)
}
}
struct
buf
*
// Look through buffer cache for block n on device dev.
// If not found, allocate fresh block.
// In either case, return locked buffer.
static
struct
buf
*
getblk
(
uint
dev
,
uint
sector
)
{
struct
buf
*
b
;
...
...
@@ -63,11 +93,12 @@ getblk(uint dev, uint sector)
return
b
;
}
}
panic
(
"
getblk
: no buffers"
);
panic
(
"
bget
: no buffers"
);
}
}
}
// Read buf's contents from disk.
struct
buf
*
bread
(
uint
dev
,
uint
sector
)
{
...
...
@@ -75,7 +106,7 @@ bread(uint dev, uint sector)
struct
buf
*
b
;
extern
struct
spinlock
ide_lock
;
b
=
getblk
(
dev
,
sector
);
b
=
bget
(
dev
,
sector
);
if
(
b
->
flags
&
B_VALID
)
return
b
;
...
...
@@ -89,6 +120,7 @@ bread(uint dev, uint sector)
return
b
;
}
// Write buf's contents to disk.
void
bwrite
(
struct
buf
*
b
,
uint
sector
)
{
...
...
@@ -103,6 +135,7 @@ bwrite(struct buf *b, uint sector)
release
(
&
ide_lock
);
}
// Release the buffer buf.
void
brelse
(
struct
buf
*
b
)
{
...
...
file.c
浏览文件 @
bb207a1d
...
...
@@ -41,8 +41,7 @@ filealloc(void)
return
0
;
}
// Write to file descriptor;
// addr is a kernel address, pointing into some process's p->mem.
// Write to file f. Addr is kernel address.
int
filewrite
(
struct
file
*
fd
,
char
*
addr
,
int
n
)
{
...
...
@@ -64,7 +63,7 @@ filewrite(struct file *fd, char *addr, int n)
}
}
// Read from file
descriptor
.
// Read from file
f. Addr is kernel address
.
int
fileread
(
struct
file
*
fd
,
char
*
addr
,
int
n
)
{
...
...
@@ -85,7 +84,7 @@ fileread(struct file *fd, char *addr, int n)
}
}
// Close file
descriptor.
// Close file
f. (Decrement ref count, close when reaches 0.)
void
fileclose
(
struct
file
*
fd
)
{
...
...
@@ -113,7 +112,7 @@ fileclose(struct file *fd)
}
}
// Get metadata about file
descriptor
.
// Get metadata about file
f
.
int
filestat
(
struct
file
*
fd
,
struct
stat
*
st
)
{
...
...
@@ -126,7 +125,7 @@ filestat(struct file *fd, struct stat *st)
return
-
1
;
}
// Increment
file descriptor reference count
.
// Increment
ref count for file f
.
void
fileincref
(
struct
file
*
fd
)
{
...
...
fs.c
浏览文件 @
bb207a1d
...
...
@@ -11,8 +11,24 @@
#include "fsvar.h"
#include "dev.h"
// these are inodes currently in use
// an entry is free if count == 0
// Inode table. The inode table is an in-memory cache of the
// on-disk inode structures. If an inode in the table has a non-zero
// reference count, then some open files refer to it and it must stay
// in memory. If an inode has a zero reference count, it is only in
// memory as a cache in hopes of being used again (avoiding a disk read).
// Any inode with reference count zero can be evicted from the table.
//
// In addition to having a reference count, inodes can be marked busy
// (just like bufs), meaning that some code has logically locked the
// inode, and others are not allowed to look at it.
// This locking can last for a long
// time (for example, if the inode is busy during a disk access),
// so we don't use spin locks. Instead, if a process wants to use
// a particular inode, it must sleep(ip) to wait for it to be not busy.
// See iget below.
//
// XXX Inodes with dev == 0 exist only in memory. They have no on-disk
// representation. This functionality is used to implement pipes.
struct
inode
inode
[
NINODE
];
struct
spinlock
inode_table_lock
;
...
...
@@ -61,6 +77,7 @@ balloc(uint dev)
return
b
;
}
// Free a disk block.
static
void
bfree
(
int
dev
,
uint
b
)
{
...
...
@@ -108,6 +125,10 @@ iget(uint dev, uint inum)
if
(
ip
->
count
>
0
&&
ip
->
dev
==
dev
&&
ip
->
inum
==
inum
){
if
(
ip
->
busy
){
sleep
(
ip
,
&
inode_table_lock
);
// Since we droped inode_table_lock, ip might have been reused
// for some other inode entirely. Must start the scan over,
// and hopefully this time we will find the inode we want
// and it will not be busy.
goto
loop
;
}
ip
->
count
++
;
...
...
@@ -142,6 +163,8 @@ iget(uint dev, uint inum)
return
nip
;
}
// Copy ip->d, which has changed, to disk.
// Caller must have locked ip.
void
iupdate
(
struct
inode
*
ip
)
{
...
...
@@ -160,6 +183,8 @@ iupdate(struct inode *ip)
brelse
(
bp
);
}
// Allocate a new inode with the given type
// from the file system on device dev.
struct
inode
*
ialloc
(
uint
dev
,
short
type
)
{
...
...
@@ -195,6 +220,7 @@ ialloc(uint dev, short type)
return
ip
;
}
// Free the given inode from its file system.
static
void
ifree
(
struct
inode
*
ip
)
{
...
...
@@ -202,6 +228,11 @@ ifree(struct inode *ip)
iupdate
(
ip
);
}
// Lock the given inode (wait for it to be not busy,
// and then ip->busy).
// Caller must already hold a reference to ip.
// Otherwise, if all the references to ip go away,
// it might be reused underfoot.
void
ilock
(
struct
inode
*
ip
)
{
...
...
@@ -217,8 +248,9 @@ ilock(struct inode *ip)
release
(
&
inode_table_lock
);
}
// caller is holding onto a reference to this inode, but no
// longer needs to examine or change it, so clear ip->busy.
// Caller holds reference to ip and has locked it.
// Caller no longer needs to examine / change it.
// Unlock it, but keep the reference.
void
iunlock
(
struct
inode
*
ip
)
{
...
...
@@ -233,6 +265,7 @@ iunlock(struct inode *ip)
release
(
&
inode_table_lock
);
}
// Return the disk block address of the nth block in inode ip.
uint
bmap
(
struct
inode
*
ip
,
uint
bn
)
{
...
...
@@ -259,6 +292,7 @@ bmap(struct inode *ip, uint bn)
return
x
;
}
// Truncate the inode ip, discarding all its data blocks.
void
itrunc
(
struct
inode
*
ip
)
{
...
...
@@ -286,8 +320,9 @@ itrunc(struct inode *ip)
iupdate
(
ip
);
}
// caller is releasing a reference to this inode.
// you must have the inode lock.
// Caller holds reference to ip and has locked it,
// possibly editing it.
// Release lock and drop the reference.
void
iput
(
struct
inode
*
ip
)
{
...
...
@@ -308,6 +343,8 @@ iput(struct inode *ip)
release
(
&
inode_table_lock
);
}
// Caller holds reference to ip but not lock.
// Drop reference.
void
idecref
(
struct
inode
*
ip
)
{
...
...
@@ -315,6 +352,7 @@ idecref(struct inode *ip)
iput
(
ip
);
}
// Increment reference count for ip.
void
iincref
(
struct
inode
*
ip
)
{
...
...
@@ -323,6 +361,8 @@ iincref(struct inode *ip)
iunlock
(
ip
);
}
// Copy stat information from inode.
// XXX Assumes inode is from disk file system.
void
stati
(
struct
inode
*
ip
,
struct
stat
*
st
)
{
...
...
@@ -335,6 +375,8 @@ stati(struct inode *ip, struct stat *st)
#define min(a, b) ((a) < (b) ? (a) : (b))
// Read data from inode.
// XXX Assumes inode is from disk file system.
int
readi
(
struct
inode
*
ip
,
char
*
dst
,
uint
off
,
uint
n
)
{
...
...
@@ -361,6 +403,7 @@ readi(struct inode *ip, char *dst, uint off, uint n)
return
target
-
n
;
}
// Allocate the nth block in inode ip if necessary.
static
int
newblock
(
struct
inode
*
ip
,
uint
lbn
)
{
...
...
@@ -396,6 +439,8 @@ newblock(struct inode *ip, uint lbn)
return
0
;
}
// Write data to inode.
// XXX Assumes inode is from disk file system.
int
writei
(
struct
inode
*
ip
,
char
*
addr
,
uint
off
,
uint
n
)
{
...
...
@@ -551,6 +596,8 @@ namei(char *path, int mode, uint *ret_off,
}
}
// Write a new directory entry (name, ino) into the directory dp.
// Caller must have locked dp.
void
wdir
(
struct
inode
*
dp
,
char
*
name
,
uint
ino
)
{
...
...
@@ -575,6 +622,8 @@ wdir(struct inode *dp, char *name, uint ino)
panic
(
"wdir write"
);
}
// Create the path cp and return its locked inode structure.
// If cp already exists, return 0.
struct
inode
*
mknod
(
char
*
cp
,
short
type
,
short
major
,
short
minor
)
{
...
...
@@ -591,6 +640,9 @@ mknod(char *cp, short type, short major, short minor)
return
ip
;
}
// Create a new inode named name inside dp
// and return its locked inode structure.
// If name already exists, return 0.
struct
inode
*
mknod1
(
struct
inode
*
dp
,
char
*
name
,
short
type
,
short
major
,
short
minor
)
{
...
...
@@ -611,6 +663,7 @@ mknod1(struct inode *dp, char *name, short type, short major, short minor)
return
ip
;
}
// Unlink the inode named cp.
int
unlink
(
char
*
cp
)
{
...
...
@@ -649,6 +702,7 @@ unlink(char *cp)
return
0
;
}
// Create the path new as a link to the same inode as old.
int
link
(
char
*
name1
,
char
*
name2
)
{
...
...
ide.c
浏览文件 @
bb207a1d
...
...
@@ -17,6 +17,12 @@
#define IDE_CMD_READ 0x20
#define IDE_CMD_WRITE 0x30
// IDE request queue.
// The next request will be stored in request[head],
// and the request currently being served by the disk
// is request[tail].
// Must hold ide_lock while manipulating queue.
struct
ide_request
{
int
diskno
;
uint
secno
;
...
...
@@ -28,6 +34,7 @@ struct ide_request {
struct
ide_request
request
[
NREQUEST
];
int
head
,
tail
;
struct
spinlock
ide_lock
;
int
disk_1_present
;
int
disk_channel
;
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论