Changeset View
Changeset View
Standalone View
Standalone View
sys/boot/i386/libi386/biosdisk.c
Show First 20 Lines • Show All 828 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
#ifdef LOADER_GELI_SUPPORT | #ifdef LOADER_GELI_SUPPORT | ||||
struct dsk dskp; | struct dsk dskp; | ||||
off_t p_off, diff; | off_t p_off, diff; | ||||
daddr_t alignlba; | daddr_t alignlba; | ||||
int err, n, alignblks; | int err, n, alignblks; | ||||
char *tmpbuf; | char *tmpbuf; | ||||
/* if we already know there is no GELI, skip the rest */ | |||||
if (geli_status[dev->d_unit][dev->d_slice] != ISGELI_YES) | |||||
return (bd_io(dev, dblk, blks, dest, 0)); | |||||
if (geli_status[dev->d_unit][dev->d_slice] == ISGELI_YES) { | if (geli_status[dev->d_unit][dev->d_slice] == ISGELI_YES) { | ||||
/* | /* | ||||
* Align reads to DEV_GELIBOOT_BSIZE bytes because partial | * Align reads to DEV_GELIBOOT_BSIZE bytes because partial | ||||
* sectors cannot be decrypted. Round the requested LBA down to | * sectors cannot be decrypted. Round the requested LBA down to | ||||
* nearest multiple of DEV_GELIBOOT_BSIZE bytes. | * nearest multiple of DEV_GELIBOOT_BSIZE bytes. | ||||
*/ | */ | ||||
alignlba = rounddown2(dblk * BD(dev).bd_sectorsize, | alignlba = rounddown2(dblk * BD(dev).bd_sectorsize, | ||||
DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize; | DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize; | ||||
Show All 28 Lines | if (geli_status[dev->d_unit][dev->d_slice] == ISGELI_YES) { | ||||
dskp.unit = dev->d_unit; | dskp.unit = dev->d_unit; | ||||
dskp.slice = dev->d_slice; | dskp.slice = dev->d_slice; | ||||
dskp.part = dev->d_partition; | dskp.part = dev->d_partition; | ||||
dskp.start = dev->d_offset; | dskp.start = dev->d_offset; | ||||
/* GELI needs the offset relative to the partition start */ | /* GELI needs the offset relative to the partition start */ | ||||
p_off = alignlba - dskp.start; | p_off = alignlba - dskp.start; | ||||
err = geli_read(&dskp, p_off * BD(dev).bd_sectorsize, tmpbuf, | err = geli_io(&dskp, 0, p_off * BD(dev).bd_sectorsize, tmpbuf, | ||||
tsoome: I think we really should have better construct instead of 0/1:D enum for example for nice… | |||||
alignblks * BD(dev).bd_sectorsize); | alignblks * BD(dev).bd_sectorsize); | ||||
if (err) | if (err) | ||||
return (err); | return (err); | ||||
if (tmpbuf != dest) { | if (tmpbuf != dest) { | ||||
bcopy(tmpbuf + diff, dest, blks * BD(dev).bd_sectorsize); | bcopy(tmpbuf + diff, dest, blks * BD(dev).bd_sectorsize); | ||||
free(tmpbuf); | free(tmpbuf); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
#endif /* LOADER_GELI_SUPPORT */ | #endif /* LOADER_GELI_SUPPORT */ | ||||
return (bd_io(dev, dblk, blks, dest, 0)); | return (bd_io(dev, dblk, blks, dest, 0)); | ||||
} | } | ||||
static int | static int | ||||
bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) | bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) | ||||
{ | { | ||||
#ifdef LOADER_GELI_SUPPORT | |||||
struct dsk dskp; | |||||
off_t p_off, diff; | |||||
daddr_t alignlba; | |||||
int err, n, alignblks; | |||||
char *tmpbuf; | |||||
if (geli_status[dev->d_unit][dev->d_slice] == ISGELI_YES) { | |||||
dskp.drive = bd_unit2bios(dev->d_unit); | |||||
dskp.type = dev->d_type; | |||||
dskp.unit = dev->d_unit; | |||||
dskp.slice = dev->d_slice; | |||||
dskp.part = dev->d_partition; | |||||
dskp.start = dev->d_offset; | |||||
/* | |||||
* Align writes to DEV_GELIBOOT_BSIZE bytes because partial | |||||
* sectors cannot be encrypted. Round the requested LBA down to | |||||
* nearest multiple of DEV_GELIBOOT_BSIZE bytes. | |||||
*/ | |||||
alignlba = rounddown2(dblk * BD(dev).bd_sectorsize, | |||||
DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize; | |||||
/* | |||||
* Round number of blocks to read up to nearest multiple of | |||||
* DEV_GELIBOOT_BSIZE | |||||
*/ | |||||
diff = (dblk - alignlba) * BD(dev).bd_sectorsize; | |||||
alignblks = roundup2(blks * BD(dev).bd_sectorsize + diff, | |||||
DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize; | |||||
/* GELI needs the offset relative to the partition start */ | |||||
p_off = alignlba - dskp.start; | |||||
/* | |||||
* If the read is rounded up to a larger size, use a temporary | |||||
* buffer here because the buffer provided by the caller may be | |||||
* too small. | |||||
*/ | |||||
if (diff == 0) { | |||||
tmpbuf = dest; | |||||
} else { | |||||
ngieUnsubmitted Not Done Inline Actionsstyle(9): superfluous braces? ngie: style(9): superfluous braces? | |||||
tmpbuf = malloc(alignblks * BD(dev).bd_sectorsize); | |||||
if (tmpbuf == NULL) { | |||||
return (-1); | |||||
} | |||||
ngieUnsubmitted Not Done Inline Actionsstyle(9): superfluous braces? ngie: style(9): superfluous braces? | |||||
/* | |||||
* Unaligned writes require read/modify/write. | |||||
*/ | |||||
err = bd_io(dev, alignlba, DEV_GELIBOOT_BSIZE, tmpbuf, | |||||
0); | |||||
if (err) | |||||
return (err); | |||||
/* Decrypt */ | |||||
err = geli_io(&dskp, 0, p_off * BD(dev).bd_sectorsize, | |||||
tmpbuf, DEV_GELIBOOT_BSIZE); | |||||
if (err) | |||||
return (err); | |||||
bcopy(dest, tmpbuf + diff, blks * BD(dev).bd_sectorsize); | |||||
} | |||||
err = geli_io(&dskp, 0, p_off * BD(dev).bd_sectorsize, tmpbuf, | |||||
alignblks * BD(dev).bd_sectorsize); | |||||
if (err) | |||||
return (err); | |||||
err = bd_io(dev, alignlba, alignblks, tmpbuf, 1); | |||||
if (err) | |||||
return (err); | |||||
if (tmpbuf != dest) { | |||||
free(tmpbuf); | |||||
} | |||||
ngieUnsubmitted Not Done Inline Actionsstyle(9): superfluous braces? ngie: style(9): superfluous braces? | |||||
return (0); | |||||
} | |||||
#endif /* LOADER_GELI_SUPPORT */ | |||||
return (bd_io(dev, dblk, blks, dest, 1)); | return (bd_io(dev, dblk, blks, dest, 1)); | ||||
} | } | ||||
/* | /* | ||||
* Return the BIOS geometry of a given "fixed drive" in a format | * Return the BIOS geometry of a given "fixed drive" in a format | ||||
* suitable for the legacy bootinfo structure. Since the kernel is | * suitable for the legacy bootinfo structure. Since the kernel is | ||||
* expecting raw int 0x13/0x8 values for N_BIOS_GEOM drives, we | * expecting raw int 0x13/0x8 values for N_BIOS_GEOM drives, we | ||||
* prefer to get the information directly, rather than rely on being | * prefer to get the information directly, rather than rely on being | ||||
▲ Show 20 Lines • Show All 101 Lines • Show Last 20 Lines |
I think we really should have better construct instead of 0/1:D enum for example for nice verbose constants;) same for other occurrences of geli_io() call.