apfs: move object code to separate files

Create the object.c and object.h files.  The intention is to be able to
verify the checksum of objects other than the superblock.

Signed-off-by: Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com>
This commit is contained in:
Ernesto A. Fernández
2019-01-12 19:58:55 -03:00
parent 341664248f
commit 303360577a
7 changed files with 141 additions and 116 deletions
+1 -1
View File
@@ -6,4 +6,4 @@
obj-$(CONFIG_APFS_FS) += apfs.o
apfs-y := btree.o dir.o extents.o file.o inode.o key.o message.o \
namei.o node.o super.o symlink.o unicode.o xattr.o
namei.o node.o object.o super.o symlink.o unicode.o xattr.o
-80
View File
@@ -9,90 +9,10 @@
#define _APFS_H
#include <linux/fs.h>
#include <linux/types.h>
#define EFSBADCRC EBADMSG /* Bad CRC detected */
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
/* APFS Objects */
/* Object identifiers constants */
#define APFS_OID_NX_SUPERBLOCK 1
#define APFS_OID_INVALID 0ULL
#define APFS_OID_RESERVED_COUNT 1024
/* Object type masks */
#define APFS_OBJECT_TYPE_MASK 0x0000ffff
#define APFS_OBJECT_TYPE_FLAGS_MASK 0xffff0000
#define APFS_OBJ_STORAGETYPE_MASK 0xc0000000
#define APFS_OBJECT_TYPE_FLAGS_DEFINED_MASK 0xf8000000
/* Object types */
#define APFS_OBJECT_TYPE_NX_SUPERBLOCK 0x00000001
#define APFS_OBJECT_TYPE_BTREE 0x00000002
#define APFS_OBJECT_TYPE_BTREE_NODE 0x00000003
#define APFS_OBJECT_TYPE_SPACEMAN 0x00000005
#define APFS_OBJECT_TYPE_SPACEMAN_CAB 0x00000006
#define APFS_OBJECT_TYPE_SPACEMAN_CIB 0x00000007
#define APFS_OBJECT_TYPE_SPACEMAN_BITMAP 0x00000008
#define APFS_OBJECT_TYPE_SPACEMAN_FREE_QUEUE 0x00000009
#define APFS_OBJECT_TYPE_EXTENT_LIST_TREE 0x0000000a
#define APFS_OBJECT_TYPE_OMAP 0x0000000b
#define APFS_OBJECT_TYPE_CHECKPOINT_MAP 0x0000000c
#define APFS_OBJECT_TYPE_FS 0x0000000d
#define APFS_OBJECT_TYPE_FSTREE 0x0000000e
#define APFS_OBJECT_TYPE_BLOCKREFTREE 0x0000000f
#define APFS_OBJECT_TYPE_SNAPMETATREE 0x00000010
#define APFS_OBJECT_TYPE_NX_REAPER 0x00000011
#define APFS_OBJECT_TYPE_NX_REAP_LIST 0x00000012
#define APFS_OBJECT_TYPE_OMAP_SNAPSHOT 0x00000013
#define APFS_OBJECT_TYPE_EFI_JUMPSTART 0x00000014
#define APFS_OBJECT_TYPE_FUSION_MIDDLE_TREE 0x00000015
#define APFS_OBJECT_TYPE_NX_FUSION_WBC 0x00000016
#define APFS_OBJECT_TYPE_NX_FUSION_WBC_LIST 0x00000017
#define APFS_OBJECT_TYPE_ER_STATE 0x00000018
#define APFS_OBJECT_TYPE_GBITMAP 0x00000019
#define APFS_OBJECT_TYPE_GBITMAP_TREE 0x0000001a
#define APFS_OBJECT_TYPE_GBITMAP_BLOCK 0x0000001b
#define APFS_OBJECT_TYPE_INVALID 0x00000000
#define APFS_OBJECT_TYPE_TEST 0x000000ff
/* Object type flags */
#define APFS_OBJ_VIRTUAL 0x00000000
#define APFS_OBJ_EPHEMERAL 0x80000000
#define APFS_OBJ_PHYSICAL 0x40000000
#define APFS_OBJ_NOHEADER 0x20000000
#define APFS_OBJ_ENCRYPTED 0x10000000
#define APFS_OBJ_NONPERSISTENT 0x08000000
/*
* On-disk representation of an APFS object
*/
struct apfs_obj_phys {
/*00*/ __le64 o_cksum; /* Fletcher checksum */
__le64 o_oid; /* Object-id */
/*10*/ __le64 o_xid; /* Transaction ID */
__le32 o_type; /* Object type */
__le32 o_subtype; /* Object subtype */
} __packed;
/*
* In-memory representation of an APFS object
*/
struct apfs_object {
struct super_block *sb;
u64 block_nr;
u64 oid; /* Often the same as the block number */
/*
* Buffer head containing the one block of the object. TODO: support
* objects with more than one block.
*/
struct buffer_head *bh;
};
#define APFS_MAX_CKSUM_SIZE 8
/*
* Inode and file operations
*/
+1
View File
@@ -13,6 +13,7 @@
#include <linux/types.h>
#include "apfs.h"
#include "btree.h"
#include "object.h"
/*
* On-disk representation of an object map
+43
View File
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: GPL-2.0
/*
* linux/fs/apfs/object.c
*
* Checksum routines for an APFS object
*/
#include <linux/fs.h>
#include "object.h"
/*
* Note that this is not a generic implementation of fletcher64, as it assumes
* a message length that doesn't overflow sum1 and sum2. This constraint is ok
* for apfs, though, since the block size is limited to 2^16. For a more
* generic optimized implementation, see Nakassis (1988).
*/
static u64 apfs_fletcher64(void *addr, size_t len)
{
__le32 *buff = addr;
u64 sum1 = 0;
u64 sum2 = 0;
u64 c1, c2;
int i;
for (i = 0; i < len/sizeof(u32); i++) {
sum1 += le32_to_cpu(buff[i]);
sum2 += sum1;
}
c1 = sum1 + sum2;
c1 = 0xFFFFFFFF - do_div(c1, 0xFFFFFFFF);
c2 = sum1 + c1;
c2 = 0xFFFFFFFF - do_div(c2, 0xFFFFFFFF);
return (c2 << 32) | c1;
}
int apfs_obj_verify_csum(struct super_block *sb, struct apfs_obj_phys *obj)
{
return (le64_to_cpu(obj->o_cksum) ==
apfs_fletcher64((char *) obj + APFS_MAX_CKSUM_SIZE,
sb->s_blocksize - APFS_MAX_CKSUM_SIZE));
}
+94
View File
@@ -0,0 +1,94 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/fs/apfs/object.h
*
* Copyright (C) 2018 Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com>
*/
#ifndef _OBJECT_H
#define _OBJECT_H
#include <linux/fs.h>
#include <linux/types.h>
/* Object identifiers constants */
#define APFS_OID_NX_SUPERBLOCK 1
#define APFS_OID_INVALID 0ULL
#define APFS_OID_RESERVED_COUNT 1024
/* Object type masks */
#define APFS_OBJECT_TYPE_MASK 0x0000ffff
#define APFS_OBJECT_TYPE_FLAGS_MASK 0xffff0000
#define APFS_OBJ_STORAGETYPE_MASK 0xc0000000
#define APFS_OBJECT_TYPE_FLAGS_DEFINED_MASK 0xf8000000
/* Object types */
#define APFS_OBJECT_TYPE_NX_SUPERBLOCK 0x00000001
#define APFS_OBJECT_TYPE_BTREE 0x00000002
#define APFS_OBJECT_TYPE_BTREE_NODE 0x00000003
#define APFS_OBJECT_TYPE_SPACEMAN 0x00000005
#define APFS_OBJECT_TYPE_SPACEMAN_CAB 0x00000006
#define APFS_OBJECT_TYPE_SPACEMAN_CIB 0x00000007
#define APFS_OBJECT_TYPE_SPACEMAN_BITMAP 0x00000008
#define APFS_OBJECT_TYPE_SPACEMAN_FREE_QUEUE 0x00000009
#define APFS_OBJECT_TYPE_EXTENT_LIST_TREE 0x0000000a
#define APFS_OBJECT_TYPE_OMAP 0x0000000b
#define APFS_OBJECT_TYPE_CHECKPOINT_MAP 0x0000000c
#define APFS_OBJECT_TYPE_FS 0x0000000d
#define APFS_OBJECT_TYPE_FSTREE 0x0000000e
#define APFS_OBJECT_TYPE_BLOCKREFTREE 0x0000000f
#define APFS_OBJECT_TYPE_SNAPMETATREE 0x00000010
#define APFS_OBJECT_TYPE_NX_REAPER 0x00000011
#define APFS_OBJECT_TYPE_NX_REAP_LIST 0x00000012
#define APFS_OBJECT_TYPE_OMAP_SNAPSHOT 0x00000013
#define APFS_OBJECT_TYPE_EFI_JUMPSTART 0x00000014
#define APFS_OBJECT_TYPE_FUSION_MIDDLE_TREE 0x00000015
#define APFS_OBJECT_TYPE_NX_FUSION_WBC 0x00000016
#define APFS_OBJECT_TYPE_NX_FUSION_WBC_LIST 0x00000017
#define APFS_OBJECT_TYPE_ER_STATE 0x00000018
#define APFS_OBJECT_TYPE_GBITMAP 0x00000019
#define APFS_OBJECT_TYPE_GBITMAP_TREE 0x0000001a
#define APFS_OBJECT_TYPE_GBITMAP_BLOCK 0x0000001b
#define APFS_OBJECT_TYPE_INVALID 0x00000000
#define APFS_OBJECT_TYPE_TEST 0x000000ff
/* Object type flags */
#define APFS_OBJ_VIRTUAL 0x00000000
#define APFS_OBJ_EPHEMERAL 0x80000000
#define APFS_OBJ_PHYSICAL 0x40000000
#define APFS_OBJ_NOHEADER 0x20000000
#define APFS_OBJ_ENCRYPTED 0x10000000
#define APFS_OBJ_NONPERSISTENT 0x08000000
/*
* On-disk representation of an APFS object
*/
struct apfs_obj_phys {
/*00*/ __le64 o_cksum; /* Fletcher checksum */
__le64 o_oid; /* Object-id */
/*10*/ __le64 o_xid; /* Transaction ID */
__le32 o_type; /* Object type */
__le32 o_subtype; /* Object subtype */
} __packed;
/*
* In-memory representation of an APFS object
*/
struct apfs_object {
struct super_block *sb;
u64 block_nr;
u64 oid; /* Often the same as the block number */
/*
* Buffer head containing the one block of the object. TODO: support
* objects with more than one block.
*/
struct buffer_head *bh;
};
#define APFS_MAX_CKSUM_SIZE 8
extern int apfs_obj_verify_csum(struct super_block *sb,
struct apfs_obj_phys *obj);
#endif /* _OBJECT_H */
+1 -35
View File
@@ -20,44 +20,10 @@
#include "key.h"
#include "message.h"
#include "node.h"
#include "object.h"
#include "super.h"
#include "xattr.h"
/*
* Note that this is not a generic implementation of fletcher64, as it assumes
* a message length that doesn't overflow sum1 and sum2. This constraint is ok
* for apfs, though, since the block size is limited to 2^16. For a more
* generic optimized implementation, see Nakassis (1988).
*/
static u64 apfs_fletcher64(void *addr, size_t len)
{
__le32 *buff = addr;
u64 sum1 = 0;
u64 sum2 = 0;
u64 c1, c2;
int i;
for (i = 0; i < len/sizeof(u32); i++) {
sum1 += le32_to_cpu(buff[i]);
sum2 += sum1;
}
c1 = sum1 + sum2;
c1 = 0xFFFFFFFF - do_div(c1, 0xFFFFFFFF);
c2 = sum1 + c1;
c2 = 0xFFFFFFFF - do_div(c2, 0xFFFFFFFF);
return (c2 << 32) | c1;
}
static int apfs_obj_verify_csum(struct super_block *sb,
struct apfs_obj_phys *obj)
{
return (le64_to_cpu(obj->o_cksum) ==
apfs_fletcher64((char *) obj + APFS_MAX_CKSUM_SIZE,
sb->s_blocksize - APFS_MAX_CKSUM_SIZE));
}
/**
* apfs_map_main_super - Verify the container superblock and map it into memory
* @sb: superblock structure
+1
View File
@@ -11,6 +11,7 @@
#include <linux/fs.h>
#include <linux/types.h>
#include "apfs.h"
#include "object.h"
/*
* Structure used to store a range of physical blocks