• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/fstools/libblkid-tiny/ext.c

  1 /*
  2  * Copyright (C) 1999, 2001 by Andries Brouwer
  3  * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
  4  * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
  5  *
  6  * This file may be redistributed under the terms of the
  7  * GNU Lesser General Public License.
  8  */
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <unistd.h>
 12 #include <string.h>
 13 #include <errno.h>
 14 #include <ctype.h>
 15 #include <stdint.h>
 16 #ifdef __linux__
 17 #include <sys/utsname.h>
 18 #endif
 19 #include <time.h>
 20 
 21 #include "superblocks.h"
 22 
 23 struct ext2_super_block {
 24         uint32_t                s_inodes_count;
 25         uint32_t                s_blocks_count;
 26         uint32_t                s_r_blocks_count;
 27         uint32_t                s_free_blocks_count;
 28         uint32_t                s_free_inodes_count;
 29         uint32_t                s_first_data_block;
 30         uint32_t                s_log_block_size;
 31         uint32_t                s_dummy3[7];
 32         unsigned char           s_magic[2];
 33         uint16_t                s_state;
 34         uint16_t                s_errors;
 35         uint16_t                s_minor_rev_level;
 36         uint32_t                s_lastcheck;
 37         uint32_t                s_checkinterval;
 38         uint32_t                s_creator_os;
 39         uint32_t                s_rev_level;
 40         uint16_t                s_def_resuid;
 41         uint16_t                s_def_resgid;
 42         uint32_t                s_first_ino;
 43         uint16_t                s_inode_size;
 44         uint16_t                s_block_group_nr;
 45         uint32_t                s_feature_compat;
 46         uint32_t                s_feature_incompat;
 47         uint32_t                s_feature_ro_compat;
 48         unsigned char           s_uuid[16];
 49         char                    s_volume_name[16];
 50         char                    s_last_mounted[64];
 51         uint32_t                s_algorithm_usage_bitmap;
 52         uint8_t                 s_prealloc_blocks;
 53         uint8_t                 s_prealloc_dir_blocks;
 54         uint16_t                s_reserved_gdt_blocks;
 55         uint8_t                 s_journal_uuid[16];
 56         uint32_t                s_journal_inum;
 57         uint32_t                s_journal_dev;
 58         uint32_t                s_last_orphan;
 59         uint32_t                s_hash_seed[4];
 60         uint8_t                 s_def_hash_version;
 61         uint8_t                 s_jnl_backup_type;
 62         uint16_t                s_reserved_word_pad;
 63         uint32_t                s_default_mount_opts;
 64         uint32_t                s_first_meta_bg;
 65         uint32_t                s_mkfs_time;
 66         uint32_t                s_jnl_blocks[17];
 67         uint32_t                s_blocks_count_hi;
 68         uint32_t                s_r_blocks_count_hi;
 69         uint32_t                s_free_blocks_hi;
 70         uint16_t                s_min_extra_isize;
 71         uint16_t                s_want_extra_isize;
 72         uint32_t                s_flags;
 73         uint16_t                s_raid_stride;
 74         uint16_t                s_mmp_interval;
 75         uint64_t                s_mmp_block;
 76         uint32_t                s_raid_stripe_width;
 77         uint32_t                s_reserved[163];
 78 } __attribute__((packed));
 79 
 80 /* magic string */
 81 #define EXT_SB_MAGIC                            "\123\357"
 82 /* supper block offset */
 83 #define EXT_SB_OFF                              0x400
 84 /* supper block offset in kB */
 85 #define EXT_SB_KBOFF                            (EXT_SB_OFF >> 10)
 86 /* magic string offset within super block */
 87 #define EXT_MAG_OFF                             0x38
 88 
 89 
 90 
 91 /* for s_flags */
 92 #define EXT2_FLAGS_TEST_FILESYS         0x0004
 93 
 94 /* for s_feature_compat */
 95 #define EXT3_FEATURE_COMPAT_HAS_JOURNAL         0x0004
 96 
 97 /* for s_feature_ro_compat */
 98 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER     0x0001
 99 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE       0x0002
