panic() cleanup.
[minix.git] / servers / iso9660fs / cache.c
blob990aa190dbabbac011af1736dbea617f5e59768b
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
4 * cache.
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
10 * Private functions:
11 * read_block: read physically the block
14 #include "inc.h"
15 #include <minix/com.h>
16 #include <minix/u64.h>
17 #include "buf.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 /*===========================================================================*
26 * get_block *
27 *===========================================================================*/
28 PUBLIC struct buf *get_block(block)
29 register block_t block; /* which block is wanted? */
31 int b;
32 register struct buf *bp, *free_bp;
34 free_bp = NIL_BUF;
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 */
40 bp->b_count++;
41 return bp;
42 } else
43 if (bp == bp_to_pickup) {
44 if (bp->b_count == 0)
45 free_bp = bp;
46 else /* Increment the node to pickup */
47 if (bp_to_pickup < &buf[NR_BUFS] - 1)
48 bp_to_pickup++;
49 else
50 bp_to_pickup = buf;
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;
62 free_bp->b_count = 1;
64 if (bp_to_pickup < &buf[NR_BUFS] - 1)
65 bp_to_pickup++;
66 else
67 bp_to_pickup = buf;
69 return free_bp;
70 } else {
71 /* No free blocks. Return NIL_BUF */
72 return NIL_BUF;
76 /*===========================================================================*
77 * put_block *
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 /*===========================================================================*
88 * read_block *
89 *===========================================================================*/
90 PRIVATE int read_block(bp)
91 register struct buf *bp; /* buffer pointer */
93 int r, op;
94 u64_t pos;
95 int block_size;
97 block_size = v_pri.logical_block_size_l; /* The block size is indicated by
98 * the superblock */
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,
109 bp->b_blocknr);
111 rdwt_err = r;
112 return EINVAL;
115 return OK;