Lines 36-41
Link Here
|
36 |
#include <errno.h> |
36 |
#include <errno.h> |
37 |
#include <endian.h> |
37 |
#include <endian.h> |
38 |
#include <byteswap.h> |
38 |
#include <byteswap.h> |
|
|
39 |
#include <linux/fs.h> |
39 |
#include "crc32.h" |
40 |
#include "crc32.h" |
40 |
|
41 |
|
41 |
#if BYTE_ORDER == LITTLE_ENDIAN |
42 |
#if BYTE_ORDER == LITTLE_ENDIAN |
Lines 50-59
Link Here
|
50 |
# define __cpu_to_le32(x) bswap_32(x) |
51 |
# define __cpu_to_le32(x) bswap_32(x) |
51 |
#endif |
52 |
#endif |
52 |
|
53 |
|
|
|
54 |
#ifndef BLKGETLASTSECT |
53 |
#define BLKGETLASTSECT _IO(0x12,108) /* get last sector of block device */ |
55 |
#define BLKGETLASTSECT _IO(0x12,108) /* get last sector of block device */ |
|
|
56 |
#endif |
57 |
#ifndef BLKGETSIZE |
54 |
#define BLKGETSIZE _IO(0x12,96) /* return device size */ |
58 |
#define BLKGETSIZE _IO(0x12,96) /* return device size */ |
|
|
59 |
#endif |
60 |
#ifndef BLKSSZGET |
55 |
#define BLKSSZGET _IO(0x12,104) /* get block device sector size */ |
61 |
#define BLKSSZGET _IO(0x12,104) /* get block device sector size */ |
|
|
62 |
#endif |
63 |
#ifndef BLKGETSIZE64 |
56 |
#define BLKGETSIZE64 _IOR(0x12,114,sizeof(uint64_t)) /* return device size in bytes (u64 *arg) */ |
64 |
#define BLKGETSIZE64 _IOR(0x12,114,sizeof(uint64_t)) /* return device size in bytes (u64 *arg) */ |
|
|
65 |
#endif |
57 |
|
66 |
|
58 |
struct blkdev_ioctl_param { |
67 |
struct blkdev_ioctl_param { |
59 |
unsigned int block; |
68 |
unsigned int block; |
Lines 143-162
get_sector_size(int filedes)
Link Here
|
143 |
static uint64_t |
152 |
static uint64_t |
144 |
_get_num_sectors(int filedes) |
153 |
_get_num_sectors(int filedes) |
145 |
{ |
154 |
{ |
146 |
unsigned long sectors=0; |
|
|
147 |
int rc; |
155 |
int rc; |
148 |
#if 0 |
156 |
uint64_t bytes=0; |
149 |
uint64_t bytes=0; |
|
|
150 |
|
157 |
|
151 |
rc = ioctl(filedes, BLKGETSIZE64, &bytes); |
158 |
rc = ioctl(filedes, BLKGETSIZE64, &bytes); |
152 |
if (!rc) |
159 |
if (!rc) |
153 |
return bytes / get_sector_size(filedes); |
160 |
return bytes / get_sector_size(filedes); |
154 |
#endif |
161 |
|
155 |
rc = ioctl(filedes, BLKGETSIZE, §ors); |
162 |
return 0; |
156 |
if (rc) |
|
|
157 |
return 0; |
158 |
|
159 |
return sectors; |
160 |
} |
163 |
} |
161 |
|
164 |
|
162 |
/************************************************************ |
165 |
/************************************************************ |
Lines 193-199
last_lba(int filedes)
Link Here
|
193 |
sectors = 1; |
196 |
sectors = 1; |
194 |
} |
197 |
} |
195 |
|
198 |
|
196 |
return sectors - 1; |
199 |
return sectors ? sectors - 1 : 0; |
197 |
} |
200 |
} |
198 |
|
201 |
|
199 |
|
202 |
|
Lines 220-236
read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
Link Here
|
220 |
{ |
223 |
{ |
221 |
int sector_size = get_sector_size(fd); |
224 |
int sector_size = get_sector_size(fd); |
222 |
off_t offset = lba * sector_size; |
225 |
off_t offset = lba * sector_size; |
|
|
226 |
uint64_t lastlba; |
223 |
ssize_t bytesread; |
227 |
ssize_t bytesread; |
224 |
|
228 |
|
225 |
lseek(fd, offset, SEEK_SET); |
229 |
lseek(fd, offset, SEEK_SET); |
226 |
bytesread = read(fd, buffer, bytes); |
230 |
bytesread = read(fd, buffer, bytes); |
227 |
|
231 |
|
|
|
232 |
lastlba = last_lba(fd); |
233 |
if (!lastlba) |
234 |
return bytesread; |
235 |
|
228 |
/* Kludge. This is necessary to read/write the last |
236 |
/* Kludge. This is necessary to read/write the last |
229 |
block of an odd-sized disk, until Linux 2.5.x kernel fixes. |
237 |
block of an odd-sized disk, until Linux 2.5.x kernel fixes. |
230 |
This is only used by gpt.c, and only to read |
238 |
This is only used by gpt.c, and only to read |
231 |
one sector, so we don't have to be fancy. |
239 |
one sector, so we don't have to be fancy. |
232 |
*/ |
240 |
*/ |
233 |
if (!bytesread && !(last_lba(fd) & 1) && lba == last_lba(fd)) { |
241 |
if (!bytesread && !(lastlba & 1) && lba == lastlba) { |
234 |
bytesread = read_lastoddsector(fd, lba, buffer, bytes); |
242 |
bytesread = read_lastoddsector(fd, lba, buffer, bytes); |
235 |
} |
243 |
} |
236 |
return bytesread; |
244 |
return bytesread; |
Lines 505-511
find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes)
Link Here
|
505 |
if (!gpt || !ptes) |
513 |
if (!gpt || !ptes) |
506 |
return 0; |
514 |
return 0; |
507 |
|
515 |
|
508 |
lastlba = last_lba(fd); |
516 |
if (!(lastlba = last_lba(fd))) |
|
|
517 |
return 0; |
509 |
good_pgpt = is_gpt_valid(fd, GPT_PRIMARY_PARTITION_TABLE_LBA, |
518 |
good_pgpt = is_gpt_valid(fd, GPT_PRIMARY_PARTITION_TABLE_LBA, |
510 |
&pgpt, &pptes); |
519 |
&pgpt, &pptes); |
511 |
if (good_pgpt) { |
520 |
if (good_pgpt) { |