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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.