104 lines
2.4 KiB
C
104 lines
2.4 KiB
C
|
#include "fs.h"
|
||
|
#include "buf.h"
|
||
|
#include "inode.h"
|
||
|
#include <sys/types.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
FORWARD _PROTOTYPE( struct buf *new_block, (dev_t dev, ino_t inum) );
|
||
|
|
||
|
/*===========================================================================*
|
||
|
* buf_pool *
|
||
|
*===========================================================================*/
|
||
|
PUBLIC void buf_pool(void)
|
||
|
{
|
||
|
/* Initialize the buffer pool. */
|
||
|
|
||
|
front = NULL;
|
||
|
rear = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*===========================================================================*
|
||
|
* get_block *
|
||
|
*===========================================================================*/
|
||
|
PUBLIC struct buf *get_block(dev_t dev, ino_t inum)
|
||
|
{
|
||
|
struct buf *bp = front;
|
||
|
|
||
|
while(bp != NULL) {
|
||
|
if (bp->b_dev == dev && bp->b_num == inum) {
|
||
|
bp->b_count++;
|
||
|
return(bp);
|
||
|
}
|
||
|
bp = bp->b_next;
|
||
|
}
|
||
|
|
||
|
/* Buffer was not found. Try to allocate a new one */
|
||
|
return new_block(dev, inum);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*===========================================================================*
|
||
|
* new_block *
|
||
|
*===========================================================================*/
|
||
|
PRIVATE struct buf *new_block(dev_t dev, ino_t inum)
|
||
|
{
|
||
|
/* Allocate a new buffer and add it to the double linked buffer list */
|
||
|
struct buf *bp;
|
||
|
|
||
|
bp = malloc(sizeof(struct buf));
|
||
|
if (bp == NULL) {
|
||
|
err_code = ENOSPC;
|
||
|
return(NULL);
|
||
|
}
|
||
|
bp->b_num = inum;
|
||
|
bp->b_dev = dev;
|
||
|
bp->b_bytes = 0;
|
||
|
bp->b_count = 1;
|
||
|
memset(bp->b_data, 0 , PIPE_BUF);
|
||
|
|
||
|
/* Add at the end of the buffer */
|
||
|
if (front == NULL) { /* Empty list? */
|
||
|
front = bp;
|
||
|
bp->b_prev = NULL;
|
||
|
} else {
|
||
|
rear->b_next = bp;
|
||
|
bp->b_prev = rear;
|
||
|
}
|
||
|
bp->b_next = NULL;
|
||
|
rear = bp;
|
||
|
|
||
|
return(bp);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*===========================================================================*
|
||
|
* put_block *
|
||
|
*===========================================================================*/
|
||
|
PUBLIC void put_block(dev_t dev, ino_t inum)
|
||
|
{
|
||
|
struct buf *bp;
|
||
|
|
||
|
bp = get_block(dev, inum);
|
||
|
if (bp == NULL) return; /* We didn't find the block. Nothing to put. */
|
||
|
|
||
|
bp->b_count--; /* Compensate for above 'get_block'. */
|
||
|
if (--bp->b_count > 0) return;
|
||
|
|
||
|
/* Cut bp out of the loop */
|
||
|
if (bp->b_prev == NULL)
|
||
|
front = bp->b_next;
|
||
|
else
|
||
|
bp->b_prev->b_next = bp->b_next;
|
||
|
|
||
|
if (bp->b_next == NULL)
|
||
|
rear = bp->b_prev;
|
||
|
else
|
||
|
bp->b_next->b_prev = bp->b_prev;
|
||
|
|
||
|
/* Buffer administration is done. Now it's safe to free up bp. */
|
||
|
free(bp);
|
||
|
}
|