summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorprabahar <none@none>2008-01-07 18:44:16 -0800
committerprabahar <none@none>2008-01-07 18:44:16 -0800
commitca29f3da510ba7f712a40977b04aeceda9b70b95 (patch)
tree3e3156e6ebba5af8601b38f34f647a9d7b7ff8d9
parentbc067c093baf59b221b56b32762cb813a8ad2ea9 (diff)
downloadillumos-gate-ca29f3da510ba7f712a40977b04aeceda9b70b95.tar.gz
6567512 fstyp needs to support 2kB sectorsize media
-rw-r--r--usr/src/cmd/fstyp/fstyp.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/usr/src/cmd/fstyp/fstyp.c b/usr/src/cmd/fstyp/fstyp.c
index 5fb5a6bc17..201c5b7743 100644
--- a/usr/src/cmd/fstyp/fstyp.c
+++ b/usr/src/cmd/fstyp/fstyp.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -40,6 +40,8 @@
#include <dlfcn.h>
#include <sys/wait.h>
#include <sys/fstyp.h>
+#include <sys/dkio.h>
+#include <sys/param.h>
#include <libfstyp.h>
#include <sys/dktp/fdisk.h>
#include <sys/fs/pc_label.h>
@@ -50,8 +52,7 @@ static const char *getmodfsname();
static char *getexecpathname();
static void dump_nvlist(nvlist_t *list, int indent);
static boolean_t dos_to_dev(char *path, char **devpath, int *num);
-static boolean_t find_dos_drive(int fd, int num, int *relsect, int *numsect,
- int *systid);
+static boolean_t find_dos_drive(int fd, int num, off_t *offset);
static void run_legacy_cmds(int fd, char *device, int vflag);
static int run_cmd(char *path, char *arg0, char *arg1, char *arg2);
@@ -73,7 +74,7 @@ main(int argc, char **argv)
int indent = 0;
char *devpath;
boolean_t is_dos;
- int dos_num, systid, relsect, numsect;
+ int dos_num;
off_t offset = 0;
nvlist_t *attr = NULL;
fstyp_handle_t h = NULL;
@@ -122,9 +123,7 @@ main(int argc, char **argv)
goto out;
}
if (is_dos) {
- if (find_dos_drive(fd, dos_num, &relsect, &numsect, &systid)) {
- offset = (off_t)relsect * 512;
- } else {
+ if (!find_dos_drive(fd, dos_num, &offset)) {
error = FSTYP_ERR_NO_PARTITION;
goto out;
}
@@ -447,8 +446,8 @@ enum { WALK_CONTINUE, WALK_TERMINATE };
* Walk partition tables and invoke a callback for each.
*/
static void
-walk_partitions(int fd, int startsec, int (*f)(void *, int, int, int),
- void *arg)
+walk_partitions(int fd, int startsec, off_t secsz,
+ int (*f)(void *, int, int, int), void *arg)
{
uint32_t buf[1024/4];
int bufsize = 1024;
@@ -463,7 +462,7 @@ walk_partitions(int fd, int startsec, int (*f)(void *, int, int, int),
int i;
while (sec != lastsec) {
- if (pread(fd, buf, bufsize, (off_t)sec * 512) != bufsize) {
+ if (pread(fd, buf, bufsize, (off_t)sec * secsz) != bufsize) {
break;
}
lastsec = sec;
@@ -513,22 +512,31 @@ find_dos_drive_cb(void *arg, int systid, int relsect, int numsect)
}
/*
- * Given a dos drive number, return its relative sector number,
- * number of sectors in partition and the system id.
+ * Given a dos drive number, return its relative offset in the drive.
*/
static boolean_t
-find_dos_drive(int fd, int num, int *relsect, int *numsect, int *systid)
+find_dos_drive(int fd, int num, off_t *offset)
{
+ struct dk_minfo mi;
+ off_t secsz;
struct part_find_s p = { 0, 0, 0, 0, 0, 0 };
p.num = num;
+ /*
+ * It is possible that the media we are dealing with can have different
+ * sector size than the default 512 bytes. Query the driver and check
+ * whether the media has different sector size.
+ */
+ if (ioctl(fd, DKIOCGMEDIAINFO, &mi) < 0)
+ secsz = DEV_BSIZE;
+ else
+ secsz = mi.dki_lbsize;
+
if (num > 0) {
- walk_partitions(fd, 0, find_dos_drive_cb, &p);
+ walk_partitions(fd, 0, secsz, find_dos_drive_cb, &p);
if (p.count == num) {
- *relsect = p.r_relsect;
- *numsect = p.r_numsect;
- *systid = p.r_systid;
+ *offset = secsz * (off_t)p.r_relsect;
return (B_TRUE);
}
}