100 #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR        0x0004
101 #define EXT4_FEATURE_RO_COMPAT_HUGE_FILE        0x0008
102 #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM         0x0010
103 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK        0x0020
104 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE      0x0040
105 
106 /* for s_feature_incompat */
107 #define EXT2_FEATURE_INCOMPAT_FILETYPE          0x0002
108 #define EXT3_FEATURE_INCOMPAT_RECOVER           0x0004
109 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV       0x0008
110 #define EXT2_FEATURE_INCOMPAT_META_BG           0x0010
111 #define EXT4_FEATURE_INCOMPAT_EXTENTS           0x0040 /* extents support */
112 #define EXT4_FEATURE_INCOMPAT_64BIT             0x0080
113 #define EXT4_FEATURE_INCOMPAT_MMP               0x0100
114 #define EXT4_FEATURE_INCOMPAT_FLEX_BG           0x0200
115 
116 #define EXT2_FEATURE_RO_COMPAT_SUPP     (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
117                                          EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
118                                          EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
119 #define EXT2_FEATURE_INCOMPAT_SUPP      (EXT2_FEATURE_INCOMPAT_FILETYPE| \
120                                          EXT2_FEATURE_INCOMPAT_META_BG)
121 #define EXT2_FEATURE_INCOMPAT_UNSUPPORTED       ~EXT2_FEATURE_INCOMPAT_SUPP
122 #define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED      ~EXT2_FEATURE_RO_COMPAT_SUPP
123 
124 #define EXT3_FEATURE_RO_COMPAT_SUPP     (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
125                                          EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
126                                          EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
127 #define EXT3_FEATURE_INCOMPAT_SUPP      (EXT2_FEATURE_INCOMPAT_FILETYPE| \
128                                          EXT3_FEATURE_INCOMPAT_RECOVER| \
129                                          EXT2_FEATURE_INCOMPAT_META_BG)
130 #define EXT3_FEATURE_INCOMPAT_UNSUPPORTED       ~EXT3_FEATURE_INCOMPAT_SUPP
131 #define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED      ~EXT3_FEATURE_RO_COMPAT_SUPP
132 
133 /*
134  * Starting in 2.6.29, ext4 can be used to support filesystems
135  * without a journal.
136  */
137 #define EXT4_SUPPORTS_EXT2 KERNEL_VERSION(2, 6, 29)
138 
139 /*
140  * reads superblock and returns:
141  *      fc = feature_compat
142  *      fi = feature_incompat
143  *      frc = feature_ro_compat
144  */
145 static struct ext2_super_block *ext_get_super(
146                 blkid_probe pr, uint32_t *fc, uint32_t *fi, uint32_t *frc)
147 {
148         struct ext2_super_block *es;
149 
150         es = (struct ext2_super_block *)
151                         blkid_probe_get_buffer(pr, EXT_SB_OFF, 0x200);
152         if (!es)
153                 return NULL;
154         if (fc)
155                 *fc = le32_to_cpu(es->s_feature_compat);
156         if (fi)
157                 *fi = le32_to_cpu(es->s_feature_incompat);
158         if (frc)
159                 *frc = le32_to_cpu(es->s_feature_ro_compat);
160 
161         return es;
162 }
163 
164 static void ext_get_info(blkid_probe pr, int ver, struct ext2_super_block *es)
165 {
166 #if 0
167         struct blkid_chain *chn = blkid_probe_get_chain(pr);
168 #endif
169 
170         DBG(PROBE, ul_debug("ext2_sb.compat = %08X:%08X:%08X",
171                    le32_to_cpu(es->s_feature_compat),
172                    le32_to_cpu(es->s_feature_incompat),
173                    le32_to_cpu(es->s_feature_ro_compat)));
174 
175         if (strlen(es->s_volume_name))
176                 blkid_probe_set_label(pr, (unsigned char *) es->s_volume_name,
177                                         sizeof(es->s_volume_name));
178         blkid_probe_set_uuid(pr, es->s_uuid);
179 
180         if (le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL)
181                 blkid_probe_set_uuid_as(pr, es->s_journal_uuid, "EXT_JOURNAL");
182 
183 #if 0
184         if (ver != 2 && (chn->flags & BLKID_SUBLKS_SECTYPE) &&
185             ((le32_to_cpu(es->s_feature_incompat) & EXT2_FEATURE_INCOMPAT_UNSUPPORTED) == 0))
186                 blkid_probe_set_value(pr, "SEC_TYPE",
187                                 (unsigned char *) "ext2",
188                                 sizeof("ext2"));
189 #endif
190 
191         blkid_probe_sprintf_version(pr, "%u.%u",
192                 le32_to_cpu(es->s_rev_level),
193                 le16_to_cpu(es->s_minor_rev_level));
194 }
195 
196 
197 static int probe_jbd(blkid_probe pr,
198                 const struct blkid_idmag *mag __attribute__((__unused__)))
199 {
200         struct ext2_super_block *es;
201         uint32_t fi;
202 
203         es = ext_get_super(pr, NULL, &fi, NULL);
204         if (!es)
205                 return errno ? -errno : 1;
206         if (!(fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
207                 return 1;
208 
209         ext_get_info(pr, 2, es);
210         blkid_probe_set_uuid_as(pr, es->s_uuid, "LOGUUID");
211 
212         return 0;
213 }
214 
215 static int probe_ext2(blkid_probe pr,
216                 const struct blkid_idmag *mag __attribute__((__unused__)))
217 {
218         struct ext2_super_block *es;
219         uint32_t fc, frc, fi;
220 
221         es = ext_get_super(pr, &fc, &fi, &frc);
222         if (!es)
223                 return errno ? -errno : 1;
224 
225         /* Distinguish between ext3 and ext2 */
226         if (fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL)
227                 return 1;
228 
229         /* Any features which ext2 doesn't understand */
230         if ((frc & EXT2_FEATURE_RO_COMPAT_UNSUPPORTED) ||
231             (fi  & EXT2_FEATURE_INCOMPAT_UNSUPPORTED))
232                 return 1;
233 
234         ext_get_info(pr, 2, es);
235         return 0;
236 }
237 
238 static int probe_ext3(blkid_probe pr,
239                 const struct blkid_idmag *mag __attribute__((__unused__)))
240 {
241         struct ext2_super_block *es;
242         uint32_t fc, frc, fi;
243 
244         es = ext_get_super(pr, &fc, &fi, &frc);
245         if (!es)
246                 return errno ? -errno : 1;
247 
248         /* ext3 requires journal */
249         if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
250                 return 1;
251 
252         /* Any features which ext3 doesn't understand */
253         if ((frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) ||
254             (fi  & EXT3_FEATURE_INCOMPAT_UNSUPPORTED))
255                 return 1;
256 
257         ext_get_info(pr, 3, es);
258         return 0;
259 }
260 
261 
262 static int probe_ext4dev(blkid_probe pr,
263                 const struct blkid_idmag *mag __attribute__((__unused__)))
264 {
265         struct ext2_super_block *es;
266         uint32_t fc, frc, fi;
267 
268         es = ext_get_super(pr, &fc, &fi, &frc);
269         if (!es)
270                 return errno ? -errno : 1;
271 
272         /* Distinguish from jbd */
273         if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
274                 return 1;
275 
276         if (!(le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS))
277                 return 1;
278 
279         ext_get_info(pr, 4, es);
280         return 0;
281 }
282 
283 static int probe_ext4(blkid_probe pr,
284                 const struct blkid_idmag *mag __attribute__((__unused__)))
285 {
286         struct ext2_super_block *es;
287         uint32_t fc, frc, fi;
288 
289         es = ext_get_super(pr, &fc, &fi, &frc);
290         if (!es)
291                 return errno ? -errno : 1;
292 
293         /* Distinguish from jbd */
294         if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
295                 return 1;
296 
297         /* Ext4 has at least one feature which ext3 doesn't understand */
298         if (!(frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) &&
299             !(fi  & EXT3_FEATURE_INCOMPAT_UNSUPPORTED))
300                 return 1;
301 
302         /*
303          * If the filesystem is a OK for use by in-development
304          * filesystem code, and ext4dev is supported or ext4 is not
305          * supported, then don't call ourselves ext4, so we can redo
306          * the detection and mark the filesystem as ext4dev.
307          *
308          * If the filesystem is marked as in use by production
309          * filesystem, then it can only be used by ext4 and NOT by
310          * ext4dev.
311          */
312         if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS)
313                 return 1;
314 
315         ext_get_info(pr, 4, es);
316         return 0;
317 }
318 
319 #define BLKID_EXT_MAGICS \
320         { \
321                 {        \
322                         .magic = EXT_SB_MAGIC, \
323                         .len = sizeof(EXT_SB_MAGIC) - 1, \
324                         .kboff = EXT_SB_KBOFF, \
325                         .sboff = EXT_MAG_OFF \
326                 }, \
327                 { NULL } \
328         }
329 
330 const struct blkid_idinfo jbd_idinfo =
331 {
332         .name           = "jbd",
333         .usage          = BLKID_USAGE_OTHER,
334         .probefunc      = probe_jbd,
335         .magics         = BLKID_EXT_MAGICS
336 };
337 
338 const struct blkid_idinfo ext2_idinfo =
339 {
340         .name           = "ext2",
341         .usage          = BLKID_USAGE_FILESYSTEM,
342         .probefunc      = probe_ext2,
343         .magics         = BLKID_EXT_MAGICS
344 };
345 
346 const struct blkid_idinfo ext3_idinfo =
347 {
348         .name           = "ext3",
349         .usage          = BLKID_USAGE_FILESYSTEM,
350         .probefunc      = probe_ext3,
351         .magics         = BLKID_EXT_MAGICS
352 };
353 
354 const struct blkid_idinfo ext4_idinfo =
355 {
356         .name           = "ext4",
357         .usage          = BLKID_USAGE_FILESYSTEM,
358         .probefunc      = probe_ext4,
359         .magics         = BLKID_EXT_MAGICS
360 };
361 
362 const struct blkid_idinfo ext4dev_idinfo =
363 {
364         .name           = "ext4dev",
365         .usage          = BLKID_USAGE_FILESYSTEM,
366         .probefunc      = probe_ext4dev,
367         .magics         = BLKID_EXT_MAGICS
368 };
369 
370 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt