diff -u e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/lib/blkid/probe.c e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/lib/blkid/probe.c --- e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/lib/blkid/probe.c +++ e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/lib/blkid/probe.c @@ -46,7 +46,7 @@ } static unsigned char *get_buffer(struct blkid_probe *pr, - unsigned off, size_t len) + blkid_loff_t off, size_t len) { ssize_t ret_read; unsigned char *newbuf; @@ -74,7 +74,7 @@ pr->buf = newbuf; pr->buf_max = len; } - if (lseek(pr->fd, off, SEEK_SET) < 0) + if (blkid_llseek(pr->fd, off, SEEK_SET) < 0) return NULL; ret_read = read(pr->fd, pr->buf, len); if (ret_read != (ssize_t) len) @@ -398,6 +398,111 @@ return probe_fat(probe, id, buf); } +static int probe_ntfs(struct blkid_probe *probe, + struct blkid_magic *id __BLKID_ATTR((unused)), + unsigned char *buf) +{ + struct ntfs_super_block *ns; + struct master_file_table_record *mft; + struct file_attribute *attr; + char uuid_str[17], label_str[129], *cp; + int bytes_per_sector, sectors_per_cluster; + int mft_record_size, attr_off, attr_len; + unsigned int i, attr_type, val_len; + int val_off; + __u64 nr_clusters; + blkid_loff_t off; + unsigned char *buf_mft, *val; + + ns = (struct ntfs_super_block *) buf; + + bytes_per_sector = ns->bios_parameter_block[0] + + (ns->bios_parameter_block[1] << 8); + sectors_per_cluster = ns->bios_parameter_block[2]; + + if (ns->cluster_per_mft_record < 0) + mft_record_size = 1 << - ns->cluster_per_mft_record; + else + mft_record_size = ns->cluster_per_mft_record * + sectors_per_cluster * bytes_per_sector; + nr_clusters = blkid_le64(ns->number_of_sectors) / sectors_per_cluster; + + if ((blkid_le64(ns->mft_cluster_location) > nr_clusters) || + (blkid_le64(ns->mft_mirror_cluster_location) > nr_clusters)) + return 1; + + off = blkid_le64(ns->mft_mirror_cluster_location) * + bytes_per_sector * sectors_per_cluster; + + buf_mft = get_buffer(probe, off, mft_record_size); + if (!buf_mft) + return 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + + off = blkid_le64(ns->mft_cluster_location) * bytes_per_sector * + sectors_per_cluster; + + buf_mft = get_buffer(probe, off, mft_record_size); + if (!buf_mft) + return 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + + off += MFT_RECORD_VOLUME * mft_record_size; + + buf_mft = get_buffer(probe, off, mft_record_size); + if (!buf_mft) + return 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + + mft = (struct master_file_table_record *) buf_mft; + + attr_off = blkid_le16(mft->attrs_offset); + label_str[0] = 0; + + while (1) { + attr = (struct file_attribute *) (buf_mft + attr_off); + attr_len = blkid_le16(attr->len); + attr_type = blkid_le32(attr->type); + val_off = blkid_le16(attr->value_offset); + val_len = blkid_le32(attr->value_len); + + attr_off += attr_len; + + if ((attr_off > mft_record_size) || + (attr_len == 0)) + break; + + if (attr_type == MFT_RECORD_ATTR_END) + break; + + if (attr_type == MFT_RECORD_ATTR_VOLUME_NAME) { + if (val_len > sizeof(label_str)) + val_len = sizeof(label_str)-1; + + for (i=0, cp=label_str; i < val_len; i+=2,cp++) { + val = ((__u8 *) attr) + val_off + i; + *cp = val[0]; + if (val[1]) + *cp = '?'; + } + *cp = 0; + } + } + + sprintf(uuid_str, "%llX", blkid_le64(ns->volume_serial)); + blkid_set_tag(probe->dev, "UUID", uuid_str, 0); + if (label_str[0]) + blkid_set_tag(probe->dev, "LABEL", label_str, 0); + return 0; +} + + static int probe_xfs(struct blkid_probe *probe, struct blkid_magic *id __BLKID_ATTR((unused)), unsigned char *buf) @@ -709,7 +814,7 @@ static struct blkid_magic type_array[] = { /* type kboff sboff len magic probe */ { "oracleasm", 0, 32, 8, "ORCLDISK", probe_oracleasm }, - { "ntfs", 0, 3, 8, "NTFS ", 0 }, + { "ntfs", 0, 3, 8, "NTFS ", probe_ntfs }, { "jbd", 1, 0x38, 2, "\123\357", probe_jbd }, { "ext3", 1, 0x38, 2, "\123\357", probe_ext3 }, { "ext2", 1, 0x38, 2, "\123\357", probe_ext2 }, diff -u e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/lib/blkid/ChangeLog e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/lib/blkid/ChangeLog --- e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/lib/blkid/ChangeLog +++ e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/lib/blkid/ChangeLog @@ -1,3 +1,10 @@ +2007-06-19 Theodore Tso + + * probe.c (probe_ntfs): Add probe function which is more paranoid + about checking for a valid NTFS partition, and which sets + the UUID and LABEL information. (Addresses Launchpad Bug + #110138) + 2007-03-06 Theodore Tso * devname.c (dm_probe_all), probe.c (blkid_verify): Fix memory diff -u e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/debian/changelog e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/debian/changelog --- e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/debian/changelog +++ e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/debian/changelog @@ -1,3 +1,13 @@ +e2fsprogs (1.39+1.40-WIP-2006.11.14+dfsg-2ubuntu1.1) feisty-proposed; urgency=low + + * Fix "blkid detects partition as ntfs (without UUID)" + (http://launchpadlibrarian.net/8125325/ntfs-probe-patch) + (LP: #110138) + * Changed Maintainer field according to + https://wiki.ubuntu.com/DebianMaintainerField + + -- dAniel hAhler Thu, 21 Jun 2007 01:43:16 +0200 + e2fsprogs (1.39+1.40-WIP-2006.11.14+dfsg-2ubuntu1) feisty; urgency=low * Merge with Debian, needed for the new nfs-utils. only in patch2: unchanged: --- e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg.orig/debian/control +++ e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/debian/control @@ -1,7 +1,8 @@ Source: e2fsprogs Section: admin Priority: required -Maintainer: Theodore Y. Ts'o +Maintainer: Ubuntu Core Developers +XSBC-Original-Maintainer: Theodore Y. Ts'o Build-Depends: texi2html (>= 1.76), gettext, texinfo, dc, libsepol1-dev, libdevmapper-dev, libselinux1-dev, debhelper (>= 4) Standards-Version: 3.7.2 only in patch2: unchanged: --- e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg.orig/lib/blkid/probe.h +++ e2fsprogs-1.39+1.40-WIP-2006.11.14+dfsg/lib/blkid/probe.h @@ -393,6 +393,53 @@ /* In gfs1, quota and license dinodes followed */ }; +struct ntfs_super_block { + __u8 jump[3]; + __u8 oem_id[8]; + __u8 bios_parameter_block[25]; + __u16 unused[2]; + __u64 number_of_sectors; + __u64 mft_cluster_location; + __u64 mft_mirror_cluster_location; + __s8 cluster_per_mft_record; + __u8 reserved1[3]; + __s8 cluster_per_index_record; + __u8 reserved2[3]; + __u64 volume_serial; + __u16 checksum; +}; + +struct master_file_table_record { + __u32 magic; + __u16 usa_ofs; + __u16 usa_count; + __u64 lsn; + __u16 sequence_number; + __u16 link_count; + __u16 attrs_offset; + __u16 flags; + __u32 bytes_in_use; + __u32 bytes_allocated; +} __attribute__((__packed__)); + +struct file_attribute { + __u32 type; + __u32 len; + __u8 non_resident; + __u8 name_len; + __u16 name_offset; + __u16 flags; + __u16 instance; + __u32 value_len; + __u16 value_offset; +} __attribute__((__packed__)); + +#define MFT_RECORD_VOLUME 3 +#define MFT_RECORD_ATTR_VOLUME_NAME 0x60 +#define MFT_RECORD_ATTR_VOLUME_INFO 0x70 +#define MFT_RECORD_ATTR_OBJECT_ID 0x40 +#define MFT_RECORD_ATTR_END 0xffffffffu + /* * Byte swap functions */