#include #include #include #include #include #include #include #include #include #include "fuse.h" #include "fuseactions.h" /* * Steps to formatting inodes: * 1) Check if file exists already in directory * 2) If file does not exist in directory, provide new inode * 3) Inodes are placed inside of inodes that are directories * */ // TODO: Take BlockStruct out of InodeStruct // Make a method for turning names into Inodes // Main handler for Fuse void Fuse(int argc, char* argv[]) { FileSystem* fsptr; fuseArgStruct fuseArgs; GetArguments(argc, argv, &fuseArgs); OpenFS(&fuseArgs, argv[0]); fsptr = SetupFS(&fuseArgs); RunFuse(fsptr, &fuseArgs); TearDownFS(); } // Gets command line arguments and puts information into fuseArgs void GetArguments(int argc, char* argv[], fuseArgStruct* fuseArgs) { for (int i = 0; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1] == 'l') fuseArgs->list = 1; if (argv[i][0] == '-' && argv[i][1] == 'a') { fuseArgs->add = 1; fuseArgs->toAdd = strdup(argv[i+1]); } if (argv[i][0] == '-' && argv[i][1] == 'r') { fuseArgs->remove = 1; fuseArgs->toRemove = strdup(argv[i+1]); } if (argv[i][0] == '-' && argv[i][1] == 'e') { fuseArgs->extract = 1; fuseArgs->toExtract = strdup(argv[i+1]); } if (argv[i][0] == '-' && argv[i][1] == 'f') { fuseArgs->filefsname = 1; fuseArgs->fsname = strdup(argv[i+1]); } } } void OpenFS(fuseArgStruct* fuseArgs, char* programPath) { if (!fuseArgs->filefsname) FuseUsageError(programPath); fuseArgs->fd = open(fuseArgs->fsname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (fuseArgs->fd == -1) { perror("open failed"); exit(EXIT_FAILURE); } if (zerosize(fuseArgs->fd)) fuseArgs->newfs = 1; if (fuseArgs->newfs) { if (lseek(fuseArgs->fd, FSSIZE-1, SEEK_SET) == -1) { perror("seek failed"); exit(EXIT_FAILURE); } if (write(fuseArgs->fd, "\0", 1) == -1) { perror("write failed"); exit(EXIT_FAILURE); } } return; } FileSystem* SetupFS(fuseArgStruct* fuseArgs) { FileSystem* fs; MapFS(fuseArgs->fd); LoadFS(&fs); if (fuseArgs->newfs) FormatFS(fs); return fs; } void RunFuse(FileSystem* fs, fuseArgStruct* fuseArgs) { if (fuseArgs->add) AddFileToFS(fs, fuseArgs->toAdd); if (fuseArgs->remove) RemoveFileFromFS(fs, fuseArgs->toRemove); if (fuseArgs->extract) ExtractFileFromFS(fs, fuseArgs->toExtract); if(fuseArgs->list) ListFS(fs); return; } void TearDownFS(void) { UnmapFS(); return; } // Initialize entire fuseStruct void FuseStructInit(fuseArgStruct* fuseStruct) { fuseStruct->create = 0; fuseStruct->list = 0; fuseStruct->add = 0; fuseStruct->remove = 0; fuseStruct->extract = 0; fuseStruct->toAdd = NULL; fuseStruct->toRemove = NULL; fuseStruct->toExtract = NULL; fuseStruct->fsname = NULL; fuseStruct->fd = -1; fuseStruct->newfs = 0; fuseStruct->filefsname = 0; } // Print error if usage is wrong void FuseUsageError(char* programPath) { fprintf(stderr, "Usage %s [-l] [-a path] [-e path] [-r path] -f name\n", programPath); exit(EXIT_FAILURE); } // Return bool of if the size is 0 int zerosize(int fd) { struct stat stats; fstat(fd, &stats); if(stats.st_size == 0) return 1; return 0; } // Finds next empty bit in Free Block List int FindEmptyBitPosition(int number) { for (int i = 0; i < 32; i++) if ((~number & (1 << i)) == (1 << i)) return i; return -1; } // Gets next free inode number and returns it ino_t GetFreeBlockNumber(int fbl[]) { int bitPosition; for (int i = 0; i < (DEFAULTINODEMAX/32); i++) { bitPosition = FindEmptyBitPosition(fbl[i]); if (bitPosition >= 0) { fbl[i] = (fbl[i] | (1 << bitPosition)); return ((i*32) + bitPosition); } } return -1; } ino_t GetFreeInodeNumber(Inode inodes[]) { for (int i = 0; i < DEFAULTINODEMAX; i++) if (!(inodes[i].isValid)) return i; return -1; } // Function for setting all defaults of filesystem void SetFileSystemDefaults(FileSystem* fs) { fs->superBlock.blockSize = DEFAULTBLOCKSIZE; fs->superBlock.blockCount = DEFAULTBLOCKMAX; fs->superBlock.inodeCount = DEFAULTINODEMAX; for (int i = 0; i < 4; i++) fs->fbl.freeList[i] = 0; for (int i = 0; i < DEFAULTINODEMAX; i++) fs->inodes[i].isValid = 0; return; } void SetupRootDirectory(FileSystem* fs) { fs->inodes[0].isValid = 1; return; }