Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
CSEP551
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Krishna Vinnakota
CSEP551
Commits
bb207a1d
Commit
bb207a1d
authored
18 years ago
by
rsc
Browse files
Options
Downloads
Patches
Plain Diff
comments
parent
52253dce
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
bio.c
+37
-4
37 additions, 4 deletions
bio.c
file.c
+5
-6
5 additions, 6 deletions
file.c
fs.c
+60
-6
60 additions, 6 deletions
fs.c
ide.c
+7
-0
7 additions, 0 deletions
ide.c
with
109 additions
and
16 deletions
bio.c
+
37
−
4
View file @
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
(
"get
blk
: no buffers"
);
panic
(
"
b
get: 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
=
get
blk
(
dev
,
sector
);
b
=
b
get
(
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
)
{
...
...
This diff is collapsed.
Click to expand it.
file.c
+
5
−
6
View file @
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
)
{
...
...
This diff is collapsed.
Click to expand it.
fs.c
+
60
−
6
View file @
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
)
{
...
...
This diff is collapsed.
Click to expand it.
ide.c
+
7
−
0
View file @
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
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment