mirror of
https://github.com/linux-apfs/apfsprogs.git
synced 2026-08-18 02:19:50 -07:00
For small filesystems, the addresses of the CIBs are kept as an array in the spaceman block. For huge filesystems, the spaceman instead lists the addresses of CABs, and those in turn list the CIBs. One might expect the boundary between the two to be before the point where the CIBs overrun the spaceman block, but that's not correct. I used the official newfs_apfs to create a filesystem with 8574096900096 bytes (~7.8T), which is the maximum size that would fit in a single CAB. As it turns out, this filesystem still keeps the CIB list inside the spaceman, but the length of the spaceman object is now two blocks instead of one. I had never encountered a multiblock ephemeral object before, but I always suspected they were possible because the object size is reported in checkpoint mappings. This is a bit annoying because pretty much all objects are a single block in size, and now I need to pass the object size around everywhere just for this one crazy spaceman case. There is no way around it though, so just do it. By the way, filesystems bigger that 8574096900096 bytes do use CABs as expected. That's where the limit is: containers that would fit in a single CAB don't use it at all. This had been my guess in the previous patch, I just failed to realize that the CIB list would overrun the spaceman block. Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
45 lines
1.2 KiB
C
45 lines
1.2 KiB
C
/*
|
|
* Copyright (C) 2019 Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com>
|
|
*/
|
|
|
|
#ifndef _OBJECT_H
|
|
#define _OBJECT_H
|
|
|
|
#include <apfs/types.h>
|
|
#include "htable.h"
|
|
|
|
struct apfs_obj_phys;
|
|
struct super_block;
|
|
struct node;
|
|
|
|
/*
|
|
* In-memory representation of an APFS object
|
|
*/
|
|
struct object {
|
|
u64 block_nr;
|
|
u64 oid; /* Often the same as the block number */
|
|
u64 xid;
|
|
u32 type;
|
|
u32 subtype;
|
|
u32 flags;
|
|
|
|
/*
|
|
* Size of the object in bytes. It's usually a single block, the only
|
|
* exception I've found so far are the spacemans of containers that are
|
|
* too big to have all cib addresses in one block, but too small to fill
|
|
* a whole cab with cib addresses.
|
|
*/
|
|
u32 size;
|
|
};
|
|
|
|
extern int obj_verify_csum(struct apfs_obj_phys *obj);
|
|
extern void *read_object_nocheck(u64 bno, u32 size, struct object *obj);
|
|
extern u32 parse_object_flags(u32 flags, bool encrypted);
|
|
extern void *read_object(u64 oid, struct htable_entry **omap_table, struct object *obj);
|
|
extern void *read_object_noheader(u64 oid, struct htable_entry **omap_table, struct object *obj);
|
|
extern void free_cpoint_map_table(struct htable_entry **table);
|
|
extern struct cpoint_map *get_cpoint_map(u64 oid);
|
|
extern void *read_ephemeral_object(u64 oid, struct object *obj);
|
|
|
|
#endif /* _OBJECT_H */
|