tar: use utime() to restore timestamps
[minix.git] / servers / mfs / cache.c
blob147332c40e7e233b2cb3d43fabc79b86866cf936
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
9 * alloc_zone: allocate a new zone (to increase the length of a file)
10 * free_zone: release a zone (when a file is removed)
11 * invalidate: remove all the cache blocks on some device
13 * Private functions:
14 * read_block: read or write a block from the disk itself
17 #include "fs.h"
18 #include <minix/u64.h>
19 #include <minix/bdev.h>
20 #include <sys/param.h>
21 #include <stdlib.h>
22 #include <assert.h>
23 #include <minix/libminixfs.h>
24 #include <math.h>
25 #include "buf.h"
26 #include "super.h"
27 #include "inode.h"
29 /*===========================================================================*
30 * alloc_zone *
31 *===========================================================================*/
32 zone_t alloc_zone(
33 dev_t dev, /* device where zone wanted */
34 zone_t z /* try to allocate new zone near this one */
37 /* Allocate a new zone on the indicated device and return its number. */
39 bit_t b, bit;
40 struct super_block *sp;
41 static int print_oos_msg = 1;
43 /* Note that the routine alloc_bit() returns 1 for the lowest possible
44 * zone, which corresponds to sp->s_firstdatazone. To convert a value
45 * between the bit number, 'b', used by alloc_bit() and the zone number, 'z',
46 * stored in the inode, use the formula:
47 * z = b + sp->s_firstdatazone - 1
48 * Alloc_bit() never returns 0, since this is used for NO_BIT (failure).
50 sp = get_super(dev);
52 /* If z is 0, skip initial part of the map known to be fully in use. */
53 if (z == sp->s_firstdatazone) {
54 bit = sp->s_zsearch;
55 } else {
56 bit = (bit_t) (z - (sp->s_firstdatazone - 1));
58 b = alloc_bit(sp, ZMAP, bit);
59 if (b == NO_BIT) {
60 err_code = ENOSPC;
61 if (print_oos_msg)
62 printf("No space on device %d/%d\n", major(sp->s_dev),
63 minor(sp->s_dev));
64 print_oos_msg = 0; /* Don't repeat message */
65 return(NO_ZONE);
67 print_oos_msg = 1;
68 if (z == sp->s_firstdatazone) sp->s_zsearch = b; /* for next time */
69 return( (zone_t) (sp->s_firstdatazone - 1) + (zone_t) b);
72 /*===========================================================================*
73 * free_zone *
74 *===========================================================================*/
75 void free_zone(
76 dev_t dev, /* device where zone located */
77 zone_t numb /* zone to be returned */
80 /* Return a zone. */
82 register struct super_block *sp;
83 bit_t bit;
85 /* Locate the appropriate super_block and return bit. */
86 sp = get_super(dev);
87 if (numb < sp->s_firstdatazone || numb >= sp->s_zones) return;
88 bit = (bit_t) (numb - (zone_t) (sp->s_firstdatazone - 1));
89 free_bit(sp, ZMAP, bit);
90 if (bit < sp->s_zsearch) sp->s_zsearch = bit;