Welcome to mirror list, hosted at ThFree Co, Russian Federation.

lfs.h - github.com/littlefs-project/littlefs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lfs.h
blob: f091a66a1773c290bdb0d04b7b5eb330ab39402c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/*
 * The little filesystem
 *
 * Copyright (c) 2017 Christopher Haster
 * Distributed under the MIT license
 */
#ifndef LFS_H
#define LFS_H

#include "lfs_config.h"


// The littefs constants
enum lfs_error {
    LFS_ERROR_OK       = 0,
    LFS_ERROR_CORRUPT  = -3,
    LFS_ERROR_NO_ENTRY = -4,
    LFS_ERROR_EXISTS   = -5,
    LFS_ERROR_NOT_DIR  = -6,
    LFS_ERROR_IS_DIR   = -7,
    LFS_ERROR_INVALID  = -8,
    LFS_ERROR_NO_SPACE = -9,
    LFS_ERROR_NO_MEM   = -10,
};

enum lfs_type {
    LFS_TYPE_REG        = 0x01,
    LFS_TYPE_DIR        = 0x02,
    LFS_TYPE_SUPERBLOCK = 0x10,
};

enum lfs_open_flags {
    LFS_O_RDONLY = 0,
    LFS_O_WRONLY = 1,
    LFS_O_RDWR   = 2,
    LFS_O_CREAT  = 0x020,
    LFS_O_EXCL   = 0x040,
    LFS_O_TRUNC  = 0x080,
    LFS_O_APPEND = 0x100,
    LFS_O_SYNC   = 0x200,
};

enum lfs_whence_flags {
    LFS_SEEK_SET = 0,
    LFS_SEEK_CUR = 1,
    LFS_SEEK_END = 2,
};


// Configuration provided during initialization of the littlefs
struct lfs_config {
    // Opaque user provided context
    void *context;

    // Read a region in a block
    int (*read)(const struct lfs_config *c, lfs_block_t block,
            lfs_off_t off, lfs_size_t size, void *buffer);

    // Program a region in a block. The block must have previously
    // been erased.
    int (*prog)(const struct lfs_config *c, lfs_block_t block,
            lfs_off_t off, lfs_size_t size, const void *buffer);

    // Erase a block. A block must be erased before being programmed.
    // The state of an erased block is undefined.
    int (*erase)(const struct lfs_config *c, lfs_block_t block);

    // Sync the state of the underlying block device
    int (*sync)(const struct lfs_config *c);

    // Minimum size of a read. This may be larger than the physical
    // read size to cache reads from the block device.
    lfs_size_t read_size;

    // Minimum size of a program. This may be larger than the physical
    // program size to cache programs to the block device.
    lfs_size_t prog_size;

    // Size of an erasable block.
    lfs_size_t block_size;

    // Number of erasable blocks on the device.
    lfs_size_t block_count;

    // Number of blocks to lookahead during block allocation.
    lfs_size_t lookahead;

    // Optional, statically allocated read buffer. Must be read sized.
    void *read_buffer;

    // Optional, statically allocated program buffer. Must be program sized.
    void *prog_buffer;

    // Optional, statically allocated lookahead buffer.
    // Must be 1 bit per lookahead block.
    void *lookahead_buffer;
};

// File info structure
struct lfs_info {
    // Type of the file, either REG or DIR
    uint8_t type;

    // Size of the file, only valid for REG files
    lfs_size_t size;

    // Name of the file stored as a null-terminated string
    char name[LFS_NAME_MAX+1];
};


// Internal data structures
typedef struct lfs_entry {
    lfs_block_t pair[2];
    lfs_off_t off;

    struct lfs_disk_entry {
        uint16_t type;
        uint16_t len;
        union {
            struct {
                lfs_block_t head;
                lfs_size_t size;
            } file;
            lfs_block_t dir[2];
        } u;
    } d;
} lfs_entry_t;

typedef struct lfs_file {
    struct lfs_entry entry;
    int flags;

    lfs_off_t wpos;
    lfs_block_t wblock;
    lfs_off_t woff;

    lfs_off_t rpos;
    lfs_block_t rblock;
    lfs_off_t roff;
} lfs_file_t;

typedef struct lfs_dir {
    lfs_block_t pair[2];
    lfs_off_t off;

    lfs_block_t head[2];
    lfs_off_t pos;

    struct lfs_disk_dir {
        uint32_t rev;
        lfs_size_t size;
        lfs_block_t tail[2];
    } d;
} lfs_dir_t;

typedef struct lfs_superblock {
    lfs_block_t pair[2];
    lfs_off_t off;

    struct lfs_disk_superblock {
        uint16_t type;
        uint16_t len;
        uint32_t version;
        char magic[8];
        uint32_t block_size;
        uint32_t block_count;
        lfs_block_t root[2];
    } d;
} lfs_superblock_t;


// Little filesystem type
typedef struct lfs {
    const struct lfs_config *cfg;
    lfs_size_t words;       // number of 32-bit words that can fit in a block

    lfs_block_t root[2];

    struct {
        lfs_block_t block;
        lfs_off_t off;
        uint8_t *buffer;
    } rcache, pcache;

    struct {
        lfs_block_t start;
        lfs_block_t off;
        uint32_t *lookahead;
    } free;
} lfs_t;


// Functions
int lfs_format(lfs_t *lfs, const struct lfs_config *config);
int lfs_mount(lfs_t *lfs, const struct lfs_config *config);
int lfs_unmount(lfs_t *lfs);

int lfs_remove(lfs_t *lfs, const char *path);
int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);

int lfs_mkdir(lfs_t *lfs, const char *path);
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path);
int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir);
int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info);
int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off);
lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir);
int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);

int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
        const char *path, int flags);
int lfs_file_close(lfs_t *lfs, lfs_file_t *file);
int lfs_file_sync(lfs_t *lfs, lfs_file_t *file);
lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
        const void *buffer, lfs_size_t size);
lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
        void *buffer, lfs_size_t size);
lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
        lfs_soff_t off, int whence);
lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file);
int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);

int lfs_deorphan(lfs_t *lfs);
int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);


#endif