Welcome to Code Forum!

Join a community that supports you and your coding journey from day one. We strive to be a friendly, supportive community that empowers everyone to be better developers. By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.

    GIF shows where to locate </> in the thread and or post editor toolbar.
    To learn more about how to use our BBCode feature, review our "How to post your code into threads" here.

    Thank you, Code Forum.

Help with EXT3 Filesystem work

FatihBabba

New Coder
I need to program an ext3 file system, but I'm stuck,
I brought together the first requirement ,the instructions are:

C:
#ifndef EXT3LIB_H
#define EXT3LIB_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ext3.h"
#include "tools.h"
#include <libext3.h>

#define BLOCK_SIZE 0x400
#define SUPERBLOCK_POS 0x400
#define GROUPDESC_START_POS 0x800

/* read_superblock:
superblock is read from file pointer fp to ext3_super_block structure in sb up to sb_len bytes
return value: 0 on success
*/
int read_superblock(FILE *fp, struct ext3_super_block *sb, unsigned int sb_len)
{
fseek(fp,SUPERBLOCK_POS,SEEK_SET);
int len_estimated = sb_len < BLOCK_SIZE ? sb_len : BLOCK_SIZE;
int len_read = fread(sb,sizeof(char), len_estimated,fp);
return len_read == len_estimated ? 0 : -1;
}

/* read_group_descriptor:
group descriptor number gd_num is read from file pointer fp to ext3_group_desc structure in gd up to gd_len bytes
return value: 0 on success
*/
int read_group_descriptor(FILE *fp, struct ext3_group_desc *gd, unsigned int gd_len, unsigned int gd_num)

/* read_inode_in_group:
inode number in_num in group descriptor in gd is read from file pointer fp to ext3_inode structure in inode up to in_len bytes
parameters are used from superblock in sb
return value: 0 on success
*/
int read_inode_in_group(FILE *fp, struct ext3_inode *in, unsigned int in_len, struct ext3_super_block *sb, struct ext3_group_desc *gd, unsigned int in_num);

/* read_data_block:
data block number block_num is read from file pointer fp to buffer up to buffer_len bytes
return value: number of bytes is returned on success, 0 on failure
*/
int read_data_block(FILE *fp, char* buffer, unsigned int buffer_len, unsigned int block_num);

/* get_next_directory_entry:
directory entry at position start_pos is read from buffer to ext3_dir_entry_2 strucutre dirent
return value: position of next directory entry in buffer, -1 is last entry is reached
*/
int get_next_directory_entry(char* buffer, unsigned int buffer_len, struct ext3_dir_entry_2 *dirent, unsigned int start_pos);

/* get_next_path_element:
extracts next path element from path starting at offset 0 to element if path_len >= 0
return value: position of next element in path, 1 if no element can be found
*/
int get_next_path_element(char* path, int path_len, char* element);

#endif /* EXT3LIB_H */
 
Last edited by a moderator:
I have given this my best shot but I don't have enough information for everything and had to guess a bit. So there are a few variables/macros/structs you'll need to fit to the rest of your files but all in all nothing too difficult. However, I have taken a few shortcuts because I just wanted to show how it is supposed to look. Let's call this a bit of an advanced "pseudo"code that just needs a few things changed ^^

Disclaimer: I will not take responsibility for using insecure/deprecated functions. Please make sure you check the code for problems yourself as I gave this more of a quick and dirty approach because I assume this is homework by the way the header looks. (Also the reason for the comment heavy code)

Tell me what grade you got if anyone else needs this in the future.

C:
/* Reads the group descriptor
*
* @param fp - Filepointer for reading a file
* @param gd - Some group descriptory struct
* @param gd_len - Length of the group descriptor
* @param gd_num - Amount of group descriptors
*
* @return 0 for success or -1 for failure
*/
int read_group_descriptor(FILE *fp, struct ext3_group_desc *gd, unsigned int gd_len, unsigned int gd_num) {
   fseek(fp, GROUPDESC_START_POS + (0x20 * gd_num), SEEK_SET); // Seek the file position at the start position of the group descriptor(GD) + the amount of GDs multiplied by size
   int len_estimated = gd_len < 0x20 ? gd_len : 0x20; // Get the estimated length. Smallest size is 0x20
   int len_read = fread(gd, sizeof(char), len_estimated, fp); // fread returns the number of read elements as size_t - Change if you need to use fread_s for security
   return len_read == len_estimated ? 0 : -1; // Return 0 on success or -1 on failure (make sure to catch the return value after calling this function somewhere else)
}

