From: Lukasz Majewski <l.majewski@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 04/13] ext4: Scan all directory blocks for space when inserting a new entry
Date: Mon, 29 Aug 2016 15:56:52 +0200 [thread overview]
Message-ID: <20160829155652.05af2487@amdc2363> (raw)
In-Reply-To: <5f87fb1422db45bb964ff6aa6b4ed557@rwthex-w2-b.rwth-ad.de>
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 <stefan.bruens@rwth-aachen.de>
> ---
> 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--;
> + goto restart_read;
> + }
> + printf("All blocks full: Allocate
> new\n");
> if
> (le32_to_cpu(g_parent_inode->flags) & EXT4_EXTENTS_FL) {
> printf("Directory uses
> extents\n"); goto fail;
> }
> - if (direct_blk_idx ==
> INDIRECT_BLOCKS - 1) {
> + if (directory_blocks >=
> INDIRECT_BLOCKS) { printf("Directory exceeds limit\n");
> goto fail;
> }
> @@ -465,7 +450,8 @@ restart:
> goto fail;
> }
> put_ext4((uint64_t)new_blk_no *
> fs->blksz, zero_buffer, fs->blksz);
> -
> g_parent_inode->b.blocks.dir_blocks[direct_blk_idx] =
> + g_parent_inode->b.blocks.
> + dir_blocks[directory_blocks]
> = cpu_to_le32(new_blk_no);
>
> new_size =
> le32_to_cpu(g_parent_inode->size); @@ -482,8 +468,6 @@ restart:
> goto fail;
> goto restart;
> }
> - dir->direntlen =
> cpu_to_le16(last_entry_dirlen);
> - break;
> }
>
> templength = le16_to_cpu(dir->direntlen);
Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>
--
Best regards,
Lukasz Majewski
Samsung R&D Institute Poland (SRPOL) | Linux Platform Group
next prev parent reply other threads:[~2016-08-29 13:56 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20160828204238.10809-1-stefan.bruens@rwth-aachen.de>
2016-08-28 20:42 ` [U-Boot] [PATCH v3 01/13] ext4: fix possible crash on directory traversal, ignore deleted entries Stefan Brüns
2016-08-28 20:42 ` [U-Boot] [PATCH v3 02/13] ext4: propagate error if creation of directory entry fails Stefan Brüns
2016-08-28 20:42 ` [U-Boot] [PATCH v3 03/13] ext4: Do not crash when trying to grow a directory using extents Stefan Brüns
2016-08-28 20:42 ` [U-Boot] [PATCH v3 04/13] ext4: Scan all directory blocks for space when inserting a new entry Stefan Brüns
2016-08-29 13:56 ` Lukasz Majewski [this message]
2016-08-28 20:42 ` [U-Boot] [PATCH v3 05/13] ext4: Avoid corruption of directories with hash tree indexes Stefan Brüns
2016-08-28 20:42 ` [U-Boot] [PATCH v3 06/13] ext4: scan all directory blocks when looking up an entry Stefan Brüns
2016-08-28 20:42 ` [U-Boot] [PATCH v3 07/13] ext4: only update number of of unused inodes if GDT_CSUM feature is set Stefan Brüns
2016-08-29 14:03 ` Lukasz Majewski
2016-08-28 20:42 ` [U-Boot] [PATCH v3 08/13] ext4: do not clear zalloc'ed buffers a second time Stefan Brüns
2016-08-29 14:04 ` Lukasz Majewski
2016-08-28 20:42 ` [U-Boot] [PATCH v3 09/13] ext4: After completely filled group, scan next group from the beginning Stefan Brüns
2016-08-29 14:06 ` Lukasz Majewski
2016-08-28 20:42 ` [U-Boot] [PATCH v3 10/13] ext4: Avoid out-of-bounds access of block bitmap Stefan Brüns
2016-08-29 14:08 ` Lukasz Majewski
2016-08-28 20:42 ` [U-Boot] [PATCH v3 11/13] ext4: Fix memory leak in case of failure Stefan Brüns
2016-08-29 14:09 ` Lukasz Majewski
2016-08-28 20:42 ` [U-Boot] [PATCH v3 12/13] ext4: Use correct value for inode size even on revision 0 filesystems Stefan Brüns
2016-08-29 14:09 ` Lukasz Majewski
2016-08-28 20:42 ` [U-Boot] [PATCH v3 13/13] ext4: initialize full inode for inodes bigger than 128 bytes Stefan Brüns
2016-08-29 14:11 ` Lukasz Majewski
[not found] ` <20160828204238.10809-14-stefan.bruens@rwth-aachen.de>
2016-09-05 23:56 ` Stefan Bruens
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160829155652.05af2487@amdc2363 \
--to=l.majewski@samsung.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox