2006-12-06 17:25:33 -06:00
|
|
|
/*
|
|
|
|
fdisk.h
|
|
|
|
*/
|
|
|
|
|
2009-10-15 18:26:46 -05:00
|
|
|
#include "c.h"
|
|
|
|
|
2006-12-06 17:25:37 -06:00
|
|
|
#define DEFAULT_SECTOR_SIZE 512
|
|
|
|
#define MAX_SECTOR_SIZE 2048
|
|
|
|
#define SECTOR_SIZE 512 /* still used in BSD code */
|
2006-12-06 17:25:35 -06:00
|
|
|
#define MAXIMUM_PARTS 60
|
|
|
|
|
2006-12-06 17:25:37 -06:00
|
|
|
#define ACTIVE_FLAG 0x80
|
|
|
|
|
|
|
|
#define EXTENDED 0x05
|
|
|
|
#define WIN98_EXTENDED 0x0f
|
|
|
|
#define LINUX_PARTITION 0x81
|
|
|
|
#define LINUX_SWAP 0x82
|
|
|
|
#define LINUX_NATIVE 0x83
|
|
|
|
#define LINUX_EXTENDED 0x85
|
2006-12-06 17:25:46 -06:00
|
|
|
#define LINUX_LVM 0x8e
|
|
|
|
#define LINUX_RAID 0xfd
|
2006-12-06 17:25:37 -06:00
|
|
|
|
2012-05-06 07:10:18 -05:00
|
|
|
#define ALIGN_UP 1
|
|
|
|
#define ALIGN_DOWN 2
|
|
|
|
#define ALIGN_NEAREST 3
|
|
|
|
|
|
|
|
#define LINE_LENGTH 800
|
|
|
|
|
2006-12-06 17:25:37 -06:00
|
|
|
#define IS_EXTENDED(i) \
|
|
|
|
((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
|
|
|
|
|
2006-12-06 17:25:39 -06:00
|
|
|
#define cround(n) (display_in_cyl_units ? ((n)/units_per_sector)+1 : (n))
|
|
|
|
#define scround(x) (((x)+units_per_sector-1)/units_per_sector)
|
2006-12-06 17:25:33 -06:00
|
|
|
|
2012-05-21 15:32:25 -05:00
|
|
|
/* fdisk debugging flags/options */
|
|
|
|
#define FDISK_DEBUG_INIT (1 << 1)
|
|
|
|
#define FDISK_DEBUG_CONTEXT (1 << 2)
|
2012-06-17 11:10:04 -05:00
|
|
|
#define FDISK_DEBUG_TOPOLOGY (1 << 3)
|
2012-06-17 11:10:33 -05:00
|
|
|
#define FDISK_DEBUG_GEOMETRY (1 << 4)
|
2012-07-08 16:40:27 -05:00
|
|
|
#define FDISK_DEBUG_LABEL (1 << 5)
|
2012-05-21 15:32:25 -05:00
|
|
|
#define FDISK_DEBUG_ALL 0xFFFF
|
|
|
|
|
|
|
|
# define ON_DBG(m, x) do { \
|
|
|
|
if ((FDISK_DEBUG_ ## m) & fdisk_debug_mask) { \
|
|
|
|
x; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
# define DBG(m, x) do { \
|
|
|
|
if ((FDISK_DEBUG_ ## m) & fdisk_debug_mask) { \
|
|
|
|
fprintf(stderr, "%d: fdisk: %8s: ", getpid(), # m); \
|
|
|
|
x; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
# define DBG_FLUSH do { \
|
|
|
|
if (fdisk_debug_mask && \
|
|
|
|
fdisk_debug_mask != FDISK_DEBUG_INIT) \
|
|
|
|
fflush(stderr); \
|
|
|
|
} while(0)
|
|
|
|
|
2012-05-23 04:09:49 -05:00
|
|
|
static inline void __attribute__ ((__format__ (__printf__, 1, 2)))
|
|
|
|
dbgprint(const char *mesg, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, mesg);
|
|
|
|
vfprintf(stderr, mesg, ap);
|
|
|
|
va_end(ap);
|
|
|
|
fputc('\n', stderr);
|
|
|
|
}
|
|
|
|
|
2012-05-21 15:32:25 -05:00
|
|
|
extern int fdisk_debug_mask;
|
|
|
|
extern void fdisk_init_debug(int mask);
|
|
|
|
|
2006-12-06 17:25:35 -06:00
|
|
|
struct partition {
|
|
|
|
unsigned char boot_ind; /* 0x80 - active */
|
|
|
|
unsigned char head; /* starting head */
|
|
|
|
unsigned char sector; /* starting sector */
|
|
|
|
unsigned char cyl; /* starting cylinder */
|
|
|
|
unsigned char sys_ind; /* What partition type */
|
|
|
|
unsigned char end_head; /* end head */
|
|
|
|
unsigned char end_sector; /* end sector */
|
|
|
|
unsigned char end_cyl; /* end cylinder */
|
|
|
|
unsigned char start4[4]; /* starting sector counting from 0 */
|
|
|
|
unsigned char size4[4]; /* nr of sectors in partition */
|
2012-01-05 10:01:19 -06:00
|
|
|
} __attribute__ ((packed));
|
2006-12-06 17:25:35 -06:00
|
|
|
|
2011-11-09 12:04:12 -06:00
|
|
|
enum menutype {
|
|
|
|
MAIN_MENU,
|
|
|
|
EXPERT_MENU,
|
|
|
|
};
|
|
|
|
|
2012-04-27 06:23:51 -05:00
|
|
|
enum failure {
|
|
|
|
ioctl_error,
|
|
|
|
unable_to_read,
|
|
|
|
unable_to_seek,
|
|
|
|
unable_to_write
|
|
|
|
};
|
2006-12-06 17:25:33 -06:00
|
|
|
|
2012-06-17 11:10:33 -05:00
|
|
|
typedef unsigned long long sector_t;
|
|
|
|
|
2012-11-25 22:25:49 -06:00
|
|
|
/*
|
|
|
|
* Supported partition table types (labels)
|
|
|
|
*/
|
|
|
|
enum fdisk_labeltype {
|
|
|
|
FDISK_DISKLABEL_DOS = 1,
|
|
|
|
FDISK_DISKLABEL_SUN = 2,
|
|
|
|
FDISK_DISKLABEL_SGI = 4,
|
|
|
|
FDISK_DISKLABEL_AIX = 8,
|
|
|
|
FDISK_DISKLABEL_OSF = 16,
|
|
|
|
FDISK_DISKLABEL_MAC = 32,
|
|
|
|
FDISK_DISKLABEL_GPT = 64,
|
|
|
|
FDISK_DISKLABEL_ANY = -1
|
|
|
|
};
|
|
|
|
|
2012-09-24 04:30:26 -05:00
|
|
|
/*
|
|
|
|
* Partition types
|
|
|
|
*/
|
|
|
|
struct fdisk_parttype {
|
|
|
|
unsigned int type; /* type as number or zero */
|
2012-09-25 03:23:36 -05:00
|
|
|
const char *name; /* description */
|
2012-09-24 06:24:09 -05:00
|
|
|
char *typestr; /* type as string or NULL */
|
2012-09-25 03:23:36 -05:00
|
|
|
|
|
|
|
unsigned int flags; /* FDISK_PARTTYPE_* flags */
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
FDISK_PARTTYPE_UNKNOWN = (1 << 1),
|
|
|
|
FDISK_PARTTYPE_INVISIBLE = (1 << 2),
|
|
|
|
FDISK_PARTTYPE_ALLOCATED = (1 << 3)
|
2012-09-24 04:30:26 -05:00
|
|
|
};
|
|
|
|
|
2012-09-25 03:23:36 -05:00
|
|
|
#define fdisk_parttype_is_unknown(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_UNKNONW))
|
|
|
|
#define fdisk_parttype_is_invisible(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_INVISIBLE))
|
|
|
|
#define fdisk_parttype_is_allocated(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_ALLOCATED))
|
|
|
|
|
2012-06-17 11:10:33 -05:00
|
|
|
/*
|
|
|
|
* Legacy CHS based geometry
|
|
|
|
*/
|
|
|
|
struct fdisk_geometry {
|
2006-12-06 17:25:43 -06:00
|
|
|
unsigned int heads;
|
2012-06-17 11:10:33 -05:00
|
|
|
sector_t sectors;
|
|
|
|
sector_t cylinders;
|
2006-12-06 17:25:43 -06:00
|
|
|
};
|
|
|
|
|
2012-05-21 15:28:03 -05:00
|
|
|
struct fdisk_context {
|
2012-06-17 11:10:07 -05:00
|
|
|
int dev_fd; /* device descriptor */
|
|
|
|
char *dev_path; /* device path */
|
2012-07-23 07:24:25 -05:00
|
|
|
unsigned char *firstsector; /* buffer with master boot record */
|
2012-06-03 13:15:17 -05:00
|
|
|
|
|
|
|
/* topology */
|
2012-06-06 04:03:23 -05:00
|
|
|
unsigned long io_size; /* I/O size used by fdisk */
|
|
|
|
unsigned long optimal_io_size; /* optional I/O returned by device */
|
|
|
|
unsigned long min_io_size; /* minimal I/O size */
|
|
|
|
unsigned long phy_sector_size; /* physical size */
|
|
|
|
unsigned long sector_size; /* logical size */
|
2012-06-03 13:15:17 -05:00
|
|
|
unsigned long alignment_offset;
|
2012-06-03 13:15:20 -05:00
|
|
|
|
2012-11-25 22:25:49 -06:00
|
|
|
enum fdisk_labeltype disklabel; /* current disklabel */
|
|
|
|
|
2012-12-03 08:32:16 -06:00
|
|
|
/* alignment */
|
2012-07-26 09:04:24 -05:00
|
|
|
unsigned long grain; /* alignment unit */
|
2012-12-03 08:32:16 -06:00
|
|
|
sector_t first_lba; /* recommended begin of the first partition */
|
2012-07-26 09:04:24 -05:00
|
|
|
|
2012-06-03 13:15:20 -05:00
|
|
|
/* geometry */
|
|
|
|
sector_t total_sectors; /* in logical sectors */
|
2012-06-17 11:10:33 -05:00
|
|
|
struct fdisk_geometry geom;
|
2012-07-22 12:05:01 -05:00
|
|
|
|
|
|
|
/* label operations and description */
|
|
|
|
const struct fdisk_label *label;
|
2012-05-21 15:28:03 -05:00
|
|
|
};
|
|
|
|
|
2012-12-03 08:32:16 -06:00
|
|
|
#define fdisk_is_disklabel(c, x) fdisk_dev_is_disklabel(c, FDISK_DISKLABEL_ ## x)
|
|
|
|
|
2012-07-08 16:40:27 -05:00
|
|
|
/*
|
|
|
|
* Label specific operations
|
|
|
|
*/
|
|
|
|
struct fdisk_label {
|
|
|
|
const char *name;
|
2012-07-22 12:05:01 -05:00
|
|
|
|
2012-09-24 04:30:26 -05:00
|
|
|
/* array with partition types */
|
|
|
|
struct fdisk_parttype *parttypes;
|
2012-09-25 03:23:36 -05:00
|
|
|
size_t nparttypes; /* number of items in parttypes[] */
|
2012-09-24 04:30:26 -05:00
|
|
|
|
2012-07-22 12:05:01 -05:00
|
|
|
/* probe disk label */
|
2012-07-08 16:40:27 -05:00
|
|
|
int (*probe)(struct fdisk_context *cxt);
|
2012-07-23 11:47:42 -05:00
|
|
|
/* write in-memory changes to disk */
|
|
|
|
int (*write)(struct fdisk_context *cxt);
|
2012-07-24 02:54:52 -05:00
|
|
|
/* verify the partition table */
|
|
|
|
int (*verify)(struct fdisk_context *cxt);
|
2012-07-24 03:31:32 -05:00
|
|
|
/* create new disk label */
|
|
|
|
int (*create)(struct fdisk_context *cxt);
|
2012-07-24 02:34:22 -05:00
|
|
|
/* new partition */
|
2012-11-25 22:29:18 -06:00
|
|
|
int (*part_add)(struct fdisk_context *cxt, int partnum, struct fdisk_parttype *t);
|
2012-07-23 11:15:57 -05:00
|
|
|
/* delete partition */
|
2012-10-07 09:33:37 -05:00
|
|
|
int (*part_delete)(struct fdisk_context *cxt, int partnum);
|
2012-09-25 05:12:28 -05:00
|
|
|
/* get partition type */
|
|
|
|
struct fdisk_parttype *(*part_get_type)(struct fdisk_context *cxt, int partnum);
|
2012-09-26 06:30:44 -05:00
|
|
|
/* set partition type */
|
|
|
|
int (*part_set_type)(struct fdisk_context *cxt, int partnum, struct fdisk_parttype *t);
|
2012-12-03 08:32:16 -06:00
|
|
|
/* refresh alignment setting */
|
|
|
|
int (*reset_alignment)(struct fdisk_context *cxt);
|
2012-07-08 16:40:27 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* labels
|
|
|
|
*/
|
|
|
|
extern const struct fdisk_label aix_label;
|
|
|
|
extern const struct fdisk_label dos_label;
|
|
|
|
extern const struct fdisk_label bsd_label;
|
|
|
|
extern const struct fdisk_label mac_label;
|
|
|
|
extern const struct fdisk_label sun_label;
|
|
|
|
extern const struct fdisk_label sgi_label;
|
fdisk: add GPT support
This patch allows fdisk to handle GUID partition tables, based on the latest UEFI specifications
version 2.3.1, from June 27th, 2012. The following operations are supported:
- Probing (detects both protective and hybrid MBRs)
- Writing to disk
- Listing used partitions
- Adding partitions
- Deleting partitions
- Data integrity verifications (for both headers and partitions).
A few considerations:
- Currently we do not fix invalid primary headers -- we just abort!
- Header checksums are updated upon every change (ie: add/delete partitions), this allows us
to mathematically verify the changes on-the-fly, and not only when writing to disk, like
most other related tools do.
- We are extremly picky when writing to disk, any error aborts the opeartion.
- When creating a new partition, the following GUIDs are available:
http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs
For test cases, the gpt.img from libblkid tests, scsi_debug and my own hard drive (/dev/sda) were used.
For the image, all operations were tested successfully, and for /dev/sda all except write, which
was not tested - hey, I'm not suicidal!
[kzak@redhat.com: - add get/set partition type functions
- use unified on strings based table for partition types
- add partition type to table list function]
Tested-and-reviewed-by: Petr Uzel <petr.uzel@suse.cz>
Signed-off-by: Davidlohr Bueso <dave@gnu.org>
Signed-off-by: Karel Zak <kzak@redhat.com>
2012-09-27 02:50:27 -05:00
|
|
|
extern const struct fdisk_label gpt_label;
|
2012-07-08 16:40:27 -05:00
|
|
|
|
2012-05-23 04:24:04 -05:00
|
|
|
extern struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int readonly);
|
2012-06-03 13:15:17 -05:00
|
|
|
extern int fdisk_dev_has_topology(struct fdisk_context *cxt);
|
2012-07-23 03:56:06 -05:00
|
|
|
extern int fdisk_dev_has_disklabel(struct fdisk_context *cxt);
|
2012-11-25 22:25:49 -06:00
|
|
|
extern int fdisk_dev_is_disklabel(struct fdisk_context *cxt, enum fdisk_labeltype l);
|
2012-06-03 13:15:34 -05:00
|
|
|
extern int fdisk_dev_sectsz_is_default(struct fdisk_context *cxt);
|
2012-05-21 15:28:03 -05:00
|
|
|
extern void fdisk_free_context(struct fdisk_context *cxt);
|
2012-07-23 07:24:25 -05:00
|
|
|
extern void fdisk_zeroize_firstsector(struct fdisk_context *cxt);
|
2012-07-23 03:11:08 -05:00
|
|
|
extern int fdisk_context_force_sector_size(struct fdisk_context *cxt, sector_t s);
|
|
|
|
extern int fdisk_context_set_user_geometry(struct fdisk_context *cxt,
|
|
|
|
unsigned int cylinders, unsigned int heads,
|
|
|
|
unsigned int sectors);
|
2012-07-23 11:15:57 -05:00
|
|
|
extern int fdisk_delete_partition(struct fdisk_context *cxt, int partnum);
|
2012-09-26 07:14:54 -05:00
|
|
|
extern int fdisk_add_partition(struct fdisk_context *cxt, int partnum, struct fdisk_parttype *t);
|
2012-07-23 11:47:42 -05:00
|
|
|
extern int fdisk_write_disklabel(struct fdisk_context *cxt);
|
2012-07-24 02:54:52 -05:00
|
|
|
extern int fdisk_verify_disklabel(struct fdisk_context *cxt);
|
2012-07-24 03:31:32 -05:00
|
|
|
extern int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name);
|
2012-12-03 08:32:16 -06:00
|
|
|
extern int fdisk_reset_alignment(struct fdisk_context *cxt);
|
2012-09-25 05:12:28 -05:00
|
|
|
extern struct fdisk_parttype *fdisk_get_partition_type(struct fdisk_context *cxt, int partnum);
|
2012-09-26 06:30:44 -05:00
|
|
|
extern int fdisk_set_partition_type(struct fdisk_context *cxt, int partnum,
|
|
|
|
struct fdisk_parttype *t);
|
2012-05-21 15:28:03 -05:00
|
|
|
|
2012-09-25 03:23:36 -05:00
|
|
|
extern size_t fdisk_get_nparttypes(struct fdisk_context *cxt);
|
|
|
|
extern struct fdisk_parttype *fdisk_get_parttype_from_code(struct fdisk_context *cxt,
|
|
|
|
unsigned int code);
|
|
|
|
extern struct fdisk_parttype *fdisk_get_parttype_from_string(struct fdisk_context *cxt,
|
|
|
|
const char *str);
|
|
|
|
extern struct fdisk_parttype *fdisk_parse_parttype(struct fdisk_context *cxt, const char *str);
|
|
|
|
|
2012-09-25 05:12:28 -05:00
|
|
|
extern struct fdisk_parttype *fdisk_new_unknown_parttype(unsigned int type, const char *typestr);
|
2012-09-25 03:23:36 -05:00
|
|
|
extern void fdisk_free_parttype(struct fdisk_parttype *type);
|
|
|
|
|
2012-12-03 08:32:16 -06:00
|
|
|
extern sector_t fdisk_topology_get_first_lba(struct fdisk_context *cxt);
|
|
|
|
extern unsigned long fdisk_topology_get_grain(struct fdisk_context *cxt);
|
|
|
|
|
2006-12-06 17:25:33 -06:00
|
|
|
/* prototypes for fdisk.c */
|
2012-07-24 03:52:09 -05:00
|
|
|
extern char *line_ptr;
|
|
|
|
extern int partitions;
|
2006-12-06 17:26:12 -06:00
|
|
|
extern unsigned int display_in_cyl_units, units_per_sector;
|
2012-07-24 02:54:52 -05:00
|
|
|
|
|
|
|
extern void check_consistency(struct fdisk_context *cxt, struct partition *p, int partition);
|
|
|
|
extern void check_alignment(struct fdisk_context *cxt, sector_t lba, int partition);
|
|
|
|
extern void check(struct fdisk_context *cxt, int n, unsigned int h, unsigned int s, unsigned int c, unsigned int start);
|
|
|
|
|
2012-05-27 14:44:04 -05:00
|
|
|
extern void fatal(struct fdisk_context *cxt, enum failure why);
|
2012-06-03 13:15:17 -05:00
|
|
|
extern int get_partition(struct fdisk_context *cxt, int warn, int max);
|
2012-09-24 06:24:09 -05:00
|
|
|
extern void list_partition_types(struct fdisk_context *cxt);
|
2011-01-05 09:50:47 -06:00
|
|
|
extern int read_line (int *asked);
|
2006-12-06 17:25:33 -06:00
|
|
|
extern char read_char(char *mesg);
|
2012-09-25 03:23:36 -05:00
|
|
|
extern struct fdisk_parttype *read_partition_type(struct fdisk_context *cxt);
|
2012-05-27 14:44:04 -05:00
|
|
|
extern void reread_partition_table(struct fdisk_context *cxt, int leave);
|
2006-12-06 17:25:43 -06:00
|
|
|
extern struct partition *get_part_table(int);
|
2012-06-03 13:15:17 -05:00
|
|
|
extern unsigned int read_int(struct fdisk_context *cxt,
|
|
|
|
unsigned int low, unsigned int dflt,
|
2006-12-06 17:26:12 -06:00
|
|
|
unsigned int high, unsigned int base, char *mesg);
|
2012-11-25 22:25:49 -06:00
|
|
|
extern void print_menu(struct fdisk_context *cxt, enum menutype menu);
|
2012-06-03 13:15:17 -05:00
|
|
|
extern void print_partition_size(struct fdisk_context *cxt, int num, sector_t start, sector_t stop, int sysid);
|
2006-12-06 17:25:43 -06:00
|
|
|
|
2012-05-27 14:44:13 -05:00
|
|
|
extern void fill_bounds(sector_t *first, sector_t *last);
|
2012-07-24 03:52:09 -05:00
|
|
|
|
2012-09-24 04:30:26 -05:00
|
|
|
extern char *partition_type(struct fdisk_context *cxt, unsigned char type);
|
2007-06-27 16:36:08 -05:00
|
|
|
extern char read_chars(char *mesg);
|
|
|
|
extern void set_changed(int);
|
|
|
|
extern void set_all_unchanged(void);
|
2012-06-17 11:10:33 -05:00
|
|
|
extern int warn_geometry(struct fdisk_context *cxt);
|
2012-06-03 13:15:17 -05:00
|
|
|
extern void warn_limits(struct fdisk_context *cxt);
|
|
|
|
extern unsigned int read_int_with_suffix(struct fdisk_context *cxt,
|
|
|
|
unsigned int low, unsigned int dflt, unsigned int high,
|
2012-05-06 07:10:18 -05:00
|
|
|
unsigned int base, char *mesg, int *is_suffix_used);
|
2012-06-03 13:15:17 -05:00
|
|
|
extern sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction);
|
2012-12-04 10:54:15 -06:00
|
|
|
extern sector_t align_lba_in_range(struct fdisk_context *cxt, sector_t lba, sector_t start, sector_t stop);
|
2012-06-03 13:15:17 -05:00
|
|
|
extern int get_partition_dflt(struct fdisk_context *cxt, int warn, int max, int dflt);
|
2006-12-06 17:25:39 -06:00
|
|
|
|
|
|
|
#define PLURAL 0
|
|
|
|
#define SINGULAR 1
|
2007-05-30 10:41:14 -05:00
|
|
|
extern const char * str_units(int);
|
2006-12-06 17:25:33 -06:00
|
|
|
|
2012-05-27 14:44:13 -05:00
|
|
|
extern sector_t get_nr_sects(struct partition *p);
|
2006-12-06 17:25:35 -06:00
|
|
|
|
2012-12-03 09:22:17 -06:00
|
|
|
extern int nowarn;
|
2012-05-02 07:05:51 -05:00
|
|
|
extern int MBRbuffer_changed;
|
2012-06-03 13:15:20 -05:00
|
|
|
|
2012-04-28 17:02:45 -05:00
|
|
|
/* start_sect and nr_sects are stored little endian on all machines */
|
|
|
|
/* moreover, they are not aligned correctly */
|
2012-05-02 07:05:51 -05:00
|
|
|
static inline void
|
2012-04-28 17:02:45 -05:00
|
|
|
store4_little_endian(unsigned char *cp, unsigned int val) {
|
|
|
|
cp[0] = (val & 0xff);
|
|
|
|
cp[1] = ((val >> 8) & 0xff);
|
|
|
|
cp[2] = ((val >> 16) & 0xff);
|
|
|
|
cp[3] = ((val >> 24) & 0xff);
|
|
|
|
}
|
|
|
|
|
2012-05-02 07:05:51 -05:00
|
|
|
static inline unsigned int read4_little_endian(const unsigned char *cp)
|
2012-04-28 17:02:45 -05:00
|
|
|
{
|
|
|
|
return (unsigned int)(cp[0]) + ((unsigned int)(cp[1]) << 8)
|
|
|
|
+ ((unsigned int)(cp[2]) << 16)
|
|
|
|
+ ((unsigned int)(cp[3]) << 24);
|
|
|
|
}
|
|
|
|
|
2012-05-27 14:44:13 -05:00
|
|
|
static inline void set_nr_sects(struct partition *p, sector_t nr_sects)
|
2012-04-28 17:02:45 -05:00
|
|
|
{
|
|
|
|
store4_little_endian(p->size4, nr_sects);
|
|
|
|
}
|
|
|
|
|
2012-05-02 07:05:51 -05:00
|
|
|
static inline void set_start_sect(struct partition *p, unsigned int start_sect)
|
2012-04-28 17:02:45 -05:00
|
|
|
{
|
|
|
|
store4_little_endian(p->start4, start_sect);
|
|
|
|
}
|
|
|
|
|
2012-11-30 04:54:10 -06:00
|
|
|
static inline int seek_sector(struct fdisk_context *cxt, sector_t secno)
|
2012-04-28 17:02:45 -05:00
|
|
|
{
|
2012-06-03 13:15:17 -05:00
|
|
|
off_t offset = (off_t) secno * cxt->sector_size;
|
2012-11-30 04:54:10 -06:00
|
|
|
|
|
|
|
return lseek(cxt->dev_fd, offset, SEEK_SET) == (off_t) -1 ? -errno : 0;
|
2012-04-28 17:02:45 -05:00
|
|
|
}
|
|
|
|
|
2012-11-30 04:54:10 -06:00
|
|
|
static inline int read_sector(struct fdisk_context *cxt, sector_t secno, unsigned char *buf)
|
2012-04-28 17:02:45 -05:00
|
|
|
{
|
2012-11-30 04:54:10 -06:00
|
|
|
int rc = seek_sector(cxt, secno);
|
|
|
|
|
|
|
|
if (rc < 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
return read(cxt->dev_fd, buf, cxt->sector_size) !=
|
|
|
|
(ssize_t) cxt->sector_size ? -errno : 0;
|
2012-04-28 17:02:45 -05:00
|
|
|
}
|
|
|
|
|
2012-05-27 14:44:13 -05:00
|
|
|
static inline sector_t get_start_sect(struct partition *p)
|
2012-04-28 17:02:45 -05:00
|
|
|
{
|
|
|
|
return read4_little_endian(p->start4);
|
|
|
|
}
|
|
|
|
|
2012-05-06 07:10:18 -05:00
|
|
|
static inline int is_cleared_partition(struct partition *p)
|
|
|
|
{
|
|
|
|
return !(!p || p->boot_ind || p->head || p->sector || p->cyl ||
|
|
|
|
p->sys_ind || p->end_head || p->end_sector || p->end_cyl ||
|
|
|
|
get_start_sect(p) || get_nr_sects(p));
|
|
|
|
}
|