phunix/minix/fs/pfs/buffer.c
David van Moolenbroek f859061eaf PFS: use libfsdriver
In order to avoid creating libfsdriver exceptions, two changes to VFS
are necessary:

- the returned position field for reads/writes is no longer abused to
  return the new pipe size; VFS is perfectly capable of updating the
  size itself;
- during system startup, PFS is now sent a mount request, just like all
  other file systems.

In proper "two steps forward, one step back" fashion, the latter point
has the consequence that PFS can no longer drop its privileges at
startup.  This is probably best resolved with a more general solution
for all boot image system services.  The upside is that PFS no longer
needs to be linked with libc.

Change-Id: I92e2410cdb0d93d0e6107bae10bc08efc2dbb8b3
2014-09-18 12:46:28 +00:00

99 lines
2.3 KiB
C

#include "fs.h"
static struct buf *new_block(dev_t dev, ino_t inum);
/*===========================================================================*
* buf_pool *
*===========================================================================*/
void buf_pool(void)
{
/* Initialize the buffer pool. */
front = NULL;
rear = NULL;
}
/*===========================================================================*
* get_block *
*===========================================================================*/
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 *
*===========================================================================*/
static 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 *
*===========================================================================*/
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);
}