[f2fs-dev] [PATCH AUTOSEL 4.14 87/95] f2fs: fix to data block override node segment by mistake
From: zhengliang [ Upstream commit a0770e13c8da83bdb64738c0209ab02dd3cfff8b ] v4: Rearrange the previous three versions. The following scenario could lead to data block override by mistake. TASK A| TASK kworker| TASK B| TASK C | | | open | | | write | | | close | | | | f2fs_write_data_pages | | |f2fs_write_cache_pages| | | f2fs_outplace_write_data| | |f2fs_allocate_data_block (get block in seg S, | | | S is full, and only | | | have this valid data| | | block) | | | allocate_segment| | | locate_dirty_segment (mark S as PRE)| | |f2fs_submit_page_write (submit but is not | | |written on dev) | | unlink| | | iput_final | | | f2fs_drop_inode | | | f2fs_truncate | | | (not evict) | | | | | write_checkpoint | | | flush merged bio but not wait file data writeback| | | set_prefree_as_free (mark S as FREE) | | | | update NODE/DATA | | | allocate_segment (select S) | writeback done | | So we need to guarantee io complete before truncate inode in f2fs_drop_inode. Reviewed-by: Chao Yu Signed-off-by: Zheng Liang Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/super.c | 4 1 file changed, 4 insertions(+) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 4c169ba50c0f..06b75737b1a0 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -668,6 +668,10 @@ static int f2fs_drop_inode(struct inode *inode) sb_start_intwrite(inode->i_sb); f2fs_i_size_write(inode, 0); + f2fs_submit_merged_write_cond(F2FS_I_SB(inode), + inode, NULL, 0, DATA); + truncate_inode_pages_final(inode->i_mapping); + if (F2FS_HAS_BLOCKS(inode)) f2fs_truncate(inode); -- 2.20.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH AUTOSEL 4.19 69/81] f2fs: fix to data block override node segment by mistake
From: zhengliang [ Upstream commit a0770e13c8da83bdb64738c0209ab02dd3cfff8b ] v4: Rearrange the previous three versions. The following scenario could lead to data block override by mistake. TASK A| TASK kworker| TASK B| TASK C | | | open | | | write | | | close | | | | f2fs_write_data_pages | | |f2fs_write_cache_pages| | | f2fs_outplace_write_data| | |f2fs_allocate_data_block (get block in seg S, | | | S is full, and only | | | have this valid data| | | block) | | | allocate_segment| | | locate_dirty_segment (mark S as PRE)| | |f2fs_submit_page_write (submit but is not | | |written on dev) | | unlink| | | iput_final | | | f2fs_drop_inode | | | f2fs_truncate | | | (not evict) | | | | | write_checkpoint | | | flush merged bio but not wait file data writeback| | | set_prefree_as_free (mark S as FREE) | | | | update NODE/DATA | | | allocate_segment (select S) | writeback done | | So we need to guarantee io complete before truncate inode in f2fs_drop_inode. Reviewed-by: Chao Yu Signed-off-by: Zheng Liang Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/super.c | 4 1 file changed, 4 insertions(+) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 2264f27fd26d..036eb1e0d557 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -890,6 +890,10 @@ static int f2fs_drop_inode(struct inode *inode) sb_start_intwrite(inode->i_sb); f2fs_i_size_write(inode, 0); + f2fs_submit_merged_write_cond(F2FS_I_SB(inode), + inode, NULL, 0, DATA); + truncate_inode_pages_final(inode->i_mapping); + if (F2FS_HAS_BLOCKS(inode)) f2fs_truncate(inode); -- 2.20.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [RFC PATCH 0/7] xfstests: verify fscrypt-encrypted contents and filenames
On Fri, Apr 26, 2019 at 01:41:46PM -0700, Eric Biggers wrote: > Hello, > > This series adds xfstests which verify that encrypted contents and > filenames on ext4 and f2fs are actually correct, i.e. that the > encryption uses the correct algorithms, keys, IVs, and padding amounts. > The new tests work by creating encrypted files, unmounting the > filesystem, reading the ciphertext from disk using dd and debugfs or > dump.f2fs, and then comparing it against ciphertext computed > independently by a new test program that implements the same algorithms. > > These tests are important because: > > - The whole point of file encryption is that the files are actually > encrypted correctly on-disk. Except for generic/399, current xfstests > only tests the filesystem semantics, not the actual encryption. > generic/399 only tests for incompressibility of encrypted file > contents using one particular encryption setting, which isn't much. > > - fscrypt now supports 4 main combinations of encryption settings, > rather than 1 as it did originally. This may be doubled to 8 soon > (https://patchwork.kernel.org/patch/10908153/). We should test all > settings. And without tests, even if the initial implementation is > correct, breakage in one specific setting could go undetected. > > - Though Linux's crypto API has self-tests, these only test the > algorithms themselves, not how they are used, e.g. by fscrypt. > > Patch 1 is a cleanup patch. Patches 2-4 add the common helpers for > ciphertext verification tests. Patches 5-7 add the actual tests. > > These tests require e2fsprogs and f2fs-tools patches I recently sent out > to fix printing encrypted filenames. So, this series might not be > suitable for merging into mainline xfstests until those patches are > applied. Regardless, comments are appreciated. The needed patches are: > > debugfs: avoid ambiguity when printing filenames > (https://marc.info/?l=linux-ext4=155596495624232=2) > f2fs-tools: improve filename printing > (https://sourceforge.net/p/linux-f2fs/mailman/message/36648641/) > > This series can also be retrieved from git at > https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/xfstests-dev.git > branch "ciphertext-verification". > > I also have patches on top of this series which verify the ciphertext > produced from v2 encryption policies, which are proposed by my kernel > patch series "fscrypt: key management improvements" > (https://patchwork.kernel.org/cover/10908107/). v2 encryption policies > will use a different key derivation function, and thus their ciphertext > will be different. These additional patches can be found at branch > "fscrypt-key-mgmt-improvements" of my git repo above. But I've arranged > things such that this shorter series can potentially be applied earlier, > to test what's in the kernel now. > > Eric Biggers (7): > common/encrypt: introduce helpers for set_encpolicy and get_encpolicy > fscrypt-crypt-util: add utility for reproducing fscrypt encrypted data > common/encrypt: support requiring other encryption settings > common/encrypt: add helper for ciphertext verification tests > generic: verify ciphertext of v1 encryption policies with AES-256 > generic: verify ciphertext of v1 encryption policies with AES-128 > generic: verify ciphertext of v1 encryption policies with Adiantum > > .gitignore |1 + > common/encrypt | 482 ++- > src/Makefile |3 +- > src/fscrypt-crypt-util.c | 1645 ++ > tests/ext4/024 |3 +- > tests/generic/395| 28 +- > tests/generic/395.out|2 +- > tests/generic/396| 15 +- > tests/generic/397|3 +- > tests/generic/398|5 +- > tests/generic/399|3 +- > tests/generic/419|3 +- > tests/generic/421|3 +- > tests/generic/429|3 +- > tests/generic/435|3 +- > tests/generic/440|5 +- > tests/generic/700| 41 + > tests/generic/700.out|5 + > tests/generic/701| 41 + > tests/generic/701.out|5 + > tests/generic/702| 43 + > tests/generic/702.out| 10 + > tests/generic/group |3 + > 23 files changed, 2308 insertions(+), 47 deletions(-) > create mode 100644 src/fscrypt-crypt-util.c > create mode 100755 tests/generic/700 > create mode 100644 tests/generic/700.out > create mode 100755 tests/generic/701 > create mode 100644 tests/generic/701.out > create mode 100755 tests/generic/702 > create mode 100644 tests/generic/702.out > > -- > 2.21.0.593.g511ec345e18-goog > Any comments on this? FYI, the e2fsprogs patch that these tests need was applied. I'm still waiting for the f2fs-tools patch. - Eric ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net
Re: [f2fs-dev] [PATCH 06/13] fscrypt: support encrypting multiple filesystem blocks per page
On Thursday, May 2, 2019 4:15:08 AM IST Eric Biggers wrote: > From: Eric Biggers > > Rename fscrypt_encrypt_page() to fscrypt_encrypt_pagecache_blocks() and > redefine its behavior to encrypt all filesystem blocks from the given > region of the given page, rather than assuming that the region consists > of just one filesystem block. Also remove the 'inode' and 'lblk_num' > parameters, since they can be retrieved from the page as it's already > assumed to be a pagecache page. > > This is in preparation for allowing encryption on ext4 filesystems with > blocksize != PAGE_SIZE. > > This is based on work by Chandan Rajendra. Looks good to me, Reviewed-by: Chandan Rajendra -- chandan ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 08/13] fscrypt: introduce fscrypt_decrypt_block_inplace()
On Thursday, May 2, 2019 4:15:10 AM IST Eric Biggers wrote: > From: Eric Biggers > > fscrypt_decrypt_page() behaves very differently depending on whether the > filesystem set FS_CFLG_OWN_PAGES in its fscrypt_operations. This makes > the function difficult to understand and document. It also makes it so > that all callers have to provide inode and lblk_num, when fscrypt could > determine these itself for pagecache pages. > > Therefore, move the FS_CFLG_OWN_PAGES behavior into a new function > fscrypt_decrypt_block_inplace(). > Looks good to me, Reviewed-by: Chandan Rajendra -- chandan ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 09/13] fscrypt: support decrypting multiple filesystem blocks per page
On Thursday, May 2, 2019 4:15:11 AM IST Eric Biggers wrote: > From: Eric Biggers > > Rename fscrypt_decrypt_page() to fscrypt_decrypt_pagecache_blocks() and > redefine its behavior to decrypt all filesystem blocks in the given > region of the given page, rather than assuming that the region consists > of just one filesystem block. Also remove the 'inode' and 'lblk_num' > parameters, since they can be retrieved from the page as it's already > assumed to be a pagecache page. > > This is in preparation for allowing encryption on ext4 filesystems with > blocksize != PAGE_SIZE. > > This is based on work by Chandan Rajendra. Looks good to me, Reviewed-by: Chandan Rajendra -- chandan ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 05/13] fscrypt: introduce fscrypt_encrypt_block_inplace()
On Thursday, May 2, 2019 4:15:07 AM IST Eric Biggers wrote: > From: Eric Biggers > > fscrypt_encrypt_page() behaves very differently depending on whether the > filesystem set FS_CFLG_OWN_PAGES in its fscrypt_operations. This makes > the function difficult to understand and document. It also makes it so > that all callers have to provide inode and lblk_num, when fscrypt could > determine these itself for pagecache pages. > > Therefore, move the FS_CFLG_OWN_PAGES behavior into a new function > fscrypt_encrypt_block_inplace(). Looks good to me, Reviewed-by: Chandan Rajendra -- chandan ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 07/13] fscrypt: handle blocksize < PAGE_SIZE in fscrypt_zeroout_range()
On Thursday, May 2, 2019 4:15:09 AM IST Eric Biggers wrote: > From: Eric Biggers > > Adjust fscrypt_zeroout_range() to encrypt a block at a time rather than > a page at a time, so that it works when blocksize < PAGE_SIZE. > > This isn't optimized for performance, but then again this function > already wasn't optimized for performance. As a future optimization, we > could submit much larger bios here. > > This is in preparation for allowing encryption on ext4 filesystems with > blocksize != PAGE_SIZE. > > This is based on work by Chandan Rajendra. Looks good to me, Reviewed-by: Chandan Rajendra -- chandan ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 13/13] ext4: encrypt only up to last block in ext4_bio_write_page()
On Thursday, May 2, 2019 4:15:15 AM IST Eric Biggers wrote: > From: Eric Biggers > > As an optimization, don't encrypt blocks fully beyond i_size, since > those definitely won't need to be written out. Also add a comment. > > This is in preparation for allowing encryption on ext4 filesystems with > blocksize != PAGE_SIZE. > > This is based on work by Chandan Rajendra. > Looks good to me, Reviewed-by: Chandan Rajendra -- chandan ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 04/13] fscrypt: clean up some BUG_ON()s in block encryption/decryption
On Thursday, May 2, 2019 4:15:06 AM IST Eric Biggers wrote: > From: Eric Biggers > > Replace some BUG_ON()s with WARN_ON_ONCE() and returning an error code, > and move the check for len divisible by FS_CRYPTO_BLOCK_SIZE into > fscrypt_crypt_block() so that it's done for both encryption and > decryption, not just encryption. Looks good to me, Reviewed-by: Chandan Rajendra -- chandan ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v4 2/2] sload.f2fs: introduce f2fs_sparse_initialize_meta()
This patch fixes to initialize NAT/SIT/CP.payload region in sparse file mode for sload. Signed-off-by: Chao Yu --- - move initialize_meta() before do_umount(). fsck/fsck.h | 1 + fsck/main.c | 4 +++ fsck/mount.c | 70 3 files changed, 75 insertions(+) diff --git a/fsck/fsck.h b/fsck/fsck.h index dd831de..4db14af 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -181,6 +181,7 @@ extern int fsck_verify(struct f2fs_sb_info *); extern void fsck_free(struct f2fs_sb_info *); extern int f2fs_do_mount(struct f2fs_sb_info *); extern void f2fs_do_umount(struct f2fs_sb_info *); +extern int f2fs_sparse_initialize_meta(struct f2fs_sb_info *); extern void flush_journal_entries(struct f2fs_sb_info *); extern void zero_journal_entries(struct f2fs_sb_info *); diff --git a/fsck/main.c b/fsck/main.c index afdfec9..d844820 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -813,6 +813,10 @@ fsck_again: if (do_sload(sbi)) goto out_err; + ret = f2fs_sparse_initialize_meta(sbi); + if (ret < 0) + goto out_err; + f2fs_do_umount(sbi); /* fsck to fix missing quota */ diff --git a/fsck/mount.c b/fsck/mount.c index 843742e..230f330 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -2721,3 +2721,73 @@ void f2fs_do_umount(struct f2fs_sb_info *sbi) free(sbi->ckpt); free(sbi->raw_super); } + +#ifdef WITH_ANDROID +int f2fs_sparse_initialize_meta(struct f2fs_sb_info *sbi) +{ + struct f2fs_super_block *sb = sbi->raw_super; + u_int32_t sit_seg_count, sit_size; + u_int32_t nat_seg_count, nat_size; + u_int64_t sit_seg_addr, nat_seg_addr, payload_addr; + u_int32_t seg_size = 1 << get_sb(log_blocks_per_seg); + int ret; + + if (!c.sparse_mode) + return 0; + + sit_seg_addr = get_sb(sit_blkaddr); + sit_seg_count = get_sb(segment_count_sit); + sit_size = sit_seg_count * seg_size; + + DBG(1, "\tSparse: filling sit area at block offset: 0x%08"PRIx64" len: %u\n", + sit_seg_addr, sit_size); + ret = dev_fill(NULL, sit_seg_addr * F2FS_BLKSIZE, + sit_size * F2FS_BLKSIZE); + if (ret) { + MSG(1, "\tError: While zeroing out the sit area " + "on disk!!!\n"); + return -1; + } + + nat_seg_addr = get_sb(nat_blkaddr); + nat_seg_count = get_sb(segment_count_nat); + nat_size = nat_seg_count * seg_size; + + DBG(1, "\tSparse: filling nat area at block offset 0x%08"PRIx64" len: %u\n", + nat_seg_addr, nat_size); + ret = dev_fill(NULL, nat_seg_addr * F2FS_BLKSIZE, + nat_size * F2FS_BLKSIZE); + if (ret) { + MSG(1, "\tError: While zeroing out the nat area " + "on disk!!!\n"); + return -1; + } + + payload_addr = get_sb(segment0_blkaddr) + 1; + + DBG(1, "\tSparse: filling bitmap area at block offset 0x%08"PRIx64" len: %u\n", + payload_addr, get_sb(cp_payload)); + ret = dev_fill(NULL, payload_addr * F2FS_BLKSIZE, + get_sb(cp_payload) * F2FS_BLKSIZE); + if (ret) { + MSG(1, "\tError: While zeroing out the nat/sit bitmap area " + "on disk!!!\n"); + return -1; + } + + payload_addr += seg_size; + + DBG(1, "\tSparse: filling bitmap area at block offset 0x%08"PRIx64" len: %u\n", + payload_addr, get_sb(cp_payload)); + ret = dev_fill(NULL, payload_addr * F2FS_BLKSIZE, + get_sb(cp_payload) * F2FS_BLKSIZE); + if (ret) { + MSG(1, "\tError: While zeroing out the nat/sit bitmap area " + "on disk!!!\n"); + return -1; + } + return 0; +} +#else +int f2fs_sparse_initialize_meta(struct f2fs_sb_info *sbi) { return 0; } +#endif -- 2.18.0.rc1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v3 2/2] f2fs-tools: introduce f2fs_update_sparse_file()
This patch fixes to initialize NAT/SIT/CP.payload region in sparse file mode for fsck/sload/resize/defrag/dump tools. Signed-off-by: Chao Yu --- v3: - print message after variable assignment. - use DEFAULT_BLOCKS_PER_SEGMENT instead of get_sb(log_blocks_per_seg). fsck/fsck.h | 1 + fsck/main.c | 5 +++ fsck/mount.c | 82 lib/libf2fs_io.c | 9 -- 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/fsck/fsck.h b/fsck/fsck.h index dd831de..95bb7d3 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -181,6 +181,7 @@ extern int fsck_verify(struct f2fs_sb_info *); extern void fsck_free(struct f2fs_sb_info *); extern int f2fs_do_mount(struct f2fs_sb_info *); extern void f2fs_do_umount(struct f2fs_sb_info *); +extern int f2fs_update_sparse_file(struct f2fs_sb_info *); extern void flush_journal_entries(struct f2fs_sb_info *); extern void zero_journal_entries(struct f2fs_sb_info *); diff --git a/fsck/main.c b/fsck/main.c index afdfec9..0670696 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -845,6 +845,11 @@ retry: goto fsck_again; } } + + ret = f2fs_update_sparse_file(sbi); + if (ret < 0) + return ret; + ret = f2fs_finalize_device(); if (ret < 0) return ret; diff --git a/fsck/mount.c b/fsck/mount.c index 843742e..9c73cda 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -2721,3 +2721,85 @@ void f2fs_do_umount(struct f2fs_sb_info *sbi) free(sbi->ckpt); free(sbi->raw_super); } + +#ifdef WITH_ANDROID +static int sparse_initialize_meta(struct f2fs_sb_info *sbi) +{ + u_int32_t sit_seg_count, sit_size; + u_int32_t nat_seg_count, nat_size; + u_int64_t sit_seg_addr, nat_seg_addr, payload_addr; + u_int32_t seg_size = DEFAULT_BLOCKS_PER_SEGMENT; + int ret; + + sit_seg_addr = get_sb(sit_blkaddr); + sit_seg_count = get_sb(segment_count_sit); + sit_size = sit_seg_count * seg_size; + + DBG(1, "\tSparse: filling sit area at block offset: 0x%08"PRIx64" len: %u\n", + sit_seg_addr, sit_size); + ret = dev_fill(NULL, sit_seg_addr * F2FS_BLKSIZE, + sit_size * F2FS_BLKSIZE); + if (ret) { + MSG(1, "\tError: While zeroing out the sit area " + "on disk!!!\n"); + return -1; + } + + nat_seg_addr = get_sb(nat_blkaddr); + nat_seg_count = get_sb(segment_count_nat); + nat_size = nat_seg_count * seg_size; + + DBG(1, "\tSparse: filling nat area at block offset 0x%08"PRIx64" len: %u\n", + nat_seg_addr, nat_size); + ret = dev_fill(NULL, nat_seg_addr * F2FS_BLKSIZE, + nat_size * F2FS_BLKSIZE); + if (ret) { + MSG(1, "\tError: While zeroing out the nat area " + "on disk!!!\n"); + return -1; + } + + payload_addr = get_sb(segment0_blkaddr) + 1; + + DBG(1, "\tSparse: filling bitmap area at block offset 0x%08"PRIx64" len: %u\n", + payload_addr, get_sb(cp_payload)); + ret = dev_fill(NULL, payload_addr * F2FS_BLKSIZE, + get_sb(cp_payload) * F2FS_BLKSIZE); + if (ret) { + MSG(1, "\tError: While zeroing out the nat/sit bitmap area " + "on disk!!!\n"); + return -1; + } + + payload_addr += seg_size; + + DBG(1, "\tSparse: filling bitmap area at block offset 0x%08"PRIx64" len: %u\n", + payload_addr, get_sb(cp_payload)); + ret = dev_fill(NULL, payload_addr * F2FS_BLKSIZE, + get_sb(cp_payload) * F2FS_BLKSIZE); + if (ret) { + MSG(1, "\tError: While zeroing out the nat/sit bitmap area " + "on disk!!!\n"); + return -1; + } + return 0; +} + +int f2fs_update_sparse_file(struct f2fs_sb_info *sbi) +{ + int ret; + + if (!c.sparse_mode) + return 0; + + sparse_file_destroy(f2fs_sparse_file); + ret = ftruncate(c.devices[0].fd, 0); + ASSERT(!ret); + lseek(c.devices[0].fd, 0, SEEK_SET); + f2fs_sparse_file = sparse_file_new(F2FS_BLKSIZE, c.device_size); + + return sparse_initialize_meta(sbi); +} +#else +int f2fs_update_sparse_file(struct f2fs_sb_info *sbi) { return 0; } +#endif diff --git a/lib/libf2fs_io.c b/lib/libf2fs_io.c index 4d0ea0d..2f2b6bd 100644 --- a/lib/libf2fs_io.c +++ b/lib/libf2fs_io.c @@ -358,15 +358,6 @@ int f2fs_finalize_device(void) int64_t chunk_start = (blocks[0] == NULL) ? -1 : 0; uint64_t j; - if