Re: [U-Boot] [PATCH v3 04/13] ext4: Scan all directory blocks for space when inserting a new entry

2016-08-29 Thread Lukasz Majewski
Hi Stefan,

> Previously, only the last directory block was scanned for available
> space. Instead, scan all blocks back to front, and if no sufficient
> space is found, eventually append a new block.
> Blocks are only appended if the directory does not use extents or the
> new block would require insertion of indirect blocks, as the old code
> does.
> 
> Signed-off-by: Stefan Brüns 
> ---
>  fs/ext4/ext4_common.c | 72
> --- 1 file changed,
> 28 insertions(+), 44 deletions(-)
> 
> v3: Patch added to series
> 
> diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
> index 49d6465..96dc371 100644
> --- a/fs/ext4/ext4_common.c
> +++ b/fs/ext4/ext4_common.c
> @@ -365,14 +365,10 @@ int ext4fs_update_parent_dentry(char *filename,
> int file_type) {
>   unsigned int *zero_buffer = NULL;
>   char *root_first_block_buffer = NULL;
> - int direct_blk_idx;
> - long int root_blknr;
> + int blk_idx;
>   long int first_block_no_of_root = 0;
> - long int previous_blknr = -1;
>   int totalbytes = 0;
> - short int padding_factor = 0;
>   unsigned int new_entry_byte_reqd;
> - unsigned int last_entry_dirlen;
>   int sizeof_void_space = 0;
>   int templength = 0;
>   int inodeno = -1;
> @@ -384,6 +380,7 @@ int ext4fs_update_parent_dentry(char *filename,
> int file_type) uint32_t new_blk_no;
>   uint32_t new_size;
>   uint32_t new_blockcnt;
> + uint32_t directory_blocks;
>  
>   zero_buffer = zalloc(fs->blksz);
>   if (!zero_buffer) {
> @@ -396,19 +393,16 @@ int ext4fs_update_parent_dentry(char *filename,
> int file_type) printf("No Memory\n");
>   return -1;
>   }
> + new_entry_byte_reqd = ROUND(strlen(filename) +
> + sizeof(struct ext2_dirent), 4);
>  restart:
> + directory_blocks = le32_to_cpu(g_parent_inode->size) >>
> + LOG2_BLOCK_SIZE(ext4fs_root);
> + blk_idx = directory_blocks - 1;
>  
> +restart_read:
>   /* read the block no allocated to a file */
> - for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS;
> -  direct_blk_idx++) {
> - root_blknr = read_allocated_block(g_parent_inode,
> -   direct_blk_idx);
> - if (root_blknr == 0) {
> - first_block_no_of_root = previous_blknr;
> - break;
> - }
> - previous_blknr = root_blknr;
> - }
> + first_block_no_of_root =
> read_allocated_block(g_parent_inode, blk_idx); 
>   status = ext4fs_devread((lbaint_t)first_block_no_of_root
>   * fs->sect_perblk,
> @@ -420,42 +414,33 @@ restart:
>   goto fail;
>   dir = (struct ext2_dirent *)root_first_block_buffer;
>   totalbytes = 0;
> +
>   while (le16_to_cpu(dir->direntlen) > 0) {
> - /*
> -  * blocksize-totalbytes because last directory length
> -  * i.e. dir->direntlen is free availble space in the
> -  * block that means  it is a last entry of directory
> -  * entry
> -  */
> + unsigned short used_len = ROUND(dir->namelen +
> + sizeof(struct ext2_dirent), 4);
>  
> - /* traversing the each directory entry */
> + /* last entry of block */
>   if (fs->blksz - totalbytes ==
> le16_to_cpu(dir->direntlen)) {
> - if (strlen(filename) % 4 != 0)
> - padding_factor = 4 -
> (strlen(filename) % 4); -
> - new_entry_byte_reqd = strlen(filename) +
> - sizeof(struct ext2_dirent) +
> padding_factor;
> - padding_factor = 0;
> - /*
> -  * update last directory entry length to its
> -  * length because we are creating new
> directory
> -  * entry
> -  */
> - if (dir->namelen % 4 != 0)
> - padding_factor = 4 - (dir->namelen %
> 4); 
> - last_entry_dirlen = dir->namelen +
> - sizeof(struct ext2_dirent) +
> padding_factor;
> - if ((fs->blksz - totalbytes -
> last_entry_dirlen) <
> - new_entry_byte_reqd) {
> - printf("Last Block Full:Allocate new
> block\n");
> + /* check if new entry fits */
> + if ((used_len + new_entry_byte_reqd) <=
> + le16_to_cpu(dir->direntlen)) {
> + dir->direntlen =
> cpu_to_le16(used_len);
> + break;
> + } else {
> + if (blk_idx > 0) {
> + printf("Block full, trying
> previous\n");
> 

[U-Boot] [PATCH v3 04/13] ext4: Scan all directory blocks for space when inserting a new entry

2016-08-28 Thread Stefan Brüns
Previously, only the last directory block was scanned for available space.
Instead, scan all blocks back to front, and if no sufficient space is
found, eventually append a new block.
Blocks are only appended if the directory does not use extents or the new
block would require insertion of indirect blocks, as the old code does.

Signed-off-by: Stefan Brüns 
---
 fs/ext4/ext4_common.c | 72 ---
 1 file changed, 28 insertions(+), 44 deletions(-)

v3: Patch added to series

diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 49d6465..96dc371 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -365,14 +365,10 @@ int ext4fs_update_parent_dentry(char *filename, int 
file_type)
 {
unsigned int *zero_buffer = NULL;
char *root_first_block_buffer = NULL;
-   int direct_blk_idx;
-   long int root_blknr;
+   int blk_idx;
long int first_block_no_of_root = 0;
-   long int previous_blknr = -1;
int totalbytes = 0;
-   short int padding_factor = 0;
unsigned int new_entry_byte_reqd;
-   unsigned int last_entry_dirlen;
int sizeof_void_space = 0;
int templength = 0;
int inodeno = -1;
@@ -384,6 +380,7 @@ int ext4fs_update_parent_dentry(char *filename, int 
file_type)
uint32_t new_blk_no;
uint32_t new_size;
uint32_t new_blockcnt;
+   uint32_t directory_blocks;
 
zero_buffer = zalloc(fs->blksz);
if (!zero_buffer) {
@@ -396,19 +393,16 @@ int ext4fs_update_parent_dentry(char *filename, int 
file_type)
printf("No Memory\n");
return -1;
}
+   new_entry_byte_reqd = ROUND(strlen(filename) +
+   sizeof(struct ext2_dirent), 4);
 restart:
+   directory_blocks = le32_to_cpu(g_parent_inode->size) >>
+   LOG2_BLOCK_SIZE(ext4fs_root);
+   blk_idx = directory_blocks - 1;
 
+restart_read:
/* read the block no allocated to a file */
-   for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS;
-direct_blk_idx++) {
-   root_blknr = read_allocated_block(g_parent_inode,
- direct_blk_idx);
-   if (root_blknr == 0) {
-   first_block_no_of_root = previous_blknr;
-   break;
-   }
-   previous_blknr = root_blknr;
-   }
+   first_block_no_of_root = read_allocated_block(g_parent_inode, blk_idx);
 
status = ext4fs_devread((lbaint_t)first_block_no_of_root
* fs->sect_perblk,
@@ -420,42 +414,33 @@ restart:
goto fail;
dir = (struct ext2_dirent *)root_first_block_buffer;
totalbytes = 0;
+
while (le16_to_cpu(dir->direntlen) > 0) {
-   /*
-* blocksize-totalbytes because last directory length
-* i.e. dir->direntlen is free availble space in the
-* block that means  it is a last entry of directory
-* entry
-*/
+   unsigned short used_len = ROUND(dir->namelen +
+   sizeof(struct ext2_dirent), 4);
 
-   /* traversing the each directory entry */
+   /* last entry of block */
if (fs->blksz - totalbytes == le16_to_cpu(dir->direntlen)) {
-   if (strlen(filename) % 4 != 0)
-   padding_factor = 4 - (strlen(filename) % 4);
-
-   new_entry_byte_reqd = strlen(filename) +
-   sizeof(struct ext2_dirent) + padding_factor;
-   padding_factor = 0;
-   /*
-* update last directory entry length to its
-* length because we are creating new directory
-* entry
-*/
-   if (dir->namelen % 4 != 0)
-   padding_factor = 4 - (dir->namelen % 4);
 
-   last_entry_dirlen = dir->namelen +
-   sizeof(struct ext2_dirent) + padding_factor;
-   if ((fs->blksz - totalbytes - last_entry_dirlen) <
-   new_entry_byte_reqd) {
-   printf("Last Block Full:Allocate new block\n");
+   /* check if new entry fits */
+   if ((used_len + new_entry_byte_reqd) <=
+   le16_to_cpu(dir->direntlen)) {
+   dir->direntlen = cpu_to_le16(used_len);
+   break;
+   } else {
+   if (blk_idx > 0) {
+   printf("Block full, trying previous\n");
+   blk_idx--;
+