mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-07 13:32:57 +00:00
Use rust memoffset crate to replace C offsetof().
Cherry-picked from Eric's PR #208
This commit is contained in:
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -928,6 +928,15 @@ version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.16"
|
||||
@@ -1364,6 +1373,7 @@ dependencies = [
|
||||
"hex",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"memoffset",
|
||||
"rand",
|
||||
"regex",
|
||||
"thiserror",
|
||||
|
||||
@@ -17,6 +17,7 @@ crc32c = "0.6.0"
|
||||
hex = "0.4.3"
|
||||
lazy_static = "1.4"
|
||||
log = "0.4.14"
|
||||
memoffset = "0.6.2"
|
||||
thiserror = "1.0"
|
||||
workspace_hack = { path = "../workspace_hack" }
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ fn main() {
|
||||
//
|
||||
.whitelist_type("ControlFileData")
|
||||
.whitelist_var("PG_CONTROL_FILE_SIZE")
|
||||
.whitelist_var("PG_CONTROLFILEDATA_OFFSETOF_CRC")
|
||||
.whitelist_type("DBState")
|
||||
//
|
||||
// Path the server include dir. It is in tmp_install/include/server, if you did
|
||||
|
||||
@@ -6,10 +6,3 @@
|
||||
*/
|
||||
#include "c.h"
|
||||
#include "catalog/pg_control.h"
|
||||
|
||||
/*
|
||||
* PostgreSQL uses "offsetof(ControlFileData, crc)" in multiple places to get the
|
||||
* size of the control file up to the CRC, which is the last field, but there is
|
||||
* no constant for it. We also need it in the Rust code.
|
||||
*/
|
||||
const uint32 PG_CONTROLFILEDATA_OFFSETOF_CRC = offsetof(ControlFileData, crc);
|
||||
|
||||
@@ -23,15 +23,20 @@
|
||||
//! information. You can use PostgreSQL's pg_controldata utility to view its
|
||||
//! contents.
|
||||
//!
|
||||
use crate::{ControlFileData, PG_CONTROLFILEDATA_OFFSETOF_CRC, PG_CONTROL_FILE_SIZE};
|
||||
use crate::{ControlFileData, PG_CONTROL_FILE_SIZE};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use bytes::{Bytes, BytesMut};
|
||||
|
||||
// sizeof(ControlFileData)
|
||||
/// Equivalent to sizeof(ControlFileData) in C
|
||||
const SIZEOF_CONTROLDATA: usize = std::mem::size_of::<ControlFileData>();
|
||||
// offsetof(ControlFileData, crc)
|
||||
const OFFSETOF_CRC: usize = PG_CONTROLFILEDATA_OFFSETOF_CRC as usize;
|
||||
|
||||
/// Compute the offset of the `crc` field within the `ControlFileData` struct.
|
||||
/// Equivalent to offsetof(ControlFileData, crc) in C.
|
||||
// Someday this can be const when the right compiler features land.
|
||||
fn pg_control_crc_offset() -> usize {
|
||||
memoffset::offset_of!(ControlFileData, crc)
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
@@ -47,6 +52,7 @@ pub fn decode_pg_control(buf: &[u8]) -> Result<ControlFileData> {
|
||||
}
|
||||
|
||||
// Compute the expected CRC of the content.
|
||||
let OFFSETOF_CRC = pg_control_crc_offset();
|
||||
let expectedcrc = crc32c::crc32c(&buf[0..OFFSETOF_CRC]);
|
||||
|
||||
// Convert the slice into an array of the right size, and use `transmute` to
|
||||
@@ -104,9 +110,8 @@ pub fn encode_pg_control(controlfile: &ControlFileData) -> Bytes {
|
||||
unsafe { std::mem::transmute::<ControlFileData, [u8; SIZEOF_CONTROLDATA]>(*controlfile) };
|
||||
|
||||
// Recompute the CRC
|
||||
let mut data_without_crc: [u8; OFFSETOF_CRC] = [0u8; OFFSETOF_CRC];
|
||||
data_without_crc.copy_from_slice(&b[0..OFFSETOF_CRC]);
|
||||
let newcrc = crc32c::crc32c(&data_without_crc);
|
||||
let OFFSETOF_CRC = pg_control_crc_offset();
|
||||
let newcrc = crc32c::crc32c(&b[0..OFFSETOF_CRC]);
|
||||
|
||||
let mut buf = BytesMut::with_capacity(PG_CONTROL_FILE_SIZE as usize);
|
||||
buf.extend_from_slice(&b[0..OFFSETOF_CRC]);
|
||||
|
||||
Reference in New Issue
Block a user