Creating a filesystem

Introduction

This page will present how to create a new filesystem driver for the VFS.

This is an advanced topic, not usually explored by many people. Please make sure you are familiar with VFS basics before going further.

In order to create a file system driver, we must create a library that implements a certain set of functions.

Typically, our driver would then also provide some 'initialization' function that takes care of registering the driver with the VFS.

Ideally, our driver would also provide a small substrate to auto-register it with the VFS, taking away the need for the user to do it manually.

Skeleton

Below is a complete skeleton for a file system driver. This will cover all aspects presented above including dfe.conf and substrate.

This skeleton will be for an imaginary file system driver called 'exfs' (example fs).

Library definition (dfe.conf)

Let's start with the dfe.conf for our library:

name: exfs
type: lib
deps:
  - vfs
  - storage

Driver code

Next, below is the code skeleton for the driver implementation. While this is shown as a single C file, it can of course be split into multiple files for easier management.

  1 #include <storage/storage.h>
  2 #include <vfs/vfs.h>
  3 
  4 // File System Name
  5 #define EXFS        "exfs"
  6 
  7 // EXFS-specific Mountpoint Data Structure
  8 struct exfs_mountpoint_data
  9 {
 10     /* Our file system can store some information
 11      * about the mountpoint here.
 12      */
 13 };
 14 
 15 // Define the above structure as VFS Mountpoint Data
 16 vfs_mountpoint_data_struct(exfs_mountpoint_data);
 17 
 18 // Handle Data Structure
 19 struct exfs_handle_data
 20 {
 21     /* Our file system can store some information
 22      * about the object handle here.
 23      */
 24 };
 25 
 26 // Define the above structure as VFS Handle Data
 27 vfs_handle_data_struct(exfs_handle_data);
 28 
 29 // Structure to hold our File System info
 30 struct vfs_fs exfs;
 31 
 32 // Mount a Storage Device through Example File System
 33 uint8_t exfs_mount(struct vfs_mountpoint *mp, struct storage *st)
 34 {
 35     struct exfs_mountpoint_data *d;
 36 
 37     // Acquire & Setup FS Data Structure
 38     d = (struct exfs_mountpoint_data *)(mp->data);
 39 
 40     /* Our file system driver can store information
 41      * in the mountpoint data structure.
 42      */
 43 
 44     // ToDo: Write implementation
 45     return 1;
 46 }
 47 
 48 // Un-Mount
 49 uint8_t exfs_unmount(struct vfs_mountpoint *mp)
 50 {
 51     // ToDo: Write implementation
 52     return 1;
 53 }
 54 
 55 // Create Object
 56 uint8_t exfs_mkobj(struct vfs_mountpoint *mp, char *path, uint8_t path_len, uint8_t otype)
 57 {
 58     // ToDo: Write implementation
 59     return 1;
 60 }
 61 
 62 // Destroy Object
 63 uint8_t exfs_rmobj(struct vfs_mountpoint *mp, char *path, uint8_t path_len)
 64 {
 65     // ToDo: Write implementation
 66     return 1;
 67 }
 68 
 69 // Move Object
 70 uint8_t exfs_mvobj(struct vfs_mountpoint *mp, char *src, uint8_t src_len, char *dst, uint8_t dst_len)
 71 {
 72     // ToDo: Write implementation
 73     return 1;
 74 }
 75 
 76 // Open Handle
 77 uint8_t exfs_open(struct vfs_mountpoint *mp, struct vfs_handle *h, char *path, uint8_t path_len)
 78 {
 79     struct exfs_handle_data *d;
 80 
 81     // Acquire Handle Data Structure
 82     d = (struct exfs_handle_data *)(h->data);
 83 
 84     // ToDo: Write implementation
 85     return 1;
 86 }
 87 
 88 // Close Handle
 89 void exfs_close(struct vfs_mountpoint *mp, struct vfs_handle *h)
 90 {
 91     // ToDo: Write implementation
 92 }
 93 
 94 // Truncate File
 95 uint8_t exfs_truncate(struct vfs_mountpoint *mp, struct vfs_handle *h, uint64_t size)
 96 {
 97     // ToDo: Write implementation
 98     return 1;
 99 }
100 
101 // Read File
102 uint8_t exfs_read(struct vfs_mountpoint *mp, struct vfs_handle *h, void *data, uint16_t size, uint16_t *rd)
103 {
104     // ToDo: Write implementation
105     return 1;
106 }
107 
108 // Write File
109 uint8_t exfs_write(struct vfs_mountpoint *mp, struct vfs_handle *h, void *data, uint16_t size, uint16_t *wr)
110 {
111     // ToDo: Write implementation
112     return 1;
113 }
114 
115 // Read Directory
116 uint8_t exfs_readdir(struct vfs_mountpoint *mp, struct vfs_handle *h, struct vfs_dirent *e)
117 {
118     // ToDo: Write implementation
119     return 1;
120 }
121 
122 // Initialization (register file system into VFS)
123 void exfs_init()
124 {
125     // Initialize File System Interface
126     vfs_register(&exfs, exfs_mount, exfs_unmount, exfs_mkobj, exfs_rmobj, exfs_mvobj, exfs_open, exfs_close, exfs_truncate, exfs_read, exfs_write, exfs_readdir, EXFS);
127 }

Substrate

Let's also create a small substrate to make our file system automatically register itself into the VFS:

# Provider for our File System
provide :exfs do |params|

	# Use VFS
	uses :vfs

	# Provide EXFS
	uses_global_header 'exfs/exfs.h' # Replace this with a header file containing the definition of our 'init' function
	register_code section: :init, code: "exfs_init();"
end

# Register Filesystem
register_filesystem :exfs