linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
From: zhaowuyun via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
To: 'Chao Yu' <yuchao0@huawei.com>, linux-f2fs-devel@lists.sourceforge.net
Cc: jaegeuk@kernel.org
Subject: Re: [PATCH v2 1/2] mkfs.f2fs: write fill chunk in sparse file for zeroed block
Date: Tue, 14 May 2019 20:22:13 +0800	[thread overview]
Message-ID: <000801d50a4f$a957dee0$fc079ca0$@wingtech.com> (raw)

Hi Chao,

using the same steps, 
make the userdata partition dirty and fastboot-flash userdata.img to see the mount is successful or not

to test the patch, confirm that issue is fixed by this patch.
Hope to see it accepted.

Tested-by: zhaowuyun <zhaowuyun@wingtech.com>

Best Wishes,
Zac (zhaowuyun@wingtech.com)

> 
> As zhaowuyun reported:
> 
> we met one problem of f2fs, and found one issue of make_f2fs, so I write
> this email to search for your help to confirm this issue.
> 
> The issue was found on one of Android projects. We use f2fs as the
> filesystem of userdata, and make sparse userdata.img using following
> command, which invoked in script mkf2fsuserimg.sh make_f2fs -S $SIZE -f -O
> encrypt -O quota -O verity $MKFS_OPTS $OUTPUT_FILE
> 
> use fastboot to flash this userdata.img to device, and it encountered f2fs
> problem and leading to the mount fail of data partition.
> 
> we can make this issue 100% persent reproduced by making the data
> partition dirty before flashing userdata.img.
> 
> suspect that issue is caused by the dirty data in the data partition.
> so we checked that source code of make_f2fs in f2fs-tool, found that when
> making f2fs, it use dev_fill to do some process:
> 
> ...
> 
> we change code to the following, and the issue is gone.
> 
> if (c.sparse_mode)
>        return dev_write(buf, offset, len);
> 
> Chao Yu:
> >
> > After checking the codes, IIUC, I guess the problem here is, unlike
> > img2simg, mkfs.f2fs won't record zeroed block in sparse image, so
> > during transforming to normal image, some critical region like
> > NAT/SIT/CP.payload area weren't be zeroed correctly, later kernel may
> > load obsoleting data from those region.
> >
> > Also, The way you provide will obviously increase the size of sparse
> > file, since with it we need to write all zeroed blocks of
> > NAT/SIT/CP.payload to sparse file, it's not needed.
> >
> > Not sure, maybe we should use sparse_file_add_fill() to record zeroed
> > blocks, so that this will make formatted image more like img2simged one.
> 
> Jaegeuk:
> > We have to call sparse_file_add_fill() for dev_fill().
> 
> This patch fixes to support writing fill chunk sparse file for those zeroed
> blocks in mkfs.f2fs.
> 
> Reported-by: zhaowuyun <zhaowuyun@wingtech.com>
> Signed-off-by: Chao Yu <yuchao0@huawei.com>
> ---
> v2:
> - don't return -EEXIST if block[x] has non-zeroed data.
>  lib/libf2fs_io.c | 84 +++++++++++++++++++++++++++++++++++++++-------
> --
>  1 file changed, 69 insertions(+), 15 deletions(-)
> 
> diff --git a/lib/libf2fs_io.c b/lib/libf2fs_io.c index f848510..4d0ea0d 100644
> --- a/lib/libf2fs_io.c
> +++ b/lib/libf2fs_io.c
> @@ -36,6 +36,7 @@ struct f2fs_configuration c;  struct sparse_file
> *f2fs_sparse_file;  static char **blocks;  u_int64_t blocks_count;
> +static char *zeroed_block;
>  #endif
> 
>  static int __get_device_fd(__u64 *offset) @@ -103,6 +104,8 @@ static int
> sparse_write_blk(__u64 block, int count, const void *buf)
> 
>  	for (i = 0; i < count; ++i) {
>  		cur_block = block + i;
> +		if (blocks[cur_block] == zeroed_block)
> +			blocks[cur_block] = NULL;
>  		if (!blocks[cur_block]) {
>  			blocks[cur_block] = calloc(1, F2FS_BLKSIZE);
>  			if (!blocks[cur_block])
> @@ -114,6 +117,20 @@ static int sparse_write_blk(__u64 block, int count,
> const void *buf)
>  	return 0;
>  }
> 
> +static int sparse_write_zeroed_blk(__u64 block, int count) {
> +	int i;
> +	__u64 cur_block;
> +
> +	for (i = 0; i < count; ++i) {
> +		cur_block = block + i;
> +		if (blocks[cur_block])
> +			continue;
> +		blocks[cur_block] = zeroed_block;
> +	}
> +	return 0;
> +}
> +
>  #ifdef SPARSE_CALLBACK_USES_SIZE_T
>  static int sparse_import_segment(void *UNUSED(priv), const void *data,
>  		size_t len, unsigned int block, unsigned int nr_blocks) @@ -
> 129,11 +146,17 @@ static int sparse_import_segment(void *UNUSED(priv),
> const void *data, int len,
>  	return sparse_write_blk(block, nr_blocks, data);  }
> 
> -static int sparse_merge_blocks(uint64_t start, uint64_t num)
> +static int sparse_merge_blocks(uint64_t start, uint64_t num, int zero)
>  {
>  	char *buf;
>  	uint64_t i;
> 
> +	if (zero) {
> +		blocks[start] = NULL;
> +		return sparse_file_add_fill(f2fs_sparse_file, 0x0,
> +					F2FS_BLKSIZE * num, start);
> +	}
> +
>  	buf = calloc(num, F2FS_BLKSIZE);
>  	if (!buf) {
>  		fprintf(stderr, "failed to alloc %llu\n", @@ -156,6 +179,7 @@
> static int sparse_merge_blocks(uint64_t start, uint64_t num)  #else  static int
> sparse_read_blk(__u64 block, int count, void *buf) { return 0; }  static int
> sparse_write_blk(__u64 block, int count, const void *buf) { return 0; }
> +static int sparse_write_zeroed_blk(__u64 block, int count) { return 0;
> +}
>  #endif
> 
>  int dev_read(void *buf, __u64 offset, size_t len) @@ -235,7 +259,8 @@ int
> dev_fill(void *buf, __u64 offset, size_t len)
>  	int fd;
> 
>  	if (c.sparse_mode)
> -		return 0;
> +		return sparse_write_zeroed_blk(offset / F2FS_BLKSIZE,
> +						len / F2FS_BLKSIZE);
> 
>  	fd = __get_device_fd(&offset);
>  	if (fd < 0)
> @@ -307,6 +332,12 @@ int f2fs_init_sparse_file(void)
>  		return -1;
>  	}
> 
> +	zeroed_block = calloc(1, F2FS_BLKSIZE);
> +	if (!zeroed_block) {
> +		MSG(0, "\tError: Calloc Failed for zeroed block!!!\n");
> +		return -1;
> +	}
> +
>  	return sparse_file_foreach_chunk(f2fs_sparse_file, true, false,
>  				sparse_import_segment, NULL);
>  #else
> @@ -315,7 +346,8 @@ int f2fs_init_sparse_file(void)  #endif  }
> 
> -#define MAX_CHUNK_SIZE (1 * 1024 * 1024 * 1024ULL)
> +#define MAX_CHUNK_SIZE		(1 * 1024 * 1024 * 1024ULL)
> +#define MAX_CHUNK_COUNT		(MAX_CHUNK_SIZE /
> F2FS_BLKSIZE)
>  int f2fs_finalize_device(void)
>  {
>  	int i;
> @@ -336,24 +368,44 @@ int f2fs_finalize_device(void)
>  		}
> 
>  		for (j = 0; j < blocks_count; ++j) {
> -			if (!blocks[j] && chunk_start != -1) {
> -				ret = sparse_merge_blocks(chunk_start,
> -							j - chunk_start);
> -				chunk_start = -1;
> -			} else if (blocks[j] && chunk_start == -1) {
> -				chunk_start = j;
> -			} else if (blocks[j] && (chunk_start != -1) &&
> -				 (j + 1 - chunk_start >=
> -					(MAX_CHUNK_SIZE / F2FS_BLKSIZE)))
> {
> +			if (chunk_start != -1) {
> +				if (j - chunk_start >= MAX_CHUNK_COUNT) {
> +					ret =
> sparse_merge_blocks(chunk_start,
> +							j - chunk_start, 0);
> +					ASSERT(!ret);
> +					chunk_start = -1;
> +				}
> +			}
> +
> +			if (chunk_start == -1) {
> +				if (!blocks[j])
> +					continue;
> +
> +				if (blocks[j] == zeroed_block) {
> +					ret = sparse_merge_blocks(j, 1, 1);
> +					ASSERT(!ret);
> +				} else {
> +					chunk_start = j;
> +				}
> +			} else {
> +				if (blocks[j] && blocks[j] != zeroed_block)
> +					continue;
> +
>  				ret = sparse_merge_blocks(chunk_start,
> -							  j + 1 - chunk_start);
> +						j - chunk_start, 0);
> +				ASSERT(!ret);
> +
> +				if (blocks[j] == zeroed_block) {
> +					ret = sparse_merge_blocks(j, 1, 1);
> +					ASSERT(!ret);
> +				}
> +
>  				chunk_start = -1;
>  			}
> -			ASSERT(!ret);
>  		}
>  		if (chunk_start != -1) {
>  			ret = sparse_merge_blocks(chunk_start,
> -						blocks_count - chunk_start);
> +						blocks_count - chunk_start,
> 0);
>  			ASSERT(!ret);
>  		}
> 
> @@ -365,6 +417,8 @@ int f2fs_finalize_device(void)
>  			free(blocks[j]);
>  		free(blocks);
>  		blocks = NULL;
> +		free(zeroed_block);
> +		zeroed_block = NULL;
>  		f2fs_sparse_file = NULL;
>  	}
>  #endif
> --
> 2.18.0.rc1

             reply	other threads:[~2019-05-14 12:22 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-14 12:22 zhaowuyun via Linux-f2fs-devel [this message]
2019-05-15  2:09 ` [PATCH v2 1/2] mkfs.f2fs: write fill chunk in sparse file for zeroed block Chao Yu
2019-05-15  2:23   ` 答复: " zhaowuyun via Linux-f2fs-devel
  -- strict thread matches above, loose matches on Subject: below --
2019-05-05  7:45 Chao Yu

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='000801d50a4f$a957dee0$fc079ca0$@wingtech.com' \
    --to=linux-f2fs-devel@lists.sourceforge.net \
    --cc=jaegeuk@kernel.org \
    --cc=yuchao0@huawei.com \
    --cc=zhaowuyun@wingtech.com \
    /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;
as well as URLs for NNTP newsgroup(s).