1. Extra directory remove caching.
[lwext4.git] / lwext4 / ext4.c
index 3f5af2b8301736a495cd5b34239f85b3edfcf3a7..f7fe07a0f3b61d7e803027615894a3e892517b3b 100644 (file)
 \r
 #include <ext4.h>\r
 \r
-/**@brief      Mount point OS dependent lock*/\r
+/**@brief   Mount point OS dependent lock*/\r
 #define EXT4_MP_LOCK(_m)    \\r
         do { (_m)->os_locks ? (_m)->os_locks->lock() : 0; }while(0)\r
 \r
-/**@brief      Mount point OS dependent unlock*/\r
+/**@brief   Mount point OS dependent unlock*/\r
 #define EXT4_MP_UNLOCK(_m)  \\r
         do { (_m)->os_locks ? (_m)->os_locks->unlock() : 0; }while(0)\r
 \r
-/**@brief      Mount point descrpitor.*/\r
+/**@brief   Mount point descrpitor.*/\r
 struct ext4_mountpoint {\r
 \r
-    /**@brief  Mount point name (@ref ext4_mount)*/\r
-    const char                  *name;\r
+    /**@brief   Mount point name (@ref ext4_mount)*/\r
+    const char *name;\r
 \r
-    /**@brief  Os dependent lock/unlock functions.*/\r
+    /**@brief   Os dependent lock/unlock functions.*/\r
     struct ext4_lock *os_locks;\r
 \r
-    /**@brief  Ext4 filesystem internals.*/\r
-    struct ext4_fs      fs;\r
+    /**@brief   Ext4 filesystem internals.*/\r
+    struct ext4_fs fs;\r
 \r
-    /**@brief  Dynamic alocation cache flag.*/\r
-    bool            cache_dynamic;\r
+    /**@brief   Dynamic alocation cache flag.*/\r
+    bool cache_dynamic;\r
 };\r
 \r
