1 /* 2 * Copyright (c) 1992 University of Utah. 3 * Copyright (c) 1982, 1986, 1988, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: label.c 1.1 92/12/05$ 13 * 14 * @(#)label.c 8.1 (Berkeley) 06/10/93 15 */ 16 17 /* 18 * Derived from routines in ufs/ufs/ufs_disksubr.c. 19 */ 20 21 #include <sys/param.h> 22 #include <sys/disklabel.h> 23 #include <stand.att/saio.h> 24 25 /* 26 * Attempt to read a disk label from a device using the indicated stategy 27 * routine. Returns NULL on success and an error string on failure. 28 */ 29 char * 30 readdisklabel(io, strat, lp) 31 struct iob *io; 32 int (*strat)(); 33 register struct disklabel *lp; 34 { 35 struct iob liob; 36 struct disklabel *dlp; 37 char *msg = NULL; 38 39 liob.i_adapt = io->i_adapt; 40 liob.i_ctlr = io->i_ctlr; 41 liob.i_unit = io->i_unit; 42 liob.i_part = 2; 43 liob.i_boff = 0; 44 liob.i_cyloff = 0; 45 liob.i_bn = LABELSECTOR; 46 liob.i_ma = liob.i_buf; 47 liob.i_cc = lp->d_secsize ? lp->d_secsize : DEV_BSIZE; 48 if ((*strat)(&liob, F_READ) == -1) 49 return ("I/O error"); 50 51 for (dlp = (struct disklabel *)liob.i_buf; 52 dlp <= (struct disklabel *)(liob.i_buf+DEV_BSIZE-sizeof(*dlp)); 53 dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { 54 if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { 55 if (msg == NULL) 56 msg = "no disk label"; 57 } else if (dlp->d_npartitions > MAXPARTITIONS || dkcksum(dlp)) 58 msg = "disk label corrupted"; 59 else { 60 *lp = *dlp; 61 msg = NULL; 62 break; 63 } 64 } 65 return (msg); 66 } 67 68 /* 69 * Compute checksum for disk label. 70 */ 71 dkcksum(lp) 72 register struct disklabel *lp; 73 { 74 register u_short *start, *end; 75 register u_short sum = 0; 76 77 start = (u_short *)lp; 78 end = (u_short *)&lp->d_partitions[lp->d_npartitions]; 79 while (start < end) 80 sum ^= *start++; 81 return (sum); 82 } 83