Browse Source

1. Directory opreations:

- ext4_dir_rm - delete dir recursive
 - ext4_dir_mk - make dir

2. Bugfix in ext4_dir (bad iterator behaviour).
3. Comments inr ext4.h.
4. Demo app has directory operations test.
5. Better ext4_femove implementation.
6. Most file functions base on ext4_open_generic.
7. Extent feature preprocessor switches.
pull/1/head
gkostka 11 years ago
parent
commit
ffb796f2aa
  1. 108
      demos/generic/main.c
  2. 93
      ext4.h
  3. 360
      lwext4/ext4.c
  4. 16
      lwext4/ext4_dir.c
  5. 27
      lwext4/ext4_fs.c

108
demos/generic/main.c

@ -46,6 +46,9 @@ static int rw_szie = 1024;
/**@brief Read-write size*/
static int rw_count = 1024;
/**@brief Directory test count*/
static int dir_cnt = 10;
static bool cache_mode = false;
@ -65,10 +68,11 @@ static const char *usage = " \n\
Welcome in ext4 generic demo. \n\
Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com) \n\
Usage: \n\
-i - input file (default = ext2) \n\
-rws - single R/W size (default = 1024) \n\
-rwc - R/W count (default = 1024) \n\
-cache - 0 static, 1 dynamic (default = 0) \n\
-i - input file (default = ext2) \n\
-rws - single R/W size (default = 1024) \n\
-rwc - R/W count (default = 1024) \n\
-cache - 0 static, 1 dynamic (default = 0) \n\
-dirs - directory test count (default = 0) \n\
\n";
static char* entry_to_str(uint8_t type)
@ -106,7 +110,7 @@ static void dir_ls(const char *path)
printf("**********************************************\n");
ext4_dir_open(&d, path);
de = ext4_entry_get(&d, j++);
de = ext4_dir_entry_get(&d, j++);
printf("ls %s\n", path);
while(de){
@ -115,7 +119,7 @@ static void dir_ls(const char *path)
printf(entry_to_str(de->inode_type));
printf(sss);
printf("\n");
de = ext4_entry_get(&d, j++);
de = ext4_dir_entry_get(&d, j++);
}
printf("**********************************************\n");
ext4_dir_close(&d);
@ -128,14 +132,14 @@ static void mp_stats(void)
printf("**********************************************\n");
printf("ext4_mount_point_stats\n");
printf("inodes_count = %d\n", stats.inodes_count);
printf("free_inodes_count = %d\n", stats.free_inodes_count);
printf("blocks_count = %d\n", stats.blocks_count);
printf("free_blocks_count = %d\n", stats.free_blocks_count);
printf("block_size = %d\n", stats.block_size);
printf("block_group_count = %d\n", stats.block_group_count);
printf("blocks_per_group = %d\n", stats.blocks_per_group);
printf("inodes_per_group = %d\n", stats.inodes_per_group);
printf("inodes_count = %u\n", stats.inodes_count);
printf("free_inodes_count = %u\n", stats.free_inodes_count);
printf("blocks_count = %u\n", (uint32_t)stats.blocks_count);
printf("free_blocks_count = %u\n", (uint32_t)stats.free_blocks_count);
printf("block_size = %u\n", stats.block_size);
printf("block_group_count = %u\n", stats.block_group_count);
printf("blocks_per_group = %u\n", stats.blocks_per_group);
printf("inodes_per_group = %u\n", stats.inodes_per_group);
printf("volume_name = %s\n", stats.volume_name);
printf("**********************************************\n");
@ -148,22 +152,22 @@ static void block_stats(void)
printf("**********************************************\n");
printf("ext4 blockdev stats\n");
printf("bdev->bread_ctr = %d\n", bd->bread_ctr);
printf("bdev->bwrite_ctr = %d\n", bd->bwrite_ctr);
printf("bdev->bread_ctr = %u\n", bd->bread_ctr);
printf("bdev->bwrite_ctr = %u\n", bd->bwrite_ctr);
printf("bcache->ref_blocks = %d\n", bc->ref_blocks);
printf("bcache->max_ref_blocks = %d\n", bc->max_ref_blocks);
printf("bcache->lru_ctr = %d\n", bc->lru_ctr);
printf("bcache->ref_blocks = %u\n", bc->ref_blocks);
printf("bcache->max_ref_blocks = %u\n", bc->max_ref_blocks);
printf("bcache->lru_ctr = %u\n", bc->lru_ctr);
printf("\n");
for (i = 0; i < bc->cnt; ++i) {
printf("bcache->refctr[%d] = %d\n", i, bc->refctr[i]);
printf("bcache->refctr[%d] = %u\n", i, bc->refctr[i]);
}
printf("\n");
for (i = 0; i < bc->cnt; ++i) {
printf("bcache->lru_id[%d] = %d\n", i, bc->lru_id[i]);
printf("bcache->lru_id[%d] = %u\n", i, bc->lru_id[i]);
}
printf("\n");
@ -173,7 +177,7 @@ static void block_stats(void)
printf("\n");
for (i = 0; i < bc->cnt; ++i) {
printf("bcache->lba[%d] = %d\n", i, bc->lba[i]);
printf("bcache->lba[%d] = %u\n", i, (uint32_t)bc->lba[i]);
}
@ -181,6 +185,59 @@ static void block_stats(void)
printf("**********************************************\n");
}
static bool dir_test(int len)
{
ext4_file f;
int r;
int i;
char path[64];
printf("Remove directory /mp/dir1\n");
ext4_dir_rm("/mp/dir1");
printf("Directory create: /mp/dir1\n");
r = ext4_dir_mk("/mp/dir1");
if(r != EOK){
printf("Unable to create directory: /mp/dir1\n");
return false;
}
printf("Add files to: /mp/dir1\n");
for (i = 0; i < len; ++i) {
sprintf(path, "/mp/dir1/f%d", i);
r = ext4_fopen(&f, path, "wb");
if(r != EOK){
printf("Unable to create file in directory: /mp/dir1\n");
return false;
}
}
printf("Add directories to: /mp/dir1\n");
for (i = 0; i < len; ++i) {
sprintf(path, "/mp/dir1/d%d", i);
r = ext4_dir_mk(path);
if(r != EOK){
printf("Unable to create directory in directory: /mp/dir1\n");
return false;
}
}
printf("Add file directories in: /mp/dir1\n");
for (i = 0; i < len; ++i) {
sprintf(path, "/mp/dir1/d%d/ff", i);
r = ext4_fopen(&f, path, "wb");
if(r != EOK){
printf("Unable to create file in directory: /mp/dir1\n");
return false;
}
}
dir_ls("/mp/dir1");
return true;
}
int main(int argc, char **argv)
{
@ -197,10 +254,11 @@ int main(int argc, char **argv)
{"rws", required_argument, 0, 'b'},
{"rwc", required_argument, 0, 'c'},
{"cache", required_argument, 0, 'd'},
{"dirs", required_argument, 0, 'e'},
{0, 0, 0, 0}
};
while(-1 != (c = getopt_long (argc, argv, "a:b:c:d:", long_options, &option_index))) {
while(-1 != (c = getopt_long (argc, argv, "a:b:c:d:e:", long_options, &option_index))) {
switch(c){
case 'a':
@ -215,6 +273,9 @@ int main(int argc, char **argv)
case 'd':
cache_mode = atoi(optarg);
break;
case 'e':
dir_cnt = atoi(optarg);
break;
default:
printf(usage);
return EXIT_FAILURE;
@ -262,6 +323,7 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
dir_test(dir_cnt);
ext4_fremove("/mp/hello.txt");
ext4_fremove("/mp/test1");

93
ext4.h

@ -42,34 +42,34 @@
#include <ext4_blockdev.h>
#include <stdint.h>
/********************************FILE OPEN FLAGS********************************/
/********************************FILE OPEN FLAGS*****************************/
#ifndef O_RDONLY
#define O_RDONLY 00
#define O_RDONLY 00
#endif
#ifndef O_WRONLY
#define O_WRONLY 01
#define O_WRONLY 01
#endif
#ifndef O_RDWR
#define O_RDWR 02
#define O_RDWR 02
#endif
#ifndef O_CREAT
#define O_CREAT 0100
#define O_CREAT 0100
#endif
#ifndef O_EXCL
#define O_EXCL 0200
#define O_EXCL 0200
#endif
#ifndef O_TRUNC
#define O_TRUNC 01000
#define O_TRUNC 01000
#endif
#ifndef O_APPEND
#define O_APPEND 02000
#define O_APPEND 02000
#endif
/********************************FILE SEEK FLAGS*****************************/
@ -133,7 +133,7 @@ enum {
EXT4_DIRENTRY_SYMLINK
};
/**@brief Directory entry descriptor. Copy from ext4_types.h*/
/**@brief Directory entry descriptor. Copy from ext4_types.h*/
typedef struct {
uint32_t inode;
uint16_t entry_length;
@ -182,7 +182,7 @@ int ext4_mount(const char * dev_name, char *mount_point);
int ext4_umount(char *mount_point);
/**@brief Some of the filesystem params.*/
/**@brief Some of the filesystem stats.*/
struct ext4_mount_stats {
uint32_t inodes_count;
uint32_t free_inodes_count;
@ -197,12 +197,18 @@ struct ext4_mount_stats {
char volume_name[16];
};
/**@brief Get file system params.
* @param mount_point mount path
* @param stats ext fs stats
* @return standard error code */
int ext4_mount_point_stats(const char *mount_point,
struct ext4_mount_stats *stats);
/********************************FILE OPERATIONS*****************************/
/**@brief */
/**@brief Remove file by path.
* @param path path to file
* @return standard error code */
int ext4_fremove(const char *path);
/**@brief File open function.
@ -226,39 +232,76 @@ int ext4_fremove(const char *path);
* @return standard error code*/
int ext4_fopen (ext4_file *f, const char *path, const char *flags);
/**@brief */
/**@brief File close function.
* @param f file handle
* @return standard error code*/
int ext4_fclose(ext4_file *f);
/**@brief */
/**@brief Read data from file.
* @param f file handle
* @param buf output buffer
* @param size bytes to read
* @param rcnt readed bytes (may be NULL)
* @return standard error code*/
int ext4_fread (ext4_file *f, void *buf, uint32_t size, uint32_t *rcnt);
/**@brief */
/**@brief Write data to file.
* @param f file handle
* @param buf data to write
* @param size write length
* @param wcnt bytes written (may be NULL)
* @return standard error code*/
int ext4_fwrite(ext4_file *f, void *buf, uint32_t size, uint32_t *wcnt);
/**@brief */
/**@brief File seek operation.
* @param f file handle
* @param offset offset to seek
* @param origin seek type:
* @ref SEEK_SET
* @ref SEEK_CUR
* @ref SEEK_END
* @return standard error code*/
int ext4_fseek (ext4_file *f, uint64_t offset, uint32_t origin);
/**@brief */
/**@brief Get file position.
* @param f file handle
* @return actual file position */
uint64_t ext4_ftell (ext4_file *f);
/**@brief */
/**@brief Get file size.
* @param f file handle
* @return file size */
uint64_t ext4_fsize (ext4_file *f);
/*********************************DIRECTORY OPERATION***********************/
/**@brief */
int ext4_mkdir(const char *path);
/**@brief */
int ext4_rmdir(const char *path);
/**@brief Recursive directory remove.
* @param path directory path to remove
* @return standard error code*/
int ext4_dir_rm(const char *path);
/**@brief */
/**@brief Create new directory.
* @param name new directory name
* @return standard error code*/
int ext4_dir_mk(const char *path);
/**@brief Directory open.
* @param d directory handle
* @param path directory path
* @return standard error code*/
int ext4_dir_open (ext4_dir *d, const char *path);
/**@brief */
/**@brief Directory close.
* @param d directory handle
* @return standard error code*/
int ext4_dir_close(ext4_dir *d);
/**@brief */
ext4_direntry* ext4_entry_get(ext4_dir *d, uint32_t id);
/**@brief Return directory entry by id.
* @param d directory handle
* @param id entry id
* @return directory entry id (NULL id no entry)*/
ext4_direntry* ext4_dir_entry_get(ext4_dir *d, uint32_t id);
#endif /* EXT4_H_ */

360
lwext4/ext4.c

@ -52,11 +52,11 @@
/**@brief Mount point OS dependent lock*/
#define EXT4_MP_LOCK(_m) \
do { (_m)->os_locks ? (_m)->os_locks->lock() : 0; }while(0)
do { (_m)->os_locks ? (_m)->os_locks->lock() : 0; }while(0)
/**@brief Mount point OS dependent unlock*/
#define EXT4_MP_UNLOCK(_m) \
do { (_m)->os_locks ? (_m)->os_locks->unlock() : 0; }while(0)
do { (_m)->os_locks ? (_m)->os_locks->unlock() : 0; }while(0)
/**@brief Mount point descrpitor.*/
struct ext4_mountpoint {
@ -491,7 +491,6 @@ static int ext4_path_check(const char *path, bool* is_goal)
return 0;
}
static bool ext4_parse_flags(const char *flags, uint32_t *file_flags)
{
if(!flags)
@ -533,7 +532,7 @@ static bool ext4_parse_flags(const char *flags, uint32_t *file_flags)
/****************************************************************************/
static int ext4_generic_open (ext4_file *f, const char *path,
const char *flags, bool file_expect)
const char *flags, bool file_expect, uint32_t *parent_inode, uint32_t *name_off)
{
struct ext4_mountpoint *mp = ext4_get_mount(path);
struct ext4_directory_search_result result;
@ -554,7 +553,8 @@ static int ext4_generic_open (ext4_file *f, const char *path,
/*Skip mount point*/
path += strlen(mp->name);
EXT4_MP_LOCK(mp);
if(name_off)
*name_off = strlen(mp->name);
/*Load root*/
r = ext4_fs_get_inode_ref(&mp->fs, EXT4_INODE_ROOT_INDEX, &ref);
@ -562,17 +562,20 @@ static int ext4_generic_open (ext4_file *f, const char *path,
if(r != EOK)
return r;
int len = ext4_path_check(path, &is_goal);
if(parent_inode)
*parent_inode = ref.index;
/*If root open was request.*/
if(!len && is_goal)
goto IsGoal;
int len = ext4_path_check(path, &is_goal);
while(1){
len = ext4_path_check(path, &is_goal);
if(!len){
/*If root open was request.*/
if(is_goal && !file_expect)
break;
r = ENOENT;
break;
}
@ -586,9 +589,9 @@ static int ext4_generic_open (ext4_file *f, const char *path,
if(!(f->flags & O_CREAT))
break;
/*O_CREAT allows to create new entry*/
/*O_CREAT allows create new entry*/
struct ext4_inode_ref child_ref;
r = ext4_fs_alloc_inode(&mp->fs, &child_ref, !is_goal);
r = ext4_fs_alloc_inode(&mp->fs, &child_ref, is_goal ? !file_expect : true);
if(r != EOK)
break;
@ -612,6 +615,9 @@ static int ext4_generic_open (ext4_file *f, const char *path,
continue;
}
if(parent_inode)
*parent_inode = ref.index;
next_inode = result.dentry->inode;
inode_type = ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
@ -645,18 +651,20 @@ static int ext4_generic_open (ext4_file *f, const char *path,
break;
path += len + 1;
if(name_off)
*name_off += len + 1;
};
if(r != EOK){
ext4_fs_put_inode_ref(&ref);
EXT4_MP_UNLOCK(mp);
return r;
}
IsGoal:
if(is_goal){
if(f->flags & O_TRUNC){
if((f->flags & O_TRUNC) &&
(inode_type == EXT4_DIRECTORY_FILETYPE_REG_FILE)){
/*Turncate.*/
ext4_block_delay_cache_flush(mp->fs.bdev, 1);
/*Truncate may be IO heavy.
@ -666,7 +674,6 @@ static int ext4_generic_open (ext4_file *f, const char *path,
if(r != EOK){
ext4_fs_put_inode_ref(&ref);
EXT4_MP_UNLOCK(mp);
return r;
}
}
@ -682,7 +689,6 @@ static int ext4_generic_open (ext4_file *f, const char *path,
}
r = ext4_fs_put_inode_ref(&ref);
EXT4_MP_UNLOCK(mp);
return r;
}
@ -690,97 +696,37 @@ static int ext4_generic_open (ext4_file *f, const char *path,
int ext4_fremove(const char *path)
{
ext4_file f;
uint32_t parent_inode;
uint32_t name_off;
int r;
int len;
bool is_goal;
struct ext4_mountpoint *mp = ext4_get_mount(path);
struct ext4_directory_search_result result;
bool is_goal = false;
uint8_t inode_type;
int r = ENOENT;
uint32_t next_inode;
struct ext4_inode_ref parent;
struct ext4_inode_ref child;
int len = 0;
struct ext4_inode_ref child;
struct ext4_inode_ref parent;
if(!mp)
return ENOENT;
/*Skip mount point*/
path += strlen(mp->name);
/*Lock mountpoint*/
EXT4_MP_LOCK(mp);
/*Load root*/
r = ext4_fs_get_inode_ref(&mp->fs, EXT4_INODE_ROOT_INDEX, &parent);
r = ext4_generic_open(&f, path, "r", true, &parent_inode, &name_off);
if(r != EOK){
EXT4_MP_UNLOCK(mp);
return r;
}
while(1){
len = ext4_path_check(path, &is_goal);
if(!len){
r = ENOENT;
break;
}
r = ext4_dir_find_entry(&result, &parent, path, len);
if(r != EOK){
ext4_dir_destroy_result(&parent, &result);
break;
}
next_inode = result.dentry->inode;
inode_type = ext4_dir_entry_ll_get_inode_type(&mp->fs.sb,
result.dentry);
r = ext4_dir_destroy_result(&parent, &result);
if(r != EOK)
break;
/*If expected file error*/
if((inode_type == EXT4_DIRECTORY_FILETYPE_REG_FILE) && !is_goal){
r = ENOENT;
break;
}
/*If expected directory error*/
if((inode_type == EXT4_DIRECTORY_FILETYPE_DIR) && is_goal){
r = ENOENT;
break;
}
if(is_goal)
break;
r = ext4_fs_put_inode_ref(&parent);
if(r != EOK)
break;
r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &parent);
if(r != EOK)
break;
path += len + 1;
};
/*Load parent*/
r = ext4_fs_get_inode_ref(&mp->fs, parent_inode, &parent);
if(r != EOK){
/*No entry or other error.*/
ext4_fs_put_inode_ref(&parent);
EXT4_MP_UNLOCK(mp);
return r;
}
/*We have file to delete. Load it.*/
r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &child);
r = ext4_fs_get_inode_ref(&mp->fs, f.inode, &child);
if(r != EOK){
/*Parent free*/
ext4_fs_put_inode_ref(&parent);
EXT4_MP_UNLOCK(mp);
return r;
@ -788,14 +734,18 @@ int ext4_fremove(const char *path)
/*Turncate.*/
ext4_block_delay_cache_flush(mp->fs.bdev, 1);
/*Truncate may be IO heavy. Do it with delayed cache flush mode.*/
r = ext4_fs_truncate_inode(&child, 0);
ext4_block_delay_cache_flush(mp->fs.bdev, 0);
if(r != EOK)
goto Finish;
/*Set path*/
path += name_off;
len = ext4_path_check(path, &is_goal);
/*Unlink from parent.*/
r = ext4_unlink(mp, &parent, &child, path, len);
if(r != EOK)
@ -805,7 +755,6 @@ int ext4_fremove(const char *path)
if(r != EOK)
goto Finish;
Finish:
ext4_fs_put_inode_ref(&child);
ext4_fs_put_inode_ref(&parent);
@ -816,7 +765,16 @@ int ext4_fremove(const char *path)
int ext4_fopen (ext4_file *f, const char *path, const char *flags)
{
return ext4_generic_open(f, path, flags, true);
struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
if(!mp)
return ENOENT;
EXT4_MP_LOCK(mp);
r = ext4_generic_open(f, path, flags, true, 0, 0);
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_fclose(ext4_file *f)
@ -1144,9 +1102,222 @@ uint64_t ext4_fsize (ext4_file *f)
/*********************************DIRECTORY OPERATION************************/
int ext4_dir_rm(const char *path)
{
int r;
int len;
ext4_file f;
struct ext4_mountpoint *mp = ext4_get_mount(path);
struct ext4_inode_ref current;
struct ext4_inode_ref child;
struct ext4_directory_iterator it;
uint32_t name_off;
uint32_t inode_up;
uint32_t inode_current;
uint32_t depth = 1;
bool has_children;
bool is_goal;
bool dir_end;
if(!mp)
return ENOENT;
EXT4_MP_LOCK(mp);
/*Check if exist.*/
r = ext4_generic_open(&f, path, "r", false, &inode_up, &name_off);
if(r != EOK){
EXT4_MP_UNLOCK(mp);
return r;
}
path += name_off;
len = ext4_path_check(path, &is_goal);
inode_current = f.inode;
dir_end = false;
do {
/*Load directory node.*/
r = ext4_fs_get_inode_ref(&f.mp->fs, inode_current, &current);
if(r != EOK){
break;
}
/*Initialize iterator.*/
r = ext4_dir_iterator_init(&it, &current, 0);
if(r != EOK){
ext4_fs_put_inode_ref(&current);
break;
}
while(r == EOK){
if(!it.current){
dir_end = true;
break;
}
/*Get up directory inode when ".." entry*/
if((it.current->name_length == 2) &&
ext4_is_dots(it.current->name, it.current->name_length)){
inode_up = it.current->inode;
}
/*If directory or file entry, but not "." ".." entry*/
if(!ext4_is_dots(it.current->name, it.current->name_length)){
/*Get child inode reference do unlink directory/file.*/
r = ext4_fs_get_inode_ref(&f.mp->fs, it.current->inode, &child);
if(r != EOK)
break;
/*If directory with no leaf children*/
r = ext4_has_children(&has_children, &child);
if(r != EOK){
ext4_fs_put_inode_ref(&child);
break;
}
if(has_children){
/*Has directory children. Go into this tirectory.*/
inode_up = inode_current;
inode_current = it.current->inode;
depth++;
ext4_fs_put_inode_ref(&child);
break;
}
/*Directory is empty. Truncate it.*/
r = ext4_fs_truncate_inode(&child, 0);
if(r != EOK){
ext4_fs_put_inode_ref(&child);
break;
}
/*No children in child directory or file. Just unlink.*/
r = ext4_unlink(f.mp, &current, &child,
(char *)it.current->name, it.current->name_length);
if(r != EOK){
ext4_fs_put_inode_ref(&child);
break;
}
r = ext4_fs_free_inode(&child);
if(r != EOK){
ext4_fs_put_inode_ref(&child);
break;
}
r = ext4_fs_put_inode_ref(&child);
if(r != EOK)
break;
}
r = ext4_dir_iterator_next(&it);
}
if(dir_end){
/*Directory iterator reached last entry*/
ext4_has_children(&has_children, &current);
if(!has_children){
inode_current = inode_up;
if(depth)
depth--;
}
/*Last unlink*/
if(!depth){
/*Load parent.*/
struct ext4_inode_ref parent;
r = ext4_fs_get_inode_ref(&f.mp->fs, inode_up, &parent);
if(r != EOK)
goto End;
r = ext4_fs_truncate_inode(&current, 0);
if(r != EOK){
ext4_fs_put_inode_ref(&parent);
goto End;
}
/* In this place all directories should be unlinked.
* Last unlink from root of current directory*/
r = ext4_unlink(f.mp, &parent, &current, (char *)path, len);
if(r != EOK){
ext4_fs_put_inode_ref(&parent);
goto End;
}
r = ext4_fs_free_inode(&current);
if(r != EOK){
ext4_fs_put_inode_ref(&parent);
goto End;
}
r = ext4_fs_put_inode_ref(&parent);
if(r != EOK)
goto End;
}
}
End:
ext4_dir_iterator_fini(&it);
ext4_fs_put_inode_ref(&current);
dir_end = false;
/*When something goes wrong. End loop.*/
if(r != EOK)
break;
}while(depth);
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_dir_mk(const char *path)
{
int r;
ext4_file f;
struct ext4_mountpoint *mp = ext4_get_mount(path);
if(!mp)
return ENOENT;
EXT4_MP_LOCK(mp);
/*Check if exist.*/
r = ext4_generic_open(&f, path, "r", false, 0, 0);
if(r == EOK){
/*Directory already created*/
EXT4_MP_UNLOCK(mp);
return r;
}
/*Create new dir*/
r = ext4_generic_open(&f, path, "w", false, 0, 0);
if(r != EOK){
EXT4_MP_UNLOCK(mp);
return r;
}
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_dir_open (ext4_dir *d, const char *path)
{
return ext4_generic_open(&d->f, path, "r", false);
struct ext4_mountpoint *mp = ext4_get_mount(path);
int r;
if(!mp)
return ENOENT;
EXT4_MP_LOCK(mp);
r = ext4_generic_open(&d->f, path, "r", false, 0, 0);
EXT4_MP_UNLOCK(mp);
return r;
}
int ext4_dir_close(ext4_dir *d)
@ -1154,7 +1325,7 @@ int ext4_dir_close(ext4_dir *d)
return ext4_fclose(&d->f);
}
ext4_direntry* ext4_entry_get(ext4_dir *d, uint32_t id)
ext4_direntry* ext4_dir_entry_get(ext4_dir *d, uint32_t id)
{
int r;
uint32_t i;
@ -1187,7 +1358,6 @@ ext4_direntry* ext4_entry_get(ext4_dir *d, uint32_t id)
break;
}
i++;
r = ext4_dir_iterator_next(&it);
}

16
lwext4/ext4_dir.c

@ -228,9 +228,21 @@ int ext4_dir_iterator_init(struct ext4_directory_iterator *it,
int ext4_dir_iterator_next(struct ext4_directory_iterator *it)
{
uint16_t skip = ext4_dir_entry_ll_get_entry_length(it->current);
int r = EOK;
uint16_t skip;
return ext4_dir_iterator_seek(it, it->current_offset + skip);
while(r == EOK){
skip = ext4_dir_entry_ll_get_entry_length(it->current);
r = ext4_dir_iterator_seek(it, it->current_offset + skip);
if(!it->current)
break;
/*Skip NULL referenced entry*/
if(it->current->inode != 0)
break;
}
return r;
}
int ext4_dir_iterator_fini(struct ext4_directory_iterator *it)

27
lwext4/ext4_fs.c

@ -546,7 +546,7 @@ int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,
for (i = 0; i < EXT4_INODE_BLOCKS; i++)
inode->blocks[i] = 0;
#if 0
#if CONFIG_EXTENT_ENABLE
/* Initialize extents if needed */
if (ext4_sb_check_feature_incompatible(
&fs->sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
@ -577,6 +577,7 @@ int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref)
struct ext4_fs *fs = inode_ref->fs;
uint32_t offset;
uint32_t suboffset;
#if CONFIG_EXTENT_ENABLE
/* For extents must be data block destroyed by other way */
if ((ext4_sb_check_feature_incompatible(&fs->sb,
EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
@ -584,7 +585,7 @@ int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref)
/* Data structures are released during truncate operation... */
goto finish;
}
#endif
/* Release all indirect (no data) blocks */
/* 1) Single indirect */
@ -739,18 +740,20 @@ int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref,
uint32_t old_blocks_count = old_size / block_size;
if (old_size % block_size != 0)
old_blocks_count++;
#if CONFIG_EXTENT_ENABLE
if ((ext4_sb_check_feature_incompatible(sb,
EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
(ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
#if 0
/* Extents require special operation */
int rc = ext4_extent_release_blocks_from(inode_ref,
old_blocks_count - diff_blocks_count);
if (rc != EOK)
return rc;
} else
#endif
} else {
{
/* Release data blocks from the end of file */
/* Starting from 1 because of logical blocks are numbered from 0 */
@ -781,21 +784,21 @@ int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref,
}
uint32_t current_block;
#if CONFIG_EXTENT_ENABLE
/* Handle i-node using extents */
if ((ext4_sb_check_feature_incompatible(&fs->sb,
EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
(ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
#if 0
int rc = ext4_extent_find_block(inode_ref, iblock, &current_block);
if (rc != EOK)
return rc;
*fblock = current_block;
return EOK;
#endif
}
#endif
struct ext4_inode *inode = inode_ref->inode;
@ -882,6 +885,7 @@ int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref,
{
struct ext4_fs *fs = inode_ref->fs;
#if CONFIG_EXTENT_ENABLE
/* Handle inode using extents */
if ((ext4_sb_check_feature_incompatible(&fs->sb,
EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
@ -889,6 +893,7 @@ int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref,
/* Not reachable */
return ENOTSUP;
}
#endif
/* Handle simple case when we are dealing with direct reference */
if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
@ -1136,16 +1141,14 @@ int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref,
int ext4_fs_append_inode_block(struct ext4_inode_ref *inode_ref,
uint32_t *fblock, uint32_t *iblock)
{
#if CONFIG_EXTENT_ENABLE
/* Handle extents separately */
if ((ext4_sb_check_feature_incompatible(&inode_ref->fs->sb,
EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
(ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))){
#if 0
return ext4_extent_append_block(inode_ref, iblock, fblock, true);
#endif
}
#endif
struct ext4_sblock *sb = &inode_ref->fs->sb;
/* Compute next block index and allocate data block */

Loading…
Cancel
Save