
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
99 lines
2.3 KiB
C
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);
|
|
}
|