/* vdev.c - for 415.340 and 415.341 Assignment 2 Provides the virtual device layer. Written by Robert Sheehan - 27/07/96 */ #include #include #include #include #include #include #include "vdev.h" #define NUMBLOCKS 64 /* a very small device */ #define BLOCKSIZE 256 /* small block size */ int vdev; /* file descriptor for the virtual file system */ /*------------------------------------------------------------*/ void sysErrMsg(const char *message) /* Shows the error message and quits. */ { extern int errno, sys_nerr; fprintf(stderr, "System error: %d - ", errno); if (errno > 0 && errno < sys_nerr) perror(message); else fprintf(stderr, "%s\n", message); exit(1); } /*------------------------------------------------------------*/ void vdev_init() /* Initialises the virtual device. If the device doesn't exist it is created. */ { struct stat vdevStat; char blankblock[BLOCKSIZE]; int block; if ((vdev = open("vdev", O_RDWR | O_CREAT, 0600)) == -1) sysErrMsg("Can't open the \"vdev\"."); if (fstat(vdev, &vdevStat) == -1) sysErrMsg("Can't stat the \"vdev\"."); if (vdevStat.st_size == 0){ printf("\"vdev\" is empty.\n"); memset(blankblock, 0, BLOCKSIZE); for (block = 0; block < NUMBLOCKS; block++) if (write(vdev, blankblock, BLOCKSIZE) < BLOCKSIZE) sysErrMsg("Writing the \"vdev\"."); } } /*------------------------------------------------------------*/ int vdev_blockread(const int blocknum, void *blockbuf) /* Reads "blocknum" from the vdev and returns the data in "blockbuf". Possible errors are in vdev.h */ { if (blocknum < 0 || blocknum >= NUMBLOCKS) return VDBADBLOCK; /* should really check "blockbuf" as well */ if (lseek(vdev, blocknum * BLOCKSIZE, SEEK_SET) == -1) return VDBADDEV; if (read(vdev, blockbuf, BLOCKSIZE) != BLOCKSIZE) return VDBADDEV; return VDOK; } /*------------------------------------------------------------*/ int vdev_blockwrite(const int blocknum, const void *blockbuf) /* Writes the contents of "blockbuf" into "blocknum" on the vdev. Possible errors are in vdev.h */ { if (blocknum < 0 || blocknum >= NUMBLOCKS) return VDBADBLOCK; /* should really check "blockbuf" as well */ if (lseek(vdev, blocknum * BLOCKSIZE, SEEK_SET) == -1) return VDBADDEV; if (write(vdev, blockbuf, BLOCKSIZE) != BLOCKSIZE) return VDBADDEV; return VDOK; } /*------------------------------------------------------------*/ int vdev_numblocks() /* Returns the number of blocks on the vdev. */ { return NUMBLOCKS; } /*------------------------------------------------------------*/ int vdev_blocksize() /* Returns the number of blocks on the vdev. */ { return BLOCKSIZE; }