From ed5fc9b0694d6f5016f2fcbeae218578bb76f248 Mon Sep 17 00:00:00 2001 From: Paul Lawrence Date: Tue, 26 Jan 2021 13:31:09 -0800 Subject: [PATCH] Revert "ANDROID: Incremental fs: Remove attributes from file" This reverts commit 37436094c8751bb9d5c2cfe710b4e8cc232059de. Set incfs back to rvc shipping incfs Bug: 178509184 Test: incfs_test passes Signed-off-by: Paul Lawrence Change-Id: Ifb78100c507a1f78eda0962e13c068118f87402e --- fs/incfs/data_mgmt.c | 20 +++++++++++++++++ fs/incfs/format.c | 48 +++++++++++++++++++++++++++++++++++++++++ fs/incfs/format.h | 18 ++++++++++++++++ fs/incfs/pseudo_files.c | 7 ++++++ 4 files changed, 93 insertions(+) diff --git a/fs/incfs/data_mgmt.c b/fs/incfs/data_mgmt.c index fc868f786e6c..7cc530b8c1f4 100644 --- a/fs/incfs/data_mgmt.c +++ b/fs/incfs/data_mgmt.c @@ -1228,6 +1228,25 @@ static int process_blockmap_md(struct incfs_blockmap *bm, return error; } +static int process_file_attr_md(struct incfs_file_attr *fa, + struct metadata_handler *handler) +{ + struct data_file *df = handler->context; + u16 attr_size = le16_to_cpu(fa->fa_size); + + if (!df) + return -EFAULT; + + if (attr_size > INCFS_MAX_FILE_ATTR_SIZE) + return -E2BIG; + + df->n_attr.fa_value_offset = le64_to_cpu(fa->fa_offset); + df->n_attr.fa_value_size = attr_size; + df->n_attr.fa_crc = le32_to_cpu(fa->fa_crc); + + return 0; +} + static int process_file_signature_md(struct incfs_file_signature *sg, struct metadata_handler *handler) { @@ -1329,6 +1348,7 @@ int incfs_scan_metadata_chain(struct data_file *df) handler->md_record_offset = df->df_metadata_off; handler->context = df; handler->handle_blockmap = process_blockmap_md; + handler->handle_file_attr = process_file_attr_md; handler->handle_signature = process_file_signature_md; while (handler->md_record_offset > 0) { diff --git a/fs/incfs/format.c b/fs/incfs/format.c index 05c23bc87ee5..a5239a5a17f5 100644 --- a/fs/incfs/format.c +++ b/fs/incfs/format.c @@ -274,6 +274,49 @@ int incfs_write_blockmap_to_backing_file(struct backing_file_context *bfc, return result; } +/* + * Write file attribute data and metadata record to the backing file. + */ +int incfs_write_file_attr_to_backing_file(struct backing_file_context *bfc, + struct mem_range value, struct incfs_file_attr *attr) +{ + struct incfs_file_attr file_attr = {}; + int result = 0; + u32 crc = 0; + loff_t value_offset = 0; + + if (!bfc) + return -EFAULT; + + if (value.len > INCFS_MAX_FILE_ATTR_SIZE) + return -ENOSPC; + + LOCK_REQUIRED(bfc->bc_mutex); + + crc = crc32(0, value.data, value.len); + value_offset = incfs_get_end_offset(bfc->bc_file); + file_attr.fa_header.h_md_entry_type = INCFS_MD_FILE_ATTR; + file_attr.fa_header.h_record_size = cpu_to_le16(sizeof(file_attr)); + file_attr.fa_header.h_next_md_offset = cpu_to_le64(0); + file_attr.fa_size = cpu_to_le16((u16)value.len); + file_attr.fa_offset = cpu_to_le64(value_offset); + file_attr.fa_crc = cpu_to_le32(crc); + + result = write_to_bf(bfc, value.data, value.len, value_offset); + if (result) + return result; + + result = append_md_to_backing_file(bfc, &file_attr.fa_header); + if (result) { + /* Error, rollback file changes */ + truncate_backing_file(bfc, value_offset); + } else if (attr) { + *attr = file_attr; + } + + return result; +} + int incfs_write_signature_to_backing_file(struct backing_file_context *bfc, struct mem_range sig, u32 tree_size) { @@ -661,6 +704,11 @@ 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: + if (handler->handle_file_attr) + res = handler->handle_file_attr( + &handler->md_buffer.file_attr, handler); + 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 c7960e9b6e9c..90cadce26c55 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 }; @@ -224,6 +225,17 @@ struct incfs_blockmap { __le32 m_block_count; } __packed; +/* Metadata record for file attribute. Type = INCFS_MD_FILE_ATTR */ +struct incfs_file_attr { + struct incfs_md_header fa_header; + + __le64 fa_offset; + + __le16 fa_size; + + __le32 fa_crc; +} __packed; + /* Metadata record for file signature. Type = INCFS_MD_SIGNATURE */ struct incfs_file_signature { struct incfs_md_header sg_header; @@ -268,11 +280,14 @@ struct metadata_handler { union { struct incfs_md_header md_header; struct incfs_blockmap blockmap; + struct incfs_file_attr file_attr; struct incfs_file_signature signature; } md_buffer; int (*handle_blockmap)(struct incfs_blockmap *bm, struct metadata_handler *handler); + int (*handle_file_attr)(struct incfs_file_attr *fa, + struct metadata_handler *handler); int (*handle_signature)(struct incfs_file_signature *sig, struct metadata_handler *handler); }; @@ -308,6 +323,9 @@ int incfs_write_hash_block_to_backing_file(struct backing_file_context *bfc, loff_t bm_base_off, loff_t file_size); +int incfs_write_file_attr_to_backing_file(struct backing_file_context *bfc, + struct mem_range value, struct incfs_file_attr *attr); + int incfs_write_signature_to_backing_file(struct backing_file_context *bfc, struct mem_range sig, u32 tree_size); diff --git a/fs/incfs/pseudo_files.c b/fs/incfs/pseudo_files.c index ca8d1b206158..22863204bb59 100644 --- a/fs/incfs/pseudo_files.c +++ b/fs/incfs/pseudo_files.c @@ -463,6 +463,13 @@ static int init_new_file(struct mount_info *mi, struct dentry *dentry, if (error) goto out; + if (attr.data && attr.len) { + error = incfs_write_file_attr_to_backing_file(bfc, + attr, NULL); + if (error) + goto out; + } + block_count = (u32)get_blocks_count_for_size(size); if (user_signature_info) {