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_blkid.h"
42 #include "mount_guess_fstype.h"
43 #include "sundries.h" /* for xstrdup */
46 #define ETC_FILESYSTEMS "/etc/filesystems"
47 #define PROC_FILESYSTEMS "/proc/filesystems"
52 do_guess_fstype(const char *device
)
54 return blkid_get_tag_value(blkid
, "TYPE", device
);
58 known_fstype(const char *fstype
)
60 return blkid_known_fstype(fstype
);
64 #define SIZE(a) (sizeof(a)/sizeof(a[0]))
66 /* Most file system types can be recognized by a `magic' number
67 in the superblock. Note that the order of the tests is
68 significant: by coincidence a filesystem can have the
69 magic numbers for several file system types simultaneously.
70 For example, the romfs magic lives in the 1st sector;
71 xiafs does not touch the 1st sector and has its magic in
72 the 2nd sector; ext2 does not touch the first two sectors. */
74 static inline unsigned short
75 swapped(unsigned short a
) {
76 return (a
>>8) | (a
<<8);
80 char *guess_fstype(const char *device);
82 Probes the device and attempts to determine the type of filesystem
85 Original routine by <jmorriso@bogomips.ww.ubc.ca>; made into a function
86 for mount(8) by Mike Grupenhoff <kashmir@umiacs.umd.edu>.
87 Corrected the test for xiafs - aeb
88 Read the superblock only once - aeb
89 Added a very weak heuristic for vfat - aeb
90 Added efs, iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb
91 Added a test for high sierra (iso9660) - quinlan@bucknell.edu
92 Added ufs from a patch by jj. But maybe there are several types of ufs?
93 Added ntfs from a patch by Richard Russon.
94 Added xfs - 2000-03-21 Martin K. Petersen <mkp@linuxcare.com>
95 Added cramfs, hfs, hpfs, adfs - Sepp Wijnands <mrrazz@garbage-coderz.net>
96 Added ext3 - Andrew Morton
97 Added jfs - Christoph Hellwig
98 Added sysv - Tim Launchbury
99 Added udf - Bryce Nesbitt
100 Added ocfs, ocfs2 - Manish Singh - http://oss.oracle.com/projects/ocfs2/
104 "adfs", "bfs", "cramfs", "efs", "ext", "ext2", "ext3",
105 "hfs", "hpfs", "iso9660", "jfs", "minix", "ntfs", "ocfs", "ocfs2",
106 "qnx4", "reiserfs", "romfs", "swap", "sysv", "udf", "ufs",
107 "vxfs", "xfs", "xiafs"
111 known_fstype(const char *fstype
) {
114 for (m
= magic_known
; m
- magic_known
< SIZE(magic_known
); m
++)
115 if (!strcmp(*m
, fstype
))
121 * udf magic - I find that trying to mount garbage as an udf fs
122 * causes a very large kernel delay, almost killing the machine.
123 * So, we do not try udf unless there is positive evidence that it
124 * might work. Strings below taken from ECMA 167.
127 * It seems that before udf 2.00 the volume descriptor was not well
128 * defined. For 2.00 you're supposed to keep scanning records until
129 * you find one NOT in this list. (See ECMA 2/8.3.1).
132 *udf_magic
[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02",
137 may_be_udf(const char *id
) {
140 for (m
= udf_magic
; m
- udf_magic
< SIZE(udf_magic
); m
++)
141 if (!strncmp(*m
, id
, 5))
146 /* we saw "CD001" - may be iso9660 or udf - Bryce Nesbitt */
148 is_really_udf(int fd
) {
150 struct iso_volume_descriptor isosb
;
152 /* determine the block size by scanning in 2K increments
153 (block sizes larger than 2K will be null padded) */
154 for (bs
= 1; bs
< 16; bs
++) {
155 lseek(fd
, bs
*2048+32768, SEEK_SET
);
156 if (read(fd
, (char *)&isosb
, sizeof(isosb
)) != sizeof(isosb
))
162 /* Scan up to another 64 blocks looking for additional VSD's */
163 for (j
= 1; j
< 64; j
++) {
165 lseek(fd
, j
*bs
*2048+32768, SEEK_SET
);
166 if (read(fd
, (char *)&isosb
, sizeof(isosb
))
170 /* If we find NSR0x then call it udf:
173 NSR03 for UDF 2.00 */
174 if (!strncmp(isosb
.id
, "NSR0", 4))
176 if (!may_be_udf(isosb
.id
))
184 may_be_swap(const char *s
) {
185 return (strncmp(s
-10, "SWAP-SPACE", 10) == 0 ||
186 strncmp(s
-10, "SWAPSPACE2", 10) == 0);
189 /* rather weak necessary condition */
191 may_be_adfs(const u_char
*s
) {
195 p
= (u_char
*) s
+ 511;
198 sum
= (sum
>> 8) + (sum
& 0xff) + *p
;
200 return (sum
== p
[511]);
204 do_guess_fstype(const char *device
) {
208 struct xiafs_super_block xiasb
;
210 char qnx4fs_magic
[10]; /* ignore first 4 bytes */
212 struct ntfs_super_block ntfssb
;
213 struct fat_super_block fatsb
;
214 struct xfs_super_block xfsb
;
215 struct cramfs_super_block cramfssb
;
216 struct ocfs_volume_header ovh
;
217 struct efs_volume_header efsvh
;
218 struct efs_super efssb
;
219 } xsb
; /* stuff at 0 */
221 struct minix_super_block ms
;
222 struct ext_super_block es
;
223 struct ext2_super_block e2s
;
224 struct vxfs_super_block vs
;
225 } sb
; /* stuff at 1024 */
226 struct ufs_super_block ufssb
;
228 struct iso_volume_descriptor iso
;
229 struct hs_volume_descriptor hs
;
231 struct reiserfs_super_block reiserfssb
; /* block 64 or 8 */
232 struct jfs_super_block jfssb
; /* block 32 */
233 struct hfs_super_block hfssb
;
234 struct hpfs_super_block hpfssb
;
235 struct adfs_super_block adfssb
;
236 struct sysv_super_block svsb
;
237 struct ocfs2_super_block osb
;
240 /* opening and reading an arbitrary unknown path can have
241 undesired side effects - first check that `device' refers
242 to a block device or ordinary file */
243 if (stat (device
, &statbuf
) ||
244 !(S_ISBLK(statbuf
.st_mode
) || S_ISREG(statbuf
.st_mode
)))
247 fd
= open(device
, O_RDONLY
);
251 /* do seeks and reads in disk order, otherwise a very short
252 partition may cause a failure because of read error */
256 if (lseek(fd
, 0, SEEK_SET
) != 0
257 || read(fd
, (char *) &xsb
, sizeof(xsb
)) != sizeof(xsb
))
259 /* Gyorgy Kovesdi: none of my photocds has a readable block 0 */
261 if (xiafsmagic(xsb
.xiasb
) == _XIAFS_SUPER_MAGIC
)
263 else if(!strncmp(xsb
.romfs_magic
, "-rom1fs-", 8))
265 else if(!strncmp(xsb
.xfsb
.s_magic
, XFS_SUPER_MAGIC
, 4))
267 else if(!strncmp(xsb
.ovh
.signature
, OCFS_MAGIC
, sizeof(OCFS_MAGIC
)))
269 else if(!strncmp(xsb
.qnx4fs_magic
+4, "QNX4FS", 6))
271 else if(xsb
.bfs_magic
== 0x1badface)
273 else if(!strncmp(xsb
.ntfssb
.s_magic
, NTFS_SUPER_MAGIC
,
274 sizeof(xsb
.ntfssb
.s_magic
)))
276 else if(cramfsmagic(xsb
.cramfssb
) == CRAMFS_SUPER_MAGIC
||
277 cramfsmagic(xsb
.cramfssb
) == CRAMFS_SUPER_MAGIC_BE
)
279 else if (assemble4be(xsb
.efsvh
.vh_magic
) == EFS_VHMAGIC
)
280 type
= "efs"; /* EFS volume header */
281 /* might check checksum here */
282 else if (assemble4be(xsb
.efssb
.fs_magic
) == EFS_SBMAGIC
||
283 assemble4be(xsb
.efssb
.fs_magic
) == EFS_SBMAGIC2
)
284 type
= "efs"; /* EFS partition */
285 else if ((!strncmp(xsb
.fatsb
.s_os
, "MSDOS", 5) ||
286 !strncmp(xsb
.fatsb
.s_os
, "MSWIN", 5) ||
287 !strncmp(xsb
.fatsb
.s_os
, "MTOOL", 5) ||
288 !strncmp(xsb
.fatsb
.s_os
, "IBM", 3) ||
289 !strncmp(xsb
.fatsb
.s_os
, "DRDOS", 5) ||
290 !strncmp(xsb
.fatsb
.s_os
, "mkdosfs", 7) ||
291 !strncmp(xsb
.fatsb
.s_os
, "kmkdosfs", 8) ||
292 /* Michal Svec: created by fdformat, old msdos utility for
293 formatting large (1.7) floppy disks. */
294 !strncmp(xsb
.fatsb
.s_os
, "CH-FOR18", 8))
295 && (!strncmp(xsb
.fatsb
.s_fs
, "FAT12 ", 8) ||
296 !strncmp(xsb
.fatsb
.s_fs
, "FAT16 ", 8) ||
297 !strncmp(xsb
.fatsb
.s_fs2
, "FAT32 ", 8)))
298 type
= "vfat"; /* only guessing - might as well be fat or umsdos */
303 if (lseek(fd
, 512 , SEEK_SET
) != 512
304 || read(fd
, (char *) &svsb
, sizeof(svsb
)) != sizeof(svsb
))
306 if (sysvmagic(svsb
) == SYSV_SUPER_MAGIC
)
312 if (lseek(fd
, 1024, SEEK_SET
) != 1024 ||
313 read(fd
, (char *) &sb
, sizeof(sb
)) != sizeof(sb
))
316 /* ext2 has magic in little-endian on disk, so "swapped" is
317 superfluous; however, there have existed strange byteswapped
319 if (ext2magic(sb
.e2s
) == EXT2_SUPER_MAGIC
||
320 ext2magic(sb
.e2s
) == EXT2_PRE_02B_MAGIC
||
321 ext2magic(sb
.e2s
) == swapped(EXT2_SUPER_MAGIC
)) {
324 /* maybe even ext3? */
325 if ((assemble4le(sb
.e2s
.s_feature_compat
)
326 & EXT3_FEATURE_COMPAT_HAS_JOURNAL
) &&
327 assemble4le(sb
.e2s
.s_journal_inum
) != 0)
328 type
= "ext3"; /* "ext3,ext2" */
331 else if (minixmagic(sb
.ms
) == MINIX_SUPER_MAGIC
||
332 minixmagic(sb
.ms
) == MINIX_SUPER_MAGIC2
||
333 minixmagic(sb
.ms
) == swapped(MINIX_SUPER_MAGIC2
) ||
334 minixmagic(sb
.ms
) == MINIX2_SUPER_MAGIC
||
335 minixmagic(sb
.ms
) == MINIX2_SUPER_MAGIC2
)
338 else if (extmagic(sb
.es
) == EXT_SUPER_MAGIC
)
341 else if (vxfsmagic(sb
.vs
) == VXFS_SUPER_MAGIC
)
347 if (lseek(fd
, 0x400, SEEK_SET
) != 0x400
348 || read(fd
, (char *) &hfssb
, sizeof(hfssb
)) != sizeof(hfssb
))
351 /* also check if block size is equal to 512 bytes,
352 or a multiple. (I see 1536 here.) */
353 if (hfsmagic(hfssb
) == HFS_SUPER_MAGIC
&& /* always BE */
354 hfsblksize(hfssb
) != 0 &&
355 (hfsblksize(hfssb
) & 0x1ff) == 0)
361 if (lseek(fd
, 0xc00, SEEK_SET
) != 0xc00
362 || read(fd
, (char *) &adfssb
, sizeof(adfssb
)) != sizeof(adfssb
))
365 /* only a weak test */
366 if (may_be_adfs((u_char
*) &adfssb
)
367 && (adfsblksize(adfssb
) >= 8 &&
368 adfsblksize(adfssb
) <= 10))
376 if (lseek(fd
, 8192, SEEK_SET
) != 8192
377 || read(fd
, (char *) &ufssb
, sizeof(ufssb
)) != sizeof(ufssb
))
380 mag
= ufsmagic(ufssb
);
381 if (mag
== UFS_SUPER_MAGIC_LE
|| mag
== UFS_SUPER_MAGIC_BE
)
387 if (lseek(fd
, REISERFS_OLD_DISK_OFFSET_IN_BYTES
, SEEK_SET
) !=
388 REISERFS_OLD_DISK_OFFSET_IN_BYTES
389 || read(fd
, (char *) &reiserfssb
, sizeof(reiserfssb
)) !=
392 if (reiserfs_magic_version(reiserfssb
.s_magic
))
398 if (lseek(fd
, 0x2000, SEEK_SET
) != 0x2000
399 || read(fd
, (char *) &hpfssb
, sizeof(hpfssb
)) != sizeof(hpfssb
))
402 if (hpfsmagic(hpfssb
) == HPFS_SUPER_MAGIC
)
408 if (lseek(fd
, JFS_SUPER1_OFF
, SEEK_SET
) != JFS_SUPER1_OFF
409 || read(fd
, (char *) &jfssb
, sizeof(jfssb
)) != sizeof(jfssb
))
411 if (!strncmp(jfssb
.s_magic
, JFS_MAGIC
, 4))
418 if (lseek(fd
, 0x8000, SEEK_SET
) != 0x8000
419 || read(fd
, (char *) &isosb
, sizeof(isosb
)) != sizeof(isosb
))
422 if (strncmp(isosb
.hs
.id
, HS_STANDARD_ID
, sizeof(isosb
.hs
.id
)) == 0) {
425 } else if (strncmp(isosb
.iso
.id
, ISO_STANDARD_ID
,
426 sizeof(isosb
.iso
.id
)) == 0) {
429 if (is_really_udf(fd
))
431 } else if (may_be_udf(isosb
.iso
.id
))
437 if (lseek(fd
, REISERFS_DISK_OFFSET_IN_BYTES
, SEEK_SET
) !=
438 REISERFS_DISK_OFFSET_IN_BYTES
439 || read(fd
, (char *) &reiserfssb
, sizeof(reiserfssb
)) !=
442 if (reiserfs_magic_version(reiserfssb
.s_magic
))
449 for (blksize
= OCFS2_MIN_BLOCKSIZE
;
450 blksize
<= OCFS2_MAX_BLOCKSIZE
;
452 blkoff
= blksize
* OCFS2_SUPER_BLOCK_BLKNO
;
453 if (lseek(fd
, blkoff
, SEEK_SET
) != blkoff
454 || read(fd
, (char *) &osb
, sizeof(osb
)) != sizeof(osb
))
456 if (strncmp(osb
.signature
, OCFS2_SUPER_BLOCK_SIGNATURE
,
457 sizeof(OCFS2_SUPER_BLOCK_SIGNATURE
)) == 0)
463 /* perhaps the user tries to mount the swap space
464 on a new disk; warn her before she does mke2fs on it */
465 int pagesize
= getpagesize();
472 if (rd
> sizeof(buf
))
474 if (lseek(fd
, 0, SEEK_SET
) != 0
475 || read(fd
, buf
, rd
) != rd
)
477 if (may_be_swap(buf
+pagesize
) ||
478 may_be_swap(buf
+4096) || may_be_swap(buf
+8192))
489 fprintf(stderr
, _("mount: error while guessing filesystem type\n"));
496 static struct tried
{
502 was_tested(const char *fstype
) {
505 if (known_fstype(fstype
))
507 for (t
= tried
; t
; t
= t
->next
) {
508 if (!strcmp(t
->type
, fstype
))
515 set_tested(const char *fstype
) {
516 struct tried
*t
= xmalloc(sizeof(struct tried
));
519 t
->type
= xstrdup(fstype
);
525 struct tried
*t
, *tt
;
538 guess_fstype(const char *spec
) {
539 char *type
= do_guess_fstype(spec
);
541 printf (_("mount: you didn't specify a filesystem type for %s\n"),
544 printf (_(" I will try all types mentioned in %s or %s\n"),
545 ETC_FILESYSTEMS
, PROC_FILESYSTEMS
);
546 else if (!strcmp(type
, "swap"))
547 printf (_(" and it looks like this is swapspace\n"));
549 printf (_(" I will try type %s\n"), type
);
555 procfsnext(FILE *procfs
) {
559 while (fgets(line
, sizeof(line
), procfs
)) {
560 if (sscanf (line
, "nodev %[^\n]\n", fsname
) == 1) continue;
561 if (sscanf (line
, " %[^ \n]\n", fsname
) != 1) continue;
562 return xstrdup(fsname
);
567 /* Only use /proc/filesystems here, this is meant to test what
568 the kernel knows about, so /etc/filesystems is irrelevant.
569 Return: 1: yes, 0: no, -1: cannot open procfs */
571 is_in_procfs(const char *type
) {
576 procfs
= fopen(PROC_FILESYSTEMS
, "r");
579 while ((fsname
= procfsnext(procfs
)) != NULL
)
580 if (!strcmp(fsname
, type
)) {
590 /* Try all types in FILESYSTEMS, except those in *types,
591 in case *types starts with "no" */
592 /* return: 0: OK, -1: error in errno, 1: type not found */
593 /* when 0 or -1 is returned, *types contains the type used */
594 /* when 1 is returned, *types is NULL */
596 procfsloop(int (*mount_fn
)(struct mountargs
*), struct mountargs
*args
,
597 const char **types
) {
598 char *files
[2] = { ETC_FILESYSTEMS
, PROC_FILESYSTEMS
};
601 const char *notypes
= NULL
;
607 if (*types
&& !strncmp(*types
, "no", 2)) {
609 notypes
= (*types
) + 2;
613 /* Use PROC_FILESYSTEMS only when ETC_FILESYSTEMS does not exist.
614 In some cases trying a filesystem that the kernel knows about
615 on the wrong data will crash the kernel; in such cases
616 ETC_FILESYSTEMS can be used to list the filesystems that we
617 are allowed to try, and in the order they should be tried.
618 End ETC_FILESYSTEMS with a line containing a single '*' only,
619 if PROC_FILESYSTEMS should be tried afterwards. */
621 for (i
=0; i
<2; i
++) {
622 procfs
= fopen(files
[i
], "r");
625 while ((fsname
= procfsnext(procfs
)) != NULL
) {
626 if (!strcmp(fsname
, "*")) {
630 if (was_tested (fsname
))
632 if (no
&& matching_type(fsname
, notypes
))
637 printf(_("Trying %s\n"), fsname
);
640 if ((*mount_fn
) (args
) == 0) {
644 } else if (errno
!= EINVAL
&&
645 is_in_procfs(fsname
) == 1) {