Node based file systems, offset and FAT

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
LPeter
Member
Member
Posts: 30
Joined: Wed Jan 28, 2015 7:41 am

Node based file systems, offset and FAT

Post by LPeter »

So I'm just a beginner OS developer and I look at a lot of implementations to see how others solve different tasks. A file node structure in a VFS could look like this:

Code: Select all

typedef struct
{
    char name[128];
    uint32_t flags;
    uint32_t inode;
    uint32_t length;
    /* And some function pointers for various file operations */
} fs_node;
And so my VFS fread could look like:

Code: Select all

vfs_fread(fs_node *fnode, uint32_t offset, uint32_t length, uint8_t *buffer);
This is what I see a lot, the offset is passed as a parameter. So my first question is: Then how would I keep tract of how much I've read from a file? Should I make a field called offset for fs_node? Then I only need to pass the offset parameter if I want to offset it even more for some reason.
Second thing that the first file system that I've implemented is FAT12. FAT files need to store their current cluster (or base cluster, depends on if I want to calculate with offsets). So should I add another field to the struct, something like fs_offset? (I plan to support ext and other file systems too) Or is there a better design?

Thanks in advance!
User avatar
darkinsanity
Member
Member
Posts: 45
Joined: Wed Sep 17, 2008 3:59 am
Location: Germany

Re: Node based file systems, offset and FAT

Post by darkinsanity »

LPeter wrote:And so my VFS fread could look like:

Code: Select all

vfs_fread(fs_node *fnode, uint32_t offset, uint32_t length, uint8_t *buffer);
This is what I see a lot, the offset is passed as a parameter. So my first question is: Then how would I keep tract of how much I've read from a file?
By making vfs_fread return the number of bytes it was actually able to read and letting the caller figure it out?
LPeter wrote:Should I make a field called offset for fs_node? Then I only need to pass the offset parameter if I want to offset it even more for some reason.
Imagine two processes opening the same file for read access, and both of them do a seek operation. What would happen?
LPeter
Member
Member
Posts: 30
Joined: Wed Jan 28, 2015 7:41 am

Re: Node based file systems, offset and FAT

Post by LPeter »

darkinsanity wrote:
LPeter wrote:And so my VFS fread could look like:

Code: Select all

vfs_fread(fs_node *fnode, uint32_t offset, uint32_t length, uint8_t *buffer);
This is what I see a lot, the offset is passed as a parameter. So my first question is: Then how would I keep tract of how much I've read from a file?
By making vfs_fread return the number of bytes it was actually able to read and letting the caller figure it out?
LPeter wrote:Should I make a field called offset for fs_node? Then I only need to pass the offset parameter if I want to offset it even more for some reason.
Imagine two processes opening the same file for read access, and both of them do a seek operation. What would happen?
Yeah that's what I'm currently doing. Maybe I'll stay with it then. But how about my other problem?
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Node based file systems, offset and FAT

Post by onlyonemac »

In order to implement file access, you need two structures:
  • The structure describing the filesystem node itself
  • A structure describing a particular process's use of that file
You've got the first of those two, but the second (commonly called a "file pointer", "file descriptor", or "file handle") is missing, and that is the source of your problems. You need to have a file handle structure which keeps a record of
  • what file has been opened (probably some kind of pointer to the node structure which you've already described),
  • where the process is in reading the file (the "offset" that you're talking about),
  • and what mode the process has opened the file in (read-only, read-write, or whatever other modes are applicable to your operating system).
This structure is kept separate from the filesystem node itself because it is specific to each user of the file; the filesystem node is global to all users of the file.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
LPeter
Member
Member
Posts: 30
Joined: Wed Jan 28, 2015 7:41 am

Re: Node based file systems, offset and FAT

Post by LPeter »

So something like:

Code: Select all

struct fat_file_handle
{
    fs_node *node;
    /* fat specific stuff... */
};
And fat_fread would cast the node pointer into fat_file_handle? (So the handle would be created but it's first field - the node - would be returned). Good idea?
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Node based file systems, offset and FAT

Post by onlyonemac »

LPeter wrote:So something like:

Code: Select all

struct fat_file_handle
{
    fs_node *node;
    /* fat specific stuff... */
};
And fat_fread would cast the node pointer into fat_file_handle? (So the handle would be created but it's first field - the node - would be returned). Good idea?
No. Don't cast between pointers and handles; they are separate structures.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
Post Reply