From dfbe6ee1414aed7c67a66d964e953a27c226dd0e Mon Sep 17 00:00:00 2001 From: Paul Lawrence Date: Fri, 11 Sep 2020 12:32:10 -0700 Subject: [PATCH] ANDROID: Incremental fs: Make compatible with existing files Bug: 166638631 Test: incfs_test passes Signed-off-by: Paul Lawrence Change-Id: I3b4f61bf881dccd50f05f42326370421945b68db --- fs/incfs/format.c | 6 + fs/incfs/format.h | 10 ++ .../selftests/filesystems/incfs/incfs_test.c | 105 ++++++++++++++++++ .../selftests/filesystems/incfs/utils.c | 2 +- .../selftests/filesystems/incfs/utils.h | 2 +- 5 files changed, 123 insertions(+), 2 deletions(-) diff --git a/fs/incfs/format.c b/fs/incfs/format.c index 0b15317ca74d..743aebfc80b9 100644 --- a/fs/incfs/format.c +++ b/fs/incfs/format.c @@ -626,6 +626,12 @@ int incfs_read_next_metadata_record(struct backing_file_context *bfc, res = handler->handle_blockmap( &handler->md_buffer.blockmap, handler); break; + case INCFS_MD_FILE_ATTR: + /* + * File attrs no longer supported, ignore section for + * compatibility + */ + break; case INCFS_MD_SIGNATURE: if (handler->handle_signature) res = handler->handle_signature( diff --git a/fs/incfs/format.h b/fs/incfs/format.h index 626796cce214..d0f65eb1e0ab 100644 --- a/fs/incfs/format.h +++ b/fs/incfs/format.h @@ -117,6 +117,7 @@ enum incfs_metadata_type { INCFS_MD_NONE = 0, INCFS_MD_BLOCK_MAP = 1, + INCFS_MD_FILE_ATTR = 2, INCFS_MD_SIGNATURE = 3 }; @@ -135,9 +136,18 @@ struct incfs_md_header { */ __le16 h_record_size; + /* + * Was: CRC32 of the metadata record. + * (e.g. inode, dir entry etc) not just this struct. + */ + __le32 h_unused1; + /* Offset of the next metadata entry if any */ __le64 h_next_md_offset; + /* Was: Offset of the previous metadata entry if any */ + __le64 h_unused2; + } __packed; /* Backing file header */ diff --git a/tools/testing/selftests/filesystems/incfs/incfs_test.c b/tools/testing/selftests/filesystems/incfs/incfs_test.c index 893dc9474ae2..b5cbc51410a3 100644 --- a/tools/testing/selftests/filesystems/incfs/incfs_test.c +++ b/tools/testing/selftests/filesystems/incfs/incfs_test.c @@ -2948,6 +2948,110 @@ failure: return result; } +static const char v1_file[] = { + /* Header */ + /* 0x00: Magic number */ + 0x49, 0x4e, 0x43, 0x46, 0x53, 0x00, 0x00, 0x00, + /* 0x08: Version */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x10: Header size */ + 0x38, 0x00, + /* 0x12: Block size */ + 0x00, 0x10, + /* 0x14: Flags */ + 0x00, 0x00, 0x00, 0x00, + /* 0x18: First md offset */ + 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x20: File size */ + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x28: UUID */ + 0x8c, 0x7d, 0xd9, 0x22, 0xad, 0x47, 0x49, 0x4f, + 0xc0, 0x2c, 0x38, 0x8e, 0x12, 0xc0, 0x0e, 0xac, + + /* 0x38: Attribute */ + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, + + /* Attribute md record */ + /* 0x46: Type */ + 0x02, + /* 0x47: Size */ + 0x25, 0x00, + /* 0x49: CRC */ + 0x9a, 0xef, 0xef, 0x72, + /* 0x4d: Next md offset */ + 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x55: Prev md offset */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x5d: fa_offset */ + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x65: fa_size */ + 0x0e, 0x00, + /* 0x67: fa_crc */ + 0xfb, 0x5e, 0x72, 0x89, + + /* Blockmap table */ + /* 0x6b: First 10-byte entry */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* Blockmap md record */ + /* 0x75: Type */ + 0x01, + /* 0x76: Size */ + 0x23, 0x00, + /* 0x78: CRC */ + 0x74, 0x45, 0xd3, 0xb9, + /* 0x7c: Next md offset */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x84: Prev md offset */ + 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x8c: blockmap offset */ + 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x94: blockmap count */ + 0x01, 0x00, 0x00, 0x00, +}; + +#define TEST(statement, condition) \ + do { \ + statement; \ + if (!(condition)) { \ + ksft_print_msg("%s failed %d\n", \ + __func__, __LINE__); \ + goto out; \ + } \ + } while(false) + +static int compatibility_test(const char *mount_dir) +{ + char *backing_dir = NULL; + static const char *name = "file"; + int result = TEST_FAILURE; + char *filename = NULL; + int fd = -1; + int err; + uint64_t size = 0x0c; + + TEST(backing_dir = create_backing_dir(mount_dir), backing_dir); + TEST(filename = concat_file_name(backing_dir, name), filename); + TEST(fd = open(filename, O_CREAT | O_WRONLY | O_CLOEXEC), fd != -1); + TEST(err = write(fd, v1_file, sizeof(v1_file)), err == sizeof(v1_file)); + TEST(err = fsetxattr(fd, INCFS_XATTR_SIZE_NAME, &size, sizeof(size), 0), + err == 0); + TEST(err = mount_fs(mount_dir, backing_dir, 50), err == 0); + free(filename); + TEST(filename = concat_file_name(mount_dir, name), filename); + close(fd); + TEST(fd = open(filename, O_RDONLY), fd != -1); + + result = TEST_SUCCESS; +out: + close(fd); + umount(mount_dir); + free(backing_dir); + free(filename); + return result; +} + static char *setup_mount_dir() { struct stat st; @@ -3058,6 +3162,7 @@ int main(int argc, char *argv[]) MAKE_TEST(get_hash_blocks_test), MAKE_TEST(large_file_test), MAKE_TEST(mapped_file_test), + MAKE_TEST(compatibility_test), }; #undef MAKE_TEST diff --git a/tools/testing/selftests/filesystems/incfs/utils.c b/tools/testing/selftests/filesystems/incfs/utils.c index 32ba6af49bbd..e60b0d36f49d 100644 --- a/tools/testing/selftests/filesystems/incfs/utils.c +++ b/tools/testing/selftests/filesystems/incfs/utils.c @@ -314,7 +314,7 @@ int wait_for_pending_reads2(int fd, int timeout_ms, return read_res / sizeof(*prs); } -char *concat_file_name(const char *dir, char *file) +char *concat_file_name(const char *dir, const char *file) { char full_name[FILENAME_MAX] = ""; diff --git a/tools/testing/selftests/filesystems/incfs/utils.h b/tools/testing/selftests/filesystems/incfs/utils.h index 470471c7f418..f5ed8dc5f0ff 100644 --- a/tools/testing/selftests/filesystems/incfs/utils.h +++ b/tools/testing/selftests/filesystems/incfs/utils.h @@ -60,7 +60,7 @@ int wait_for_pending_reads(int fd, int timeout_ms, int wait_for_pending_reads2(int fd, int timeout_ms, struct incfs_pending_read_info2 *prs, int prs_count); -char *concat_file_name(const char *dir, char *file); +char *concat_file_name(const char *dir, const char *file); void sha256(const char *data, size_t dsize, char *hash);