LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Andries.Brouwer@cwi.nl
To: dougg@torque.net, linux-kernel@vger.kernel.org
Subject: rfc: test whether a device has a partition table
Date: Wed, 24 Sep 2003 22:29:50 +0200 (MEST) [thread overview]
Message-ID: <UTC200309242029.h8OKTo008219.aeb@smtp.cwi.nl> (raw)
As everyone knows it is a bad idea to let the kernel guess
whether there is a partition table on a given block device,
and if so, of what type.
Nevertheless this is what almost everybody does.
Until now the philosophy was: floppies do not have a partition table,
disks do have one, and for ZIP drives nobody knows. With USB we get
more types of block device that may or may not have a partition table
(and if they have none, usually there is a FAT filesystem with bootsector).
In such cases the kernel assumes a partition table, and creates a mess
if there was none. Some heuristics are needed.
Many checks are possible (for a DOS-type partition table: boot indicator
must be 0 or 0x80, partitions are not larger than the disk,
non-extended partitions are mutually disjoint; for a boot sector:
it starts with a jump, the number of bytes per sector is 512 or
at least a power of two, the number of sectors per cluster is 1
or at least a power of two, the number of reserved sectors is 1 or 32,
the number of FAT copies is 2, ...).
I tried a minimal test, and the below is good enough for the
boot sectors and DOS-type partition tables that I have here.
So, question: are there people with DOS-type partition tables
or FAT fs bootsectors where the below gives the wrong answer?
I would be interested in a copy of the sector.
I expect to submit some sanity check to DOS-type partition table
parsing, and hope to recognize with high probability the presence
of a full disk FAT filesystem.
Andries
------------ sniffsect.c -----------------
/*
* Given a block device, does it have a DOS-type partition table?
* Or does it behave like a floppy and have a whole-disk filesystem?
* Or is it something else?
*
* Return 1 for pt, -1 for boot sect, 0 for unknown.
*/
#include <stdio.h>
#include <fcntl.h>
/* DOS-type partition */
struct partition {
unsigned char bootable; /* 0 or 0x80 */
unsigned char begin_chs[3];
unsigned char systype;
unsigned char end_chs[3];
unsigned char start_sect[4];
unsigned char nr_sects[4];
};
int sniffsect(unsigned char *p) {
struct partition *pt;
int i, n;
int maybept = 1;
int maybebs = 1;
/* Both DOS-type pt and boot sector have a 55 aa signature */
if (p[510] != 0x55 || p[511] != 0xaa)
return 0;
/* A partition table has boot indicators 0 or 0x80 */
for (i=0; i<4; i++) {
pt = (struct partition *)(p + 446 + 16*i);
if (pt->bootable != 0 && pt->bootable != 0x80)
maybept = 0;
}
/* A boot sector has a power of two as #sectors/cluster */
n = p[13];
if (n == 0 || (n & (n-1)) != 0)
maybebs = 0;
/* A boot sector has a power of two as #bytes/sector */
n = (p[12] << 8) + p[11];
if (n == 0 || (n & (n-1)) != 0)
maybebs = 0;
return maybept - maybebs;
}
int main(int argc, char **argv) {
unsigned char sect[512];
int fd, n;
if (argc != 2) {
fprintf(stderr, "Call: sniffsect file\n");
exit(1);
}
fd = open(argv[1], O_RDONLY);
if (fd == -1) {
perror(argv[1]);
fprintf(stderr, "Cannot open %s\n", argv[1]);
exit(1);
}
n = read(fd, sect, sizeof(sect));
if (n != sizeof(sect)) {
if (n == -1)
perror(argv[1]);
fprintf(stderr, "Cannot read 512 bytes from %s\n", argv[1]);
exit(1);
}
n = sniffsect(sect);
printf((n == 1) ? "partition table\n" :
(n == -1) ? "boot sector\n" : "no idea\n");
return 0;
}
next reply other threads:[~2003-09-24 20:30 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-09-24 20:29 Andries.Brouwer [this message]
2003-09-24 21:54 ` Linus Torvalds
2003-09-24 23:50 ` Andries Brouwer
2003-09-25 0:05 ` viro
2003-09-25 12:14 ` Andries Brouwer
2003-09-25 0:18 ` Linus Torvalds
2003-09-25 6:53 ` Xavier Bestel
2003-09-25 10:57 ` Andries Brouwer
2003-09-25 4:47 ` Linus Torvalds
2003-09-25 4:56 ` Linus Torvalds
2003-09-25 11:42 ` Andries Brouwer
2003-10-05 9:00 ` Meelis Roos
2003-09-25 0:42 ` Douglas Gilbert
2003-09-25 1:00 ` viro
2003-09-25 1:27 ` Douglas Gilbert
2004-05-22 11:18 Uwe Bonnes
2004-05-22 12:37 ` John Bradford
2004-05-22 12:56 ` Andries Brouwer
2004-05-22 15:14 ` Uwe Bonnes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=UTC200309242029.h8OKTo008219.aeb@smtp.cwi.nl \
--to=andries.brouwer@cwi.nl \
--cc=dougg@torque.net \
--cc=linux-kernel@vger.kernel.org \
--subject='Re: rfc: test whether a device has a partition table' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).