2 * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
42 * From mount(8) source by Andries Brouwer. Hacked for XFS by mkp.
43 * Recent sync's to mount source:
44 * - util-linux-2.10o ... 06 Sep 00
45 * - util-linux-2.10r ... 06 Dec 00
46 * - util-linux-2.11g ... 02 Jul 01
47 * - util-linux-2.11u ... 24 Aug 02
50 #define SIZE(a) (sizeof(a)/sizeof(a[0]))
52 /* Most file system types can be recognized by a `magic' number
53 in the superblock. Note that the order of the tests is
54 significant: by coincidence a filesystem can have the
55 magic numbers for several file system types simultaneously.
56 For example, the romfs magic lives in the 1st sector;
57 xiafs does not touch the 1st sector and has its magic in
58 the 2nd sector; ext2 does not touch the first two sectors. */
60 static inline unsigned short
61 swapped(unsigned short a
) {
62 return (a
>>8) | (a
<<8);
66 Probes the device and attempts to determine the type of filesystem
69 Original routine by <jmorriso@bogomips.ww.ubc.ca>; made into a function
70 for mount(8) by Mike Grupenhoff <kashmir@umiacs.umd.edu>.
71 Corrected the test for xiafs - aeb
72 Read the superblock only once - aeb
73 Added a very weak heuristic for vfat - aeb
74 Added iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb
75 Added a test for high sierra (iso9660) - quinlan@bucknell.edu
76 Added ufs from a patch by jj. But maybe there are several types of ufs?
77 Added ntfs from a patch by Richard Russon.
78 Added xfs - 2000-03-21 Martin K. Petersen <mkp@linuxcare.com>
79 Added cramfs, hfs, hpfs, adfs - Sepp Wijnands <mrrazz@garbage-coderz.net>
80 Added ext3 - Andrew Morton
81 Added jfs - Christoph Hellwig
82 Added sysv - Tim Launchbury
83 Added udf - Bryce Nesbitt
87 * udf magic - I find that trying to mount garbage as an udf fs
88 * causes a very large kernel delay, almost killing the machine.
89 * So, we do not try udf unless there is positive evidence that it
90 * might work. Strings below taken from ECMA 167.
93 * It seems that before udf 2.00 the volume descriptor was not well
94 * defined. For 2.00 you're supposed to keep scanning records until
95 * you find one NOT in this list. (See ECMA 2/8.3.1).
98 *udf_magic
[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02",
103 may_be_udf(const char *id
) {
106 for (m
= udf_magic
; m
- udf_magic
< SIZE(udf_magic
); m
++)
107 if (!strncmp(*m
, id
, 5))
112 /* we saw "CD001" - may be iso9660 or udf - Bryce Nesbitt */
114 is_really_udf(int fd
) {
116 struct iso_volume_descriptor isosb
;
118 /* determine the block size by scanning in 2K increments
119 (block sizes larger than 2K will be null padded) */
120 for (bs
= 1; bs
< 16; bs
++) {
121 lseek(fd
, bs
*2048+32768, SEEK_SET
);
122 if (read(fd
, (char *)&isosb
, sizeof(isosb
)) != sizeof(isosb
))
128 /* Scan up to another 64 blocks looking for additional VSD's */
129 for (j
= 1; j
< 64; j
++) {
131 lseek(fd
, j
*bs
*2048+32768, SEEK_SET
);
132 if (read(fd
, (char *)&isosb
, sizeof(isosb
))
136 /* If we find NSR0x then call it udf:
139 NSR03 for UDF 2.00 */
140 if (!strncmp(isosb
.id
, "NSR0", 4))
142 if (!may_be_udf(isosb
.id
))
150 may_be_swap(const char *s
) {
151 return (strncmp(s
-10, "SWAP-SPACE", 10) == 0 ||
152 strncmp(s
-10, "SWAPSPACE2", 10) == 0);
155 /* rather weak necessary condition */
157 may_be_adfs(const u_char
*s
) {
161 p
= (u_char
*) s
+ 511;
164 sum
= (sum
>> 8) + (sum
& 0xff) + *p
;
166 return (sum
== p
[511]);
169 static int is_reiserfs_magic_string (struct reiserfs_super_block
* rs
)
171 return (!strncmp (rs
->s_magic
, REISERFS_SUPER_MAGIC_STRING
,
172 strlen ( REISERFS_SUPER_MAGIC_STRING
)) ||
173 !strncmp (rs
->s_magic
, REISER2FS_SUPER_MAGIC_STRING
,
174 strlen ( REISER2FS_SUPER_MAGIC_STRING
)));
178 fstype(const char *device
) {
182 struct minix_super_block ms
;
183 struct ext_super_block es
;
184 struct ext2_super_block e2s
;
185 struct vxfs_super_block vs
;
186 } sb
; /* stuff at 1024 */
188 struct xiafs_super_block xiasb
;
190 char qnx4fs_magic
[10]; /* ignore first 4 bytes */
192 struct ntfs_super_block ntfssb
;
193 struct fat_super_block fatsb
;
194 struct xfs_super_block xfsb
;
195 struct cramfs_super_block cramfssb
;
197 struct ufs_super_block ufssb
;
199 struct iso_volume_descriptor iso
;
200 struct hs_volume_descriptor hs
;
202 struct reiserfs_super_block reiserfssb
; /* block 64 or 8 */
203 struct jfs_super_block jfssb
; /* block 32 */
204 struct hfs_super_block hfssb
;
205 struct hpfs_super_block hpfssb
;
206 struct adfs_super_block adfssb
;
207 struct sysv_super_block svsb
;
210 /* opening and reading an arbitrary unknown path can have
211 undesired side effects - first check that `device' refers
212 to a block device or ordinary file */
213 if (stat (device
, &statbuf
) ||
214 !(S_ISBLK(statbuf
.st_mode
) || S_ISREG(statbuf
.st_mode
)))
217 fd
= open(device
, O_RDONLY
);
221 /* do seeks and reads in disk order, otherwise a very short
222 partition may cause a failure because of read error */
226 if (lseek(fd
, 0, SEEK_SET
) != 0
227 || read(fd
, (char *) &xsb
, sizeof(xsb
)) != sizeof(xsb
))
230 if (xiafsmagic(xsb
.xiasb
) == _XIAFS_SUPER_MAGIC
)
232 else if(!strncmp(xsb
.romfs_magic
, "-rom1fs-", 8))
234 else if(!strncmp(xsb
.xfsb
.s_magic
, XFS_SUPER_MAGIC
, 4))
236 else if(!strncmp(xsb
.qnx4fs_magic
+4, "QNX4FS", 6))
238 else if(xsb
.bfs_magic
== 0x1badface)
240 else if(!strncmp(xsb
.ntfssb
.s_magic
, NTFS_SUPER_MAGIC
,
241 sizeof(xsb
.ntfssb
.s_magic
)))
243 else if(cramfsmagic(xsb
.cramfssb
) == CRAMFS_SUPER_MAGIC
)
245 else if ((!strncmp(xsb
.fatsb
.s_os
, "MSDOS", 5) ||
246 !strncmp(xsb
.fatsb
.s_os
, "MSWIN", 5) ||
247 !strncmp(xsb
.fatsb
.s_os
, "MTOOL", 5) ||
248 !strncmp(xsb
.fatsb
.s_os
, "mkdosfs", 7) ||
249 !strncmp(xsb
.fatsb
.s_os
, "kmkdosfs", 8) ||
250 /* Michal Svec: created by fdformat, old msdos utility for
251 formatting large (1.7) floppy disks. */
252 !strncmp(xsb
.fatsb
.s_os
, "CH-FOR18", 8))
253 && (!strncmp(xsb
.fatsb
.s_fs
, "FAT12 ", 8) ||
254 !strncmp(xsb
.fatsb
.s_fs
, "FAT16 ", 8) ||
255 !strncmp(xsb
.fatsb
.s_fs2
, "FAT32 ", 8)))
256 type
= "vfat"; /* only guessing - might as well be fat or umsdos */
261 if (lseek(fd
, 512 , SEEK_SET
) != 512
262 || read(fd
, (char *) &svsb
, sizeof(svsb
)) != sizeof(svsb
))
264 if (sysvmagic(svsb
) == SYSV_SUPER_MAGIC
)
270 if (lseek(fd
, 1024, SEEK_SET
) != 1024 ||
271 read(fd
, (char *) &sb
, sizeof(sb
)) != sizeof(sb
))
274 /* ext2 has magic in little-endian on disk, so "swapped" is
275 superfluous; however, there have existed strange byteswapped
277 if (ext2magic(sb
.e2s
) == EXT2_SUPER_MAGIC
||
278 ext2magic(sb
.e2s
) == EXT2_PRE_02B_MAGIC
||
279 ext2magic(sb
.e2s
) == swapped(EXT2_SUPER_MAGIC
)) {
282 /* maybe even ext3? */
283 if ((assemble4le(sb
.e2s
.s_feature_compat
)
284 & EXT3_FEATURE_COMPAT_HAS_JOURNAL
) &&
285 assemble4le(sb
.e2s
.s_journal_inum
) != 0)
286 type
= "ext3"; /* "ext3,ext2" */
289 else if (minixmagic(sb
.ms
) == MINIX_SUPER_MAGIC
||
290 minixmagic(sb
.ms
) == MINIX_SUPER_MAGIC2
||
291 minixmagic(sb
.ms
) == swapped(MINIX_SUPER_MAGIC2
) ||
292 minixmagic(sb
.ms
) == MINIX2_SUPER_MAGIC
||
293 minixmagic(sb
.ms
) == MINIX2_SUPER_MAGIC2
)
296 else if (extmagic(sb
.es
) == EXT_SUPER_MAGIC
)
299 else if (vxfsmagic(sb
.vs
) == VXFS_SUPER_MAGIC
)
305 if (lseek(fd
, 0x400, SEEK_SET
) != 0x400
306 || read(fd
, (char *) &hfssb
, sizeof(hfssb
)) != sizeof(hfssb
))
309 /* also check if block size is equal to 512 bytes,
310 since the hfs driver currently only has support
311 for block sizes of 512 bytes long, and to be
312 more accurate (sb magic is only a short int) */
313 if ((hfsmagic(hfssb
) == HFS_SUPER_MAGIC
&&
314 hfsblksize(hfssb
) == 0x20000) ||
315 (swapped(hfsmagic(hfssb
)) == HFS_SUPER_MAGIC
&&
316 hfsblksize(hfssb
) == 0x200))
322 if (lseek(fd
, 0xc00, SEEK_SET
) != 0xc00
323 || read(fd
, (char *) &adfssb
, sizeof(adfssb
)) != sizeof(adfssb
))
326 /* only a weak test */
327 if (may_be_adfs((u_char
*) &adfssb
)
328 && (adfsblksize(adfssb
) >= 8 &&
329 adfsblksize(adfssb
) <= 10))
337 if (lseek(fd
, 8192, SEEK_SET
) != 8192
338 || read(fd
, (char *) &ufssb
, sizeof(ufssb
)) != sizeof(ufssb
))
341 mag
= ufsmagic(ufssb
);
342 if (mag
== UFS_SUPER_MAGIC_LE
|| mag
== UFS_SUPER_MAGIC_BE
)
348 if (lseek(fd
, REISERFS_OLD_DISK_OFFSET_IN_BYTES
, SEEK_SET
) !=
349 REISERFS_OLD_DISK_OFFSET_IN_BYTES
350 || read(fd
, (char *) &reiserfssb
, sizeof(reiserfssb
)) !=
353 if (is_reiserfs_magic_string(&reiserfssb
))
359 if (lseek(fd
, 0x2000, SEEK_SET
) != 0x2000
360 || read(fd
, (char *) &hpfssb
, sizeof(hpfssb
)) != sizeof(hpfssb
))
363 if (hpfsmagic(hpfssb
) == HPFS_SUPER_MAGIC
)
369 if (lseek(fd
, JFS_SUPER1_OFF
, SEEK_SET
) != JFS_SUPER1_OFF
370 || read(fd
, (char *) &jfssb
, sizeof(jfssb
)) != sizeof(jfssb
))
372 if (!strncmp(jfssb
.s_magic
, JFS_MAGIC
, 4))
378 if (lseek(fd
, 0x8000, SEEK_SET
) != 0x8000
379 || read(fd
, (char *) &isosb
, sizeof(isosb
)) != sizeof(isosb
))
382 if (strncmp(isosb
.hs
.id
, HS_STANDARD_ID
, sizeof(isosb
.hs
.id
)) == 0) {
385 } else if (strncmp(isosb
.iso
.id
, ISO_STANDARD_ID
,
386 sizeof(isosb
.iso
.id
)) == 0) {
389 if (is_really_udf(fd
))
391 } else if (may_be_udf(isosb
.iso
.id
))
397 if (lseek(fd
, REISERFS_DISK_OFFSET_IN_BYTES
, SEEK_SET
) !=
398 REISERFS_DISK_OFFSET_IN_BYTES
399 || read(fd
, (char *) &reiserfssb
, sizeof(reiserfssb
)) !=
402 if (is_reiserfs_magic_string(&reiserfssb
))
407 /* perhaps the user tries to mount the swap space
408 on a new disk; warn her before she does mke2fs on it */
409 int pagesize
= getpagesize();
416 if (rd
> sizeof(buf
))
418 if (lseek(fd
, 0, SEEK_SET
) != 0
419 || read(fd
, buf
, rd
) != rd
)
421 if (may_be_swap(buf
+pagesize
) ||
422 may_be_swap(buf
+4096) || may_be_swap(buf
+8192))