Hire Experts For Answers
Order NowRelated Study Services
- Homework Answers
- Coursework writing help
- Term paper writing help
- Writing Help
- Paper Writing Help
- Research paper help
- Thesis Help
- Dissertation Help
- Case study writing service
- Capstone Project Writing Help
- Lab report Writing
- Take my online class
- Take my online exam
- Do my test for me
- Do my homework
- Do my math homework
- Online Assignment Help
- Do my assignment
- Essay Writing Help
- Write my college essay
- Write my essay for me
DESCRIPTION
Posted
Modified
Viewed
34
This is the C assignment. The instruction is in the README file. We need to run the program via terminal of ubuntu (Use the "make" and "make run"). In this assignment, you need to leave the comment in details on the code. After you are done, you need to help me write 2 writeup. The deadline is Nov 25
?_________________
?The first writeup is for this project, the requirement below:
1. A description of your file system
2. Issues you had
3. Detail of how your driver program works.
4. Screen shots showing each of the commands listed in the readme.
_________________
??The second writeup is for individual. I attached the template below. I also attached the "step for file system design" file which can help you design file system.
Attachments
csc415-filesystem-anhduynguyen8598/b_io.c
/**************************************************************
* Class: CSC-415-0# Fall 2021
* Names:
* Student IDs:
* GitHub Name:
* Group Name:
* Project: Basic File System
*
* File: b_io.c
*
* Description: Basic File System - Key File I/O Operations
*
**************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h> // for malloc
#include <string.h> // for memcpy
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "b_io.h"
#define MAXFCBS 20
#define B_CHUNK_SIZE 512
typedef struct b_fcb
{
/** TODO add al the information you need in the file control block **/
char * buf; //holds the open file buffer
int index; //holds the current position in the buffer
int buflen; //holds how many valid bytes are in the buffer
} b_fcb;
b_fcb fcbArray[MAXFCBS];
int startup = 0; //Indicates that this has not been initialized
//Method to initialize our file system
void b_init ()
{
//init fcbArray to all free
for (int i = 0; i < MAXFCBS; i++)
{
fcbArray[i].buf = NULL; //indicates a free fcbArray
}
startup = 1;
}
//Method to get a free FCB element
b_io_fd b_getFCB ()
{
for (int i = 0; i < MAXFCBS; i++)
{
if (fcbArray[i].buff == NULL)
{
return i; //Not thread safe (But do not worry about it for this assignment)
}
}
return (-1); //all in use
}
// Interface to open a buffered file
// Modification of interface for this assignment, flags match the Linux flags for open
// O_RDONLY, O_WRONLY, or O_RDWR
b_io_fd b_open (char * filename, int flags)
{
b_io_fd returnFd;
//*** TODO ***: Modify to save or set any information needed
//
//
if (startup == 0) b_init(); //Initialize our system
returnFd = b_getFCB(); // get our own file descriptor
// check for error - all used FCB's
return (returnFd); // all set
}
// Interface to seek function
int b_seek (b_io_fd fd, off_t offset, int whence)
{
if (startup == 0) b_init(); //Initialize our system
// check that fd is between 0 and (MAXFCBS-1)
if ((fd < 0) || (fd >= MAXFCBS))
{
return (-1); //invalid file descriptor
}
return (0); //Change this
}
// Interface to write function
int b_write (b_io_fd fd, char * buffer, int count)
{
if (startup == 0) b_init(); //Initialize our system
// check that fd is between 0 and (MAXFCBS-1)
if ((fd < 0) || (fd >= MAXFCBS))
{
return (-1); //invalid file descriptor
}
return (0); //Change this
}
// Interface to read a buffer
// Filling the callers request is broken into three parts
// Part 1 is what can be filled from the current buffer, which may or may not be enough
// Part 2 is after using what was left in our buffer there is still 1 or more block
// size chunks needed to fill the callers request. This represents the number of
// bytes in multiples of the blocksize.
// Part 3 is a value less than blocksize which is what remains to copy to the callers buffer
// after fulfilling part 1 and part 2. This would always be filled from a refill
// of our buffer.
// +-------------+------------------------------------------------+--------+
// | | | |
// | filled from | filled direct in multiples of the block size | filled |
// | existing | | from |
// | buffer | |refilled|
// | | | buffer |
// | | | |
// | Part1 | Part 2 | Part3 |
// +-------------+------------------------------------------------+--------+
int b_read (b_io_fd fd, char * buffer, int count)
{
if (startup == 0) b_init(); //Initialize our system
// check that fd is between 0 and (MAXFCBS-1)
if ((fd < 0) || (fd >= MAXFCBS))
{
return (-1); //invalid file descriptor
}
return (0); //Change this
}
// Interface to Close the file
void b_close (b_io_fd fd)
{
}
csc415-filesystem-anhduynguyen8598/Makefile
# File: Standard Makefile for CSC415
#
# Description - This make file should be used for all your projects
# It should be modified as needed for each homework
#
# ROOTNAME should be set you your lastname_firstname_HW. Except for
# and group projects, this will not change throughout the semester
#
# HW should be set to the assignment number (i.e. 1, 2, 3, etc.)
#
# FOPTION can be set to blank (nothing) or to any thing starting with an
# underscore (_). This is the suffix of your file name.
#
# With these three options above set your filename for your homework
# assignment will look like: bierman_robert_HW1_main.c
#
# RUNOPTIONS can be set to default values you want passed into the program
# this can also be overridden on the command line
#
# OBJ - You can append to this line for additional files necessary for
# your program, but only when you have multiple files. Follow the convention
# but hard code the suffix as needed.
#
# To Use the Makefile - Edit as above
# then from the command line run: make
# That command will build your program, and the program will be named the same
# as your main c file without an extension.
#
# You can then execute from the command line: make run
# This will actually run your program
#
# Using the command: make clean
# will delete the executable and any object files in your directory.
#
ROOTNAME=fsshell
HW=
FOPTION=
RUNOPTIONS=SampleVolume 10000000 512
CC=gcc
CFLAGS= -g -I.
LIBS =pthread
DEPS =
# Add any additional objects to this list
ADDOBJ= fsInit.o
ARCH = $(shell uname -m)
ifeq ($(ARCH), aarch64)
ARCHOBJ=fsLowM1.o
else
ARCHOBJ=fsLow.o
endif
OBJ = $(ROOTNAME)$(HW)$(FOPTION).o $(ADDOBJ) $(ARCHOBJ)
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
$(ROOTNAME)$(HW)$(FOPTION): $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) -lm -l readline -l $(LIBS)
clean:
rm $(ROOTNAME)$(HW)$(FOPTION).o $(ADDOBJ) $(ROOTNAME)$(HW)$(FOPTION)
run: $(ROOTNAME)$(HW)$(FOPTION)
./$(ROOTNAME)$(HW)$(FOPTION) $(RUNOPTIONS)
csc415-filesystem-anhduynguyen8598/fsshell.c
/**************************************************************
* Class: CSC-415-0# - Fall 2021
* Names:
* Student IDs:
* GitHub Name:
* Group Name:
* Project: Basic File System
*
* File: fsShell.c
*
* Description: Main driver for file system assignment.
*
* Make sure to set the #defined on the CMDxxxx_ON from 0 to 1
* when you are ready to test that feature
*
**************************************************************/
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <getopt.h>
#include <string.h>
#include "fsLow.h"
#include "mfs.h"
#define SINGLE_QUOTE 0x27
#define DOUBLE_QUOTE 0x22
#define BUFFERLEN 200
#define DIRMAX_LEN 4096
/**** SET THESE TO 1 WHEN READY TO TEST THAT COMMAND ****/
#define CMDLS_ON 0
#define CMDCP_ON 0
#define CMDMV_ON 0
#define CMDMD_ON 0
#define CMDRM_ON 0
#define CMDCP2L_ON 0
#define CMDCP2FS_ON 0
#define CMDCD_ON 0
#define CMDPWD_ON 0
typedef struct dispatch_t
{
char * command;
int (*func)(int, char**);
char * description;
} dispatch_t, * dispatch_p;
int cmd_ls (int argcnt, char *argvec[]);
int cmd_cp (int argcnt, char *argvec[]);
int cmd_mv (int argcnt, char *argvec[]);
int cmd_md (int argcnt, char *argvec[]);
int cmd_rm (int argcnt, char *argvec[]);
int cmd_cp2l (int argcnt, char *argvec[]);
int cmd_cp2fs (int argcnt, char *argvec[]);
int cmd_cd (int argcnt, char *argvec[]);
int cmd_pwd (int argcnt, char *argvec[]);
int cmd_history (int argcnt, char *argvec[]);
int cmd_help (int argcnt, char *argvec[]);
dispatch_t dispatchTable[] = {
{"ls", cmd_ls, "Lists the file in a directory"},
{"cp", cmd_cp, "Copies a file - source [dest]"},
{"mv", cmd_mv, "Moves a file - source dest"},
{"md", cmd_md, "Make a new directory"},
{"rm", cmd_rm, "Removes a file or directory"},
{"cp2l", cmd_cp2l, "Copies a file from the test file system to the linux file system"},
{"cp2fs", cmd_cp2fs, "Copies a file from the Linux file system to the test file system"},
{"cd", cmd_cd, "Changes directory"},
{"pwd", cmd_pwd, "Prints the working directory"},
{"history", cmd_history, "Prints out the history"},
{"help", cmd_help, "Prints out help"}
};
static int dispatchcount = sizeof (dispatchTable) / sizeof (dispatch_t);
// Display files for use by ls command
int displayFiles (fdDir * dirp, int flall, int fllong)
{
#if (CMDLS_ON == 1)
if (dirp == NULL) //get out if error
return (-1);
struct fs_diriteminfo * di;
struct fs_stat statbuf;
di = fs_readdir (dirp);
printf("\n");
while (di != NULL)
{
if ((di->d_name[0] != '.') || (flall)) //if not all and starts with '.' it is hidden
{
if (fllong)
{
fs_stat (di->d_name, &statbuf);
printf ("%s %9ld %s\n", fs_isDir(di->d_name)?"D":"-", statbuf.st_size, di->d_name);
}
else
{
printf ("%s\n", di->d_name);
}
}
di = fs_readdir (dirp);
}
fs_closedir (dirp);
#endif
return 0;
}
/****************************************************
* ls commmand
****************************************************/
int cmd_ls (int argcnt, char *argvec[])
{
#if (CMDLS_ON == 1)
int option_index;
int c;
int fllong;
int flall;
char cwd[DIRMAX_LEN];
static struct option long_options[] =
{
/* These options set their assigned flags to value and return 0 */
/* These options don't set flags and return the value */
{"long", no_argument, 0, 'l'},
{"all", no_argument, 0, 'a'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0 }
};
option_index = 0;
#ifdef __GNU_LIBRARY__
// WORKAROUND
// Setting "optind" to 0 triggers initialization of getopt private
// structure (holds pointers on data between calls). This helps
// to avoid possible memory violation, because data passed to getopt_long()
// could be freed between parse() calls.
optind = 0;
#else
// "optind" is used between getopt() calls to get next argument for parsing and should be
// initialized before each parsing loop.
optind = 1;
#endif
fllong = 0;
flall = 0;
while (1)
{
c = getopt_long(argcnt, argvec, "alh",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0: //flag was set, ignore
printf("Unknown option %s", long_options[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
break;
case 'a':
flall = 1;
break;
case 'l':
fllong = 1;
break;
case 'h':
default:
printf ("Usage: ls [--all-a] [--long/-l] [pathname]\n");
return (-1);
break;
}
}
if (optind < argcnt)
{
//processing arguments after options
for (int k = optind; k < argcnt; k++)
{
if (fs_isDir(argvec[k]))
{
fdDir * dirp;
dirp = fs_opendir (argvec[k]);
displayFiles (dirp, flall, fllong);
}
else // it is just a file ?
{
if (fs_isFile (argvec[k]))
{
//no support for long format here
printf ("%s\n", argvec[k]);
}
else
{
printf ("%s is not found\n", argvec[k]);
}
}
}
}
else // no pathname/filename specified - use cwd
{
char * path = fs_getcwd(cwd, DIRMAX_LEN); //get current working directory
fdDir * dirp;
dirp = fs_opendir (path);
return (displayFiles (dirp, flall, fllong));
}
#endif
return 0;
}
/****************************************************
* Copy file commmand
****************************************************/
int cmd_cp (int argcnt, char *argvec[])
{
#if (CMDCP_ON == 1)
int testfs_src_fd;
int testfs_dest_fd;
char * src;
char * dest;
int readcnt;
char buf[BUFFERLEN];
switch (argcnt)
{
case 2: //only one name provided
src = argvec[1];
dest = src;
break;
case 3:
src = argvec[1];
dest = argvec[2];
break;
default:
printf("Usage: cp srcfile [destfile]\n");
return (-1);
}
testfs_src_fd = b_open (src, O_RDONLY);
testfs_dest_fd = b_open (dest, O_WRONLY | O_CREAT | O_TRUNC);
do
{
readcnt = b_read (testfs_src_fd, buf, BUFFERLEN);
b_write (testfs_dest_fd, buf, readcnt);
} while (readcnt == BUFFERLEN);
b_close (testfs_src_fd);
b_close (testfs_dest_fd);
#endif
return 0;
}
/****************************************************
* Move file commmand
****************************************************/
int cmd_mv (int argcnt, char *argvec[])
{
#if (CMDMV_ON == 1)
return -99;
// **** TODO **** For you to implement
#endif
return 0;
}
/****************************************************
* Make Directory commmand
****************************************************/
// Make Directory
int cmd_md (int argcnt, char *argvec[])
{
#if (CMDMD_ON == 1)
if (argcnt != 2)
{
printf("Usage: md pathname\n");
return -1;
}
else
{
return(fs_mkdir(argvec[1], 0777));
}
#endif
return -1;
}
/****************************************************
* Remove directory or file commmand
****************************************************/
int cmd_rm (int argcnt, char *argvec[])
{
#if (CMDRM_ON == 1)
if (argcnt != 2)
{
printf ("Usage: rm path\n");
return -1;
}
char * path = argvec[1];
//must determine if file or directory
if (fs_isDir (path))
{
return (fs_rmdir (path));
}
if (fs_isFile (path))
{
return (fs_delete(path));
}
printf("The path %s is neither a file not a directory\n", path);
#endif
return -1;
}
/****************************************************
* Copy file from test file system to Linux commmand
****************************************************/
int cmd_cp2l (int argcnt, char *argvec[])
{
#if (CMDCP2L_ON == 1)
int testfs_fd;
int linux_fd;
char * src;
char * dest;
int readcnt;
char buf[BUFFERLEN];
switch (argcnt)
{
case 2: //only one name provided
src = argvec[1];
dest = src;
break;
case 3:
src = argvec[1];
dest = argvec[2];
break;
default:
printf("Usage: cp2l srcfile [Linuxdestfile]\n");
return (-1);
}
testfs_fd = b_open (src, O_RDONLY);
linux_fd = open (dest, O_WRONLY | O_CREAT | O_TRUNC);
do
{
readcnt = b_read (testfs_fd, buf, BUFFERLEN);
write (linux_fd, buf, readcnt);
} while (readcnt == BUFFERLEN);
b_close (testfs_fd);
close (linux_fd);
#endif
return 0;
}
/****************************************************
* Copy file from Linux to test file system commmand
****************************************************/
int cmd_cp2fs (int argcnt, char *argvec[])
{
#if (CMDCP2FS_ON == 1)
int testfs_fd;
int linux_fd;
char * src;
char * dest;
int readcnt;
char buf[BUFFERLEN];
switch (argcnt)
{
case 2: //only one name provided
src = argvec[1];
dest = src;
break;
case 3:
src = argvec[1];
dest = argvec[2];
break;
default:
printf("Usage: cp2fs Linuxsrcfile [destfile]\n");
return (-1);
}
testfs_fd = b_open (dest, O_WRONLY | O_CREAT | O_TRUNC);
linux_fd = open (src, O_RDONLY);
do
{
readcnt = read (linux_fd, buf, BUFFERLEN);
b_write (testfs_fd, buf, readcnt);
} while (readcnt == BUFFERLEN);
b_close (testfs_fd);
close (linux_fd);
#endif
return 0;
}
/****************************************************
* cd commmand
****************************************************/
int cmd_cd (int argcnt, char *argvec[])
{
#if (CMDCD_ON == 1)
if (argcnt != 2)
{
printf ("Usage: cd path\n");
return (-1);
}
char * path = argvec[1]; //argument
if (path[0] == '"')
{
if (path[strlen(path)-1] == '"')
{
//remove quotes from string
path = path + 1;
path[strlen(path) - 1] = 0;
}
}
int ret = fs_setcwd (path);
if (ret != 0) //error
{
printf ("Could not change path to %s\n", path);
return (ret);
}
#endif
return 0;
}
/****************************************************
* PWD commmand
****************************************************/
int cmd_pwd (int argcnt, char *argvec[])
{
#if (CMDPWD_ON == 1)
char * dir_buf = malloc (DIRMAX_LEN +1);
char * ptr;
ptr = fs_getcwd (dir_buf, DIRMAX_LEN);
if (ptr == NULL) //an error occurred
{
printf ("An error occurred while trying to get the current working directory\n");
}
else
{
printf ("%s\n", ptr);
}
free (dir_buf);
dir_buf = NULL;
ptr = NULL;
#endif
return 0;
}
/****************************************************
* History commmand
****************************************************/
int cmd_history (int argcnt, char *argvec[])
{
HIST_ENTRY * he;
int i = 0;
for (i = history_base; i <= history_length; i++)
{
he = history_get(i);
if (he != NULL)
{
printf ("%s\n", he->line);
}
}
return 0;
}
/****************************************************
* Help commmand
****************************************************/
int cmd_help (int argcnt, char *argvec[])
{
for (int i = 0; i < dispatchcount; i++)
{
printf ("%s\t%s\n", dispatchTable[i].command, dispatchTable[i].description);
}
return 0;
}
void processcommand (char * cmd)
{
int cmdLen;
char ** cmdv; //command vector
int cmdc; //command count
int i, j;
cmdLen = strlen(cmd);
cmdv = (char **) malloc (sizeof(char *) * ((cmdLen/2)+2));
cmdc = 0;
cmdv[cmdc] = cmd;
++cmdc;
for (i = 0; i < cmdLen; i++)
{
switch (cmd[i])
{
case ' ':
cmd[i] = 0; //NULL terminate prior string
while (cmd[i+1] == ' ') // null at end will prevent from overshooting string
{
i++;
}
if ((i+1) < cmdLen) //there is still more
{
cmdv[cmdc] = &cmd[i+1];
++cmdc;
}
break;
case '\\':
++i; //skip next character
break;
case DOUBLE_QUOTE: //ignore everything till next quote (unless unterminated)
for (j = i+1; j < cmdLen; j++)
{
if (cmd[j] == '\\')
{
++j; //skip next character
}
else if (cmd[j] == DOUBLE_QUOTE)
{
break;
}
}
if (j >= cmdLen)
{
printf("Unterminated string\n");
free(cmdv);
cmdv = NULL;
return;
}
i=j;
break;
case SINGLE_QUOTE:
for (j = i+1; j < cmdLen; j++)
{
if (cmd[j] == '\\')
{
++j; //skip next character
}
else if (cmd[j] == SINGLE_QUOTE)
{
break;
}
}
if (j >= cmdLen)
{
printf("Unterminated string\n");
free(cmdv);
cmdv = NULL;
return;
}
i=j;
break;
default:
break;
}
}
#ifdef COMMAND_DEBUG
for (i = 0; i < cmdc; i++)
{
printf("%s: length %d\n", cmdv[i], strlen(cmdv[i]));
}
#endif
cmdv[cmdc] = 0; //just be safe - null terminate array of arguments
for (i = 0; i < dispatchcount; i++)
{
if (strcmp(dispatchTable[i].command, cmdv[0]) == 0)
{
dispatchTable[i].func(cmdc,cmdv);
free (cmdv);
cmdv = NULL;
return;
}
}
printf("%s is not a regonized command.\n", cmdv[0]);
cmd_help(cmdc, cmdv);
free (cmdv);
cmdv = NULL;
}
int main (int argc, char * argv[])
{
char * cmdin;
char * cmd;
HIST_ENTRY *he;
char * filename;
uint64_t volumeSize;
uint64_t blockSize;
int retVal;
if (argc > 3)
{
filename = argv[1];
volumeSize = atoll (argv[2]);
blockSize = atoll (argv[3]);
}
else
{
printf ("Usage: fsLowDriver volumeFileName volumeSize blockSize\n");
return -1;
}
retVal = startPartitionSystem (filename, &volumeSize, &blockSize);
printf("Opened %s, Volume Size: %llu; BlockSize: %llu; Return %d\n", filename, (ull_t)volumeSize, (ull_t)blockSize, retVal);
if (retVal != PART_NOERROR)
{
printf ("Start Partition Failed: %d\n", retVal);
return (retVal);
}
retVal = initFileSystem (volumeSize / blockSize, blockSize);
if (retVal != 0)
{
printf ("Initialize File System Failed: %d\n", retVal);
closePartitionSystem();
return (retVal);
}
using_history();
stifle_history(200); //max history entries
while (1)
{
cmdin = readline("Prompt > ");
#ifdef COMMAND_DEBUG
printf ("%s\n", cmdin);
#endif
cmd = malloc (strlen(cmdin) + 30);
strcpy (cmd, cmdin);
free (cmdin);
cmdin = NULL;
if (strcmp (cmd, "exit") == 0)
{
free (cmd);
cmd = NULL;
exitFileSystem();
closePartitionSystem();
// exit while loop and terminate shell
break;
}
if ((cmd != NULL) && (strlen(cmd) > 0))
{
he = history_get(history_length);
if (!((he != NULL) && (strcmp(he->line, cmd)==0)))
{
add_history(cmd);
}
processcommand (cmd);
}
free (cmd);
cmd = NULL;
} // end while
}
csc415-filesystem-anhduynguyen8598/fsInit.c
/**************************************************************
* Class: CSC-415-0# Fall 2021
* Names:
* Student IDs:
* GitHub Name:
* Group Name:
* Project: Basic File System
*
* File: fsInit.c
*
* Description: Main driver for file system assignment.
*
* This file is where you will start and initialize your system
*
**************************************************************/
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include "fsLow.h"
#include "mfs.h"
int initFileSystem (uint64_t numberOfBlocks, uint64_t blockSize)
{
printf ("Initializing File System with %ld blocks with a block size of %ld\n", numberOfBlocks, blockSize);
/* TODO: Add any code you need to initialize your file system. */
return 0;
}
void exitFileSystem ()
{
printf ("System exiting\n");
}
csc415-filesystem-anhduynguyen8598/fsLow.h
/**************************************************************
* Class: CSC-415
* Name: Professor Bierman
* Student ID: N/A
* Project: Basic File System
*
* File: fsLow.h
*
* Description: This file provides the ability to read and write
* Logical Blocks and is the main interface for the file system
* project.
* Note that the layer uses one more block than that presented
* to the file organization module. This block is used to
* hold the partition information and is not accessible from
* any other layer. But, when you use the hexdump utility
* you will see that the first block is not part of the volume.
*
* The file created by this layer represents the physical hard
* drive. It presents to the logical layer (your layer) as just
* a logical block array (a series of blocks - nominally 512 bytes,
* that the logical layer can utilize).
*
* It is imperative that the logical layer (your layer) first
* call startPartitionSystem before using any function and when
* finished calls closePartitionSystem() to ensure that the
* file that represents the physical drive is properally closed.
*
**************************************************************/
//
// Start Partition System
//
// This is the first function to call before your filesystem starts
// If the filename already exists, then the input values stored in
// volSize and blockSize are ignored. If the file does not exist, it will
// be created to the specified volume size in units of the block size
// (must be power of 2) plus one for the partition header.
//
// On return
// return value 0 = success;
// return value -1 = file exists but can not open for write
// return value -2 = insufficient space for the volume
// volSize will be filled with the volume size
// blockSize will be filled with the block size
#ifndef uint64_t
typedef u_int64_t uint64_t;
#endif
#ifndef uint32_t
typedef u_int32_t uint32_t;
#endif
typedef unsigned long long ull_t;
int startPartitionSystem (char * filename, uint64_t * volSize, uint64_t * blockSize);
int closePartitionSystem ();
int initFileSystem (uint64_t numberOfBlocks, uint64_t blockSize);
void exitFileSystem ();
uint64_t LBAwrite (void * buffer, uint64_t lbaCount, uint64_t lbaPosition);
uint64_t LBAread (void * buffer, uint64_t lbaCount, uint64_t lbaPosition);
#define MINBLOCKSIZE 512
#define PART_SIGNATURE 0x526F626572742042
#define PART_SIGNATURE2 0x4220747265626F52
#define PART_CAPTION "CSC-415 - Operating Systems File System Partition Header\n\n"
#define PART_ACTIVE 1
#define PART_INACTIVE 0
#define PART_NOERROR 0
#define PART_ERR_INVALID -4
csc415-filesystem-anhduynguyen8598/fsLow.o
csc415-filesystem-anhduynguyen8598/README.md
# CSC415 Group Term Assignment - File System
This is a GROUP assignment written in C. Only one person on the team needs to submit the project.
Over the past month you and your team have been designing components of a file system. You have defined the goals and designed the directory entry structure, the volume structure and the free space. Now it is time to implement your file system.
To help I have written the low level LBA based read and write. The routines are in fsLow.o, the necessary header for you to include file is fsLow.h. You do NOT need to understand the code in fsLow, but you do need to understand the header file and the functions. There are 2 key functions:
`uint64_t LBAwrite (void * buffer, uint64_t lbaCount, uint64_t lbaPosition);`
`uint64_t LBAread (void * buffer, uint64_t lbaCount, uint64_t lbaPosition);`
LBAread and LBAwrite take a buffer, a count of LBA blocks and the starting LBA block number (0 based). The buffer must be large enough for the number of blocks * the block size.
On return, these function returns the number of **blocks** read or written.
In addition, I have written a hexdump utility that will allow you to analyze your volume file in the Hexdump subdirectory.
**Your assignment is to write a file system!**
You will need to format your volume, create and maintain a free space management system, initialize a root directory and maintain directory information, create, read, write, and delete files, and display info. See below for specifics.
I will provide an initial “main” (fsShell.c) that will be the driver to test you file system. Your group can modifiy this driver as needed. The driver will be interactive (with all built in commands) to list directories, create directories, add and remove files, copy files, move files, and two “special commands” one to copy from the normal filesystem to your filesystem and the other from your filesystem to the normal filesystem.
You should modify this driver as needed for your filesystem, adding the display/setting of any additional meta data, and other functions you want to add.
The shell also calls two function in the file fsInit.c `initFileSystem` and `exitFileSystem` which are routines for you to fill in with whatever initialization and exit code you need for your file system.
Some specifics - you need to provide the following interfaces:
```
b_io_fd b_open (char * filename, int flags);
int b_read (b_io_fd fd, char * buffer, int count);
int b_write (b_io_fd fd, char * buffer, int count);
int b_seek (b_io_fd fd, off_t offset, int whence);
void b_close (b_io_fd fd);
```
Note that the function are similar to the b_read and b_write you have done, there is a signifigant difference since you do not have the linux open and read to use.
You have to have methods of locating files, and knowing which logical block addresses are associated with the file.
Directory Functions - see [https://www.thegeekstuff.com/2012/06/c-directory/](https://www.thegeekstuff.com/2012/06/c-directory/) for reference.
```
int fs_mkdir(const char *pathname, mode_t mode);
int fs_rmdir(const char *pathname);
fdDir * fs_opendir(const char *name);
struct fs_diriteminfo *fs_readdir(fdDir *dirp);
int fs_closedir(fdDir *dirp);
char * fs_getcwd(char *buf, size_t size);
int fs_setcwd(char *buf); //linux chdir
int fs_isFile(char * path); //return 1 if file, 0 otherwise
int fs_isDir(char * path); //return 1 if directory, 0 otherwise
int fs_delete(char* filename); //removes a file
struct fs_diriteminfo
{
unsigned short d_reclen; /* length of this record */
unsigned char fileType;
char d_name[256]; /* filename max filename is 255 characters */
};
```
Finally file stats - not all the fields in the structure are needed for this assingment
```
int fs_stat(const char *path, struct fs_stat *buf);
struct fs_stat
{
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_accesstime; /* time of last access */
time_t st_modtime; /* time of last modification */
time_t st_createtime; /* time of last status change */
/* add additional attributes here for your file system */
};
```
These interfaces will also be provided to you in mfs.h.
**Note:** You will need to modify mfs.h for the fdDIR strucutre to be what your file system need to maintain and track interation through the directory structure.
A shell program designed to demonstrate your file system called fsshell.c is proviced. It has a number of built in functions that will work if you implement the above interfaces, these are:
```
ls - Lists the file in a directory
cp - Copies a file - source [dest]
mv - Moves a file - source dest
md - Make a new directory
rm - Removes a file or directory
cp2l - Copies a file from the test file system to the linux file system
cp2fs - Copies a file from the Linux file system to the test file system
cd - Changes directory
pwd - Prints the working directory
history - Prints out the history
help - Prints out help
```
This is deliberately vague, as it is dependent on your filesystem design. And this all you may get initially for a real-world assignment, so if you have questions, please ask.
We will discuss some of this in class.
For our purposes use 10,000,000 or less (minimum 500,000) bytes for the volume size and 512 bytes per sector. These are the values to pass into startPartitionSystem.
What needs to be submitted (via GitHub and iLearn):
* All source files (.c and .h)
* Modified Driver program (must be a program that just utilizes the header file for your file system).
* The Driver program must be named: `fsshell.c`
* A make file (named “Makefile”) to build your entire program
* A PDF writeup on project that should include (this is also submitted in iLearn):
* The github link for your group submission.
* A description of your file system
* Issues you had
* Detail of how your driver program works
* Screen shots showing each of the commands listed above
* Your volume file (limit 10MB)
* There will also be an INDIVIDUAL report (form) to complete.
__MACOSX/csc415-filesystem-anhduynguyen8598/._README.md
csc415-filesystem-anhduynguyen8598/mfs.h
/**************************************************************
* Class: CSC-415
* Name: Professor Bierman
* Student ID: N/A
* Project: Basic File System
*
* File: mfs.h
*
* Description:
* This is the file system interface.
* This is the interface needed by the driver to interact with
* your filesystem.
*
**************************************************************/
#ifndef _MFS_H
#define _MFS_H
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include "b_io.h"
#include <dirent.h>
#define FT_REGFILE DT_REG
#define FT_DIRECTORY DT_DIR
#define FT_LINK DT_LNK
#ifndef uint64_t
typedef u_int64_t uint64_t;
#endif
#ifndef uint32_t
typedef u_int32_t uint32_t;
#endif
// This structure is returned by fs_readdir to provide the caller with information
// about each file as it iterates through a directory
struct fs_diriteminfo
{
unsigned short d_reclen; /* length of this record */
unsigned char fileType;
char d_name[256]; /* filename max filename is 255 characters */
};
// This is a private structure used only by fs_opendir, fs_readdir, and fs_closedir
// Think of this like a file descriptor but for a directory - one can only read
// from a directory. This structure helps you (the file system) keep track of
// which directory entry you are currently processing so that everytime the caller
// calls the function readdir, you give the next entry in the directory
typedef struct
{
/*****TO DO: Fill in this structure with what your open/read directory needs *****/
unsigned short d_reclen; /*length of this record */
unsigned short dirEntryPosition; /*which directory entry position, like file pos */
uint64_t directoryStartLocation; /*Starting LBA of directory */
} fdDir;
// Key directory functions
int fs_mkdir(const char *pathname, mode_t mode);
int fs_rmdir(const char *pathname);
// Directory iteration functions
fdDir * fs_opendir(const char *name);
struct fs_diriteminfo *fs_readdir(fdDir *dirp);
int fs_closedir(fdDir *dirp);
// Misc directory functions
char * fs_getcwd(char *buf, size_t size);
int fs_setcwd(char *buf); //linux chdir
int fs_isFile(char * path); //return 1 if file, 0 otherwise
int fs_isDir(char * path); //return 1 if directory, 0 otherwise
int fs_delete(char* filename); //removes a file
// This is the strucutre that is filled in from a call to fs_stat
struct fs_stat
{
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_accesstime; /* time of last access */
time_t st_modtime; /* time of last modification */
time_t st_createtime; /* time of last status change */
/* add additional attributes here for your file system */
};
int fs_stat(const char *path, struct fs_stat *buf);
#endif
csc415-filesystem-anhduynguyen8598/.gitignore
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
csc415-filesystem-anhduynguyen8598/b_io.h
/**************************************************************
* Class: CSC-415-0# Fall 2021
* Names:
* Student IDs:
* GitHub Name:
* Group Name:
* Project: Basic File System
*
* File: b_io.h
*
* Description: Interface of basic I/O functions
*
**************************************************************/
#ifndef _B_IO_H
#define _B_IO_H
#include <fcntl.h>
typedef int b_io_fd;
b_io_fd b_open (char * filename, int flags);
int b_read (b_io_fd fd, char * buffer, int count);
int b_write (b_io_fd fd, char * buffer, int count);
int b_seek (b_io_fd fd, off_t offset, int whence);
void b_close (b_io_fd fd);
#endif
csc415-filesystem-anhduynguyen8598/fsLowM1.o
csc415-filesystem-anhduynguyen8598/Hexdump/hexdump.linux
csc415-filesystem-anhduynguyen8598/Hexdump/Makefile
# File: Standard Makefile for CSC415
#
# Description - This make file should be used for all your projects
# It should be modified as needed for each homework
#
# ROOTNAME should be set you your lastname_firstname_HW. Except for
# and group projects, this will not change throughout the semester
#
# HW should be set to the assignment number (i.e. 1, 2, 3, etc.)
#
# FOPTION can be set to blank (nothing) or to any thing starting with an
# underscore (_). This is the suffix of your file name.
#
# With these three options above set your filename for your homework
# assignment will look like: bierman_robert_HW1_main.c
#
# RUNOPTIONS can be set to default values you want passed into the program
# this can also be overridden on the command line
#
# OBJ - You can append to this line for additional files necessary for
# your program, but only when you have multiple files. Follow the convention
# but hard code the suffix as needed.
#
# To Use the Makefile - Edit as above
# then from the command line run: make
# That command will build your program, and the program will be named the same
# as your main c file without an extension.
#
# You can then execute from the command line: make run
# This will actually run your program
#
# Using the command: make clean
# will delete the executable and any object files in your directory.
#
ROOTNAME=hexdump
HW=
FOPTION=
RUNOPTIONS=
CC=gcc
CFLAGS= -g -I.
LIBS =pthread
DEPS =
OBJ = $(ROOTNAME)$(HW)$(FOPTION).o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
$(ROOTNAME)$(HW)$(FOPTION): $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) -l $(LIBS)
clean:
rm *.o $(ROOTNAME)$(HW)$(FOPTION)
run: $(ROOTNAME)$(HW)$(FOPTION)
./$(ROOTNAME)$(HW)$(FOPTION) $(RUNOPTIONS)
csc415-filesystem-anhduynguyen8598/Hexdump/hexdump.linuxM1
csc415-filesystem-anhduynguyen8598/Hexdump/hexdump.c
/****************************************************************************
* hexdump - a program to display a file in hexadecimal and ascii
* Such as:
* 000020: 19 00 00 00 48 00 00 00 5F 5F 50 41 47 45 5A 45 | ....H...__PAGEZE
*
* Author: Robert Bierman
* Date: March 28, 2020
* Source: hexdump.c
*
* Primary Purpose:
* Written as a utility for CSC-415 Operating Systems, File System project
* to allow the dumping of the "drive" file for verification of proper
* structure and content.
*
* copyright 2020 Robert Bierman
****************************************************************************/
// Compilation: gcc hexdump.c -o hexdump
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#ifndef uint64_t
typedef u_int64_t uint64_t;
#endif
#ifndef uint32_t
typedef u_int32_t uint32_t;
#endif
#define BUFSIZE 4096 //amount read at one time
#define BLOCKSIZE 256 // number of bytes printed before a blank line
#define LBABLOCKSIZE 512 // display blocks from command line are based on 512 bytes
#define VERSION "1.0" // Version
// This procedure takes a file name, a starting block and a number of blocks and dumps the
// file to stdout.
// Output (including the number of blocks) is limited by the length of the file and
// partial blocks are counted as a whole block for the header showing how many blocks are
// being displayed.
//
// Checks are done to ensure that blanks are displayed on the last line of the output
// if the file only partially uses the last 16 bytes.
int processFile (char * filename, uint64_t startBlock, uint64_t numBlocks)
{
int readbytes;
int position = 0;
int loops = BUFSIZE / BLOCKSIZE; //number of loops of blocks within one buffer read
int offset;
int k;
uint32_t lbaBlockSize = LBABLOCKSIZE;
uint64_t numBytesToStartBlock;
uint64_t numBytesToProcess;
uint64_t endOfFile;
numBytesToProcess = numBlocks * lbaBlockSize;
numBytesToStartBlock = startBlock * lbaBlockSize;
int fd = open (filename, O_RDONLY); //open the file
// Error opening file (common if they don't enter a valid file name)
if (fd == -1)
{
printf ("ERROR: failed to open file '%s'\n", filename);
return -2;
}
endOfFile = lseek(fd, 0, SEEK_END); //will reset seek below
if (numBytesToProcess == 0)
{
numBytesToProcess = endOfFile;
//reset numBlocks for the header here
numBlocks = ((numBytesToProcess + lbaBlockSize) - 1) / lbaBlockSize;
numBlocks = numBlocks - startBlock;
}
unsigned char * buf = malloc (BUFSIZE); //Allocate the read buffer
// Very rare error - something bad if I can not allocate a small buffer
if (buf == NULL)
{
close (fd);
printf ("Failed to allocate buffer\n");
return -3;
}
//Position to the startBlock
lseek (fd, numBytesToStartBlock, SEEK_SET);
position = numBytesToStartBlock;
if (position > endOfFile) //can not start past the end of the filename
{
printf ("Can not dump file %s, starting at block %llu, past the end of the file.\n\n",
filename, (unsigned long long)startBlock);
return (-5);
}
// calculate max blocks we can display from the given start point
uint64_t maxBlocks = (((endOfFile - position) + lbaBlockSize) - 1) / lbaBlockSize;
if (numBlocks > maxBlocks)
numBlocks = maxBlocks;
//Proces the file - the do loop goes until we read less bytes than the BUFSIZE
printf ("Dumping file %s, starting at block %llu for %llu block%c:\n\n",
filename, (unsigned long long)startBlock, (unsigned long long)numBlocks, numBlocks != 1?'s':'\0');
do
{
if (position >= (numBytesToStartBlock + numBytesToProcess))
goto cleanup;
readbytes = read (fd, buf, BUFSIZE); //Read one block
offset = 0; //set our offset within the block
for (int i = 0; i < loops; i++) //Loop for each "Block" within one buffer read
{
for (int j = 0; j < BLOCKSIZE/16; j++) //loop j lines for each block
{
if (position+offset >= (numBytesToStartBlock + numBytesToProcess))
goto cleanup;
// Handle if we are at the end of the file and the line will have less
// than 16 bytes associated with it.
if (offset + 16 > readbytes)
{
printf ("%06X: ", offset+position);
for (k = 0; k < readbytes - offset; k++)
{
printf ("%02X ", buf[offset + k]);
}
for (;k < 16; k++)
{
printf (" "); //Print remaining of the hex output as blanks to fill out the line
}
printf (" | ");
for (k = 0; k < readbytes - offset; k++)
{
printf ("%c", buf[offset + k] < 32?'.':buf[offset+k]);
}
printf("\n");
}
else
{
//If a full line, do one print for the full line
printf ("%06X: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X | %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
offset+position,
buf[offset + 0],buf[offset + 1],buf[offset + 2],buf[offset + 3],
buf[offset + 4],buf[offset + 5],buf[offset + 6],buf[offset + 7],
buf[offset + 8],buf[offset + 9],buf[offset + 10],buf[offset + 11],
buf[offset + 12],buf[offset + 13],buf[offset + 14],buf[offset + 15],
buf[offset + 0] < 32?'.':buf[offset + 0],
buf[offset + 1] < 32?'.':buf[offset + 1],
buf[offset + 2] < 32?'.':buf[offset + 2],
buf[offset + 3] < 32?'.':buf[offset + 3],
buf[offset + 4] < 32?'.':buf[offset + 4],
buf[offset + 5] < 32?'.':buf[offset + 5],
buf[offset + 6] < 32?'.':buf[offset + 6],
buf[offset + 7] < 32?'.':buf[offset + 7],
buf[offset + 8] < 32?'.':buf[offset + 8],
buf[offset + 9] < 32?'.':buf[offset + 9],
buf[offset + 10] < 32?'.':buf[offset + 10],
buf[offset + 11] < 32?'.':buf[offset + 11],
buf[offset + 12] < 32?'.':buf[offset + 12],
buf[offset + 13] < 32?'.':buf[offset + 13],
buf[offset + 14] < 32?'.':buf[offset + 14],
buf[offset + 15] < 32?'.':buf[offset + 15]);
}
//up the offset by 16 for the next line
offset = offset + 16;
//if greater than the readbytes we have exhausted this buffer
if (offset >= readbytes)
break;
}
//print a blank line between each BLOCK
printf("\n");
//if greater than the readbytes we have exhausted this buffer
if (offset >= readbytes)
break;
}
//Next buffer, increment the overall position within the file.
position = position + readbytes;
// If we read the number of bytes requested (BUFSIZE), then we have not hit
// the end of file yet, and should try to read more.
} while (readbytes == BUFSIZE);
cleanup:
// clean up
free (buf);
close (fd);
return 0;
}
// processArguments handles the command line using getopt_long to parse the argv array
//
// It then sets variable and or dispatches the action necessary based on the parameters.
// it handles the multiple calls to processFile by iterating on uncontained parameters
int processArguments (int argc, char * argv[])
{
int c;
int digit_optind = 0;
uint64_t count, start;
count = 0; start = 0;
int retval;
char * filename = NULL;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] = {
{"count", required_argument, 0, 'c'}, //forces to c
{"start", required_argument, 0, 's'}, //forces to s
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{"file", required_argument, 0, 'f'},
{0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "c:s:f:vh",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0: //It is a long option (all converted so should be none)
printf("Unknown option %s", long_options[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
exit (-1);
case 'c':
count = atol(optarg);
break;
case 's':
start = atol(optarg);
break;
case 'f':
filename = optarg;
break;
case 'h':
printf ("USAGE: hexdump --file <filename> [--count num512ByteBlocks] [--start start512ByteBlock] [--help] [--version]\n");
exit (0);
case 'v':
printf("hexdump - Version %s; copyright 2020 Robert Bierman\n\n", VERSION);
exit (0);
case '?':
break;
default:
printf("Unknown option returned character code 0%o ??\n", c);
exit (-1);
}
}
//if a file name is already specified - process it
if (filename != NULL)
{
retval = processFile (filename, start, count);
if (retval != 0)
return (retval);
}
//additional files (same arguments)
if (optind < argc)
{
while (optind < argc)
{
retval = processFile (argv[optind++], start, count);
if (retval != 0)
return (retval);
}
}
return 0;
}
//Main calls process arguments which in turn calls process file.
int main (int argc, char * argv[])
{
return (processArguments (argc, argv));
}
csc415-filesystem-anhduynguyen8598/Hexdump/hexdump.mac
csc415-filesystem-anhduynguyen8598/.git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = https://github.com/CSC415-Fall2021/csc415-filesystem-anhduynguyen8598.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
csc415-filesystem-anhduynguyen8598/.git/HEAD
ref: refs/heads/main
csc415-filesystem-anhduynguyen8598/.git/description
Unnamed repository; edit this file 'description' to name the repository.
csc415-filesystem-anhduynguyen8598/.git/index
csc415-filesystem-anhduynguyen8598/.git/packed-refs
# pack-refs with: peeled fully-peeled sorted
d2e04b562e218a3bea4ab25b0dfdf8c4cc42131a refs/remotes/origin/main
csc415-filesystem-anhduynguyen8598/.git/info/exclude
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store
csc415-filesystem-anhduynguyen8598/.git/logs/HEAD
0000000000000000000000000000000000000000 d2e04b562e218a3bea4ab25b0dfdf8c4cc42131a Duy Nguyen <dnguyen53@mail.sfsu.edu> 1633975810 -0700 clone: from https://github.com/CSC415-Fall2021/csc415-filesystem-anhduynguyen8598.git
csc415-filesystem-anhduynguyen8598/.git/hooks/commit-msg.sample
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message. The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit. The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".
# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
# This example catches duplicate Signed-off-by lines.
test "" = "$(grep '^Signed-off-by: ' "$1" |
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
echo >&2 Duplicate Signed-off-by lines.
exit 1
}
csc415-filesystem-anhduynguyen8598/.git/hooks/pre-rebase.sample
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.
publish=next
basebranch="$1"
if test "$#" = 2
then
topic="refs/heads/$2"
else
topic=`git symbolic-ref HEAD` ||
exit 0 ;# we do not interrupt rebasing detached HEAD
fi
case "$topic" in
refs/heads/??/*)
;;
*)
exit 0 ;# we do not interrupt others.
;;
esac
# Now we are dealing with a topic branch being rebased
# on top of master. Is it OK to rebase it?
# Does the topic really exist?
git show-ref -q "$topic" || {
echo >&2 "No such branch $topic"
exit 1
}
# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
echo >&2 "$topic is fully merged to master; better remove it."
exit 1 ;# we could allow it, but there is no point.
fi
# Is topic ever merged to next? If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
not_in_topic=`git rev-list "^$topic" master`
if test -z "$not_in_topic"
then
echo >&2 "$topic is already up to date with master"
exit 1 ;# we could allow it, but there is no point.
else
exit 0
fi
else
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
/usr/bin/perl -e '
my $topic = $ARGV[0];
my $msg = "* $topic has commits already merged to public branch:\n";
my (%not_in_next) = map {
/^([0-9a-f]+) /;
($1 => 1);
} split(/\n/, $ARGV[1]);
for my $elem (map {
/^([0-9a-f]+) (.*)$/;
[$1 => $2];
} split(/\n/, $ARGV[2])) {
if (!exists $not_in_next{$elem->[0]}) {
if ($msg) {
print STDERR $msg;
undef $msg;
}
print STDERR " $elem->[1]\n";
}
}
' "$topic" "$not_in_next" "$not_in_master"
exit 1
fi
<<\DOC_END
This sample hook safeguards topic branches that have been
published from being rewound.
The workflow assumed here is:
* Once a topic branch forks from "master", "master" is never
merged into it again (either directly or indirectly).
* Once a topic branch is fully cooked and merged into "master",
it is deleted. If you need to build on top of it to correct
earlier mistakes, a new topic branch is created by forking at
the tip of the "master". This is not strictly necessary, but
it makes it easier to keep your history simple.
* Whenever you need to test or publish your changes to topic
branches, merge them into "next" branch.
The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.
With this workflow, you would want to know:
(1) ... if a topic branch has ever been merged to "next". Young
topic branches can have stupid mistakes you would rather
clean up before publishing, and things that have not been
merged into other branches can be easily rebased without
affecting other people. But once it is published, you would
not want to rewind it.
(2) ... if a topic branch has been fully merged to "master".
Then you can delete it. More importantly, you should not
build on top of it -- other people may already want to
change things related to the topic as patches against your
"master", so if you need further changes, it is better to
fork the topic (perhaps with the same name) afresh from the
tip of "master".
Let's look at this example:
o---o---o---o---o---o---o---o---o---o "next"
/ / / /
/ a---a---b A / /
/ / / /
/ / c---c---c---c B /
/ / / \ /
/ / / b---b C \ /
/ / / / \ /
---o---o---o---o---o---o---o---o---o---o---o "master"
A, B and C are topic branches.
* A has one fix since it was merged up to "next".
* B has finished. It has been fully merged up to "master" and "next",
and is ready to be deleted.
* C has not merged to "next" at all.
We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.
To compute (1):
git rev-list ^master ^topic next
git rev-list ^master next
if these match, topic has not merged in next at all.
To compute (2):
git rev-list master..topic
if this is empty, it is fully merged to "master".
DOC_END
csc415-filesystem-anhduynguyen8598/.git/hooks/pre-commit.sample
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=$(git hash-object -t tree /dev/null)
fi
# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --type=bool hooks.allownonascii)
# Redirect output to stderr.
exec 1>&2
# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
# Note that the use of brackets around a tr range is ok here, (it's
# even required, for portability to Solaris 10's /usr/bin/tr), since
# the square bracket bytes happen to fall in the designated range.
test $(git diff --cached --name-only --diff-filter=A -z $against |
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
cat <<\EOF
Error: Attempt to add a non-ASCII file name.
This can cause problems if you want to work with people on other platforms.
To be portable it is advisable to rename the file.
If you know what you are doing you can disable this check using:
git config hooks.allownonascii true
EOF
exit 1
fi
# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --
csc415-filesystem-anhduynguyen8598/.git/hooks/applypatch-msg.sample
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit. The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".
. git-sh-setup
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
:
csc415-filesystem-anhduynguyen8598/.git/hooks/fsmonitor-watchman.sample
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open2;
# An example hook script to integrate Watchman
# (https://facebook.github.io/watchman/) with git to speed up detecting
# new and modified files.
#
# The hook is passed a version (currently 2) and last update token
# formatted as a string and outputs to stdout a new update token and
# all files that have been modified since the update token. Paths must
# be relative to the root of the working tree and separated by a single NUL.
#
# To enable this hook, rename this file to "query-watchman" and set
# 'git config core.fsmonitor .git/hooks/query-watchman'
#
my ($version, $last_update_token) = @ARGV;
# Uncomment for debugging
# print STDERR "$0 $version $last_update_token\n";
# Check the hook interface version
if ($version ne 2) {
die "Unsupported query-fsmonitor hook version '$version'.\n" .
"Falling back to scanning...\n";
}
my $git_work_tree = get_working_dir();
my $retry = 1;
my $json_pkg;
eval {
require JSON::XS;
$json_pkg = "JSON::XS";
1;
} or do {
require JSON::PP;
$json_pkg = "JSON::PP";
};
launch_watchman();
sub launch_watchman {
my $o = watchman_query();
if (is_work_tree_watched($o)) {
output_result($o->{clock}, @{$o->{files}});
}
}
sub output_result {
my ($clockid, @files) = @_;
# Uncomment for debugging watchman output
# open (my $fh, ">", ".git/watchman-output.out");
# binmode $fh, ":utf8";
# print $fh "$clockid\n@files\n";
# close $fh;
binmode STDOUT, ":utf8";
print $clockid;
print "\0";
local $, = "\0";
print @files;
}
sub watchman_clock {
my $response = qx/watchman clock "$git_work_tree"/;
die "Failed to get clock id on '$git_work_tree'.\n" .
"Falling back to scanning...\n" if $? != 0;
return $json_pkg->new->utf8->decode($response);
}
sub watchman_query {
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
or die "open2() failed: $!\n" .
"Falling back to scanning...\n";
# In the query expression below we're asking for names of files that
# changed since $last_update_token but not from the .git folder.
#
# To accomplish this, we're using the "since" generator to use the
# recency index to select candidate nodes and "fields" to limit the
# output to file names only. Then we're using the "expression" term to
# further constrain the results.
if (substr($last_update_token, 0, 1) eq "c") {
$last_update_token = "\"$last_update_token\"";
}
my $query = <<" END";
["query", "$git_work_tree", {
"since": $last_update_token,
"fields": ["name"],
"expression": ["not", ["dirname", ".git"]]
}]
END
# Uncomment for debugging the watchman query
# open (my $fh, ">", ".git/watchman-query.json");
# print $fh $query;
# close $fh;
print CHLD_IN $query;
close CHLD_IN;
my $response = do {local $/; <CHLD_OUT>};
# Uncomment for debugging the watch response
# open ($fh, ">", ".git/watchman-response.json");
# print $fh $response;
# close $fh;
die "Watchman: command returned no output.\n" .
"Falling back to scanning...\n" if $response eq "";
die "Watchman: command returned invalid output: $response\n" .
"Falling back to scanning...\n" unless $response =~ /^\{/;
return $json_pkg->new->utf8->decode($response);
}
sub is_work_tree_watched {
my ($output) = @_;
my $error = $output->{error};
if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {
$retry--;
my $response = qx/watchman watch "$git_work_tree"/;
die "Failed to make watchman watch '$git_work_tree'.\n" .
"Falling back to scanning...\n" if $? != 0;
$output = $json_pkg->new->utf8->decode($response);
$error = $output->{error};
die "Watchman: $error.\n" .
"Falling back to scanning...\n" if $error;
# Uncomment for debugging watchman output
# open (my $fh, ">", ".git/watchman-output.out");
# close $fh;
# Watchman will always return all files on the first query so
# return the fast "everything is dirty" flag to git and do the
# Watchman query just to get it over with now so we won't pay
# the cost in git to look up each individual file.
my $o = watchman_clock();
$error = $output->{error};
die "Watchman: $error.\n" .
"Falling back to scanning...\n" if $error;
output_result($o->{clock}, ("/"));
$last_update_token = $o->{clock};
eval { launch_watchman() };
return 0;
}
die "Watchman: $error.\n" .
"Falling back to scanning...\n" if $error;
return 1;
}
sub get_working_dir {
my $working_dir;
if ($^O =~ 'msys' || $^O =~ 'cygwin') {
$working_dir = Win32::GetCwd();
$working_dir =~ tr/\\/\//;
} else {
require Cwd;
$working_dir = Cwd::cwd();
}
return $working_dir;
}
csc415-filesystem-anhduynguyen8598/.git/hooks/pre-receive.sample
#!/bin/sh
#
# An example hook script to make use of push options.
# The example simply echoes all push options that start with 'echoback='
# and rejects all pushes when the "reject" push option is used.
#
# To enable this hook, rename this file to "pre-receive".
if test -n "$GIT_PUSH_OPTION_COUNT"
then
i=0
while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
do
eval "value=\$GIT_PUSH_OPTION_$i"
case "$value" in
echoback=*)
echo "echo from the pre-receive-hook: ${value#*=}" >&2
;;
reject)
exit 1
esac
i=$((i + 1))
done
fi
csc415-filesystem-anhduynguyen8598/.git/hooks/prepare-commit-msg.sample
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source. The hook's purpose is to edit the commit
# message file. If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".
# This hook includes three examples. The first one removes the
# "# Please enter the commit message..." help message.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output. It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited. This is rarely a good idea.
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3
/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"
# case "$COMMIT_SOURCE,$SHA1" in
# ,|template,)
# /usr/bin/perl -i.bak -pe '
# print "\n" . `git diff --cached --name-status -r`
# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
# *) ;;
# esac
# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
# if test -z "$COMMIT_SOURCE"
# then
# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
# fi
csc415-filesystem-anhduynguyen8598/.git/hooks/post-update.sample
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".
exec git update-server-info
csc415-filesystem-anhduynguyen8598/.git/hooks/pre-merge-commit.sample
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git merge" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message to
# stderr if it wants to stop the merge commit.
#
# To enable this hook, rename this file to "pre-merge-commit".
. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
exec "$GIT_DIR/hooks/pre-commit"
:
csc415-filesystem-anhduynguyen8598/.git/hooks/pre-applypatch.sample
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".
. git-sh-setup
precommit="$(git rev-parse --git-path hooks/pre-commit)"
test -x "$precommit" && exec "$precommit" ${1+"$@"}
:
csc415-filesystem-anhduynguyen8598/.git/hooks/pre-push.sample
#!/bin/sh
# An example hook script to verify what is about to be pushed. Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed. If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
# <local ref> <local oid> <remote ref> <remote oid>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).
remote="$1"
url="$2"
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
while read local_ref local_oid remote_ref remote_oid
do
if test "$local_oid" = "$zero"
then
# Handle delete
:
else
if test "$remote_oid" = "$zero"
then
# New branch, examine all commits
range="$local_oid"
else
# Update to existing branch, examine new commits
range="$remote_oid..$local_oid"
fi
# Check for WIP commit
commit=$(git rev-list -n 1 --grep '^WIP' "$range")
if test -n "$commit"
then
echo >&2 "Found WIP commit in $local_ref, not pushing"
exit 1
fi
fi
done
exit 0
csc415-filesystem-anhduynguyen8598/.git/hooks/update.sample
#!/bin/sh
#
# An example hook script to block unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
# This boolean sets whether unannotated tags will be allowed into the
# repository. By default they won't be.
# hooks.allowdeletetag
# This boolean sets whether deleting tags will be allowed in the
# repository. By default they won't be.
# hooks.allowmodifytag
# This boolean sets whether a tag may be modified after creation. By default
# it won't be.
# hooks.allowdeletebranch
# This boolean sets whether deleting branches will be allowed in the
# repository. By default they won't be.
# hooks.denycreatebranch
# This boolean sets whether remotely creating branches will be denied
# in the repository. By default this is allowed.
#
# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"
# --- Safety check
if [ -z "$GIT_DIR" ]; then
echo "Don't run this script from the command line." >&2
echo " (if you want, you could supply GIT_DIR then run" >&2
echo " $0 <ref> <oldrev> <newrev>)" >&2
exit 1
fi
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
exit 1
fi
# --- Config
allowunannotated=$(git config --type=bool hooks.allowunannotated)
allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch)
denycreatebranch=$(git config --type=bool hooks.denycreatebranch)
allowdeletetag=$(git config --type=bool hooks.allowdeletetag)
allowmodifytag=$(git config --type=bool hooks.allowmodifytag)
# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
echo "*** Project description file hasn't been set" >&2
exit 1
;;
esac
# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
if [ "$newrev" = "$zero" ]; then
newrev_type=delete
else
newrev_type=$(git cat-file -t $newrev)
fi
case "$refname","$newrev_type" in
refs/tags/*,commit)
# un-annotated tag
short_refname=${refname##refs/tags/}
if [ "$allowunannotated" != "true" ]; then
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
exit 1
fi
;;
refs/tags/*,delete)
# delete tag
if [ "$allowdeletetag" != "true" ]; then
echo "*** Deleting a tag is not allowed in this repository" >&2
exit 1
fi
;;
refs/tags/*,tag)
# annotated tag
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
then
echo "*** Tag '$refname' already exists." >&2
echo "*** Modifying a tag is not allowed in this repository." >&2
exit 1
fi
;;
refs/heads/*,commit)
# branch
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
echo "*** Creating a branch is not allowed in this repository" >&2
exit 1
fi
;;
refs/heads/*,delete)
# delete branch
if [ "$allowdeletebranch" != "true" ]; then
echo "*** Deleting a branch is not allowed in this repository" >&2
exit 1
fi
;;
refs/remotes/*,commit)
# tracking branch
;;
refs/remotes/*,delete)
# delete tracking branch
if [ "$allowdeletebranch" != "true" ]; then
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
exit 1
fi
;;
*)
# Anything else (is there anything else?)
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
exit 1
;;
esac
# --- Finished
exit 0
csc415-filesystem-anhduynguyen8598/.git/hooks/push-to-checkout.sample
#!/bin/sh
# An example hook script to update a checked-out tree on a git push.
#
# This hook is invoked by git-receive-pack(1) when it reacts to git
# push and updates reference(s) in its repository, and when the push
# tries to update the branch that is currently checked out and the
# receive.denyCurrentBranch configuration variable is set to
# updateInstead.
#
# By default, such a push is refused if the working tree and the index
# of the remote repository has any difference from the currently
# checked out commit; when both the working tree and the index match
# the current commit, they are updated to match the newly pushed tip
# of the branch. This hook is to be used to override the default
# behaviour; however the code below reimplements the default behaviour
# as a starting point for convenient modification.
#
# The hook receives the commit with which the tip of the current
# branch is going to be updated:
commit=$1
# It can exit with a non-zero status to refuse the push (when it does
# so, it must not modify the index or the working tree).
die () {
echo >&2 "$*"
exit 1
}
# Or it can make any necessary changes to the working tree and to the
# index to bring them to the desired state when the tip of the current
# branch is updated to the new commit, and exit with a zero status.
#
# For example, the hook can simply run git read-tree -u -m HEAD "$1"
# in order to emulate git fetch that is run in the reverse direction
# with git push, as the two-tree form of git read-tree -u -m is
# essentially the same as git switch or git checkout that switches
# branches while keeping the local changes in the working tree that do
# not interfere with the difference between the branches.
# The below is a more-or-less exact translation to shell of the C code
# for the default behaviour for git's push-to-checkout hook defined in
# the push_to_deploy() function in builtin/receive-pack.c.
#
# Note that the hook will be executed from the repository directory,
# not from the working tree, so if you want to perform operations on
# the working tree, you will have to adapt your code accordingly, e.g.
# by adding "cd .." or using relative paths.
if ! git update-index -q --ignore-submodules --refresh
then
die "Up-to-date check failed"
fi
if ! git diff-files --quiet --ignore-submodules --
then
die "Working directory has unstaged changes"
fi
# This is a rough translation of:
#
# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX
if git cat-file -e HEAD 2>/dev/null
then
head=HEAD
else
head=$(git hash-object -t tree --stdin </dev/null)
fi
if ! git diff-index --quiet --cached --ignore-submodules $head --
then
die "Working directory has staged changes"
fi
if ! git read-tree -u -m "$commit"
then
die "Could not update working tree to new HEAD"
fi
csc415-filesystem-anhduynguyen8598/.git/objects/pack/pack-78a2709ac0bbbede70bc7d7c830d2dd1933e90af.pack
csc415-filesystem-anhduynguyen8598/.git/objects/pack/pack-78a2709ac0bbbede70bc7d7c830d2dd1933e90af.idx
csc415-filesystem-anhduynguyen8598/.git/refs/heads/main
d2e04b562e218a3bea4ab25b0dfdf8c4cc42131a
csc415-filesystem-anhduynguyen8598/.git/logs/refs/heads/main
0000000000000000000000000000000000000000 d2e04b562e218a3bea4ab25b0dfdf8c4cc42131a Duy Nguyen <dnguyen53@mail.sfsu.edu> 1633975810 -0700 clone: from https://github.com/CSC415-Fall2021/csc415-filesystem-anhduynguyen8598.git
csc415-filesystem-anhduynguyen8598/.git/refs/remotes/origin/HEAD
ref: refs/remotes/origin/main
csc415-filesystem-anhduynguyen8598/.git/logs/refs/remotes/origin/HEAD
0000000000000000000000000000000000000000 d2e04b562e218a3bea4ab25b0dfdf8c4cc42131a Duy Nguyen <dnguyen53@mail.sfsu.edu> 1633975810 -0700 clone: from https://github.com/CSC415-Fall2021/csc415-filesystem-anhduynguyen8598.git
CSC-415 – Operating Systems Individual Report
1
Name: ___________________________________ Student ID: __________________________
Term: __________________ Date: __________________ Team Name: ___________________
Regarding You
What did you get out of the project?
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
Name (Include yourself in #1)
Contribution (1 low, 5 High)
Knowledge (1 little, 5 lot)
Engagement (1 none, 5 enthusiastic)
Communication 1 none, 5 constant)
1
2
3
4
5
CSC-415 – Operating Systems Individual Report
2
What did you struggle with?
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
What was easy for you?
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
Other Comments:
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________
Name:
Student ID:
Term:
Date:
Team Name:
1:
2:
3:
4:
5:
What did you struggle with 1:
What was easy for you 1:
Other Comments 1:
Contribution1:
Communication5:
Knowledge1:
Engagement1:
Communication1:
Contribution2:
Knowledge2:
Engagement2:
Communication2:
Contribution3:
Knowledge3:
Engagement3:
Communication3:
Contribution4:
Knowledge4:
Engagement4:
Communication4:
Contribution5:
Knowledge5:
Engagement5:
What did you get out of the project 1:
Steps for milestone 1:
Remember – in order to manipulate anything on disk, you must first bring it into memory
1) Determine if you need to format the volume or not.
a. In fsInit is the initFileSystem function where you want to start this code
b. Malloc a Block of memory as your VCB pointer and LBAread block 0
c. You now have a pointer to a structure, so look at the signature (magic number)
in your structure and see if it matches.
d. If it matches you have initialized your volume already – If not you need to
initialize it
2) If you need to initialize it
a. Initialize the values in your volume control block
b. Initialize free space (see that below)
c. Initialize the root directory (see that below)
d. Set the values returned from above in the VCB
e. LBAwrite the VCB to block 0
3) Initialize the Free Space
a. Let’s assume you are using a bitmap for your free space management. Given the
default size, you will have 19,531 blocks – so you need 19,531 bits or 2,442 bytes
or 5 blocks (so from this alone you can see that the free space map is NOT part of
the VCB, but rather the VCB would have the block number where your free space
starts).
b. Before you can initialize the bits, you must have the memory to do so. So malloc
the space needed. In this example 5 * blockSize
c. Now you have a pointer to at least 2442 bytes (actually 2560 bytes). Now you
can first decide where you want to store this free space map (like from block 1 –
5 inclusive), and you know block 0 is the VCB so the first 6 bits should be marked
used and the rest marked free.
d. Now write that to disk with LBAwrite(theFreeSpaceMap, 5, 1) – that is write 5
blocks starting from block 1
e. Return the starting block number of the free space to the VCB init that called you
so it knows how to set the VCB structure variable that indicates where free space
starts. Or mark it yourself if the VCB is a global structure.
4) Initialize the Root Directory
a. First again, you need memory – how much?
b. Decide how many Directory Entries (DE) you want for a directory (at least an
initial amount). I will use 50 for this example.
c. Now multiply the size of your directory entry by the number of entries. For
example, if my directory entry is 60 bytes, I would multiply 60 * 50 = 3000 bytes
needed.
d. Now you need to determine how many blocks you need. In the example that
would be 6 blocks. But wait…. 6 blocks is 3072 bytes and I am only using 3000
bytes, and my directory entry is only 60 bytes, so I can actually fit 51 directory
entries in the space of 3072 bytes (now only wasting 12 bytes instead of 72).
e. Now you have a pointer to an array of directory entries. Loop through them (in
our case for (i = 0; i < 51; i++) and initialize each directory entry structure to be in
a known free state.
f. Now ask the free space system for 6 blocks. It should return to you the starting
block number for those 6 blocks.
g. Now set the first directory entry to the “.” Directory. So, the name is “.”, the size
is 3060 bytes, it starts at block number (whatever the free space system
returned above), the time stamps are the current time, it is a directory, etc.
h. Now set the second directory entry to “..”, but since this is the root, it is the
same as the “.” except the name is “..” rather than “.”
i. Now write the root directory – 6 blocks starting from block (what was returned
from the free space allocation).
j. Return the starting block number of the root directory (or set it in the VCB
yourself)
Note – while your system is running you only ever init or read the freespace map once. Keep it
in memory so you can manipulate it as needed and when you change it just write it out to disk
again so that the disk reflects the current state.
Explanations and Answers
0
No answers posted
Post your Answer - free or at a fee
NB: Post a homework question for free and get answers - free or paid homework help.
Get answers to: Operating Systems - File System or similar questions only at Tutlance.
Related Questions
- Need Help With Java Program Hangman
- Write A Program That Implements The Davis-Putnam Algorithm.
- Linux Driver - Kernel C Programming
- Intro To Compsci, Python Assignment, Nothing Beyond Introductory Python Stuff.
- Public Key Encryption And Aes Encryption
- Create A Computer Program Using C++ Basic Language To Check The Strength Of A Password
- Assembly Language Programming Help
- 3 Java Arraylist Problems And Dataset
- Implement The Given C File In Mips Assembly. Using Mars 4.5
- Neural Net Back Propagation Error Calculations
- Python Socket Programming Dictionary Attack
- Macro Assignment In Two Ways For The Following
- Data And Database Management With Sql
- Udp Client Socket Programming In Python
- Linux Command Line Using Vim And Bash
- The Questions Are All About Parallel Processing
- Reading Accelerometer Data Using Stm32F411
- Computer Systems Architecture.
- Msc Projuct: An Investigation Into The Cyber Security Risks Of Home\Small Business Setups
- Create A Class Called 'Indexedlist' Which Encapsulates A [Simplified] Index-Based List Collection.
- One Python Programming Question. Robot Olympics Club
- Python Programming Assignment Questions
- Need Help With A Simple C++ Assignment
- Math Foundations For Computer Science
- The Project Is Almost Complete!
- Algorithm Question/ Pseudocode
- Computer Security Principle And Practice By William Stallings 4Th Edition
- Data Structure / Java Project / Computer Science
- Your Job In This Lab Is To Write Mymalloc.c, Which Implements The Procedures Defined In Mymalloc.h:
- Someone Can Help Me On It ? ????????????????????
- Subnet Taple And Cisco Command
- Computer Maths In Jupyter Notebook
- Computer Architecture Assembly
- Create Time Class That Supports Custom Operations
- Worked Examples To Formal Logic Questions
- Write A Program Using Pep9 Using Assembly Language
- Creating A Java Program That Includes Methods In Sorting Algorithms.
- Please I Need Help Cooding In Python
- Computability And Complexity Assignment
- Assignment/Report On An Organisation
- Java Programming Assignment. Knowledge Of Sorting Algorithms.
- Comp Sci Assignment Due At 12 Today
- Data Flow Analysis Need To Be Submitted Tomorrow Oct 24 ( From Programming Language Analysis)
- C++, Java Or Python The Modification Should Be Significant, Requiring A Change In Both Syntax And Semantics
- Converting A C Program Into Mips Assembly Program Using Mars4.5
- I Need Help With Fundamentals Of Computer Systems Homework
- Finishing A Pascal Program That Is A Translation Of A C Program
- C++ College Homework: Implement The Rsa Encryption/Decryption Algorithm
- Bank Coding Project That Uses Grpc To Establish Communications Between Customer And Branch
- Practical Project, Reading Files And Creating An Output Array