/** * Constructs a full data block representation from the specified minimal * block entry. However, the resultant block's pointers are set to null, * rather than populated via hash table lookups. This behavior is useful when * the RAM representation has not been fully constructed yet. * * @param out_block On success, this gets populated with the data * block information. * @param block_entry The source block entry to convert. * * @return 0 on success; nonzero on failure. */ int nffs_block_from_hash_entry_no_ptrs(struct nffs_block *out_block, struct nffs_hash_entry *block_entry) { struct nffs_disk_block disk_block; uint32_t area_offset; uint8_t area_idx; int rc; assert(nffs_hash_id_is_block(block_entry->nhe_id)); if (nffs_hash_entry_is_dummy(block_entry)) { /* * We can't read this from disk so we'll be missing filling in anything * not already in inode_entry (e.g., prev_id). */ out_block->nb_hash_entry = block_entry; return FS_ENOENT; /* let caller know it's a partial inode_entry */ } nffs_flash_loc_expand(block_entry->nhe_flash_loc, &area_idx, &area_offset); rc = nffs_block_read_disk(area_idx, area_offset, &disk_block); if (rc != 0) { return rc; } out_block->nb_hash_entry = block_entry; nffs_block_from_disk_no_ptrs(out_block, &disk_block); return 0; }
static int nffs_block_from_disk(struct nffs_block *out_block, const struct nffs_disk_block *disk_block, uint8_t area_idx, uint32_t area_offset) { nffs_block_from_disk_no_ptrs(out_block, disk_block); out_block->nb_inode_entry = nffs_hash_find_inode(disk_block->ndb_inode_id); if (out_block->nb_inode_entry == NULL) { return FS_ECORRUPT; } if (disk_block->ndb_prev_id != NFFS_ID_NONE) { out_block->nb_prev = nffs_hash_find_block(disk_block->ndb_prev_id); if (out_block->nb_prev == NULL) { return FS_ECORRUPT; } } return 0; }
/** * Constructs a full data block representation from the specified minimal * block entry. However, the resultant block's pointers are set to null, * rather than populated via hash table lookups. This behavior is useful when * the RAM representation has not been fully constructed yet. * * @param out_block On success, this gets populated with the data * block information. * @param block_entry The source block entry to convert. * * @return 0 on success; nonzero on failure. */ int nffs_block_from_hash_entry_no_ptrs(struct nffs_block *out_block, struct nffs_hash_entry *block_entry) { struct nffs_disk_block disk_block; uint32_t area_offset; uint8_t area_idx; int rc; assert(nffs_hash_id_is_block(block_entry->nhe_id)); nffs_flash_loc_expand(block_entry->nhe_flash_loc, &area_idx, &area_offset); rc = nffs_block_read_disk(area_idx, area_offset, &disk_block); if (rc != 0) { return rc; } out_block->nb_hash_entry = block_entry; nffs_block_from_disk_no_ptrs(out_block, &disk_block); return 0; }
/** * Constructs a block representation from a disk record. If the disk block * references other objects (inode or previous data block), the resulting block * object is populated with pointers to the referenced objects. If the any * referenced objects are not present in the NFFS RAM representation, this * indicates file system corruption. In this case, the resulting block is * populated with all valid references, and an FS_ECORRUPT code is returned. * * @param out_block The resulting block is written here (regardless * of this function's return code). * @param disk_block The source disk record to convert. * * @return 0 if the block was successfully constructed; * FS_ECORRUPT if one or more pointers could not * be filled in due to file system corruption. */ static int nffs_block_from_disk(struct nffs_block *out_block, const struct nffs_disk_block *disk_block) { int rc; rc = 0; nffs_block_from_disk_no_ptrs(out_block, disk_block); out_block->nb_inode_entry = nffs_hash_find_inode(disk_block->ndb_inode_id); if (out_block->nb_inode_entry == NULL) { rc = FS_ECORRUPT; } if (disk_block->ndb_prev_id != NFFS_ID_NONE) { out_block->nb_prev = nffs_hash_find_block(disk_block->ndb_prev_id); if (out_block->nb_prev == NULL) { rc = FS_ECORRUPT; } } return rc; }