1 /* The file system maintains a buffer cache to reduce the number of disk
2 * accesses needed. Whenever a read or write to the disk is done, a check is
3 * first made to see if the block is in the cache. This file manages the
6 * The entry points into this file are:
7 * get_block: request to fetch a block for reading or writing from cache
8 * put_block: return a block previously requested with get_block
11 * read_block: read physically the block
15 #include <minix/com.h>
16 #include <minix/u64.h>
19 FORWARD
_PROTOTYPE(int read_block
, (struct buf
*));
21 PUBLIC
struct buf
*bp_to_pickup
= buf
; /* This is a pointer to the next node in the
22 * buffer cache to pick up*/
25 /*===========================================================================*
27 *===========================================================================*/
28 PUBLIC
struct buf
*get_block(block
)
29 register block_t block
; /* which block is wanted? */
32 register struct buf
*bp
, *free_bp
;
36 /* Find if the block is already loaded */
37 for (bp
= &buf
[0]; bp
< &buf
[NR_BUFS
]; bp
++)
38 if (bp
->b_blocknr
== block
) {
39 /* Block found. Increment count and return it */
43 if (bp
== bp_to_pickup
) {
46 else /* Increment the node to pickup */
47 if (bp_to_pickup
< &buf
[NR_BUFS
] - 1)
53 if (free_bp
== NIL_BUF
&&
54 bp_to_pickup
== buf
&&
55 bp_to_pickup
->b_count
== 0)
56 free_bp
= bp_to_pickup
;
58 if (free_bp
!= NIL_BUF
) {
59 /* Set fields of data structure */
60 free_bp
->b_blocknr
= block
;
61 if (read_block(free_bp
) != OK
) return NIL_BUF
;
64 if (bp_to_pickup
< &buf
[NR_BUFS
] - 1)
71 /* No free blocks. Return NIL_BUF */
76 /*===========================================================================*
78 *===========================================================================*/
79 PUBLIC
void put_block(bp
)
80 register struct buf
*bp
; /* pointer to the buffer to be released */
82 if (bp
== NIL_BUF
) return; /* it is easier to check here than in caller */
84 bp
->b_count
--; /* there is one use fewer now */
87 /*===========================================================================*
89 *===========================================================================*/
90 PRIVATE
int read_block(bp
)
91 register struct buf
*bp
; /* buffer pointer */
97 block_size
= v_pri
.logical_block_size_l
; /* The block size is indicated by
101 pos
= mul64u(bp
->b_blocknr
, block_size
); /* get absolute position */
102 op
= MFS_DEV_READ
; /* flag to read */
103 r
= block_dev_io(op
, fs_dev
, SELF_E
, bp
->b_data
, pos
, block_size
, 0);
104 if (r
!= block_size
) {
105 if (r
>= 0) r
= END_OF_FILE
;
106 if (r
!= END_OF_FILE
)
107 printf("ISOFS(%d) I/O error on device %d/%d, block %ld\n",
108 SELF_E
, (fs_dev
>>MAJOR
)&BYTE
, (fs_dev
>>MINOR
)&BYTE
,