| | 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 | }}} |