Adding files and printing works mostly, issue with first directory not solved
This commit is contained in:
parent
0e6af896c3
commit
88087f6050
3
.gitignore
vendored
3
.gitignore
vendored
@ -53,3 +53,6 @@ dkms.conf
|
|||||||
*.test
|
*.test
|
||||||
*.sh
|
*.sh
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
|
# Custom
|
||||||
|
.vscode
|
||||||
|
12
Makefile
12
Makefile
@ -8,10 +8,11 @@ all: compile link
|
|||||||
compile:
|
compile:
|
||||||
gcc $(INC) -c -o build/main.o src/main.c
|
gcc $(INC) -c -o build/main.o src/main.c
|
||||||
gcc $(INC) -c -o build/fuse.o src/fuse.c
|
gcc $(INC) -c -o build/fuse.o src/fuse.c
|
||||||
gcc $(INC) -c -o build/fuseactions.o src/fuseactions.c
|
gcc $(INC) -c -o build/fsactions.o src/fsactions.c
|
||||||
|
gcc $(INC) -c -o build/fsinterface.o src/fsinterface.c
|
||||||
|
|
||||||
link:
|
link:
|
||||||
gcc -o bin/fuse.out build/fuseactions.o build/fuse.o build/main.o
|
gcc -o bin/fuse.out build/fsinterface.o build/fsactions.o build/fuse.o build/main.o
|
||||||
|
|
||||||
test: testCompile testLink testExec
|
test: testCompile testLink testExec
|
||||||
|
|
||||||
@ -19,12 +20,13 @@ testCompile:
|
|||||||
gcc $(INC) $(UNITY) -g -c -o build/unity.o $(UNITYPATH)/unity.c
|
gcc $(INC) $(UNITY) -g -c -o build/unity.o $(UNITYPATH)/unity.c
|
||||||
gcc $(INC) $(WARNINGS) -c -o build/main.o src/main.c
|
gcc $(INC) $(WARNINGS) -c -o build/main.o src/main.c
|
||||||
gcc $(INC) $(WARNINGS) -c -o build/fuse.o src/fuse.c
|
gcc $(INC) $(WARNINGS) -c -o build/fuse.o src/fuse.c
|
||||||
gcc $(INC) $(WARNINGS) -c -o build/fuseactions.o src/fuseactions.c
|
gcc $(INC) $(WARNINGS) -c -o build/fsactions.o src/fsactions.c
|
||||||
|
gcc $(INC) $(WARNINGS) -c -o build/fsinterface.o src/fsinterface.c
|
||||||
gcc $(INC) -g -c -o build/test.o test/test.c
|
gcc $(INC) -g -c -o build/test.o test/test.c
|
||||||
|
|
||||||
testLink:
|
testLink:
|
||||||
gcc -g -o bin/test.out build/fuseactions.o build/fuse.o build/test.o build/unity.o
|
gcc -g -o bin/test.out build/fsinterface.o build/fsactions.o build/fuse.o build/test.o build/unity.o
|
||||||
gcc -o bin/fuse.out build/fuseactions.o build/fuse.o build/main.o
|
gcc -g -o bin/fuse.out build/fsinterface.o build/fsactions.o build/fuse.o build/main.o
|
||||||
|
|
||||||
testExec:
|
testExec:
|
||||||
./bin/test.out
|
./bin/test.out
|
||||||
|
20
include/fsactions.h
Normal file
20
include/fsactions.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef FSACTIONS_H
|
||||||
|
#define FSACTIONS_H
|
||||||
|
|
||||||
|
#include "fusestructs.h"
|
||||||
|
|
||||||
|
void AddFileToFS(FileSystem* fs, char* fname);
|
||||||
|
void ListFS(FileSystem* fs);
|
||||||
|
void _ListFS_(FileSystem* fs, ino_t inodeNumber, short unsigned numtabs);
|
||||||
|
void RemoveFileFromFS(FileSystem* fs, char* fname);
|
||||||
|
void ExtractFileFromFS(FileSystem* fs, char* fname);
|
||||||
|
|
||||||
|
ino_t GetFreeInodeNumber(Inode inodes[]);
|
||||||
|
ino_t GetFreeBlockNumber(int fbl[], unsigned short size);
|
||||||
|
int FindEmptyBitPosition(int number);
|
||||||
|
int FindNextDirectory(char* fname);
|
||||||
|
int IsDirectorySetup(Inode inode, ino_t* inodePosition, char* directoryName);
|
||||||
|
void SetFileSystemDefaults(FileSystem* fs);
|
||||||
|
void SetupRootDirectory(FileSystem* fs);
|
||||||
|
|
||||||
|
#endif
|
16
include/fsinterface.h
Normal file
16
include/fsinterface.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef FSINTERFACE_H
|
||||||
|
#define FSINTERFACE_H
|
||||||
|
|
||||||
|
#include "fusestructs.h"
|
||||||
|
|
||||||
|
void OpenFS(fuseArgStruct* fuseArgs, char* programPath);
|
||||||
|
FileSystem* SetupFS(fuseArgStruct* fuseArgs);
|
||||||
|
void MapFS(int fd);
|
||||||
|
void UnmapFS(void);
|
||||||
|
void FormatFS(FileSystem* fs);
|
||||||
|
void LoadFS(FileSystem** fs);
|
||||||
|
void TearDownFS(void);
|
||||||
|
int zerosize(int fd);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -2,95 +2,12 @@
|
|||||||
#define FUSE_H
|
#define FUSE_H
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include "fusestructs.h"
|
||||||
#define DEFAULTINODEMAX 128
|
|
||||||
#define DEFAULTBLOCKSIZE 512 // Size in bytes
|
|
||||||
#define DEFAULTBLOCKMAX 16384
|
|
||||||
|
|
||||||
typedef struct fuseArgStruct
|
|
||||||
{
|
|
||||||
int create;
|
|
||||||
int list;
|
|
||||||
int add;
|
|
||||||
int remove;
|
|
||||||
int extract;
|
|
||||||
char* toAdd;
|
|
||||||
char* toRemove;
|
|
||||||
char* toExtract;
|
|
||||||
char* fsname;
|
|
||||||
int fd;
|
|
||||||
int newfs;
|
|
||||||
int filefsname;
|
|
||||||
} fuseArgStruct;
|
|
||||||
|
|
||||||
typedef struct SuperBlock
|
|
||||||
{
|
|
||||||
blksize_t blockSize;
|
|
||||||
blkcnt_t blockCount;
|
|
||||||
unsigned long inodeCount;
|
|
||||||
} SuperBlock;
|
|
||||||
|
|
||||||
typedef struct FreeBlockList
|
|
||||||
{
|
|
||||||
int freeList[DEFAULTINODEMAX/32];
|
|
||||||
} FreeBlockList;
|
|
||||||
|
|
||||||
// 128 Blocks
|
|
||||||
typedef struct DataBlock
|
|
||||||
{
|
|
||||||
char byte[DEFAULTBLOCKSIZE];
|
|
||||||
} DataBlock;
|
|
||||||
|
|
||||||
// typedef struct InodeInfo
|
|
||||||
// {
|
|
||||||
// // char filePath[256];
|
|
||||||
// // off_t fileSize;
|
|
||||||
// ino_t inode;
|
|
||||||
// unsigned int isDirectory : 1;
|
|
||||||
// unsigned int isPrinted : 1;
|
|
||||||
// unsigned int isValid : 1;
|
|
||||||
// } InodeInfo;
|
|
||||||
|
|
||||||
// Inode * 128 + number
|
|
||||||
// Directblock == Files/Directories inside an inode?
|
|
||||||
typedef struct DirectBlock
|
|
||||||
{
|
|
||||||
unsigned int isValid : 1;
|
|
||||||
unsigned int isDirectory : 1;
|
|
||||||
char name[256];
|
|
||||||
ino_t inode;
|
|
||||||
off_t size;
|
|
||||||
} DirectBlock;
|
|
||||||
|
|
||||||
// Inode 0 is root
|
|
||||||
// Inode * 128
|
|
||||||
typedef struct Inode
|
|
||||||
{
|
|
||||||
unsigned int isValid : 1;
|
|
||||||
DirectBlock inodeBlocks[DEFAULTINODEMAX];
|
|
||||||
} Inode;
|
|
||||||
|
|
||||||
typedef struct FileSystem
|
|
||||||
{
|
|
||||||
SuperBlock superBlock;
|
|
||||||
FreeBlockList fbl;
|
|
||||||
Inode inodes[DEFAULTINODEMAX];
|
|
||||||
DataBlock dataBlocks[DEFAULTBLOCKMAX];
|
|
||||||
} FileSystem;
|
|
||||||
|
|
||||||
void Fuse(int argc, char* argv[]);
|
void Fuse(int argc, char* argv[]);
|
||||||
void GetArguments(int argc, char* argv[], fuseArgStruct* fuseArgs);
|
|
||||||
void OpenFS(fuseArgStruct* fuseArgs, char* programPath);
|
|
||||||
FileSystem* SetupFS(fuseArgStruct* fuseArgs);
|
|
||||||
void RunFuse(FileSystem* fs, fuseArgStruct* fuseArgs);
|
|
||||||
void TearDownFS(void);
|
|
||||||
void FuseStructInit(fuseArgStruct* fuseStruct);
|
void FuseStructInit(fuseArgStruct* fuseStruct);
|
||||||
void FuseUsageError(char* programPath);
|
void FuseUsageError(char* programPath);
|
||||||
int zerosize(int fd);
|
void GetArguments(int argc, char* argv[], fuseArgStruct* fuseArgs);
|
||||||
int FindEmptyBitPosition(int number);
|
void RunFuse(FileSystem* fs, fuseArgStruct* fuseArgs);
|
||||||
ino_t GetFreeInodeNumber(Inode inodes[]);
|
|
||||||
ino_t GetFreeBlockNumber(int fbl[]);
|
|
||||||
void SetFileSystemDefaults(FileSystem* fs);
|
|
||||||
void SetupRootDirectory(FileSystem* fs);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
#ifndef FUSEACTIONS_H
|
|
||||||
#define FUSEACTIONS_H
|
|
||||||
|
|
||||||
#include "fuse.h"
|
|
||||||
|
|
||||||
#define FSSIZE 10000000
|
|
||||||
|
|
||||||
extern unsigned char* tempfs;
|
|
||||||
|
|
||||||
void MapFS(int fd);
|
|
||||||
void UnmapFS(void);
|
|
||||||
void FormatFS(FileSystem* fs);
|
|
||||||
void LoadFS(FileSystem** fs);
|
|
||||||
void ListFS(FileSystem* fs);
|
|
||||||
void _RecursivePrintFS_(FileSystem* fs, ino_t inodePosition);
|
|
||||||
int FindNextDirectory(char* fname);
|
|
||||||
void AddFileToFS(FileSystem* fs, char* fname);
|
|
||||||
void _RecursiveAddFS_(FileSystem* fs, char* fname);
|
|
||||||
void RemoveFileFromFS(FileSystem* fs, char* fname);
|
|
||||||
void ExtractFileFromFS(FileSystem* fs, char* fname);
|
|
||||||
|
|
||||||
#endif
|
|
72
include/fusestructs.h
Normal file
72
include/fusestructs.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#ifndef FUSESTRUCTS_H
|
||||||
|
#define FUSESTRUCTS_H
|
||||||
|
|
||||||
|
#define DEFAULTINODEMAX 128
|
||||||
|
#define DEFAULTBLOCKSIZE 512 // Size in bytes
|
||||||
|
#define DEFAULTBLOCKMAX 16384
|
||||||
|
#define FSSIZE 10000000
|
||||||
|
|
||||||
|
extern unsigned char* tempfs;
|
||||||
|
|
||||||
|
typedef struct fuseArgStruct
|
||||||
|
{
|
||||||
|
int create;
|
||||||
|
int list;
|
||||||
|
int add;
|
||||||
|
int remove;
|
||||||
|
int extract;
|
||||||
|
char* toAdd;
|
||||||
|
char* toRemove;
|
||||||
|
char* toExtract;
|
||||||
|
char* fsname;
|
||||||
|
int fd;
|
||||||
|
int newfs;
|
||||||
|
int filefsname;
|
||||||
|
} fuseArgStruct;
|
||||||
|
|
||||||
|
typedef struct SuperBlock
|
||||||
|
{
|
||||||
|
blksize_t blockSize;
|
||||||
|
blkcnt_t blockCount;
|
||||||
|
unsigned long inodeCount;
|
||||||
|
} SuperBlock;
|
||||||
|
|
||||||
|
typedef struct FreeBlockList
|
||||||
|
{
|
||||||
|
int freeList[DEFAULTBLOCKMAX/32];
|
||||||
|
} FreeBlockList;
|
||||||
|
|
||||||
|
// 128 Blocks
|
||||||
|
typedef struct DataBlock
|
||||||
|
{
|
||||||
|
char byte[DEFAULTBLOCKSIZE];
|
||||||
|
} DataBlock;
|
||||||
|
|
||||||
|
// Inode * 128 + number
|
||||||
|
// Directblock == Files/Directories inside an inode?
|
||||||
|
typedef struct DirectBlock
|
||||||
|
{
|
||||||
|
unsigned int isValid : 1;
|
||||||
|
unsigned int isDirectory : 1;
|
||||||
|
char name[256];
|
||||||
|
ino_t inode;
|
||||||
|
off_t size;
|
||||||
|
} DirectBlock;
|
||||||
|
|
||||||
|
// Inode 0 is root
|
||||||
|
// Inode * 128
|
||||||
|
typedef struct Inode
|
||||||
|
{
|
||||||
|
unsigned int isValid : 1;
|
||||||
|
DirectBlock blocks[DEFAULTINODEMAX];
|
||||||
|
} Inode;
|
||||||
|
|
||||||
|
typedef struct FileSystem
|
||||||
|
{
|
||||||
|
SuperBlock superBlock;
|
||||||
|
FreeBlockList fbl;
|
||||||
|
Inode inodes[DEFAULTINODEMAX];
|
||||||
|
DataBlock dataBlocks[DEFAULTBLOCKMAX];
|
||||||
|
} FileSystem;
|
||||||
|
|
||||||
|
#endif
|
207
src/fsactions.c
Normal file
207
src/fsactions.c
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "fsactions.h"
|
||||||
|
#include "fusestructs.h"
|
||||||
|
|
||||||
|
/* Things to set for directory:
|
||||||
|
* Name, isValid, inode, isDirectory=1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Things to set for file:
|
||||||
|
* Name, size, isValid, inode, isDirectory=0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Adds a file to the filesystem
|
||||||
|
// TODO: Fix implementation to add starting at Inode 0
|
||||||
|
void AddFileToFS(FileSystem* fs, char* fname)
|
||||||
|
{
|
||||||
|
struct stat tempstat;
|
||||||
|
ino_t currentInode = 0;
|
||||||
|
ino_t newInode;
|
||||||
|
int newDirectBlock;
|
||||||
|
int tempfbl[4];
|
||||||
|
char* tempname;
|
||||||
|
stat(fname, &tempstat);
|
||||||
|
// Get first directory, labelled by 0 to splitLocation-1,
|
||||||
|
// assuming splitLocation not 0;
|
||||||
|
int splitLocation = FindNextDirectory(fname);
|
||||||
|
if (splitLocation == 0)
|
||||||
|
{
|
||||||
|
fname = fname + 1;
|
||||||
|
splitLocation = FindNextDirectory(fname);
|
||||||
|
}
|
||||||
|
// While there is a '/', make a new inode out of left and keep right side
|
||||||
|
while (splitLocation > -1)
|
||||||
|
{
|
||||||
|
// First: check if directory already exists in current inode
|
||||||
|
// if yes, then go to that inode and start with next directory
|
||||||
|
// Second: get a number for the next free direct block
|
||||||
|
// Third: get a free inode number
|
||||||
|
// Fourth: set info for direct block
|
||||||
|
tempname = strndup(fname, splitLocation - 1);
|
||||||
|
if (IsDirectorySetup(fs->inodes[currentInode], ¤tInode, tempname))
|
||||||
|
continue;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
tempfbl[i] = (currentInode*4) + i;
|
||||||
|
newDirectBlock = GetFreeBlockNumber(tempfbl, 4);
|
||||||
|
newInode = GetFreeInodeNumber(fs->inodes);
|
||||||
|
strcpy(fs->inodes[currentInode].blocks[newDirectBlock].name, tempname);
|
||||||
|
free(tempname);
|
||||||
|
fs->inodes[currentInode].blocks[newDirectBlock].isValid = 1;
|
||||||
|
fs->inodes[currentInode].blocks[newDirectBlock].isDirectory = 1;
|
||||||
|
fs->inodes[currentInode].blocks[newDirectBlock].inode = newInode;
|
||||||
|
currentInode = newInode;
|
||||||
|
fs->inodes[currentInode].isValid = 1;
|
||||||
|
// SetDirectBlock(fs->inodes[currentInode].blocks[newDirectBlock]);
|
||||||
|
// SetNewInode();
|
||||||
|
// fs->inodes[currentInode].blocks;
|
||||||
|
// inodeNumber = GetFreeInodeNumber(fs->inodes);
|
||||||
|
fname = fname + splitLocation + 1;
|
||||||
|
splitLocation = FindNextDirectory(fname);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
tempfbl[i] = (currentInode*4) + i;
|
||||||
|
newDirectBlock = GetFreeBlockNumber(tempfbl, 4);
|
||||||
|
fs->inodes[currentInode].blocks[newDirectBlock].isValid = 1;
|
||||||
|
fs->inodes[currentInode].blocks[newDirectBlock].size = tempstat.st_size;
|
||||||
|
strcpy(fs->inodes[currentInode].blocks[newDirectBlock].name, fname);
|
||||||
|
// SetFileInDirectory();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List path names of all used inodes
|
||||||
|
// TODO: Fix implementation to print starting at Inode 0
|
||||||
|
void ListFS(FileSystem* fs)
|
||||||
|
{
|
||||||
|
Inode* fsRoot = &(fs->inodes[0]);
|
||||||
|
printf("/\n");
|
||||||
|
for (int i = 0; i < fs->superBlock.inodeCount; i++)
|
||||||
|
{
|
||||||
|
if (!(fsRoot->blocks[i].isValid))
|
||||||
|
continue;
|
||||||
|
printf("%s\n", fsRoot->blocks[i].name);
|
||||||
|
if (fsRoot->blocks[i].isDirectory)
|
||||||
|
_ListFS_(fs, fsRoot->blocks[i].inode, 1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _ListFS_(FileSystem* fs, ino_t inodeNumber, short unsigned numtabs)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < fs->superBlock.inodeCount; i++)
|
||||||
|
{
|
||||||
|
if (!(fs->inodes[inodeNumber].blocks[i].isValid))
|
||||||
|
continue;
|
||||||
|
for (int j = 0; j < numtabs; j++)
|
||||||
|
printf("\t");
|
||||||
|
printf("%s\n", fs->inodes[inodeNumber].blocks[i].name);
|
||||||
|
if (fs->inodes[inodeNumber].blocks[i].isDirectory)
|
||||||
|
_ListFS_(fs, fs->inodes[inodeNumber].blocks[i].inode, numtabs + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a file from the filesystem
|
||||||
|
// TODO: Fix function so that it adds directories, then the file after
|
||||||
|
void RemoveFileFromFS(FileSystem* fs, char* fname)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract a file from the filesystem
|
||||||
|
// TODO: Fix function so that it adds directories, then the file after
|
||||||
|
void ExtractFileFromFS(FileSystem* fs, char* fname)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get the next free inode number
|
||||||
|
ino_t GetFreeInodeNumber(Inode inodes[])
|
||||||
|
{
|
||||||
|
for (int i = 0; i < DEFAULTINODEMAX; i++)
|
||||||
|
if (!(inodes[i].isValid))
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets next free inode number and returns it
|
||||||
|
ino_t GetFreeBlockNumber(int fbl[], unsigned short size)
|
||||||
|
{
|
||||||
|
int bitPosition;
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
bitPosition = FindEmptyBitPosition(fbl[i]);
|
||||||
|
if (bitPosition >= 0)
|
||||||
|
{
|
||||||
|
fbl[i] = (fbl[i] | (1 << bitPosition));
|
||||||
|
return ((i*32) + bitPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds the next split character in the path
|
||||||
|
int FindNextDirectory(char* fname)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (fname[i] != '\0')
|
||||||
|
{
|
||||||
|
if (fname[i] == '/')
|
||||||
|
return i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool function checks if directory is setup. If it is, then sets the inode
|
||||||
|
int IsDirectorySetup(Inode inode, ino_t* inodePosition, char* directoryName)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 128; i++)
|
||||||
|
{
|
||||||
|
if (!(inode.blocks[i].isValid))
|
||||||
|
continue;
|
||||||
|
if (!(inode.blocks[i].isDirectory))
|
||||||
|
continue;
|
||||||
|
if (strcmp(inode.blocks[i].name, directoryName) == 0)
|
||||||
|
{
|
||||||
|
*inodePosition = i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets first inode as root directory
|
||||||
|
void SetupRootDirectory(FileSystem* fs)
|
||||||
|
{
|
||||||
|
fs->inodes[0].isValid = 1;
|
||||||
|
return;
|
||||||
|
}
|
107
src/fsinterface.c
Normal file
107
src/fsinterface.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include "fuse.h"
|
||||||
|
#include "fsactions.h"
|
||||||
|
#include "fsinterface.h"
|
||||||
|
#include "fusestructs.h"
|
||||||
|
|
||||||
|
unsigned char* tempfs;
|
||||||
|
|
||||||
|
// Opens the filesystem file for usage
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connecting filesystem to memory
|
||||||
|
FileSystem* SetupFS(fuseArgStruct* fuseArgs)
|
||||||
|
{
|
||||||
|
FileSystem* fs;
|
||||||
|
MapFS(fuseArgs->fd);
|
||||||
|
LoadFS(&fs);
|
||||||
|
if (fuseArgs->newfs)
|
||||||
|
FormatFS(fs);
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map filesystem to memory
|
||||||
|
void MapFS(int fd)
|
||||||
|
{
|
||||||
|
tempfs = mmap(NULL, FSSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
if (tempfs == NULL)
|
||||||
|
{
|
||||||
|
perror("mmap failed");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmap filesystem from memory
|
||||||
|
void UnmapFS(void)
|
||||||
|
{
|
||||||
|
munmap(tempfs, FSSIZE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets defaults of a new filesystem
|
||||||
|
void FormatFS(FileSystem* fs)
|
||||||
|
{
|
||||||
|
SetFileSystemDefaults(fs);
|
||||||
|
SetupRootDirectory(fs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect global pointer to structured local pointer
|
||||||
|
void LoadFS(FileSystem** fs)
|
||||||
|
{
|
||||||
|
*fs = (FileSystem*) (tempfs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup after using filesystem
|
||||||
|
void TearDownFS(void)
|
||||||
|
{
|
||||||
|
UnmapFS();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
112
src/fuse.c
112
src/fuse.c
@ -8,7 +8,8 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
#include "fuseactions.h"
|
#include "fsactions.h"
|
||||||
|
#include "fsinterface.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Steps to formatting inodes:
|
* Steps to formatting inodes:
|
||||||
@ -63,44 +64,7 @@ void GetArguments(int argc, char* argv[], fuseArgStruct* fuseArgs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenFS(fuseArgStruct* fuseArgs, char* programPath)
|
// Runs the fuse functions that were previously marked
|
||||||
{
|
|
||||||
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)
|
void RunFuse(FileSystem* fs, fuseArgStruct* fuseArgs)
|
||||||
{
|
{
|
||||||
if (fuseArgs->add)
|
if (fuseArgs->add)
|
||||||
@ -114,12 +78,6 @@ void RunFuse(FileSystem* fs, fuseArgStruct* fuseArgs)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TearDownFS(void)
|
|
||||||
{
|
|
||||||
UnmapFS();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize entire fuseStruct
|
// Initialize entire fuseStruct
|
||||||
void FuseStructInit(fuseArgStruct* fuseStruct)
|
void FuseStructInit(fuseArgStruct* fuseStruct)
|
||||||
{
|
{
|
||||||
@ -135,6 +93,7 @@ void FuseStructInit(fuseArgStruct* fuseStruct)
|
|||||||
fuseStruct->fd = -1;
|
fuseStruct->fd = -1;
|
||||||
fuseStruct->newfs = 0;
|
fuseStruct->newfs = 0;
|
||||||
fuseStruct->filefsname = 0;
|
fuseStruct->filefsname = 0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print error if usage is wrong
|
// Print error if usage is wrong
|
||||||
@ -144,66 +103,3 @@ void FuseUsageError(char* programPath)
|
|||||||
programPath);
|
programPath);
|
||||||
exit(EXIT_FAILURE);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include "fuseactions.h"
|
|
||||||
|
|
||||||
unsigned char* tempfs;
|
|
||||||
|
|
||||||
// Map filesystem to memory
|
|
||||||
void MapFS(int fd)
|
|
||||||
{
|
|
||||||
tempfs = mmap(NULL, FSSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
||||||
if (tempfs == NULL)
|
|
||||||
{
|
|
||||||
perror("mmap failed");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmap filesystem from memory
|
|
||||||
void UnmapFS(void)
|
|
||||||
{
|
|
||||||
munmap(tempfs, FSSIZE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets defaults of a new filesystem
|
|
||||||
void FormatFS(FileSystem* fs)
|
|
||||||
{
|
|
||||||
SetFileSystemDefaults(fs);
|
|
||||||
SetupRootDirectory(fs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redirect global pointer to structured local pointer
|
|
||||||
void LoadFS(FileSystem** fs)
|
|
||||||
{
|
|
||||||
*fs = (FileSystem*) (tempfs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// List path names of all used inodes
|
|
||||||
// TODO: Fix implementation to print starting at Inode 0
|
|
||||||
void ListFS(FileSystem* fs)
|
|
||||||
{
|
|
||||||
Inode* fsRoot = &(fs->inodes[0]);
|
|
||||||
printf("/\n");
|
|
||||||
for (int i = 0; i < fs->superBlock.inodeCount; i++)
|
|
||||||
{
|
|
||||||
if (!(fsRoot->inodeBlocks[i].isValid))
|
|
||||||
continue;
|
|
||||||
printf("%s\n", fsRoot->inodeBlocks[i].name);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Depreciated due to new structure method
|
|
||||||
void _RecursivePrintFS_(FileSystem* fs, ino_t inodePosition)
|
|
||||||
{
|
|
||||||
// for (int i = 0; i < DEFAULTINODEMAX; i++)
|
|
||||||
// {
|
|
||||||
// if (!(fs->inodes[inodePosition].inodeBlocks[i].info.isValid))
|
|
||||||
// continue;
|
|
||||||
// printf("%s\n", fs->inodes[inodePosition].inodeBlocks[i].info.filePath);
|
|
||||||
// if (fs->inodes[inodePosition].inodeBlocks[i].info.isDirectory)
|
|
||||||
// _RecursivePrintFS_(fs, fs->inodes[inodePosition].inodeBlocks[i].info.inode);
|
|
||||||
// }
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FindNextDirectory(char* fname)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
while (fname[i] != '\0')
|
|
||||||
{
|
|
||||||
if (fname[i] == '/')
|
|
||||||
return i;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds a file to the filesystem
|
|
||||||
// TODO: Fix implementation to add starting at Inode 0
|
|
||||||
void AddFileToFS(FileSystem* fs, char* fname)
|
|
||||||
{
|
|
||||||
struct stat statBuffer;
|
|
||||||
ino_t inodeNumber = GetFreeInodeNumber(fs->fbl.freeList);
|
|
||||||
// strcpy(fs->inodes[inodeNumber].info.filePath, fname);
|
|
||||||
// stat(fname, &statBuffer);
|
|
||||||
// fs->inodes[inodeNumber].info.fileSize = statBuffer.st_size;
|
|
||||||
// int fd = open(fname, O_RDONLY);
|
|
||||||
// if (fd < 0)
|
|
||||||
// {
|
|
||||||
// perror(fname);
|
|
||||||
// exit(1);
|
|
||||||
// }
|
|
||||||
// read(fd, fs->inodes[inodeNumber].dataBlocks.byte, sizeof(BlockStruct));
|
|
||||||
// close(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Depreciated due to new structure method
|
|
||||||
void _RecursiveAddFS_(FileSystem* fs, char* fname)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove a file from the filesystem
|
|
||||||
// TODO: Fix function so that it adds directories, then the file after
|
|
||||||
void RemoveFileFromFS(FileSystem* fs, char* fname)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract a file from the filesystem
|
|
||||||
// TODO: Fix function so that it adds directories, then the file after
|
|
||||||
void ExtractFileFromFS(FileSystem* fs, char* fname)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
13
test/test.c
13
test/test.c
@ -3,7 +3,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "unity/unity.h"
|
#include "unity/unity.h"
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
#include "fuseactions.h"
|
#include "fsactions.h"
|
||||||
|
#include "fsinterface.h"
|
||||||
|
#include "fusestructs.h"
|
||||||
|
|
||||||
FileSystem* fakefs;
|
FileSystem* fakefs;
|
||||||
fuseArgStruct dummyFuse;
|
fuseArgStruct dummyFuse;
|
||||||
@ -63,6 +65,14 @@ void Test_FileSystem_Should_AddFile(void)
|
|||||||
GetArguments(argc, argv, &dummyFuse);
|
GetArguments(argc, argv, &dummyFuse);
|
||||||
RunFuse(fakefs, &dummyFuse);
|
RunFuse(fakefs, &dummyFuse);
|
||||||
TEST_ASSERT_EQUAL(1, fakefs->inodes[1].isValid);
|
TEST_ASSERT_EQUAL(1, fakefs->inodes[1].isValid);
|
||||||
|
TEST_ASSERT_EQUAL_CHAR_ARRAY("test1.txt", fakefs->inodes[2].blocks[0].name, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Test_FileSystem_Should_ListContents(void)
|
||||||
|
{
|
||||||
|
Fuse(argc, argv);
|
||||||
|
printf("%s\n", fakefs->inodes[0].blocks[0].name);
|
||||||
|
TEST_IGNORE_MESSAGE("This only runs the list operation. Check info yourself.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
@ -72,5 +82,6 @@ int main(void)
|
|||||||
RUN_TEST(Test_FindEmptyBitPosition_Should_ReturnPosition);
|
RUN_TEST(Test_FindEmptyBitPosition_Should_ReturnPosition);
|
||||||
RUN_TEST(Test_FileSystem_Should_SuccessfullyOpen);
|
RUN_TEST(Test_FileSystem_Should_SuccessfullyOpen);
|
||||||
RUN_TEST(Test_FileSystem_Should_AddFile);
|
RUN_TEST(Test_FileSystem_Should_AddFile);
|
||||||
|
RUN_TEST(Test_FileSystem_Should_ListContents);
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user