4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
31 #include <sys/dktp/fdisk.h>
37 #define MAX_LOGDRIVE_OFFSET 63
39 #define FDISK_ERRNO 200
40 #define FDISK_ETOOLONG (FDISK_ERRNO + 0)
41 #define FDISK_EOOBOUND (FDISK_ERRNO + 1)
42 #define FDISK_EZERO (FDISK_ERRNO + 2)
43 #define FDISK_EOVERLAP (FDISK_ERRNO + 3)
44 #define FDISK_ENOVGEOM (FDISK_ERRNO + 4)
45 #define FDISK_ENOPGEOM (FDISK_ERRNO + 5)
46 #define FDISK_ENOLGEOM (FDISK_ERRNO + 6)
47 #define FDISK_ENOLOGDRIVE (FDISK_ERRNO + 7)
48 #define FDISK_EBADLOGDRIVE (FDISK_ERRNO + 8)
49 #define FDISK_ENOEXTPART (FDISK_ERRNO + 9)
50 #define FDISK_EBADMAGIC (FDISK_ERRNO + 10)
51 #define FDISK_EMOUNTED (FDISK_ERRNO + 11)
53 #define FDISK_SUCCESS 0
55 #define FDISK_READ_DISK 0x00000001
57 #define LINUX_SWAP_MAGIC_LENGTH 10
69 FDISK_MINOR_WRITE
= 1,
73 #define FDISK_SECTS_PER_CYL(epp) \
74 (epp->disk_geom.phys_heads * epp->disk_geom.phys_sec)
75 #define FDISK_SECT_TO_CYL(epp, x) ((x) / (FDISK_SECTS_PER_CYL(epp)))
76 #define FDISK_CYL_TO_SECT(epp, x) ((x) * (FDISK_SECTS_PER_CYL(epp)))
77 #define FDISK_ABS_CYL_NUM(epp, x) (FDISK_SECT_TO_CYL(x) +\
80 #define FDISK_CYL_BNDRY_ALIGN(epp, x) (((x) % (FDISK_SECTS_PER_CYL(epp))) ? \
81 (((x)/(FDISK_SECTS_PER_CYL(epp))) + 1) :\
82 ((x)/(FDISK_SECTS_PER_CYL(epp))))
85 * Extended partition structure :
88 * || |----------+---> structure at the beginning of the extended partition
89 * ||--| | ( Lets call it the EBR - Extended Boot Record )
91 * |+--+ | | Logical drive within the extended partition
92 * |+---------+--+| ( We will plainly call this a logical drive )
100 * EBR is effectively "struct ipart parts[2]".
101 * The picture below shows what the EBR contains. The EBR has
102 * two important pieces of information. The first is the offset and the size
103 * of the logical drive in this extended partition. The second is the offset
104 * and size of the next extended partition. The offsets are relative to
105 * beginning of the first extended partition. These extended partitions are
106 * arranged like a linked list.
107 * Note that (currently) only one extended partition can exist in the MBR.
108 * The system ID of a logical drive within the extended partition cannot be
109 * that of an extended partition.
113 * +--------------+ | +-v------------+
115 * || |---+ | | || | |
116 * ||--| | | | ||--| |
117 * || |---|------+-+ || | |
119 * |+------v-----+| |+------------+|
123 * |+------------+| |+------------+|
124 * +--------------+ +--------------+
129 * Main structure used to record changes to the partitions made.
130 * Changes are not written to disk everytime, but maintained in this structure.
131 * This information is used when the user chooses to commit the changes.
132 * A linked list of this structure represents the ondisk partitions.
134 typedef struct logical_drive
{
136 /* structure holding the EBR data */
137 struct ipart parts
[2];
140 * Absolute beginning sector of the extended partition, and hence an
141 * indicator of where the EBR for this logical drive would go on disk.
142 * NOTE : In case the first logical drive in this extended partition is
143 * out of (disk) order, this indicates the beginning of the logical
144 * drive. The EBR will anyway be at the first sector of the extended
145 * partition, for the first logical drive.
150 * Offset of the logical drive from the beginning of its extended
153 uint32_t logdrive_offset
;
155 /* Size of the logical drive in sectors */
158 /* Beginning and ending cylinders of the extended partition */
159 uint32_t begcyl
, endcyl
;
162 * Flag to indicate if this record is to be sync'ed to disk.
163 * It takes two values : FDISK_MAJOR_WRITE and FDISK_MINOR_WRITE
164 * If it is a minor write, there is no need to update the information
165 * in the kernel structures. Example of a minor write is correction of
166 * a corrupt boot signature.
171 * This pointer points to the next extended partition in the order
174 struct logical_drive
*next
;
177 * This pointer points to the next extended partition in a sorted list
178 * sorted in the ascending order of their beginning cylinders.
180 struct logical_drive
*sorted_next
;
184 typedef struct fdisk_disk_geom
{
195 typedef struct ext_part
197 /* Structure holding geometry information about the device */
198 fdisk_disk_geom_t disk_geom
;
200 struct ipart
*mtable
;
202 char device_name
[PATH_MAX
];
209 * Head of the in memory structure (singly linked list) of extended
210 * partition information.
212 logical_drive_t
*ld_head
;
213 logical_drive_t
*sorted_ld_head
;
215 /* Beginning cylinder of the extended partition */
216 uint32_t ext_beg_cyl
;
218 /* Ending cylinder of the extended partition */
219 uint32_t ext_end_cyl
;
221 /* Beginning sector of the extended partition */
222 uint32_t ext_beg_sec
;
224 /* Ending sector of the extended partition */
225 uint32_t ext_end_sec
;
227 /* Count of the number of logical drives in the extended partition */
228 int logical_drive_count
;
231 * Flag to keep track of the update to be made to the Extended Boot
232 * Record (EBR) when all logical drives are deleted. The EBR is filled
233 * with zeroes in such a case.
235 int first_ebr_is_null
;
238 * Flag to indicate corrupt logical drives. Can happen when a partition
239 * manager creates an extended partition and does not null the first EBR
240 * or when important ondisk structures are overwritten by a bad program
242 int corrupt_logical_drives
;
245 * The boot block signature 0xAA55 might not be found on some of the
246 * EBRs. ( Even though the rest of the data might be good )
247 * The following array is used to store the list of such logical drive
250 uchar_t invalid_bb_sig
[MAX_EXT_PARTS
];
253 * Can add a "next" pointer here in case support for multiple
254 * extended partitions becomes the standard someday.
256 * struct ext_part *next;
260 #define fdisk_get_logical_drive_count(epp) ((epp)->logical_drive_count)
261 #define fdisk_corrupt_logical_drives(epp) ((epp)->corrupt_logical_drives)
262 #define fdisk_get_ext_beg_cyl(epp) ((epp)->ext_beg_cyl)
263 #define fdisk_get_ext_end_cyl(epp) ((epp)->ext_end_cyl)
264 #define fdisk_get_ext_beg_sec(epp) ((epp)->ext_beg_sec)
265 #define fdisk_get_ext_end_sec(epp) ((epp)->ext_end_sec)
266 #define fdisk_get_ld_head(epp) ((epp)->ld_head)
267 #define fdisk_is_solaris_part(id) (((id) == SUNIXOS) || ((id) == SUNIXOS2))
268 #define fdisk_is_dos_extended(id) (((id) == EXTDOS) || ((id) == FDISK_EXTLBA))
270 extern int fdisk_is_linux_swap(ext_part_t
*epp
, uint32_t part_start
,
271 uint64_t *lsm_offset
);
272 extern int libfdisk_init(ext_part_t
**epp
, char *devstr
, struct ipart
*parttab
,
274 extern int libfdisk_reset(ext_part_t
*epp
);
275 extern void libfdisk_fini(ext_part_t
**epp
);
276 extern int fdisk_ext_find_first_free_sec(ext_part_t
*epp
,
277 uint32_t *first_free_sec
);
278 extern uint32_t fdisk_ext_find_last_free_sec(ext_part_t
*epp
, uint32_t begsec
);
279 extern int fdisk_ext_part_exists(ext_part_t
*epp
);
280 extern int fdisk_validate_logical_drive(ext_part_t
*epp
, uint32_t begsec
,
281 uint32_t offset
, uint32_t numsec
);
282 extern int fdisk_ext_validate_part_start(ext_part_t
*epp
, uint32_t begcyl
,
284 extern int fdisk_get_solaris_part(ext_part_t
*epp
, int *pnum
, uint32_t *begsec
,
286 extern int fdisk_get_part_info(ext_part_t
*epp
, int pnum
, uchar_t
*sysid
,
287 uint32_t *begsec
, uint32_t *numsec
);
288 extern int fdisk_commit_ext_part(ext_part_t
*epp
);
289 extern void fdisk_change_logical_drive_id(ext_part_t
*epp
, int pno
,
291 extern void fdisk_add_logical_drive(ext_part_t
*epp
, uint32_t begsec
,
292 uint32_t endsec
, uchar_t partid
);
293 extern void fdisk_delete_logical_drive(ext_part_t
*epp
, int pno
);
294 extern int fdisk_init_ext_part(ext_part_t
*epp
, uint32_t rsect
, uint32_t nsect
);
295 extern int fdisk_delete_ext_part(ext_part_t
*epp
);
296 extern int fdisk_get_disk_geom(ext_part_t
*epp
, int type
, int what
);
297 extern int fdisk_invalid_bb_sig(ext_part_t
*epp
, uchar_t
**bbsig_arr
);
298 extern int fdisk_mounted_logical_drives(ext_part_t
*epp
);
304 #endif /* _LIBFDISK_H_ */