Question
implement the below functions in C language based on the below instructions: The file system will have just a single directory, i.e., root directory, so
implement the below functions in C language based on the below instructions:
The file system will have just a single directory, i.e., root directory, so that it will be simple to implement. No subdirectories are supported. The block size will be 2 KB (2048 bytes). Block 0 (first block) will contain super-block information (i.e., volume information). There is no boot block. File allocation table (FAT) method will be used to keep track of the disk blocks allocated to files and also the disk blocks that are free. The size of an entry in the FAT will be 4 bytes. The FAT will occupy 32 disk blocks. Hence, the number of entries in the FAT can be at most (2048/4) 32 = 16384. The maximum disk size that we may specify will be 2^23 bytes (8 MB). The minimum disk size that we may specify will be 2^18 bytes (256 KB). We will not specify a disk size outside this interval. The next 8 blocks will contain the root directory. Fixed sized directory entries will be used. Directory entry size is 128 bytes. That means each disk block can hold 16 directory entries. In this way we can have at most 16 8 = 128 directory entries; hence the file system can store at most 128 files in the disk. Maximum filename is 30 characters long. A directory entry for a file will contain the filename, the size of the file, the start data block number, and also some other attributes that you think are necessary. Hence, the first 1 + 32 + 8 = 41 blocks of the disk will contain metadata. The remaining blocks can be used to store file data (considered as data blocks). Assume, a process can open at most 16 files simultaneously. Hence your library should have an open file table with 16 entries. The rest is up to you: for example, what to store in the superblock, what else to store in a directory entry, what to store in an open file table entry, etc.
1. int vsformat (char *vdiskname, int m). This function will be used to create and format a virtual disk. The virtual disk will simply be a regular Linux file. The name of the Linux file is specified with the vdiskname pa- rameter. The size of the file (i.e., virtual disk) is indicated with the parameter disksize. Let m denote the value of the disksize parameter. Then the size of the virtual disk will be 2m bytes. This function will first create a regular bi- nary Linux file of the specified size, and then will initialize it with the file system data structures that will be explained later in this document. If successful, the function will return 0, otherwise it will return 1.
2. int vsmount (char *vdiskname). This function will be used to mount the file system, i.e., to prepare the file system for accessing. Basically, this function will open the regular Linux file (acting as the virtual disk) and obtain an integer file descriptor. The file descriptor will be used internally by the library; it will not be given to the application program. Other operations implemented in the library will use this file descriptor. Therefore it should be a global variable in the library. This function will also read the superblock and FAT table from the virtual disk and will cache them in some data structures (that you will define in your library) in memory. It will also read the root directory content from the virtual disk and cache it in a data structure in memory. Operations (reads or updates) on the FAT table, superblock, or the root directory will be done on the in-memory structures. If you wish you can immediately write the updates back to the disk as well; if not you will write them back to the disk while unmounting. The function will return 0 if it is successful, otherwise it will return 1.
3. int vsumount(). This function will be used to unmount the file system: flush the cached data to disk and close the virtual disk file descriptor. The in-memory structures of the superblock, FAT table and root directory are written back to the virtual disk (i.e., Linux file). The function will return 0 if it is successful, otherwise it will return 1.
4. int vscreate (char *filename). This function will be called by an ap- plication to create a file (i.e., a VSFS file) in the VSFS file system. Your library will use a directory entry to store information about the created file. The func- tion will return 0 if it is successful, otherwise it will return 1.
5. int vsopen (char *filename, int mode). This function will be called by an application to open a file (i.e., a VSFS file). The filename parameter is used to specify the name of the file to open. The mode parameter is used to specify in which access mode the file is opened. The mode value can be either 0 or 1 (0 indicates READ and 1 indicates APPEND). A file can not be opened for both reading and appending at the same time. In your library you should have an open file table that will have an entry for the opened file. The index of that entry will be returned as the return value of this function. Hence the return value will be a non-negative integer acting as a file descriptor to be used in subsequent file operations. If error, 1 will be returned.
6. int vssize (int fd). With this an application learns the size of an opened VSFS file whose descriptor is fd. The function will return the number of data bytes in the file. A file with no data in it (no content) has size 0. If there is an error, 1 will be returned.
7. int vsclose (int fd). With this function an application will close a VSFS file whose descriptor is fd. The related open file table entry (in your library) should be marked as free.
8. int vsread (int fd, void * buf, int n). With this, an application can read data from a file. The parameter fd specifies the file descriptor. The pa- rameter buf is a pointer pointing to the memory allocated earlier with malloc() (or it can be pointing to a static array). The data that is read from the file will be stored in the area pointed by buf. The parameter n is the amount of data to read (number of bytes/characters to read). In case of an error, the function will return 1. Otherwise, it returns the number of bytes successfully read. Note that the number of bytes read may be less than the number of bytes requested (because we might have reached the end of file).
9. int vsappend (int fd, void *buf, int n). With this, an application can append (i.e., write to the end) new data to the file. The parameter fd is the file descriptor. The parameter buf is pointing to (i.e., is the address of) a static array holding the data or a dynamically allocated memory space holding the data. The parameter n is the size of the data to write (append) into the file. In case of an error, the function returns 1. Otherwise, it returns the number of bytes successfully appended.
10. int vsdelete (char *filename). This function deletes the file specified by the parameter filename. Returns 0 on success and 1 on error.
//////////////////////////////Code///////////////////////////
#include
// globals ======================================= int vs_fd; // file descriptor of the Linux file that acts as virtual disk. // this is not visible to an application. // ========================================================
// read block k from disk (virtual disk) into buffer block. // size of the block is BLOCKSIZE. // space for block must be allocated outside of this function. // block numbers start from 0 in the virtual disk. int read_block (void *block, int k) { int n; int offset;
offset = k * BLOCKSIZE; lseek(vs_fd, (off_t) offset, SEEK_SET); n = read (vs_fd, block, BLOCKSIZE); if (n != BLOCKSIZE) { printf ("read error "); return -1; } return (0); }
// write block k into the virtual disk. int write_block (void *block, int k) { int n; int offset;
offset = k * BLOCKSIZE; lseek(vs_fd, (off_t) offset, SEEK_SET); n = write (vs_fd, block, BLOCKSIZE); if (n != BLOCKSIZE) { printf ("write error "); return (-1); } return 0; }
/********************************************************************** The following functions are to be called by applications directly. ***********************************************************************/
// this function is partially implemented. int vsformat (char *vdiskname, unsigned int m) { char command[1000]; int size; int num = 1; int count; size = num << m; count = size / BLOCKSIZE; // printf ("%d %d", m, size); sprintf (command, "dd if=/dev/zero of=%s bs=%d count=%d", vdiskname, BLOCKSIZE, count); //printf ("executing command = %s ", command); system (command);
// now write the code to format the disk. // .. your code... return (0); }
// this function is partially implemented. int vsmount (char *vdiskname) { // open the Linux file vdiskname and in this // way make it ready to be used for other operations. // vs_fd is global; hence other function can use it. vs_fd = open(vdiskname, O_RDWR); // load (chache) the superblock info from disk (Linux file) into memory // load the FAT table from disk into memory // load root directory from disk into memory //... return(0); }
// this function is partially implemented. int vsumount () { // write superblock to virtual disk file // write FAT to virtual disk file // write root directory to virtual disk file
fsync (vs_fd); // synchronize kernel file cache with the disk close (vs_fd); return (0); }
int vscreate(char *filename) { return (0); }
int vsopen(char *file, int mode) { return (0); }
int vsclose(int fd){ return (0); }
int vssize (int fd) { return (0); }
int vsread(int fd, void *buf, int n){ return (0); }
int vsappend(int fd, void *buf, int n) { return (0); }
int vsdelete(char *filename) { return (0); }
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started