2 * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 /** @addtogroup lwext4
34 * @brief Ext4 high level operations (files, directories, mount points...).
35 * Client has to include only this file.
48 #include "ext4_config.h"
49 #include "ext4_types.h"
50 #include "ext4_errno.h"
51 #include "ext4_oflags.h"
52 #include "ext4_debug.h"
54 #include "ext4_blockdev.h"
56 /********************************OS LOCK INFERFACE***************************/
58 /**@brief OS dependent lock interface.*/
61 /**@brief Lock access to mount point*/
64 /**@brief Unlock access to mount point*/
68 /********************************FILE DESCRIPTOR*****************************/
70 /**@brief File descriptor*/
71 typedef struct ext4_file {
73 /**@brief Mount point handle.*/
74 struct ext4_mountpoint *mp;
76 /**@brief File inode id*/
79 /**@brief Open flags.*/
82 /**@brief File size.*/
85 /**@brief File position*/
89 /*****************************DIRECTORY DESCRIPTOR***************************/
91 /**@brief Directory entry descriptor. Copy from ext4_types.h*/
92 typedef struct ext4_direntry {
94 uint16_t entry_length;
100 typedef struct ext4_dir {
101 /**@brief File descriptor*/
103 /**@brief Current directory entry.*/
105 /**@brief Next entry offset*/
109 /********************************MOUNT OPERATIONS****************************/
111 /**@brief Register block device.
113 * @param bd Block device.
114 * @param dev_name Block device name.
116 * @return Standard error code.*/
117 int ext4_device_register(struct ext4_blockdev *bd,
118 const char *dev_name);
120 /**@brief Un-register block device.
122 * @param dev_name Block device name.
124 * @return Standard error code.*/
125 int ext4_device_unregister(const char *dev_name);
127 /**@brief Un-register all block devices.
129 * @return Standard error code.*/
130 int ext4_device_unregister_all(void);
132 /**@brief Mount a block device with EXT4 partition to the mount point.
134 * @param dev_name block Device name (@ref ext4_device_register).
135 * @param mount_point Mount point, for example:
138 * - /my_second_partition/
139 * @param read_only mount as read-only mode.
141 * @return Standard error code */
142 int ext4_mount(const char *dev_name,
143 const char *mount_point,
146 /**@brief Umount operation.
147 * @param mount_point mount name
148 * @return standard error code */
149 int ext4_umount(const char *mount_point);
151 /**@brief Start journaling. Journaling start/stop functions are transparent
152 * and might be used on filesystems without journaling support.
154 * ext4_mount("sda1", "/");
155 * ext4_journal_start("/");
157 * //File operations here...
159 * ext4_journal_stop("/");
161 * @param mount_point mount name
162 * @return standard error code */
163 int ext4_journal_start(const char *mount_point);
165 /**@brief Stop journaling. Journaling start/stop functions are transparent
166 * and might be used on filesystems without journaling support.
167 * @param mount_point mount name
168 * @return standard error code */
169 int ext4_journal_stop(const char *mount_point);
171 /**@brief Journal recovery.
172 * @param mount_point mount point
173 * @warning Must be called after @ref ext4_mount
174 * @return standard error code */
175 int ext4_recover(const char *mount_point);
177 /**@brief Some of the filesystem stats.*/
178 struct ext4_mount_stats {
179 uint32_t inodes_count;
180 uint32_t free_inodes_count;
181 uint64_t blocks_count;
182 uint64_t free_blocks_count;
185 uint32_t block_group_count;
186 uint32_t blocks_per_group;
187 uint32_t inodes_per_group;
189 char volume_name[16];
192 /**@brief Get file system params.
193 * @param mount_point mount path
194 * @param stats ext fs stats
195 * @return standard error code */
196 int ext4_mount_point_stats(const char *mount_point,
197 struct ext4_mount_stats *stats);
199 /**@brief Setup OS lock routines.
200 * @param mount_point mount path
201 * @param locks - lock and unlock functions
202 * @return standard error code */
203 int ext4_mount_setup_locks(const char *mount_point,
204 const struct ext4_lock *locks);
206 /**@brief Acquire the filesystem superblock pointer of a mp.
207 * @param mount_point mount path
208 * @param superblock pointer
209 * @return standard error code */
210 int ext4_get_sblock(const char *mount_point, struct ext4_sblock **sb);
212 /**@brief Enable/disable write back cache mode.
213 * @warning Default model of cache is write trough. It means that when You do:
217 * < --- data is flushed to physical drive
220 * ext4_cache_write_back(..., 1);
223 * < --- data is NOT flushed to physical drive
224 * ext4_cache_write_back(..., 0);
225 * < --- when write back mode is disabled all
226 * cache data will be flushed
227 * To enable write back mode permanently just call this function
228 * once after ext4_mount (and disable before ext4_umount).
230 * Some of the function use write back cache mode internally.
231 * If you enable write back mode twice you have to disable it twice
234 * ext4_cache_write_back(..., 1);
235 * ext4_cache_write_back(..., 1);
237 * ext4_cache_write_back(..., 0);
238 * ext4_cache_write_back(..., 0);
240 * Write back mode is useful when you want to create a lot of empty
243 * @param path mount point path
244 * @param on enable/disable
246 * @return standard error code */
247 int ext4_cache_write_back(const char *path, bool on);
250 /**@brief Force cache flush.
252 * @param path mount point path
254 * @return standard error code */
255 int ext4_cache_flush(const char *path);
257 /********************************FILE OPERATIONS*****************************/
259 /**@brief Remove file by path.
260 * @param path path to file
261 * @return standard error code */
262 int ext4_fremove(const char *path);
264 /**@brief create a hardlink for a file.
265 * @param path path to file
266 * @param hardlink_path path of hardlink
267 * @return standard error code */
268 int ext4_flink(const char *path, const char *hardlink_path);
270 /**@brief Rename file
272 * @param new_path destination
273 * @return standard error code */
274 int ext4_frename(const char *path, const char *new_path);
276 /**@brief File open function.
277 * @param path filename (has to start from mount point)
278 * /my_partition/my_file
279 * @param flags open file flags
280 * |---------------------------------------------------------------|
281 * | r or rb O_RDONLY |
282 * |---------------------------------------------------------------|
283 * | w or wb O_WRONLY|O_CREAT|O_TRUNC |
284 * |---------------------------------------------------------------|
285 * | a or ab O_WRONLY|O_CREAT|O_APPEND |
286 * |---------------------------------------------------------------|
287 * | r+ or rb+ or r+b O_RDWR |
288 * |---------------------------------------------------------------|
289 * | w+ or wb+ or w+b O_RDWR|O_CREAT|O_TRUNC |
290 * |---------------------------------------------------------------|
291 * | a+ or ab+ or a+b O_RDWR|O_CREAT|O_APPEND |
292 * |---------------------------------------------------------------|
294 * @return standard error code*/
295 int ext4_fopen(ext4_file *f, const char *path, const char *flags);
297 /**@brief Alternate file open function.
298 * @param filename, (has to start from mount point)
299 * /my_partition/my_file
300 * @param flags open file flags
301 * @return standard error code*/
302 int ext4_fopen2(ext4_file *f, const char *path, int flags);
304 /**@brief File close function.
305 * @param f file handle
306 * @return standard error code*/
307 int ext4_fclose(ext4_file *f);
309 /**@brief Fill in the ext4_inode buffer.
310 * @param path fetch inode data of the path
311 * @param ret_ino the inode id of the path
312 * @param ext4_inode buffer
313 * @return standard error code*/
314 int ext4_fill_raw_inode(const char *path, uint32_t *ret_ino,
315 struct ext4_inode *inode);
317 /**@brief File truncate function.
318 * @param f file handle
319 * @param new file size
320 * @return standard error code*/
321 int ext4_ftruncate(ext4_file *f, uint64_t size);
323 /**@brief Read data from file.
324 * @param f file handle
325 * @param buf output buffer
326 * @param size bytes to read
327 * @param rcnt bytes read (may be NULL)
328 * @return standard error code*/
329 int ext4_fread(ext4_file *f, void *buf, size_t size, size_t *rcnt);
331 /**@brief Write data to file.
332 * @param f file handle
333 * @param buf data to write
334 * @param size write length
335 * @param wcnt bytes written (may be NULL)
336 * @return standard error code*/
337 int ext4_fwrite(ext4_file *f, const void *buf, size_t size, size_t *wcnt);
339 /**@brief File seek operation.
340 * @param f file handle
341 * @param offset offset to seek
342 * @param origin seek type:
346 * @return standard error code*/
347 int ext4_fseek(ext4_file *f, uint64_t offset, uint32_t origin);
349 /**@brief Get file position.
350 * @param f file handle
351 * @return actual file position */
352 uint64_t ext4_ftell(ext4_file *f);
354 /**@brief Get file size.
355 * @param f file handle
356 * @return file size */
357 uint64_t ext4_fsize(ext4_file *f);
359 /**@brief Change file/directory/link mode bits
360 * @param path to file/dir/link
361 * @param mode new mode bits (for example 0777)
362 * @return standard error code*/
363 int ext4_mode_set(const char *path, uint32_t mode);
366 /**@brief Get file/directory/link mode bits
367 * @param path to file/dir/link
368 * @param mode new mode bits (for example 0777)
369 * @return standard error code*/
370 int ext4_mode_get(const char *path, uint32_t *mode);
372 /**@brief Change file owner and group
373 * @param path to file/dir/link
375 * @param gid group id
376 * @return standard error code*/
377 int ext4_owner_set(const char *path, uint32_t uid, uint32_t gid);
379 /**@brief Get file/directory/link owner and group
380 * @param path to file/dir/link
382 * @param gid group id
383 * @return standard error code*/
384 int ext4_owner_get(const char *path, uint32_t *uid, uint32_t *gid);
386 /**@brief Set file/directory/link access time
387 * @param path to file/dir/link
388 * @param atime access timestamp
389 * @return standard error code*/
390 int ext4_atime_set(const char *path, uint32_t atime);
392 /**@brief Set file/directory/link modify time
393 * @param path to file/dir/link
394 * @param mtime modify timestamp
395 * @return standard error code*/
396 int ext4_mtime_set(const char *path, uint32_t mtime);
398 /**@brief Set file/directory/link change time
399 * @param path to file/dir/link
400 * @param ctime change timestamp
401 * @return standard error code*/
402 int ext4_ctime_set(const char *path, uint32_t ctime);
404 /**@brief Get file/directory/link access time
405 * @param path to file/dir/link
406 * @param atime access timestamp
407 * @return standard error code*/
408 int ext4_atime_get(const char *path, uint32_t *atime);
410 /**@brief Get file/directory/link modify time
411 * @param path to file/dir/link
412 * @param mtime modify timestamp
413 * @return standard error code*/
414 int ext4_mtime_get(const char *path, uint32_t *mtime);
416 /**@brief Get file/directory/link change time
417 * @param path to file/dir/link
418 * @param ctime change timestamp
419 * @return standard error code*/
420 int ext4_ctime_get(const char *path, uint32_t *ctime);
422 /**@brief Create symbolic link
423 * @param target destination path
424 * @param path source entry
425 * @return standard error code*/
426 int ext4_fsymlink(const char *target, const char *path);
428 /**@brief Create special file
429 * @param path path to new file
430 * @param filetype The filetype of the new special file
431 * (that must not be regular file, directory, or unknown type)
432 * @param dev if filetype is char device or block device,
433 * the device number will become the payload in the inode
434 * @return standard error code*/
435 int ext4_mknod(const char *path, int filetype, uint32_t dev);
437 /**@brief Read symbolic link payload
438 * @param path to symlink
439 * @param buf output buffer
440 * @param bufsize output buffer max size
441 * @param rcnt bytes read
442 * @return standard error code*/
443 int ext4_readlink(const char *path, char *buf, size_t bufsize, size_t *rcnt);
445 /**@brief Set extended attribute
446 * @param path to file/directory
447 * @param name name of the entry to add
448 * @param name_len length of @name in bytes
449 * @param data data of the entry to add
450 * @param data_size size of data to add
451 * @param replace this boolean is deprecated.
452 * @return standard error code*/
453 int ext4_setxattr(const char *path, const char *name, size_t name_len,
454 const void *data, size_t data_size, bool replace);
456 /**@brief Get extended attribute
457 * @param path to file/directory
458 * @param name name of the entry to get
459 * @param name_len length of @name in bytes
460 * @param data data of the entry to get
461 * @param data_size size of data to get
462 * @return standard error code*/
463 int ext4_getxattr(const char *path, const char *name, size_t name_len,
464 void *buf, size_t buf_size, size_t *data_size);
466 /**@brief List extended attributes
467 * @param path to file/directory
468 * @param list list to hold the name of entries
469 * @param size size of @list in bytes
470 * @param ret_size used bytes of @list
471 * @return standard error code*/
472 int ext4_listxattr(const char *path, char *list, size_t size, size_t *ret_size);
474 /**@brief Remove extended attribute
475 * @param path to file/directory
476 * @param name name of the entry to remove
477 * @param name_len length of @name in bytes
478 * @return standard error code*/
479 int ext4_removexattr(const char *path, const char *name, size_t name_len);
482 /*********************************DIRECTORY OPERATION***********************/
484 /**@brief Recursive directory remove.
485 * @param path directory path to remove
486 * @return standard error code*/
487 int ext4_dir_rm(const char *path);
489 /**@brief Rename/move directory
491 * @param new_path destination
492 * @return standard error code */
493 int ext4_dir_mv(const char *path, const char *new_path);
495 /**@brief Create new directory.
496 * @param name new directory name
497 * @return standard error code*/
498 int ext4_dir_mk(const char *path);
500 /**@brief Directory open.
501 * @param d directory handle
502 * @param path directory path
503 * @return standard error code*/
504 int ext4_dir_open(ext4_dir *d, const char *path);
506 /**@brief Directory close.
507 * @param d directory handle
508 * @return standard error code*/
509 int ext4_dir_close(ext4_dir *d);
511 /**@brief Return next directory entry.
512 * @param d directory handle
514 * @return directory entry id (NULL if no entry)*/
515 const ext4_direntry *ext4_dir_entry_next(ext4_dir *d);
517 /**@brief Rewine directory entry offset.
518 * @param d directory handle*/
519 void ext4_dir_entry_rewind(ext4_dir *d);