Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
O
osv
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
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
Verlässliche Systemsoftware
projects
osv
Commits
7ffc51ae
Commit
7ffc51ae
authored
12 years ago
by
Christoph Hellwig
Browse files
Options
Downloads
Patches
Plain Diff
add vfs_bio.c from prex
parent
2fa43ca5
No related branches found
No related tags found
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
build.mak
+1
-0
1 addition, 0 deletions
build.mak
fs/vfs/main.c
+2
-0
2 additions, 0 deletions
fs/vfs/main.c
fs/vfs/vfs_bio.c
+405
-0
405 additions, 0 deletions
fs/vfs/vfs_bio.c
include/osv/buf.h
+71
-0
71 additions, 0 deletions
include/osv/buf.h
include/osv/prex.h
+0
-1
0 additions, 1 deletion
include/osv/prex.h
with
479 additions
and
1 deletion
build.mak
+
1
−
0
View file @
7ffc51ae
...
...
@@ -102,6 +102,7 @@ fs = fs/fs.o bootfs.o
fs
+=
fs/vfs/main.o
\
fs/vfs/kern_physio.o
\
fs/vfs/subr_uio.o
\
fs/vfs/vfs_bio.o
\
fs/vfs/vfs_conf.o
\
fs/vfs/vfs_lookup.o
\
fs/vfs/vfs_mount.o
\
...
...
This diff is collapsed.
Click to expand it.
fs/vfs/main.c
+
2
−
0
View file @
7ffc51ae
...
...
@@ -1145,6 +1145,7 @@ void mount_rootfs(void)
}
int
console_init
(
void
);
void
bio_init
(
void
);
int
vfs_initialized
;
...
...
@@ -1153,6 +1154,7 @@ vfs_init(void)
{
const
struct
vfssw
*
fs
;
bio_init
();
vnode_init
();
task_alloc
(
&
main_task
);
console_init
();
...
...
This diff is collapsed.
Click to expand it.
fs/vfs/vfs_bio.c
0 → 100755
+
405
−
0
View file @
7ffc51ae
/*
* Copyright (c) 2005-2007, Kohsuke Ohtani
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* vfs_bio.c - buffered I/O operations
*/
/*
* References:
* Bach: The Design of the UNIX Operating System (Prentice Hall, 1986)
*/
#include
<osv/prex.h>
#include
<osv/list.h>
#include
<osv/buf.h>
#include
<osv/bio.h>
#include
<osv/device.h>
#include
<errno.h>
#include
<limits.h>
#include
<unistd.h>
#include
<stdlib.h>
#include
<string.h>
#include
<semaphore.h>
#include
"vfs.h"
/* number of buffer cache */
#define NBUFS 256
/* macros to clear/set/test flags. */
#define SET(t, f) (t) |= (f)
#define CLR(t, f) (t) &= ~(f)
#define ISSET(t, f) ((t) & (f))
/*
* Global lock to access all buffer headers and lists.
*/
static
mutex_t
bio_lock
=
MUTEX_INITIALIZER
;
#define BIO_LOCK() mutex_lock(&bio_lock)
#define BIO_UNLOCK() mutex_unlock(&bio_lock)
/* fixed set of buffers */
static
struct
buf
buf_table
[
NBUFS
];
static
struct
list_head
free_list
=
LIST_INIT
(
free_list
);
static
sem_t
free_sem
;
/*
* Insert buffer to the head of free list
*/
static
void
bio_insert_head
(
struct
buf
*
bp
)
{
list_insert
(
&
free_list
,
&
bp
->
b_link
);
sem_post
(
&
free_sem
);
}
/*
* Insert buffer to the tail of free list
*/
static
void
bio_insert_tail
(
struct
buf
*
bp
)
{
list_insert
(
list_prev
(
&
free_list
),
&
bp
->
b_link
);
sem_post
(
&
free_sem
);
}
/*
* Remove buffer from free list
*/
static
void
bio_remove
(
struct
buf
*
bp
)
{
sem_wait
(
&
free_sem
);
ASSERT
(
!
list_empty
(
&
free_list
));
list_remove
(
&
bp
->
b_link
);
}
/*
* Remove buffer from the head of free list
*/
static
struct
buf
*
bio_remove_head
(
void
)
{
struct
buf
*
bp
;
sem_wait
(
&
free_sem
);
ASSERT
(
!
list_empty
(
&
free_list
));
bp
=
list_entry
(
list_first
(
&
free_list
),
struct
buf
,
b_link
);
list_remove
(
&
bp
->
b_link
);
return
bp
;
}
static
int
rw_buf
(
struct
buf
*
bp
,
int
rw
)
{
struct
bio
*
bio
;
bio
=
alloc_bio
();
if
(
!
bio
)
return
ENOMEM
;
bio
->
bio_cmd
=
rw
?
BIO_WRITE
:
BIO_READ
;
bio
->
bio_dev
=
bp
->
b_dev
;
bio
->
bio_data
=
bp
->
b_data
;
bio
->
bio_offset
=
bp
->
b_blkno
<<
9
;
bio
->
bio_bcount
=
BSIZE
;
bio
->
bio_dev
->
driver
->
devops
->
strategy
(
bio
);
pthread_mutex_lock
(
&
bio
->
bio_mutex
);
while
(
!
(
bio
->
bio_flags
&
BIO_DONE
))
pthread_cond_wait
(
&
bio
->
bio_wait
,
&
bio
->
bio_mutex
);
pthread_mutex_unlock
(
&
bio
->
bio_mutex
);
destroy_bio
(
bio
);
return
0
;
}
/*
* Determine if a block is in the cache.
*/
static
struct
buf
*
incore
(
struct
device
*
dev
,
int
blkno
)
{
struct
buf
*
bp
;
int
i
;
for
(
i
=
0
;
i
<
NBUFS
;
i
++
)
{
bp
=
&
buf_table
[
i
];
if
(
bp
->
b_blkno
==
blkno
&&
bp
->
b_dev
==
dev
&&
!
ISSET
(
bp
->
b_flags
,
B_INVAL
))
return
bp
;
}
return
NULL
;
}
/*
* Assign a buffer for the given block.
*
* The block is selected from the buffer list with LRU
* algorithm. If the appropriate block already exists in the
* block list, return it. Otherwise, the least recently used
* block is used.
*/
struct
buf
*
getblk
(
struct
device
*
dev
,
int
blkno
)
{
struct
buf
*
bp
;
DPRINTF
(
VFSDB_BIO
,
(
"getblk: dev=%x blkno=%d
\n
"
,
dev
,
blkno
));
start:
BIO_LOCK
();
bp
=
incore
(
dev
,
blkno
);
if
(
bp
!=
NULL
)
{
/* Block found in cache. */
if
(
ISSET
(
bp
->
b_flags
,
B_BUSY
))
{
/*
* Wait buffer ready.
*/
BIO_UNLOCK
();
mutex_lock
(
&
bp
->
b_lock
);
mutex_unlock
(
&
bp
->
b_lock
);
/* Scan again if it's busy */
goto
start
;
}
bio_remove
(
bp
);
SET
(
bp
->
b_flags
,
B_BUSY
);
}
else
{
bp
=
bio_remove_head
();
if
(
ISSET
(
bp
->
b_flags
,
B_DELWRI
))
{
BIO_UNLOCK
();
bwrite
(
bp
);
goto
start
;
}
bp
->
b_flags
=
B_BUSY
;
bp
->
b_dev
=
dev
;
bp
->
b_blkno
=
blkno
;
}
mutex_lock
(
&
bp
->
b_lock
);
BIO_UNLOCK
();
DPRINTF
(
VFSDB_BIO
,
(
"getblk: done bp=%x
\n
"
,
bp
));
return
bp
;
}
/*
* Release a buffer, with no I/O implied.
*/
void
brelse
(
struct
buf
*
bp
)
{
ASSERT
(
ISSET
(
bp
->
b_flags
,
B_BUSY
));
DPRINTF
(
VFSDB_BIO
,
(
"brelse: bp=%x dev=%x blkno=%d
\n
"
,
bp
,
bp
->
b_dev
,
bp
->
b_blkno
));
BIO_LOCK
();
CLR
(
bp
->
b_flags
,
B_BUSY
);
mutex_unlock
(
&
bp
->
b_lock
);
if
(
ISSET
(
bp
->
b_flags
,
B_INVAL
))
bio_insert_head
(
bp
);
else
bio_insert_tail
(
bp
);
BIO_UNLOCK
();
}
/*
* Block read with cache.
* @dev: device id to read from.
* @blkno: block number.
* @buf: buffer pointer to be returned.
*
* An actual read operation is done only when the cached
* buffer is dirty.
*/
int
bread
(
struct
device
*
dev
,
int
blkno
,
struct
buf
**
bpp
)
{
struct
buf
*
bp
;
size_t
size
;
int
error
;
DPRINTF
(
VFSDB_BIO
,
(
"bread: dev=%x blkno=%d
\n
"
,
dev
,
blkno
));
bp
=
getblk
(
dev
,
blkno
);
if
(
!
ISSET
(
bp
->
b_flags
,
(
B_DONE
|
B_DELWRI
)))
{
size
=
BSIZE
;
error
=
rw_buf
(
bp
,
0
);
if
(
error
)
{
DPRINTF
(
VFSDB_BIO
,
(
"bread: i/o error
\n
"
));
brelse
(
bp
);
return
error
;
}
}
CLR
(
bp
->
b_flags
,
B_INVAL
);
SET
(
bp
->
b_flags
,
(
B_READ
|
B_DONE
));
DPRINTF
(
VFSDB_BIO
,
(
"bread: done bp=%x
\n\n
"
,
bp
));
*
bpp
=
bp
;
return
0
;
}
/*
* Block write with cache.
* @buf: buffer to write.
*
* The data is copied to the buffer.
* Then release the buffer.
*/
int
bwrite
(
struct
buf
*
bp
)
{
size_t
size
;
int
error
;
ASSERT
(
ISSET
(
bp
->
b_flags
,
B_BUSY
));
DPRINTF
(
VFSDB_BIO
,
(
"bwrite: dev=%x blkno=%d
\n
"
,
bp
->
b_dev
,
bp
->
b_blkno
));
BIO_LOCK
();
CLR
(
bp
->
b_flags
,
(
B_READ
|
B_DONE
|
B_DELWRI
));
BIO_UNLOCK
();
size
=
BSIZE
;
error
=
rw_buf
(
bp
,
1
);
if
(
error
)
return
error
;
BIO_LOCK
();
SET
(
bp
->
b_flags
,
B_DONE
);
BIO_UNLOCK
();
brelse
(
bp
);
return
0
;
}
/*
* Delayed write.
*
* The buffer is marked dirty, but an actual I/O is not
* performed. This routine should be used when the buffer
* is expected to be modified again soon.
*/
void
bdwrite
(
struct
buf
*
bp
)
{
BIO_LOCK
();
SET
(
bp
->
b_flags
,
B_DELWRI
);
CLR
(
bp
->
b_flags
,
B_DONE
);
BIO_UNLOCK
();
brelse
(
bp
);
}
/*
* Flush write-behind block
*/
void
bflush
(
struct
buf
*
bp
)
{
BIO_LOCK
();
if
(
ISSET
(
bp
->
b_flags
,
B_DELWRI
))
bwrite
(
bp
);
BIO_UNLOCK
();
}
/*
* Invalidate buffer for specified device.
* This is called when unmount.
*/
void
binval
(
struct
device
*
dev
)
{
struct
buf
*
bp
;
int
i
;
BIO_LOCK
();
for
(
i
=
0
;
i
<
NBUFS
;
i
++
)
{
bp
=
&
buf_table
[
i
];
if
(
bp
->
b_dev
==
dev
)
{
if
(
ISSET
(
bp
->
b_flags
,
B_DELWRI
))
bwrite
(
bp
);
else
if
(
ISSET
(
bp
->
b_flags
,
B_BUSY
))
brelse
(
bp
);
bp
->
b_flags
=
B_INVAL
;
}
}
BIO_UNLOCK
();
}
/*
* Invalidate all buffers.
* This is called when unmount.
*/
void
bio_sync
(
void
)
{
struct
buf
*
bp
;
int
i
;
start:
BIO_LOCK
();
for
(
i
=
0
;
i
<
NBUFS
;
i
++
)
{
bp
=
&
buf_table
[
i
];
if
(
ISSET
(
bp
->
b_flags
,
B_BUSY
))
{
BIO_UNLOCK
();
mutex_lock
(
&
bp
->
b_lock
);
mutex_unlock
(
&
bp
->
b_lock
);
goto
start
;
}
if
(
ISSET
(
bp
->
b_flags
,
B_DELWRI
))
bwrite
(
bp
);
}
BIO_UNLOCK
();
}
/*
* Initialize the buffer I/O system.
*/
void
bio_init
(
void
)
{
struct
buf
*
bp
;
int
i
;
for
(
i
=
0
;
i
<
NBUFS
;
i
++
)
{
bp
=
&
buf_table
[
i
];
bp
->
b_flags
=
B_INVAL
;
bp
->
b_data
=
malloc
(
BSIZE
);
mutex_init
(
&
bp
->
b_lock
);
list_insert
(
&
free_list
,
&
bp
->
b_link
);
}
sem_init
(
&
free_sem
,
0
,
NBUFS
);
DPRINTF
(
VFSDB_BIO
,
(
"bio: Buffer cache size %dK bytes
\n
"
,
BSIZE
*
NBUFS
/
1024
));
}
This diff is collapsed.
Click to expand it.
include/osv/buf.h
0 → 100755
+
71
−
0
View file @
7ffc51ae
/*-
* Copyright (c) 2005-2007, Kohsuke Ohtani
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _SYS_BUF_H_
#define _SYS_BUF_H_
#include
<sys/types.h>
#include
<sys/cdefs.h>
#include
<osv/list.h>
#include
<osv/mutex.h>
/*
* Buffer header
*/
struct
buf
{
struct
list_head
b_link
;
/* link to block list */
int
b_flags
;
/* see defines below */
struct
device
*
b_dev
;
/* device */
int
b_blkno
;
/* block # on device */
mutex_t
b_lock
;
/* lock for access */
char
*
b_data
;
/* pointer to data buffer */
};
/*
* These flags are kept in b_flags.
*/
#define B_BUSY 0x00000001
/* I/O in progress. */
#define B_DELWRI 0x00000002
/* delay I/O until buffer reused. */
#define B_INVAL 0x00000004
/* does not contain valid info. */
#define B_READ 0x00000008
/* read buffer. */
#define B_DONE 0x00000010
/* I/O completed. */
__BEGIN_DECLS
struct
buf
*
getblk
(
struct
device
*
,
int
);
int
bread
(
struct
device
*
,
int
,
struct
buf
**
);
int
bwrite
(
struct
buf
*
);
void
bdwrite
(
struct
buf
*
);
void
binval
(
struct
device
*
);
void
brelse
(
struct
buf
*
);
void
bflush
(
struct
buf
*
);
void
bio_sync
(
void
);
void
bio_init
(
void
);
__END_DECLS
#endif
/* !_SYS_BUF_H_ */
This diff is collapsed.
Click to expand it.
include/osv/prex.h
+
0
−
1
View file @
7ffc51ae
...
...
@@ -24,7 +24,6 @@ __BEGIN_DECLS
#define PAGE_MASK (PAGE_SIZE-1)
#define round_page(x) (((x) + PAGE_MASK) & ~PAGE_MASK)
size_t
strlcat
(
char
*
dst
,
const
char
*
src
,
size_t
siz
);
size_t
strlcpy
(
char
*
dst
,
const
char
*
src
,
size_t
siz
);
...
...
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