You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

97 lines
2.4 KiB

/* rdswrite.c - rdswrite */
#include <xinu.h>
/*------------------------------------------------------------------------
* rdswrite - Write a block to a remote disk
*------------------------------------------------------------------------
*/
devcall rdswrite (
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer that holds a disk blk */
int32 blk /* Block number to write */
)
{
struct rdscblk *rdptr; /* Pointer to control block */
struct rdbuff *bptr; /* Pointer to buffer on a list */
struct rdbuff *pptr; /* Ptr to previous buff on list */
struct rdbuff *nptr; /* Ptr to next buffer on list */
bool8 found; /* Was buff found during search?*/
/* If device not currently in use, report an error */
rdptr = &rdstab[devptr->dvminor];
if (rdptr->rd_state != RD_OPEN) {
return SYSERR;
}
/* Ensure rdsprocess is runnning */
if ( ! rdptr->rd_comruns ) {
rdptr->rd_comruns = TRUE;
resume(rdptr->rd_comproc);
}
/* If request queue already contains a write request */
/* for the block, replace the contents */
bptr = rdptr->rd_rhnext;
while (bptr != (struct rdbuff *)&rdptr->rd_rtnext) {
if ( (bptr->rd_blknum == blk) &&
(bptr->rd_op == RD_OP_WRITE) ) {
memcpy(bptr->rd_block, buff, RD_BLKSIZ);
return OK;
}
bptr = bptr->rd_next;
}
/* Search cache for cached copy of block */
bptr = rdptr->rd_chnext;
found = FALSE;
while (bptr != (struct rdbuff *)&rdptr->rd_ctnext) {
if (bptr->rd_blknum == blk) {
if (bptr->rd_refcnt <= 0) {
pptr = bptr->rd_prev;
nptr = bptr->rd_next;
/* Unlink node from cache list and reset*/
/* the available semaphore accordingly*/
pptr->rd_next = bptr->rd_next;
nptr->rd_prev = bptr->rd_prev;
semreset(rdptr->rd_availsem,
semcount(rdptr->rd_availsem) - 1);
found = TRUE;
}
break;
}
bptr = bptr->rd_next;
}
if ( !found ) {
bptr = rdsbufalloc(rdptr);
}
/* Create a write request */
memcpy(bptr->rd_block, buff, RD_BLKSIZ);
bptr->rd_op = RD_OP_WRITE;
bptr->rd_refcnt = 0;
bptr->rd_blknum = blk;
bptr->rd_status = RD_VALID;
bptr->rd_pid = getpid();
/* Insert new request into list just before tail */
pptr = rdptr->rd_rtprev;
rdptr->rd_rtprev = bptr;
bptr->rd_next = pptr->rd_next;
bptr->rd_prev = pptr;
pptr->rd_next = bptr;
/* Signal semaphore to start communication process */
signal(rdptr->rd_reqsem);
return OK;
}