2 * Thu Jul 14 07:32:40 1994: faith@cs.unc.edu added changes from Adam
3 * J. Richter (adam@adam.yggdrasil.com) so that /proc/filesystems is used
4 * if no -t option is given. I modified his patches so that, if
5 * /proc/filesystems is not available, the behavior of mount is the same as
8 * Wed Feb 8 09:23:18 1995: Mike Grupenhoff <kashmir@umiacs.UMD.EDU> added
9 * a probe of the superblock for the type before /proc/filesystems is
12 * Fri Apr 5 01:13:33 1996: quinlan@bucknell.edu, fixed up iso9660 autodetect
14 * Wed Nov 11 11:33:55 1998: K.Garloff@ping.de, try /etc/filesystems before
16 * [This was mainly in order to specify vfat before fat; these days we often
17 * detect *fat and then assume vfat, so perhaps /etc/filesystems isnt
20 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
21 * added Native Language Support
23 * 2000-12-01 Sepp Wijnands <mrrazz@garbage-coderz.net>
24 * added probes for cramfs, hfs, hpfs and adfs.
26 * 2001-10-26 Tim Launchbury
39 #include <sys/types.h>
41 #include "mount_guess_fstype.h"
42 #include "sundries.h" /* for xstrdup */
45 #define ETC_FILESYSTEMS "/etc/filesystems"
46 #define PROC_FILESYSTEMS "/proc/filesystems"
48 #define SIZE(a) (sizeof(a)/sizeof(a[0]))
50 /* Most file system types can be recognized by a `magic' number
51 in the superblock. Note that the order of the tests is
52 significant: by coincidence a filesystem can have the
53 magic numbers for several file system types simultaneously.
54 For example, the romfs magic lives in the 1st sector;
55 xiafs does not touch the 1st sector and has its magic in
56 the 2nd sector; ext2 does not touch the first two sectors. */
58 static inline unsigned short
59 swapped(unsigned short a
) {
60 return (a
>>8) | (a
<<8);
64 assemble4le(unsigned char *p
) {
65 return (p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24));
69 char *guess_fstype(const char *device);
71 Probes the device and attempts to determine the type of filesystem
74 Original routine by <jmorriso@bogomips.ww.ubc.ca>; made into a function
75 for mount(8) by Mike Grupenhoff <kashmir@umiacs.umd.edu>.
76 Corrected the test for xiafs - aeb
77 Read the superblock only once - aeb
78 Added a very weak heuristic for vfat - aeb
79 Added iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb
80 Added a test for high sierra (iso9660) - quinlan@bucknell.edu
81 Added ufs from a patch by jj. But maybe there are several types of ufs?
82 Added ntfs from a patch by Richard Russon.
83 Added xfs - 2000-03-21 Martin K. Petersen <mkp@linuxcare.com>
84 Added cramfs, hfs, hpfs, adfs - Sepp Wijnands <mrrazz@garbage-coderz.net>
85 Added ext3 - Andrew Morton
86 Added jfs - Christoph Hellwig
87 Added sysv - Tim Launchbury
88 Added udf - Bryce Nesbitt
92 "adfs", "bfs", "cramfs", "ext", "ext2", "ext3",
93 "hfs", "hpfs", "iso9660", "jfs", "minix", "ntfs",
94 "qnx4", "reiserfs", "romfs", "swap", "sysv", "udf", "ufs",
95 "vxfs", "xfs", "xiafs"
104 was_tested(const char *fstype
) {
108 for (m
= magic_known
; m
- magic_known
< SIZE(magic_known
); m
++)
109 if (!strcmp(*m
, fstype
))
111 for (t
= tried
; t
; t
= t
->next
) {
112 if (!strcmp(t
->type
, fstype
))
119 set_tested(const char *fstype
) {
120 struct tried
*t
= xmalloc(sizeof(struct tried
));
123 t
->type
= xstrdup(fstype
);
129 struct tried
*t
, *tt
;
142 * udf magic - I find that trying to mount garbage as an udf fs
143 * causes a very large kernel delay, almost killing the machine.
144 * So, we do not try udf unless there is positive evidence that it
145 * might work. Strings below taken from ECMA 167.
148 * It seems that before udf 2.00 the volume descriptor was not well
149 * defined. For 2.00 you're supposed to keep scanning records until
150 * you find one NOT in this list. (See ECMA 2/8.3.1).
153 *udf_magic
[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02",
158 may_be_udf(const char *id
) {
161 for (m
= udf_magic
; m
- udf_magic
< SIZE(udf_magic
); m
++)
162 if (!strncmp(*m
, id
, 5))
167 /* we saw "CD001" - may be iso9660 or udf - Bryce Nesbitt */
169 is_really_udf(int fd
) {
171 struct iso_volume_descriptor isosb
;
173 /* determine the block size by scanning in 2K increments
174 (block sizes larger than 2K will be null padded) */
175 for (bs
= 1; bs
< 16; bs
++) {
176 lseek(fd
, bs
*2048+32768, SEEK_SET
);
177 if (read(fd
, (char *)&isosb
, sizeof(isosb
)) != sizeof(isosb
))
183 /* Scan up to another 64 blocks looking for additional VSD's */
184 for (j
= 1; j
< 64; j
++) {
186 lseek(fd
, j
*bs
*2048+32768, SEEK_SET
);
187 if (read(fd
, (char *)&isosb
, sizeof(isosb
))
191 /* If we find NSR0x then call it udf:
194 NSR03 for UDF 2.00 */
195 if (!strncmp(isosb
.id
, "NSR0", 4))
197 if (!may_be_udf(isosb
.id
))
205 may_be_swap(const char *s
) {
206 return (strncmp(s
-10, "SWAP-SPACE", 10) == 0 ||
207 strncmp(s
-10, "SWAPSPACE2", 10) == 0);
210 /* rather weak necessary condition */
212 may_be_adfs(const u_char
*s
) {
216 p
= (u_char
*) s
+ 511;
219 sum
= (sum
>> 8) + (sum
& 0xff) + *p
;
221 return (sum
== p
[511]);
224 static int is_reiserfs_magic_string (struct reiserfs_super_block
* rs
)
226 return (!strncmp (rs
->s_magic
, REISERFS_SUPER_MAGIC_STRING
,
227 strlen ( REISERFS_SUPER_MAGIC_STRING
)) ||
228 !strncmp (rs
->s_magic
, REISER2FS_SUPER_MAGIC_STRING
,
229 strlen ( REISER2FS_SUPER_MAGIC_STRING
)));
233 do_guess_fstype(const char *device
) {
237 struct minix_super_block ms
;
238 struct ext_super_block es
;
239 struct ext2_super_block e2s
;
240 struct vxfs_super_block vs
;
241 } sb
; /* stuff at 1024 */
243 struct xiafs_super_block xiasb
;
245 char qnx4fs_magic
[10]; /* ignore first 4 bytes */
247 struct ntfs_super_block ntfssb
;
248 struct fat_super_block fatsb
;
249 struct xfs_super_block xfsb
;
250 struct cramfs_super_block cramfssb
;
252 struct ufs_super_block ufssb
;
254 struct iso_volume_descriptor iso
;
255 struct hs_volume_descriptor hs
;
257 struct reiserfs_super_block reiserfssb
; /* block 64 or 8 */
258 struct jfs_super_block jfssb
; /* block 32 */
259 struct hfs_super_block hfssb
;
260 struct hpfs_super_block hpfssb
;
261 struct adfs_super_block adfssb
;
262 struct sysv_super_block svsb
;
265 /* opening and reading an arbitrary unknown path can have
266 undesired side effects - first check that `device' refers
268 if (stat (device
, &statbuf
) || !S_ISBLK(statbuf
.st_mode
))
271 fd
= open(device
, O_RDONLY
);
275 /* do seeks and reads in disk order, otherwise a very short
276 partition may cause a failure because of read error */
280 if (lseek(fd
, 0, SEEK_SET
) != 0
281 || read(fd
, (char *) &xsb
, sizeof(xsb
)) != sizeof(xsb
))
284 if (xiafsmagic(xsb
.xiasb
) == _XIAFS_SUPER_MAGIC
)
286 else if(!strncmp(xsb
.romfs_magic
, "-rom1fs-", 8))
288 else if(!strncmp(xsb
.xfsb
.s_magic
, XFS_SUPER_MAGIC
, 4))
290 else if(!strncmp(xsb
.qnx4fs_magic
+4, "QNX4FS", 6))
292 else if(xsb
.bfs_magic
== 0x1badface)
294 else if(!strncmp(xsb
.ntfssb
.s_magic
, NTFS_SUPER_MAGIC
,
295 sizeof(xsb
.ntfssb
.s_magic
)))
297 else if(cramfsmagic(xsb
.cramfssb
) == CRAMFS_SUPER_MAGIC
)
299 else if ((!strncmp(xsb
.fatsb
.s_os
, "MSDOS", 5) ||
300 !strncmp(xsb
.fatsb
.s_os
, "MSWIN", 5) ||
301 !strncmp(xsb
.fatsb
.s_os
, "MTOOL", 5) ||
302 !strncmp(xsb
.fatsb
.s_os
, "mkdosfs", 7) ||
303 !strncmp(xsb
.fatsb
.s_os
, "kmkdosfs", 8) ||
304 /* Michal Svec: created by fdformat, old msdos utility for
305 formatting large (1.7) floppy disks. */
306 !strncmp(xsb
.fatsb
.s_os
, "CH-FOR18", 8))
307 && (!strncmp(xsb
.fatsb
.s_fs
, "FAT12 ", 8) ||
308 !strncmp(xsb
.fatsb
.s_fs
, "FAT16 ", 8) ||
309 !strncmp(xsb
.fatsb
.s_fs2
, "FAT32 ", 8)))
310 type
= "vfat"; /* only guessing - might as well be fat or umsdos */
315 if (lseek(fd
, 512 , SEEK_SET
) != 512
316 || read(fd
, (char *) &svsb
, sizeof(svsb
)) != sizeof(svsb
))
318 if (sysvmagic(svsb
) == SYSV_SUPER_MAGIC
)
324 if (lseek(fd
, 1024, SEEK_SET
) != 1024 ||
325 read(fd
, (char *) &sb
, sizeof(sb
)) != sizeof(sb
))
328 /* ext2 has magic in little-endian on disk, so "swapped" is
329 superfluous; however, there have existed strange byteswapped
331 if (ext2magic(sb
.e2s
) == EXT2_SUPER_MAGIC
||
332 ext2magic(sb
.e2s
) == EXT2_PRE_02B_MAGIC
||
333 ext2magic(sb
.e2s
) == swapped(EXT2_SUPER_MAGIC
)) {
336 /* maybe even ext3? */
337 if ((assemble4le(sb
.e2s
.s_feature_compat
)
338 & EXT3_FEATURE_COMPAT_HAS_JOURNAL
) &&
339 assemble4le(sb
.e2s
.s_journal_inum
) != 0)
340 type
= "ext3"; /* "ext3,ext2" */
343 else if (minixmagic(sb
.ms
) == MINIX_SUPER_MAGIC
||
344 minixmagic(sb
.ms
) == MINIX_SUPER_MAGIC2
||
345 minixmagic(sb
.ms
) == swapped(MINIX_SUPER_MAGIC2
) ||
346 minixmagic(sb
.ms
) == MINIX2_SUPER_MAGIC
||
347 minixmagic(sb
.ms
) == MINIX2_SUPER_MAGIC2
)
350 else if (extmagic(sb
.es
) == EXT_SUPER_MAGIC
)
353 else if (vxfsmagic(sb
.vs
) == VXFS_SUPER_MAGIC
)
359 if (lseek(fd
, 0x400, SEEK_SET
) != 0x400
360 || read(fd
, (char *) &hfssb
, sizeof(hfssb
)) != sizeof(hfssb
))
363 /* also check if block size is equal to 512 bytes,
364 since the hfs driver currently only has support
365 for block sizes of 512 bytes long, and to be
366 more accurate (sb magic is only a short int) */
367 if ((hfsmagic(hfssb
) == HFS_SUPER_MAGIC
&&
368 hfsblksize(hfssb
) == 0x20000) ||
369 (swapped(hfsmagic(hfssb
)) == HFS_SUPER_MAGIC
&&
370 hfsblksize(hfssb
) == 0x200))
376 if (lseek(fd
, 0xc00, SEEK_SET
) != 0xc00
377 || read(fd
, (char *) &adfssb
, sizeof(adfssb
)) != sizeof(adfssb
))
380 /* only a weak test */
381 if (may_be_adfs((u_char
*) &adfssb
)
382 && (adfsblksize(adfssb
) >= 8 &&
383 adfsblksize(adfssb
) <= 10))
391 if (lseek(fd
, 8192, SEEK_SET
) != 8192
392 || read(fd
, (char *) &ufssb
, sizeof(ufssb
)) != sizeof(ufssb
))
395 mag
= ufsmagic(ufssb
);
396 if (mag
== UFS_SUPER_MAGIC_LE
|| mag
== UFS_SUPER_MAGIC_BE
)
402 if (lseek(fd
, REISERFS_OLD_DISK_OFFSET_IN_BYTES
, SEEK_SET
) !=
403 REISERFS_OLD_DISK_OFFSET_IN_BYTES
404 || read(fd
, (char *) &reiserfssb
, sizeof(reiserfssb
)) !=
407 if (is_reiserfs_magic_string(&reiserfssb
))
413 if (lseek(fd
, 0x2000, SEEK_SET
) != 0x2000
414 || read(fd
, (char *) &hpfssb
, sizeof(hpfssb
)) != sizeof(hpfssb
))
417 if (hpfsmagic(hpfssb
) == HPFS_SUPER_MAGIC
)
423 if (lseek(fd
, JFS_SUPER1_OFF
, SEEK_SET
) != JFS_SUPER1_OFF
424 || read(fd
, (char *) &jfssb
, sizeof(jfssb
)) != sizeof(jfssb
))
426 if (!strncmp(jfssb
.s_magic
, JFS_MAGIC
, 4))
432 if (lseek(fd
, 0x8000, SEEK_SET
) != 0x8000
433 || read(fd
, (char *) &isosb
, sizeof(isosb
)) != sizeof(isosb
))
436 if (strncmp(isosb
.hs
.id
, HS_STANDARD_ID
, sizeof(isosb
.hs
.id
)) == 0) {
439 } else if (strncmp(isosb
.iso
.id
, ISO_STANDARD_ID
,
440 sizeof(isosb
.iso
.id
)) == 0) {
443 if (is_really_udf(fd
))
445 } else if (may_be_udf(isosb
.iso
.id
))
451 if (lseek(fd
, REISERFS_DISK_OFFSET_IN_BYTES
, SEEK_SET
) !=
452 REISERFS_DISK_OFFSET_IN_BYTES
453 || read(fd
, (char *) &reiserfssb
, sizeof(reiserfssb
)) !=
456 if (is_reiserfs_magic_string(&reiserfssb
))
461 /* perhaps the user tries to mount the swap space
462 on a new disk; warn her before she does mke2fs on it */
463 int pagesize
= getpagesize();
470 if (rd
> sizeof(buf
))
472 if (lseek(fd
, 0, SEEK_SET
) != 0
473 || read(fd
, buf
, rd
) != rd
)
475 if (may_be_swap(buf
+pagesize
) ||
476 may_be_swap(buf
+4096) || may_be_swap(buf
+8192))
487 fprintf(stderr
, _("mount: error while guessing filesystem type\n"));
493 guess_fstype(const char *spec
) {
494 char *type
= do_guess_fstype(spec
);
496 printf (_("mount: you didn't specify a filesystem type for %s\n"),
499 printf (_(" I will try all types mentioned in %s or %s\n"),
500 ETC_FILESYSTEMS
, PROC_FILESYSTEMS
);
501 else if (!strcmp(type
, "swap"))
502 printf (_(" and it looks like this is swapspace\n"));
504 printf (_(" I will try type %s\n"), type
);
510 procfsnext(FILE *procfs
) {
514 while (fgets(line
, sizeof(line
), procfs
)) {
515 if (sscanf (line
, "nodev %[^\n]\n", fsname
) == 1) continue;
516 if (sscanf (line
, " %[^ \n]\n", fsname
) != 1) continue;
517 return strdup(fsname
);
522 /* Only use /proc/filesystems here, this is meant to test what
523 the kernel knows about, so /etc/filesystems is irrelevant.
524 Return: 1: yes, 0: no, -1: cannot open procfs */
526 is_in_procfs(const char *type
) {
531 procfs
= fopen(PROC_FILESYSTEMS
, "r");
534 while ((fsname
= procfsnext(procfs
)) != NULL
)
535 if (!strcmp(fsname
, type
)) {
545 /* Try all types in FILESYSTEMS, except those in *types,
546 in case *types starts with "no" */
547 /* return: 0: OK, -1: error in errno, 1: type not found */
548 /* when 0 or -1 is returned, *types contains the type used */
549 /* when 1 is returned, *types is NULL */
551 procfsloop(int (*mount_fn
)(struct mountargs
*), struct mountargs
*args
,
553 char *files
[2] = { ETC_FILESYSTEMS
, PROC_FILESYSTEMS
};
556 char *notypes
= NULL
;
562 if (*types
&& !strncmp(*types
, "no", 2)) {
564 notypes
= (*types
) + 2;
568 /* Use PROC_FILESYSTEMS only when ETC_FILESYSTEMS does not exist.
569 In some cases trying a filesystem that the kernel knows about
570 on the wrong data will crash the kernel; in such cases
571 ETC_FILESYSTEMS can be used to list the filesystems that we
572 are allowed to try, and in the order they should be tried.
573 End ETC_FILESYSTEMS with a line containing a single '*' only,
574 if PROC_FILESYSTEMS should be tried afterwards. */
576 for (i
=0; i
<2; i
++) {
577 procfs
= fopen(files
[i
], "r");
580 while ((fsname
= procfsnext(procfs
)) != NULL
) {
581 if (!strcmp(fsname
, "*")) {
585 if (was_tested (fsname
))
587 if (no
&& matching_type(fsname
, notypes
))
592 printf(_("Trying %s\n"), fsname
);
595 if ((*mount_fn
) (args
) == 0) {
599 } else if (errno
!= EINVAL
&&
600 is_in_procfs(fsname
) == 1) {