| 1 | |
| 2 | = Block devices = |
| 3 | |
| 4 | == Block device API == |
| 5 | |
| 6 | Ajouter un champ flag dans les requetes, on peut imaginer |
| 7 | * un attribut nocache |
| 8 | |
| 9 | == Buffer cache == |
| 10 | |
| 11 | Au niveau Block device |
| 12 | * Dans deux structures: |
| 13 | * Une liste chainee de LRU |
| 14 | * Une hash table pour faire les lookups |
| 15 | * avoir un attribut dirty |
| 16 | |
| 17 | = VFS = |
| 18 | |
| 19 | {{{ |
| 20 | |
| 21 | struct vfs_mount_s |
| 22 | { |
| 23 | struct device_s *dev; |
| 24 | struct vfs_mount_private_s *pv; |
| 25 | struct vfs_node_s *mountpoint; |
| 26 | }; |
| 27 | |
| 28 | struct vfs_node_ops_s |
| 29 | { |
| 30 | error_t (*read)(struct vfs_node_s *node, void *data, pos_t pos, size_t size); |
| 31 | error_t (*write)(struct vfs_node_s *node, const void *data, pos_t pos, size_t size); |
| 32 | error_t (*trunc)(struct vfs_node_s *node, size_t size); |
| 33 | struct vfs_node_s* (*create)(struct vfs_node_s *node, int flags); |
| 34 | error_t (*link)(struct vfs_node_s *node, struct vfs_node_s *newparent, const char *newname, size_t newnamelen, int op); |
| 35 | error_t (*unlink)(struct vfs_node_s *node); |
| 36 | struct vfs_node_s* (*lookup)(struct vfs_node_s *parent, const char *name, size_t namelen); |
| 37 | void (*list_dir)(struct vfs_node_s *parent, void (*fcn)(char *name, size_t namelen, struct vfs_stat_s *st, void *pv), void *pv); |
| 38 | }; |
| 39 | |
| 40 | struct vfs_node_s |
| 41 | { |
| 42 | struct vfs_node_s *parent; |
| 43 | HASH(const char *name, struct vfs_node_s*) children; |
| 44 | struct vfs_node_private_s *pv; |
| 45 | struct vfs_mount_s *m; |
| 46 | int refcount; |
| 47 | const struct vfs_node_ops_s *ops; |
| 48 | }; |
| 49 | |
| 50 | struct vfs_file_s |
| 51 | { |
| 52 | int mode; |
| 53 | struct vfs_node_s *node; |
| 54 | }; |
| 55 | |
| 56 | }}} |
| 57 | |
| 58 | == FS API == |
| 59 | |
| 60 | = FAT = |
| 61 | |
| 62 | En couches: |
| 63 | |
| 64 | == VFAT (gestion des noms longs) == |
| 65 | |
| 66 | Est une backend optionnelle registrable dans le FS |
| 67 | |
| 68 | == FS == |
| 69 | |
| 70 | * gère la notion de répertoire |
| 71 | * gère les fichiers |
| 72 | |
| 73 | {{{ |
| 74 | struct vfs_node_s* fat_fs_open(device_s *dev, uint32_t flags); |
| 75 | }}} |
| 76 | |
| 77 | Gère bien entendu les actions décrites en haut |
| 78 | |
| 79 | == Backend == |
| 80 | |
| 81 | * gère la/les FAT, et leur recopie, les clusters, les blocs |
| 82 | * implem particulière pour FAT12/16/32 |
| 83 | * gère l'espace libre |
| 84 | * gère les listes chainées des blocs pour les fichiers (extent) |
| 85 | * représentation abstraite d'un extent par un pointeur sur struct |
| 86 | * API d'adressage au bloc (pas au cluster) dans un fichier |
| 87 | * permet de faire la traduction (extent, block no) -> lba |
| 88 | |
| 89 | flags à l'ouverture du fs: |
| 90 | * read_only |
| 91 | * extent_cache_disable |
| 92 | |
| 93 | {{{ |
| 94 | struct fat_backend_s; |
| 95 | struct extent_s; |
| 96 | |
| 97 | struct fat_backend_ops_s |
| 98 | { |
| 99 | error_t open(struct device_s *dev, struct fat_backend_s *b, uint32_t flags); |
| 100 | |
| 101 | size_t free_block_count(struct fat_backend_s *b); |
| 102 | |
| 103 | error_t extent_allocate(struct fat_backend_s *b, struct extent_s **extent_out); |
| 104 | error_t extent_release(struct fat_backend_s *b, struct extent_s *extent); |
| 105 | error_t extent_start_at(struct fat_backend_s *b, dev_block_lba_t lba, struct extent_s **extent_out); |
| 106 | dev_block_lba_t extent_get_lba(struct fat_backend_s *b, struct extent_s *extent, size_t block_no); |
| 107 | error_t extent_resize(struct fat_backend_s *b, struct extent_s *extent, size_t new_block_count); |
| 108 | } |
| 109 | }}} |