please point out the mistake I could have made. I am trying to implement a simple file system based on the guide provided here. I have decided to implement the file system interface as read and writes to a file. The code still needs refactoring but here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TOTAL_FILE_SIZE 4227104
#define TOTAL_DIR_ENTRIES 1024
#define NUM_FAT_ENTRIES 8192
typedef struct super_block {
unsigned short total_sectors; /* max value 8192 */
unsigned short bytes_per_sector; /* max value 512 */
unsigned short available_sectors; /* max value 8192 */
unsigned short total_dir_entries; /* fixing it to 1024 */
unsigned short available_dir_entries; /* max value 1024 */
unsigned char label[8]; /* label for the filesystem */
/* These are not used */
unsigned short sectors_per_cluster; /* We always set it to 1*/
unsigned char reserved[12]; /* Just making it 32 bytes */
} super_block;
/* Each dir entry is 16 bytes */
typedef struct dir_entry {
unsigned char file_name[10];
unsigned short fat_entry;
unsigned int size;
} dir_entry;
/* Each FAT entry is 2 bytes; times 8192 entries => 16 KiB
* size of data block (sector) can be varied
* number of dir_entries can be varied
* the number of fat entries is same as the number of data blocks
* the number of data blocks can be varied total_sectors
*
* the total size of our filesystem is => +
* size of super block = 32 bytes
* size of dir entry = 16 KiB
* size of fat = 16 KiB
* total size of data block = 8192 * 512 bytes => 4 MiB
* Total bytes = 4227104
* End: sFAT.c
*/
/* mkfs.c
*
*/
/* Later: integrate label of FS to argument */
void mkfs(const char *filename) {
/* Write super block, dir entries and fat table and data blocks to the file */
super_block sb = {
.total_sectors = 8192,
.bytes_per_sector = 512,
.available_sectors = 512,
.total_dir_entries = 1024,
.available_dir_entries = 1024,
.sectors_per_cluster = 1,
.label = "Demo FS",
.reserved = ""
};
dir_entry default_dir_entry = {
.file_name = "",
.fat_entry = 0,
.size = 0,
};
unsigned short default_fat_entry = 0;
/* Write sb, 1024 dir_entry and 8192 default_fat_entry and 4 MiB data to create our filesystem */
FILE *f = fopen(filename, "wb");
if (f == NULL) {
fprintf(stderr, "Error opening file: %s\n", filename);
}
/* Write super block */
/* I seem to encounter SEGMENTATION FAULT in this line */
fwrite(&sb, sizeof (super_block), 1, f);
/* Write dir entries */
fwrite(&default_dir_entry, sizeof(dir_entry), TOTAL_DIR_ENTRIES, f);
fwrite(&default_fat_entry, sizeof(unsigned short), NUM_FAT_ENTRIES, f);
char *data;
data = malloc(TOTAL_FILE_SIZE - ftell(f));
fwrite(data, TOTAL_FILE_SIZE - ftell(f), 1, f);
free(data);
fclose(f);
fprintf(stdout, "Filesystem created successfully!\n");
}
/* End: mkfs.c */
/* main.c
*
*/
void display_help(char *program_name) {
fprintf(stdout, "Usage: %s [function name]\n", program_name);
fprintf(stdout, "Functions:\n");
fprintf(stdout," mkfs\n");
}
int main(int argc, char *argv[]) {
if (argc < 2) {
display_help(argv[0]);
return 1;
}
if (strcmp(argv[1], "mkfs") == 0) {
mkfs(argv[2]);
}
else {
display_help(argv[0]);
return 1;
}
return 0;
}
/*
*
* End: main.c
*/
I encounter segmentation fault on the fwrite
statment of the super block structure. However, if I comment out that line, the file runs successfully. What mistake could I have possibly made?
I had misunderstood the documentation of fwrite
. The error was due to:
fwrite
, when supplied with nitems
argument, will write contents from ptr
upto nitems
times taking the size to be the size
.
fwrite(&default_dir_entry, sizeof(dir_entry), TOTAL_DIR_ENTRIES, f);
The code is working now.