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 contains some
4 * related routines, but the cache is now in libminixfs.
9 #include <minix/bdev.h>
10 #include <sys/param.h>
13 #include <minix/libminixfs.h>
19 /*===========================================================================*
21 *===========================================================================*/
22 struct buf
*get_block(dev_t dev
, block_t block
, int how
)
24 /* Wrapper routine for lmfs_get_block(). This MFS implementation does not deal
25 * well with block read errors pretty much anywhere. To prevent corruption due
26 * to unchecked error conditions, we panic upon an I/O failure here.
31 if ((r
= lmfs_get_block(&bp
, dev
, block
, how
)) != OK
&& r
!= ENOENT
)
32 panic("MFS: error getting block (%llu,%u): %d", dev
, block
, r
);
34 assert(r
== OK
|| how
== PEEK
);
36 return (r
== OK
) ? bp
: NULL
;
39 /*===========================================================================*
41 *===========================================================================*/
43 dev_t dev
, /* device where zone wanted */
44 zone_t z
/* try to allocate new zone near this one */
47 /* Allocate a new zone on the indicated device and return its number. */
50 struct super_block
*sp
;
51 static int print_oos_msg
= 1;
53 /* Note that the routine alloc_bit() returns 1 for the lowest possible
54 * zone, which corresponds to sp->s_firstdatazone. To convert a value
55 * between the bit number, 'b', used by alloc_bit() and the zone number, 'z',
56 * stored in the inode, use the formula:
57 * z = b + sp->s_firstdatazone - 1
58 * Alloc_bit() never returns 0, since this is used for NO_BIT (failure).
62 /* If z is 0, skip initial part of the map known to be fully in use. */
63 if (z
== sp
->s_firstdatazone
) {
66 bit
= (bit_t
) (z
- (sp
->s_firstdatazone
- 1));
68 b
= alloc_bit(sp
, ZMAP
, bit
);
72 printf("No space on device %d/%d\n", major(sp
->s_dev
),
74 print_oos_msg
= 0; /* Don't repeat message */
78 if (z
== sp
->s_firstdatazone
) sp
->s_zsearch
= b
; /* for next time */
79 return( (zone_t
) (sp
->s_firstdatazone
- 1) + (zone_t
) b
);
82 /*===========================================================================*
84 *===========================================================================*/
86 dev_t dev
, /* device where zone located */
87 zone_t numb
/* zone to be returned */
92 register struct super_block
*sp
;
95 /* Locate the appropriate super_block and return bit. */
97 if (numb
< sp
->s_firstdatazone
|| numb
>= sp
->s_zones
) return;
98 bit
= (bit_t
) (numb
- (zone_t
) (sp
->s_firstdatazone
- 1));
99 free_bit(sp
, ZMAP
, bit
);
100 if (bit
< sp
->s_zsearch
) sp
->s_zsearch
= bit
;
102 /* Also tell libminixfs, so that 1) if it has a block for this bit, it can
103 * mark it as clean, thus reducing useless writes, and 2) it can tell VM that
104 * any previous inode association is to be broken for this block, so that the
105 * block will not be mapped in erroneously later on.
107 assert(sp
->s_log_zone_size
== 0); /* otherwise we need a loop here.. */
108 lmfs_free_block(dev
, (block_t
)numb
);