1/* 2 * volume_id - reads filesystem label and uuid 3 * 4 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> 5 * Copyright (C) 2009 Vladimir Dronnikov <dronnikov@gmail.com> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22//kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_BTRFS) += btrfs.o 23 24//config: 25//config:config FEATURE_VOLUMEID_BTRFS 26//config: bool "btrfs filesystem" 27//config: default y 28//config: depends on VOLUMEID 29//config: help 30//config: TODO 31//config: 32 33#include "volume_id_internal.h" 34 35#define BTRFS_UUID_SIZE 16 36#define BTRFS_LABEL_SIZE 256 37#define BTRFS_CSUM_SIZE 32 38#define BTRFS_FSID_SIZE 16 39 40#define BTRFS_MAGIC "_BHRfS_M" 41 42struct btrfs_dev_item { 43 uint64_t devid; 44 uint64_t total_bytes; 45 uint64_t bytes_used; 46 uint32_t io_align; 47 uint32_t io_width; 48 uint32_t sector_size; 49 uint64_t type; 50 uint64_t generation; 51 uint64_t start_offset; 52 uint32_t dev_group; 53 uint8_t seek_speed; 54 uint8_t bandwidth; 55 uint8_t uuid[BTRFS_UUID_SIZE]; 56 uint8_t fsid[BTRFS_UUID_SIZE]; 57} PACKED; 58 59struct btrfs_super_block { 60 uint8_t csum[BTRFS_CSUM_SIZE]; 61 uint8_t fsid[BTRFS_FSID_SIZE]; // UUID 62 uint64_t bytenr; 63 uint64_t flags; 64 uint8_t magic[8]; 65 uint64_t generation; 66 uint64_t root; 67 uint64_t chunk_root; 68 uint64_t log_root; 69 uint64_t log_root_transid; 70 uint64_t total_bytes; 71 uint64_t bytes_used; 72 uint64_t root_dir_objectid; 73 uint64_t num_devices; 74 uint32_t sectorsize; 75 uint32_t nodesize; 76 uint32_t leafsize; 77 uint32_t stripesize; 78 uint32_t sys_chunk_array_size; 79 uint64_t chunk_root_generation; 80 uint64_t compat_flags; 81 uint64_t compat_ro_flags; 82 uint64_t incompat_flags; 83 uint16_t csum_type; 84 uint8_t root_level; 85 uint8_t chunk_root_level; 86 uint8_t log_root_level; 87 struct btrfs_dev_item dev_item; 88 uint8_t label[BTRFS_LABEL_SIZE]; // LABEL 89 // ... 90} PACKED; 91 92int FAST_FUNC volume_id_probe_btrfs(struct volume_id *id /*,uint64_t off*/) 93{ 94 // btrfs has superblocks at 64K, 64M and 256G 95 // minimum btrfs size is 256M 96 // so we never step out the device if we analyze 97 // the first and the second superblocks 98 struct btrfs_super_block *sb; 99 unsigned off = 64; 100 101 while (off < 64*1024*1024) { 102 off *= 1024; 103 dbg("btrfs: probing at offset 0x%x", off); 104 105 sb = volume_id_get_buffer(id, off, sizeof(*sb)); 106 if (sb == NULL) 107 return -1; 108 109 if (memcmp(sb->magic, BTRFS_MAGIC, 8) != 0) 110 return -1; 111 } 112 113 // N.B.: btrfs natively supports 256 (>VOLUME_ID_LABEL_SIZE) size labels 114 volume_id_set_label_string(id, sb->label, VOLUME_ID_LABEL_SIZE); 115 volume_id_set_uuid(id, sb->fsid, UUID_DCE); 116 IF_FEATURE_BLKID_TYPE(id->type = "btrfs";) 117 118 return 0; 119} 120