From patchwork Mon Dec 25 19:52:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 852845 X-Patchwork-Delegate: zajec5@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=65.50.211.133; helo=bombadil.infradead.org; envelope-from=lede-dev-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="aDe/mqLX"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="JQWX/FEV"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z58sq1nmcz9ryv for ; Tue, 26 Dec 2017 06:52:47 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Subject:MIME-Version:Message-Id:Date:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=buSYDZQ6sY3C/Y3elYdZlfQv+lFXrSPRm56yshDAwtU=; b=aDe/mqLXEoGszm gXiudYb7FvzOjjGKlaOBb8C90R5Gi696ALhGjTZW57d/AjxcyniXQ/ceHbjyqqzZtu+9x6+avKvMw 3BotVRHi5uD69Ac9tCsOqyuuJrIBNzqBsWSid6lx38Jb+cC/xsnX3BsPF0s3GVa66g518GgNVRIa+ YcrlFZEQuHzwxWSwVqG6nyqrFgMIDDlZ9OdDBi4Il9SjU6y3JZ8fziPBCbf12DD3FJHRzBu76wB/6 622sAOdTB1tgZ1B18ds9agB7VgBUS8gvODXMhqklhgDOSt5WVSni/ZKGSsg4gbTBj5MeXBpIivVYD fRQ3qxEWygn3Zgm8c8hw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eTYnl-0004fq-CE; Mon, 25 Dec 2017 19:52:45 +0000 Received: from mail-lf0-x243.google.com ([2a00:1450:4010:c07::243]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eTYni-0004eB-3v for lede-dev@lists.infradead.org; Mon, 25 Dec 2017 19:52:44 +0000 Received: by mail-lf0-x243.google.com with SMTP id f13so38071572lff.12 for ; Mon, 25 Dec 2017 11:52:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=kYpii+bXNjclgFJKk3XGx17oUAZMUacbl66bxpdc1kU=; b=JQWX/FEVVMtz4QM1DISoTwpOY/7snTLKPHl0gp/ixBbcp0neNs237XObSxzim1M2Ij AiaavUB5R7iSmUfBScSK1VH/UthPD6duBV8w4derbA/5ZAGmu7M6qiZd4U03/oxgzWtH CNGkJH5c9trbNGB0Qz6H/v8qJSRuNSguO0CjmoAnArzViXLgrgfQysAk8iBQtMp5FUHi HrfG7CYnENDDGoqYttHnk2T90Xe1IRhgASDwOcQ3YL7SOsnt6wKUnt2NUA/lQPVQv8Jn be2mDNRp6t7bkNuarKrj+CnVKFjiMwi62DIC8HtEk3mgLMDln+MsgM0i0QO2sg9JOsrq nzVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=kYpii+bXNjclgFJKk3XGx17oUAZMUacbl66bxpdc1kU=; b=MmOwWHxVHn0OkA3yBKD6dGpd5V7XjXA6JLDmproX9oEyRcUXi1TOTgOJRR/6laN4m+ WKWevoUHZdTf4WntRl5wCCsyd0ttUukRFAG1IKxekjUa23Ppkz6VlELKdMkFYndZhGbw hgDfZn5cF3F/+QJKOLPmRj7s6p7KBvuWaKMNPeHo5oD8tjGCoZ6hDvs/Jtl8Ey896vTx MwuZHO1zvctwgCA9qhh+iqWSbikSXW3b5VxAw+sq3ICK1npy8bOHbJoBgXoRoiLWgK7X keUlqhJEqrl+SxnN8Wg61vbyY2AbIdz5wVu5r/Aw8pjIguqXovX7Xt0eyIcVyLTe0uhq yzIw== X-Gm-Message-State: AKGB3mLTMzNIS/kUdvzEdpSEJITMLww/y37gwuSGATJPRNCIES0oMvSa EfbgXMLS8GSU1Vz9u3Zaur596Q== X-Google-Smtp-Source: ACJfBotzz1pNYZrqwu1JXIQNzDCSvrWlZhNfpcSMv2bPDcbh64rncpFgKvIwXzVUk4nCeRuf7SWtkg== X-Received: by 10.46.1.231 with SMTP id f100mr13853105lji.132.1514231548422; Mon, 25 Dec 2017 11:52:28 -0800 (PST) Received: from linux-samsung.lan (ip-194-187-74-233.konfederacka.maverick.com.pl. [194.187.74.233]) by smtp.gmail.com with ESMTPSA id r5sm1248492lff.87.2017.12.25.11.52.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Dec 2017 11:52:27 -0800 (PST) From: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= To: lede-dev@lists.infradead.org Date: Mon, 25 Dec 2017 20:52:11 +0100 Message-Id: <20171225195211.9380-1-zajec5@gmail.com> X-Mailer: git-send-email 2.11.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171225_115242_211570_4A709A4A X-CRM114-Status: GOOD ( 18.90 ) X-Spam-Score: -1.8 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.8 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2a00:1450:4010:c07:0:0:0:243 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit (zajec5[at]gmail.com) 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (zajec5[at]gmail.com) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain Subject: [LEDE-DEV] [PATCH fstools] libblkid-tiny: add support for NTFS superblock X-BeenThere: lede-dev@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= Sender: "Lede-dev" Errors-To: lede-dev-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Rafał Miłecki Its copied from the util-linux project and its libblkid. Call to the blkid_probe_set_utf8label was commented out due to libblkid-tiny not supporting it yet. Signed-off-by: Rafał Miłecki Acked-by: John Crispin --- CMakeLists.txt | 1 + libblkid-tiny/libblkid-tiny.c | 1 + libblkid-tiny/ntfs.c | 228 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 libblkid-tiny/ntfs.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 8752612..9e855bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ ADD_LIBRARY(blkid-tiny SHARED libblkid-tiny/ext.c libblkid-tiny/jffs2.c libblkid-tiny/vfat.c + libblkid-tiny/ntfs.c libblkid-tiny/hfs.c libblkid-tiny/swap.c libblkid-tiny/ubi.c diff --git a/libblkid-tiny/libblkid-tiny.c b/libblkid-tiny/libblkid-tiny.c index 352d1f6..f020e23 100644 --- a/libblkid-tiny/libblkid-tiny.c +++ b/libblkid-tiny/libblkid-tiny.c @@ -162,6 +162,7 @@ static const struct blkid_idinfo *idinfos[] = &ext3_idinfo, &ext2_idinfo, &jbd_idinfo, + &ntfs_idinfo, &squashfs_idinfo, &ubi_idinfo, &ubifs_idinfo, diff --git a/libblkid-tiny/ntfs.c b/libblkid-tiny/ntfs.c new file mode 100644 index 0000000..93c1d88 --- /dev/null +++ b/libblkid-tiny/ntfs.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2008 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "superblocks.h" + +struct ntfs_bios_parameters { + uint16_t sector_size; /* Size of a sector in bytes. */ + uint8_t sectors_per_cluster; /* Size of a cluster in sectors. */ + uint16_t reserved_sectors; /* zero */ + uint8_t fats; /* zero */ + uint16_t root_entries; /* zero */ + uint16_t sectors; /* zero */ + uint8_t media_type; /* 0xf8 = hard disk */ + uint16_t sectors_per_fat; /* zero */ + uint16_t sectors_per_track; /* irrelevant */ + uint16_t heads; /* irrelevant */ + uint32_t hidden_sectors; /* zero */ + uint32_t large_sectors; /* zero */ +} __attribute__ ((__packed__)); + +struct ntfs_super_block { + uint8_t jump[3]; + uint8_t oem_id[8]; /* magic string */ + + struct ntfs_bios_parameters bpb; + + uint16_t unused[2]; + uint64_t number_of_sectors; + uint64_t mft_cluster_location; + uint64_t mft_mirror_cluster_location; + int8_t clusters_per_mft_record; + uint8_t reserved1[3]; + int8_t cluster_per_index_record; + uint8_t reserved2[3]; + uint64_t volume_serial; + uint32_t checksum; +} __attribute__((packed)); + +struct master_file_table_record { + uint32_t magic; + uint16_t usa_ofs; + uint16_t usa_count; + uint64_t lsn; + uint16_t sequence_number; + uint16_t link_count; + uint16_t attrs_offset; + uint16_t flags; + uint32_t bytes_in_use; + uint32_t bytes_allocated; +} __attribute__((__packed__)); + +struct file_attribute { + uint32_t type; + uint32_t len; + uint8_t non_resident; + uint8_t name_len; + uint16_t name_offset; + uint16_t flags; + uint16_t instance; + uint32_t value_len; + uint16_t value_offset; +} __attribute__((__packed__)); + +#define MFT_RECORD_VOLUME 3 +#define NTFS_MAX_CLUSTER_SIZE (64 * 1024) + +enum { + MFT_RECORD_ATTR_VOLUME_NAME = 0x60, + MFT_RECORD_ATTR_END = 0xffffffff +}; + +static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct ntfs_super_block *ns; +#if 0 + struct master_file_table_record *mft; +#endif + + uint32_t sectors_per_cluster, mft_record_size; + uint16_t sector_size; + uint64_t nr_clusters, off; //, attr_off; + unsigned char *buf_mft; + + ns = blkid_probe_get_sb(pr, mag, struct ntfs_super_block); + if (!ns) + return errno ? -errno : 1; + + /* + * Check bios parameters block + */ + sector_size = le16_to_cpu(ns->bpb.sector_size); + sectors_per_cluster = ns->bpb.sectors_per_cluster; + + if (sector_size < 256 || sector_size > 4096) + return 1; + + switch (sectors_per_cluster) { + case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128: + break; + default: + return 1; + } + + if ((uint16_t) le16_to_cpu(ns->bpb.sector_size) * + ns->bpb.sectors_per_cluster > NTFS_MAX_CLUSTER_SIZE) + return 1; + + /* Unused fields must be zero */ + if (le16_to_cpu(ns->bpb.reserved_sectors) + || le16_to_cpu(ns->bpb.root_entries) + || le16_to_cpu(ns->bpb.sectors) + || le16_to_cpu(ns->bpb.sectors_per_fat) + || le32_to_cpu(ns->bpb.large_sectors) + || ns->bpb.fats) + return 1; + + if ((uint8_t) ns->clusters_per_mft_record < 0xe1 + || (uint8_t) ns->clusters_per_mft_record > 0xf7) { + + switch (ns->clusters_per_mft_record) { + case 1: case 2: case 4: case 8: case 16: case 32: case 64: + break; + default: + return 1; + } + } + + if (ns->clusters_per_mft_record > 0) + mft_record_size = ns->clusters_per_mft_record * + sectors_per_cluster * sector_size; + else + mft_record_size = 1 << (0 - ns->clusters_per_mft_record); + + nr_clusters = le64_to_cpu(ns->number_of_sectors) / sectors_per_cluster; + + if ((le64_to_cpu(ns->mft_cluster_location) > nr_clusters) || + (le64_to_cpu(ns->mft_mirror_cluster_location) > nr_clusters)) + return 1; + + + off = le64_to_cpu(ns->mft_cluster_location) * sector_size * + sectors_per_cluster; + + DBG(LOWPROBE, ul_debug("NTFS: sector_size=%"PRIu16", mft_record_size=%"PRIu32", " + "sectors_per_cluster=%"PRIu32", nr_clusters=%"PRIu64" " + "cluster_offset=%"PRIu64"", + sector_size, mft_record_size, + sectors_per_cluster, nr_clusters, + off)); + + buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); + if (!buf_mft) + return errno ? -errno : 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + + off += MFT_RECORD_VOLUME * mft_record_size; + + buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size); + if (!buf_mft) + return errno ? -errno : 1; + + if (memcmp(buf_mft, "FILE", 4)) + return 1; + +#if 0 + mft = (struct master_file_table_record *) buf_mft; + attr_off = le16_to_cpu(mft->attrs_offset); + + while (attr_off + sizeof(struct file_attribute) <= mft_record_size && + attr_off <= le32_to_cpu(mft->bytes_allocated)) { + + uint32_t attr_len; + struct file_attribute *attr; + + attr = (struct file_attribute *) (buf_mft + attr_off); + attr_len = le32_to_cpu(attr->len); + if (!attr_len) + break; + + if (le32_to_cpu(attr->type) == MFT_RECORD_ATTR_END) + break; + if (le32_to_cpu(attr->type) == MFT_RECORD_ATTR_VOLUME_NAME) { + unsigned int val_off = le16_to_cpu(attr->value_offset); + unsigned int val_len = le32_to_cpu(attr->value_len); + unsigned char *val = ((uint8_t *) attr) + val_off; + + if (attr_off + val_off + val_len <= mft_record_size) + blkid_probe_set_utf8label(pr, val, val_len, + BLKID_ENC_UTF16LE); + break; + } + + attr_off += attr_len; + } +#endif + + blkid_probe_sprintf_uuid(pr, + (unsigned char *) &ns->volume_serial, + sizeof(ns->volume_serial), + "%016" PRIX64, le64_to_cpu(ns->volume_serial)); + return 0; +} + + +const struct blkid_idinfo ntfs_idinfo = +{ + .name = "ntfs", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_ntfs, + .magics = + { + { .magic = "NTFS ", .len = 8, .sboff = 3 }, + { NULL } + } +}; +