/* Again, you'll need to replace according to your structs and variables - I am just guessing names and where they probably would be
*
* @param fp - Filepointer for reading a file
* @param in - Some inode struct?
* @param in_len - Inode length(?)
* @param sb - Again some struct I don't know the content of
* @param gd - Something group descriptory
* @param in_num - The number of inodes I assume
*
* @return 0 for success or -1 for failure
*/
int read_inode_in_group(FILE *fp, struct ext3_inode *in, unsigned int in_len, struct ext3_super_block *sb, struct ext3_group_desc *gd, unsigned int in_num) {
    fseek(fp, (/*One of the structs - maybe gd?*/->inode_table * BLOCK_SIZE) + (/*One of the structs*/->inode_size * (in_num - 1)), SEEK_SET); // Seek again but with a slightly more tricky size calculation (make sure it matches your version)
   int len_read = fread(in, sizeof(char), in_len, fp); // Get read length for the check again
   return len_read == in_len ? 0 : -1; // Return 0 on success or -1 on failure
}

/* Hope I understood it correctly
*
* @param fp - Filepointer for reading a file
* @param buffer - Acts as a buffer for the file content
* @param buffer_len - The length of the buffer
* @block_num - Amount of blocks
*
* @return 0 for success or -1 for failure
*/
int read_data_block(FILE *fp, char* buffer, unsigned int buffer_len, unsigned int block_num) {
   fseek(fp, (buffer_len * block_num), SEEK_SET); // Simple size calculation (amount of blocks times the length)
   int len_read = fread(buffer, sizeof(char), buffer_len, fp); // Get read length for the check again
   return len_read == buffer_len ? len_read : 0; // Return 0 on success or -1 on failure
}

/* I opted to use the deprecated memcpy function here to copy between buffers (might need to be included).
* Make sure to check if using an insecure version (instead of memcpy_s/wmemcpy_s) is okay here.
*
* @param buffer - Is a buffer for directory entry
* @param buffer_len - Length of the buffer
* @param dirent - What I assume is directory entry but no idea what it really contains
* @start_pos - The start position for the buffer
*
* @return next directory position or -1 if the end is reached
*/
int get_next_directory_entry(char* buffer, unsigned int buffer_len, struct ext3_dir_entry_2 *dirent, unsigned int start_pos) {
   memcpy(dirent, &buffer[start_pos], BYTES); // Destination, Source, number of bytes according to the comment
   return dirent->SOME_LENGTH_TO_COMPARE_TO >= BYTES ? -1 : (start_pos + dirent->SOME_LENGTH_TO_COMPARE_TO);
}

/*
* Again, make sure if deprecated functions can be used. Couldn't be bothered to take the full route if I don't have all the information needed
* Gets the next path element if len >= 0
*
* @param path - An array containing a path to check
* @param path_len - The length of the path
* @param element - I am assuming this is to be used for the next element
*
* @return i + 1 - Next element in the path
* @return 1 - No element found
*/
int get_next_path_element(char* path, int path_len, char* element) {
   int i;
   *element = '\0'; // 0 termination is important
  
   for (i = 0; i <= path_len; i++) {
      if (*(path + i) == '/') { // Iterates through the path parameter - Essentially path[i] == '/'
         memcpy(element, path, i); // Copy the path to element. Dst, Src, Num
         *(element + i) = '\0'; // Makes sure the string is terminated (element[i] = '\0')
         return i + 1;
      }
      else if (i == path_len) { // Full path without '/'
         memcpy(element, path, i + 1); // Copy the path to element.
         *(element + 1 + i) = '\0'; // Terminate element
         return i + 1;
      }
   }

   return 1;
}
 

Buy us a coffee!

Buy me a coffee.
Back
Top Bottom