-/**@brief      Block devices descriptor.*/\r
-struct _ext4_devices {\r
+/**@brief   Block devices descriptor.*/\r
+struct _ext4_devices {\r
 \r
-    /**@brief  Block device name (@ref ext4_device_register)*/\r
-    const char                         *name;\r
+    /**@brief   Block device name (@ref ext4_device_register)*/\r
+    const char *name;\r
 \r
-    /**@brief  Block device handle.*/\r
-    struct ext4_blockdev       *bd;\r
+    /**@brief   Block device handle.*/\r
+    struct ext4_blockdev *bd;\r
 \r
-    /**@brief  Block cache handle.*/\r
-    struct ext4_bcache         *bc;\r
+    /**@brief   Block cache handle.*/\r
+    struct ext4_bcache *bc;\r
 };\r
 \r
-/**@brief      Block devices.*/\r
-struct _ext4_devices _bdevices[CONFIG_EXT4_BLOCKDEVS_COUNT];\r
+/**@brief   Block devices.*/\r
+struct _ext4_devices _bdevices[CONFIG_EXT4_BLOCKDEVS_COUNT];\r
 \r
 \r
-/**@brief      Mountpoints.*/\r
-struct ext4_mountpoint _mp[CONFIG_EXT4_MOUNTPOINTS_COUNT];\r
+/**@brief   Mountpoints.*/\r
+struct ext4_mountpoint _mp[CONFIG_EXT4_MOUNTPOINTS_COUNT];\r
 \r
 \r
 \r
-int    ext4_device_register(struct ext4_blockdev *bd, struct ext4_bcache *bc,\r
-        const char *dev_name)\r
+int ext4_device_register(struct ext4_blockdev *bd, struct ext4_bcache *bc,\r
+    const char *dev_name)\r
 {\r
     uint32_t i;\r
     ext4_assert(bd && dev_name);\r
@@ -105,8 +105,8 @@ int ext4_device_register(struct ext4_blockdev *bd, struct ext4_bcache *bc,
     for (i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {\r
         if(!_bdevices[i].name){\r
             _bdevices[i].name   = dev_name;\r
-            _bdevices[i].bd    = bd;\r
-            _bdevices[i].bc    = bc;\r
+            _bdevices[i].bd = bd;\r
+            _bdevices[i].bc = bc;\r
             return EOK;\r
         }\r
     }\r
@@ -175,7 +175,7 @@ static int ext4_has_children(bool *has_children, struct ext4_inode_ref *enode)
 \r
 \r
 static int ext4_link(struct ext4_mountpoint *mp, struct ext4_inode_ref *parent,\r
-        struct ext4_inode_ref *child, const char *name, uint32_t name_len)\r
+    struct ext4_inode_ref *child, const char *name, uint32_t name_len)\r
 {\r
     /* Check maximum name length */\r
     if(name_len > EXT4_DIRECTORY_FILENAME_LEN)\r
@@ -214,7 +214,7 @@ static int ext4_link(struct ext4_mountpoint *mp, struct ext4_inode_ref *parent,
                 return rc;\r
 \r
             ext4_inode_set_flag(child->inode,\r
-                    EXT4_INODE_FLAG_INDEX);\r
+                EXT4_INODE_FLAG_INDEX);\r
             child->dirty = true;\r
         }\r
 #endif\r
@@ -304,16 +304,16 @@ static int ext4_unlink(struct ext4_mountpoint *mp,
 \r
 /****************************************************************************/\r
 \r
-int                    ext4_mount(const char * dev_name,  char *mount_point)\r
+int ext4_mount(const char * dev_name, char *mount_point)\r
 {\r
     ext4_assert(mount_point && dev_name);\r
     int r = EOK;\r
     int i;\r
 \r
     uint32_t bsize;\r
-    struct ext4_blockdev       *bd = 0;\r
-    struct ext4_bcache         *bc = 0;\r
-    struct ext4_mountpoint     *mp = 0;\r
+    struct ext4_blockdev *bd = 0;\r
+    struct ext4_bcache *bc = 0;\r
+    struct ext4_mountpoint *mp = 0;\r
 \r
     if(mount_point[strlen(mount_point) - 1] != '/')\r
         return ENOTSUP;\r
@@ -355,7 +355,6 @@ int                 ext4_mount(const char * dev_name,  char *mount_point)
     bsize = ext4_sb_get_block_size(&mp->fs.sb);\r
     ext4_block_set_lb_size(bd, bsize);\r
 \r
-\r
     mp->cache_dynamic = 0;\r
 \r
     if(!bc){\r
@@ -374,7 +373,6 @@ int                 ext4_mount(const char * dev_name,  char *mount_point)
     if(bsize != bc->itemsize)\r
         return ENOTSUP;\r
 \r
-\r
     /*Bind block cache to block device*/\r
     r = ext4_block_bind_bcache(bd, bc);\r
     if(r != EOK){\r
@@ -390,11 +388,11 @@ int                       ext4_mount(const char * dev_name,  char *mount_point)
 }\r
 \r
 \r
-int                    ext4_umount(char *mount_point)\r
+int ext4_umount(char *mount_point)\r
 {\r
-    int        i;\r
-    int        r = EOK;\r
-    struct ext4_mountpoint     *mp = 0;\r
+    int i;\r
+    int r = EOK;\r
+    struct ext4_mountpoint *mp = 0;\r
 \r
     for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {\r
         if(_mp[i].name){\r
@@ -434,11 +432,9 @@ int ext4_mount_point_stats(const char *mount_point,
             break;\r
         }\r
     }\r
-\r
     if(!mp)\r
         return ENOENT;\r
 \r
-\r
     EXT4_MP_LOCK(mp);\r
     stats->inodes_count      = ext4_get32(&mp->fs.sb, inodes_count);\r
     stats->free_inodes_count = ext4_get32(&mp->fs.sb, free_inodes_count);\r
@@ -458,7 +454,7 @@ int ext4_mount_point_stats(const char *mount_point,
 \r
 /********************************FILE OPERATIONS*****************************/\r
 \r
-static struct ext4_mountpoint*  ext4_get_mount(const char *path)\r
+static struct ext4_mountpoint* ext4_get_mount(const char *path)\r
 {\r
     int i;\r
     for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {\r
@@ -470,7 +466,6 @@ static struct ext4_mountpoint*  ext4_get_mount(const char *path)
     return 0;\r
 }\r
 \r
-\r
 static int ext4_path_check(const char *path, bool* is_goal)\r
 {\r
     int i;\r
@@ -507,7 +502,7 @@ static bool ext4_parse_flags(const char *flags, uint32_t *file_flags)
     }\r
 \r
     if(!strcmp(flags, "a") || !strcmp(flags, "ab")){\r
-        *file_flags = O_WRONLY | O_CREAT | O_APPEND    ;\r
+        *file_flags = O_WRONLY | O_CREAT | O_APPEND;\r
         return true;\r
     }\r
 \r
@@ -532,14 +527,14 @@ static bool ext4_parse_flags(const char *flags, uint32_t *file_flags)
 /****************************************************************************/\r
 \r
 static int ext4_generic_open (ext4_file *f, const char *path,\r
-        const char *flags, bool file_expect, uint32_t *parent_inode, uint32_t *name_off)\r
+    const char *flags, bool file_expect, uint32_t *parent_inode, uint32_t *name_off)\r
 {\r
     struct ext4_mountpoint *mp = ext4_get_mount(path);\r
     struct ext4_directory_search_result result;\r
-    struct ext4_inode_ref      ref;\r
-    bool       is_goal = false;\r
-    uint8_t    inode_type;\r
-    int                r = ENOENT;\r
+    struct ext4_inode_ref ref;\r
+    bool is_goal = false;\r
+    uint8_t inode_type = EXT4_DIRECTORY_FILETYPE_DIR;\r
+    int r = ENOENT;\r
     uint32_t next_inode;\r
 \r
     f->mp = 0;\r
@@ -590,7 +585,7 @@ static int ext4_generic_open (ext4_file *f, const char *path,
                 break;\r
 \r
             /*O_CREAT allows create new entry*/\r
-            struct ext4_inode_ref      child_ref;\r
+            struct ext4_inode_ref child_ref;\r
             r = ext4_fs_alloc_inode(&mp->fs, &child_ref, is_goal ? !file_expect : true);\r
             if(r != EOK)\r
                 break;\r
@@ -685,7 +680,6 @@ static int ext4_generic_open (ext4_file *f, const char *path,
 \r
         if(f->flags & O_APPEND)\r
             f->fpos = f->fsize;\r
-\r
     }\r
 \r
     r = ext4_fs_put_inode_ref(&ref);\r
@@ -697,11 +691,11 @@ static int ext4_generic_open (ext4_file *f, const char *path,
 int ext4_fremove(const char *path)\r
 {\r
     ext4_file   f;\r
-    uint32_t    parent_inode;\r
-    uint32_t    name_off;\r
-    int     r;\r
-    int     len;\r
-    bool    is_goal;\r
+    uint32_t parent_inode;\r
+    uint32_t name_off;\r
+    int r;\r
+    int len;\r
+    bool is_goal;\r
     struct ext4_mountpoint *mp = ext4_get_mount(path);\r
 \r
     struct ext4_inode_ref child;\r
@@ -763,7 +757,7 @@ int ext4_fremove(const char *path)
 }\r
 \r
 \r
-int    ext4_fopen (ext4_file *f, const char *path, const char *flags)\r
+int ext4_fopen (ext4_file *f, const char *path, const char *flags)\r
 {\r
     struct ext4_mountpoint *mp = ext4_get_mount(path);\r
     int r;\r
@@ -777,7 +771,7 @@ int ext4_fopen (ext4_file *f, const char *path, const char *flags)
     return r;\r
 }\r
 \r
-int    ext4_fclose(ext4_file *f)\r
+int ext4_fclose(ext4_file *f)\r
 {\r
     ext4_assert(f && f->mp);\r
 \r
@@ -788,15 +782,15 @@ int       ext4_fclose(ext4_file *f)
 \r
     return EOK;\r
 }\r
-int    ext4_fread (ext4_file *f, void *buf, uint32_t size, uint32_t *rcnt)\r
+int ext4_fread(ext4_file *f, void *buf, uint32_t size, uint32_t *rcnt)\r
 {\r
-    int                 r = EOK;\r
+    int r = EOK;\r
     uint32_t u;\r
     uint32_t fblock;\r
     uint32_t fblock_start;\r
     uint32_t fblock_cnt;\r
     struct ext4_block b;\r
-    uint8_t    *u8_buf = buf;\r
+    uint8_t *u8_buf = buf;\r
     struct ext4_inode_ref ref;\r
     uint32_t sblock;\r
     uint32_t sblock_end;\r
@@ -827,7 +821,7 @@ int ext4_fread (ext4_file *f, void *buf, uint32_t size, uint32_t *rcnt)
 \r
     block_size = ext4_sb_get_block_size(&f->mp->fs.sb);\r
     size = size > (f->fsize - f->fpos) ? (f->fsize - f->fpos) : size;\r
-    sblock     = (f->fpos) / block_size;\r
+    sblock = (f->fpos) / block_size;\r
     sblock_end = (f->fpos + size) / block_size;\r
     u = (f->fpos) % block_size;\r
 \r
@@ -922,13 +916,13 @@ int       ext4_fread (ext4_file *f, void *buf, uint32_t size, uint32_t *rcnt)
     return r;\r
 }\r
 \r
-int    ext4_fwrite(ext4_file *f, void *buf, uint32_t size, uint32_t *wcnt)\r
+int ext4_fwrite(ext4_file *f, void *buf, uint32_t size, uint32_t *wcnt)\r
 {\r
-    int                 r = EOK;\r
+    int r = EOK;\r
     uint32_t u;\r
     uint32_t fblock;\r
     struct ext4_block b;\r
-    uint8_t    *u8_buf = buf;\r
+    uint8_t *u8_buf = buf;\r
     struct ext4_inode_ref ref;\r
     uint32_t sblock;\r
     uint32_t sblock_end;\r
@@ -968,7 +962,7 @@ int ext4_fwrite(ext4_file *f, void *buf, uint32_t size, uint32_t *wcnt)
     if(f->fsize % block_size)\r
         file_blocks++;\r
 \r
-    sblock     = (f->fpos) / block_size;\r
+    sblock = (f->fpos) / block_size;\r
 \r
     u = (f->fpos) % block_size;\r
 \r
@@ -1098,13 +1092,10 @@ int     ext4_fwrite(ext4_file *f, void *buf, uint32_t size, uint32_t *wcnt)
 \r
 }\r
 \r
-\r
-\r
-int ext4_fseek (ext4_file *f, uint64_t offset, uint32_t origin)\r
+int ext4_fseek(ext4_file *f, uint64_t offset, uint32_t origin)\r
 {\r
     switch(origin){\r
     case SEEK_SET:\r
-\r
         if(offset > f->fsize)\r
             return EINVAL;\r
 \r
@@ -1119,43 +1110,45 @@ int ext4_fseek (ext4_file *f, uint64_t offset, uint32_t origin)
     case SEEK_END:\r
         if(offset > f->fsize)\r
             return EINVAL;\r
+\r
         f->fpos = f->fsize - offset;\r
         return EOK;\r
 \r
     }\r
-\r
     return EINVAL;\r
 }\r
 \r
 uint64_t ext4_ftell (ext4_file *f)\r
 {\r
-    return  f->fpos;\r
+    return f->fpos;\r
 }\r
 \r
 uint64_t ext4_fsize (ext4_file *f)\r
 {\r
-    return  f->fsize;\r
+    return f->fsize;\r
 }\r
 \r
 /*********************************DIRECTORY OPERATION************************/\r
 \r
 int ext4_dir_rm(const char *path)\r
 {\r
-    int         r;\r
-    int         len;\r
-    ext4_file   f;\r
-    struct ext4_mountpoint *mp = ext4_get_mount(path);\r
-    struct ext4_inode_ref   current;\r
-    struct ext4_inode_ref   child;\r
+    int r;\r
+    int len;\r
+    ext4_file f;\r
 \r
+    struct ext4_mountpoint *mp = ext4_get_mount(path);\r
+    struct ext4_inode_ref current;\r
+    struct ext4_inode_ref child;\r
     struct ext4_directory_iterator it;\r
+\r
     uint32_t name_off;\r
     uint32_t inode_up;\r
     uint32_t inode_current;\r
     uint32_t depth = 1;\r
-    bool     has_children;\r
-    bool     is_goal;\r
-    bool     dir_end;\r
+\r
+    bool has_children;\r
+    bool is_goal;\r
+    bool dir_end;\r
 \r
     if(!mp)\r
         return ENOENT;\r
@@ -1174,6 +1167,9 @@ int ext4_dir_rm(const char *path)
 \r
     inode_current = f.inode;\r
     dir_end = false;\r
+\r
+    ext4_block_delay_cache_flush(mp->fs.bdev, 1);\r
+\r
     do {\r
         /*Load directory node.*/\r
         r = ext4_fs_get_inode_ref(&f.mp->fs, inode_current, &current);\r
@@ -1307,7 +1303,7 @@ int ext4_dir_rm(const char *path)
 \r
     }while(depth);\r
 \r
-\r
+    ext4_block_delay_cache_flush(mp->fs.bdev, 0);\r
     EXT4_MP_UNLOCK(mp);\r
     return r;\r
 }\r
@@ -1315,7 +1311,7 @@ int ext4_dir_rm(const char *path)
 int ext4_dir_mk(const char *path)\r
 {\r
     int r;\r
-    ext4_file   f;\r
+    ext4_file f;\r
 \r
     struct ext4_mountpoint *mp = ext4_get_mount(path);\r
 \r
@@ -1343,7 +1339,7 @@ int ext4_dir_mk(const char *path)
     return r;\r
 }\r
 \r
-int    ext4_dir_open (ext4_dir *d, const char *path)\r
+int ext4_dir_open (ext4_dir *d, const char *path)\r
 {\r
     struct ext4_mountpoint *mp = ext4_get_mount(path);\r
     int r;\r
@@ -1357,14 +1353,14 @@ int     ext4_dir_open (ext4_dir *d, const char *path)
     return r;\r
 }\r
 \r
-int    ext4_dir_close(ext4_dir *d)\r
+int ext4_dir_close(ext4_dir *d)\r
 {\r
     return ext4_fclose(&d->f);\r
 }\r
 \r
-ext4_direntry* ext4_dir_entry_get(ext4_dir *d, uint32_t id)\r
+ext4_direntry* ext4_dir_entry_get(ext4_dir *d, uint32_t id)\r
 {\r
-    int         r;\r
+    int r;\r
     uint32_t i;\r
     ext4_direntry *de = 0;\r
     struct ext4_inode_ref dir;\r