最近因项目需要,需要对块设备进行判断:是否有文件系统,以及文件系统的类型。
虽然linux下自带有几种命令可以知道文件系统:fdisk -l , blkid ,parted -l , df -T ,file -sL
但没有直接的函数调用来获取设备上的文件系统。
下面用C语言实现一个函数:char * fstype(char*device); 返回 指定设备上的文件系统,没有返回NULL
参考自mkfs.xfs的源代码
<span style="font-size:18px;">
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include "fstype.h" #undef XFS_SUPER_MAGIC /* * From mount(8) source by Andries Brouwer. Hacked for XFS by mkp. * Recent sync's to mount source: * - util-linux-2.10o ... 06 Sep 00 * - util-linux-2.10r ... 06 Dec 00 * - util-linux-2.11g ... 02 Jul 01 * - util-linux-2.11u ... 24 Aug 02 * - util-linux-2.11z ... 13 May 03 */ /* Including <linux/fs.h> became more and more painful. Below a very abbreviated version of some declarations, only designed to be able to check a magic number in case no filesystem type was given. */ #define MINIX_SUPER_MAGIC 0x137F /* minix v1, 14 char names */ #define MINIX_SUPER_MAGIC2 0x138F /* minix v1, 30 char names */ #define MINIX2_SUPER_MAGIC 0x2468 /* minix v2, 14 char names */ #define MINIX2_SUPER_MAGIC2 0x2478 /* minix v2, 30 char names */ struct minix_super_block { char s_dummy[16]; char s_magic[2]; }; #define minixmagic(s) assemble2le(s.s_magic) #define ISODCL(from, to) (to - from + 1) #define ISO_STANDARD_ID "CD001" struct iso_volume_descriptor { char type[ISODCL(1,1)]; /* 711 */ char id[ISODCL(2,6)]; char version[ISODCL(7,7)]; char data[ISODCL(8,2048)]; }; #define HS_STANDARD_ID "CDROM" struct hs_volume_descriptor { char foo[ISODCL ( 1, 8)]; /* 733 */ char type[ISODCL ( 9, 9)]; /* 711 */ char id[ISODCL ( 10, 14)]; char version[ISODCL ( 15, 15)]; /* 711 */ char data[ISODCL(16,2048)]; }; #define EXT_SUPER_MAGIC 0x137D struct ext_super_block { char s_dummy[56]; char s_magic[2]; }; #define extmagic(s) assemble2le(s.s_magic) #define EXT2_PRE_02B_MAGIC 0xEF51 #define EXT2_SUPER_MAGIC 0xEF53 #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 #define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 struct ext2_super_block { char s_dummy1[56]; char s_magic[2]; char s_dummy2[34]; char s_feature_compat[4]; char s_feature_incompat[4]; char s_feature_ro_compat[4]; char s_uuid[16]; char s_volume_name[16]; char s_dummy3[88]; char s_journal_inum[4]; /* ext3 only */ }; #define ext2magic(s) assemble2le(s.s_magic) struct reiserfs_super_block { char s_block_count[4]; char s_free_blocks[4]; char s_root_block[4]; char s_journal_block[4]; char s_journal_dev[4]; char s_orig_journal_size[4]; char s_journal_trans_max[4]; char s_journal_block_count[4]; char s_journal_max_batch[4]; char s_journal_max_commit_age[4]; char s_journal_max_trans_age[4]; char s_blocksize[2]; char s_oid_maxsize[2]; char s_oid_cursize[2]; char s_state[2]; char s_magic[12]; }; #define REISERFS_SUPER_MAGIC_STRING "ReIsErFs" #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs" #define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024) /* the spot for the super in versions 3.5 - 3.5.10 (inclusive) */ #define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024) #define _XIAFS_SUPER_MAGIC 0x012FD16D struct xiafs_super_block { char s_boot_segment[512]; /* 1st sector reserved for boot */ char s_dummy[60]; char s_magic[4]; }; #define xiafsmagic(s) assemble4le(s.s_magic) /* From [email protected] Mon Mar 23 15:19:05 1998 */ #define UFS_SUPER_MAGIC_LE 0x00011954 #define UFS_SUPER_MAGIC_BE 0x54190100 struct ufs_super_block { char s_dummy[0x55c]; char s_magic[4]; }; #define ufsmagic(s) assemble4le(s.s_magic) /* From [email protected] Wed Feb 24 08:05:27 1999 */ #define NTFS_SUPER_MAGIC "NTFS" struct ntfs_super_block { char s_dummy[3]; char s_magic[4]; }; /* From inspection of a few FAT filesystems - aeb */ /* Unfortunately I find almost the same thing on an extended partition; it looks like a primary has some directory entries where the extended has a partition table: IO.SYS, MSDOS.SYS, WINBOOT.SYS */ struct fat_super_block { char s_dummy[3]; char s_os[8]; /* "MSDOS5.0" or "MSWIN4.0" or "MSWIN4.1" */ /* mtools-3.9.4 writes "MTOOL394" */ char s_dummy2[32]; char s_label[11]; /* for DOS? */ char s_fs[8]; /* "FAT12 " or "FAT16 " or all zero */ /* OS/2 BM has "FAT " here. */ char s_dummy3[9]; char s_label2[11]; /* for Windows? */ char s_fs2[8]; /* garbage or "FAT32 " */ }; #define XFS_SUPER_MAGIC "XFSB" struct xfs_super_block { char s_magic[4]; char s_dummy[28]; char s_uuid[16]; char s_dummy2[60]; char s_fname[12]; }; #define CRAMFS_SUPER_MAGIC 0x28cd3d45 #define CRAMFS_SUPER_MAGIC_BE 0x453dcd28 struct cramfs_super_block { char s_magic[4]; char s_dummy[12]; char s_id[16]; }; #define cramfsmagic(s) assemble4le(s.s_magic) #define HFS_SUPER_MAGIC 0x4244 #define HFSPLUS_SUPER_MAGIC 0x482B #define HFSPLUS_SUPER_VERSION 0x004 struct hfs_super_block { char s_magic[2]; char s_version[2]; }; #define hfsmagic(s) assemble2le(s.s_magic) #define hfsversion(s) assemble2le(s.s_version) #define HPFS_SUPER_MAGIC 0xf995e849 struct hpfs_super_block { char s_magic[4]; char s_magic2[4]; }; #define hpfsmagic(s) assemble4le(s.s_magic) struct adfs_super_block { char s_dummy[448]; char s_blksize[1]; char s_dummy2[62]; char s_checksum[1]; }; #define adfsblksize(s) ((uint) s.s_blksize[0]) /* found in first 4 bytes of block 1 */ struct vxfs_super_block { char s_magic[4]; }; #define vxfsmagic(s) assemble4le(s.s_magic) #define VXFS_SUPER_MAGIC 0xa501FCF5 struct jfs_super_block { char s_magic[4]; char s_version[4]; char s_dummy1[93]; char s_fpack[11]; char s_dummy2[24]; char s_uuid[16]; char s_label[16]; }; #define JFS_SUPER1_OFF 0x8000 #define JFS_MAGIC "JFS1" struct sysv_super_block { char s_dummy1[504]; char s_magic[4]; char type[4]; }; #define sysvmagic(s) assemble4le(s.s_magic) #define SYSV_SUPER_MAGIC 0xfd187e20 struct mdp_super_block { char md_magic[4]; }; #define MD_SB_MAGIC 0xa92b4efc #define mdsbmagic(s) assemble4le(s.md_magic) struct ocfs_volume_header { char minor_version[4]; char major_version[4]; char signature[128]; }; struct ocfs_volume_label { char disk_lock[48]; char label[64]; char label_len[2]; }; #define ocfslabellen(o) assemble2le(o.label_len) #define OCFS_MAGIC "OracleCFS" /* Common gfs/gfs2 constants: */ #define GFS_MAGIC 0x01161970 #define GFS_DEFAULT_BSIZE 4096 #define GFS_SUPERBLOCK_OFFSET (0x10 * GFS_DEFAULT_BSIZE) #define GFS_LOCKNAME_LEN 64 /* gfs1 constants: */ #define GFS_FORMAT_FS 1309 #define GFS_FORMAT_MULTI 1401 /* gfs2 constants: */ #define GFS2_FORMAT_FS 1801 #define GFS2_FORMAT_MULTI 1900 struct gfs2_meta_header { char mh_magic[4]; char mh_type[4]; char __pad0[8]; /* Was generation number in gfs1 */ char mh_format[4]; char __pad1[4]; /* Was incarnation number in gfs1 */ }; struct gfs2_inum { char no_formal_ino[8]; char no_addr[8]; }; struct gfs2_sb { struct gfs2_meta_header sb_header; char sb_fs_format[4]; char sb_multihost_format[4]; char __pad0[4]; /* Was superblock flags in gfs1 */ char sb_bsize[4]; char sb_bsize_shift[4]; char __pad1[4]; /* Was journal segment size in gfs1 */ struct gfs2_inum sb_master_dir; /* Was jindex dinode in gfs1 */ struct gfs2_inum __pad2; /* Was rindex dinode in gfs1 */ struct gfs2_inum sb_root_dir; char sb_lockproto[GFS_LOCKNAME_LEN]; char sb_locktable[GFS_LOCKNAME_LEN]; /* In gfs1, quota and license dinodes followed */ }; #define gfsmagic(s) assemble4be(s.sb_header.mh_magic) #define gfsformat(s) assemble4be(s.sb_fs_format) #define gfsmultiformat(s) assemble4be(s.sb_multihost_format) /* btrfs constants */ #define BTRFS_SUPER_INFO_OFFSET (64 * 1024) /* 32 bytes in various csum fields */ #define BTRFS_CSUM_SIZE 32 #define BTRFS_FSID_SIZE 16 #define BTRFS_MAGIC "_BHRfS_M" /* * the super block basically lists the main trees of the FS * it currently lacks any block count etc etc */ struct btrfs_super_block { char csum[BTRFS_CSUM_SIZE]; /* the first 3 fields must match struct btrfs_header */ char fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ char bytenr[8]; /* this block number */ char flags[8]; /* allowed to be different from the btrfs_header from here own down */ char magic[8]; /* more follows but this is all our libdisk cares about*/ } __attribute__ ((__packed__)); static inline unsigned short assemble2le(char *p) { return (unsigned short)(p[0] | (p[1] << 8)); } static inline int assemble4le(char *p) { return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24)); } static inline int assemble4be(char *p) { return (p[3] | (p[2] << 8) | (p[1] << 16) | (p[0] << 24)); } /* * From mount(8) source by Andries Brouwer. Hacked for XFS by mkp. * Recent sync's to mount source: * - util-linux-2.10o ... 06 Sep 00 * - util-linux-2.10r ... 06 Dec 00 * - util-linux-2.11g ... 02 Jul 01 * - util-linux-2.11u ... 24 Aug 02 * - util-linux-2.11z ... 13 May 03 */ #define SIZE(a) (sizeof(a)/sizeof(a[0])) /* Most file system types can be recognized by a `magic' number in the superblock. Note that the order of the tests is significant: by coincidence a filesystem can have the magic numbers for several file system types simultaneously. For example, the romfs magic lives in the 1st sector; xiafs does not touch the 1st sector and has its magic in the 2nd sector; ext2 does not touch the first two sectors. */ static inline unsigned short swapped(unsigned short a) { return (a>>8) | (a<<8); } /* Probes the device and attempts to determine the type of filesystem contained within. Original routine by <[email protected]>; made into a function for mount(8) by Mike Grupenhoff <[email protected]>. Corrected the test for xiafs - aeb Read the superblock only once - aeb Added a very weak heuristic for vfat - aeb Added iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb Added a test for high sierra (iso9660) - [email protected] Added ufs from a patch by jj. But maybe there are several types of ufs? Added ntfs from a patch by Richard Russon. Added xfs - 2000-03-21 Martin K. Petersen <[email protected]> Added cramfs, hfs, hpfs, adfs - Sepp Wijnands <[email protected]> Added ext3 - Andrew Morton Added jfs - Christoph Hellwig Added sysv - Tim Launchbury Added udf - Bryce Nesbitt Added gfs/gfs2, btrfs - Eric Sandeen */ /* * udf magic - I find that trying to mount garbage as an udf fs * causes a very large kernel delay, almost killing the machine. * So, we do not try udf unless there is positive evidence that it * might work. Strings below taken from ECMA 167. */ /* * It seems that before udf 2.00 the volume descriptor was not well * defined. For 2.00 you're supposed to keep scanning records until * you find one NOT in this list. (See ECMA 2/8.3.1). */ static char *udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02","NSR03", "TEA01" }; static int may_be_udf(const char *id) { char **m; for (m = udf_magic; m - udf_magic < SIZE(udf_magic); m++) if (!strncmp(*m, id, 5)) return 1; return 0; } /* we saw "CD001" - may be iso9660 or udf - Bryce Nesbitt */ static int is_really_udf(int fd) { int j, bs; struct iso_volume_descriptor isosb; /* determine the block size by scanning in 2K increments (block sizes larger than 2K will be null padded) */ for (bs = 1; bs < 16; bs++) { lseek(fd, bs*2048+32768, SEEK_SET); if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb)) return 0; if (isosb.id[0]) break; } /* Scan up to another 64 blocks looking for additional VSD's */ for (j = 1; j < 64; j++) { if (j > 1) { lseek(fd, j*bs*2048+32768, SEEK_SET); if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb)) return 0; } /* If we find NSR0x then call it udf: NSR01 for UDF 1.00 NSR02 for UDF 1.50 NSR03 for UDF 2.00 */ if (!strncmp(isosb.id, "NSR0", 4)) return 1; if (!may_be_udf(isosb.id)) return 0; } return 0; } static int may_be_swap(const char *s) { return (strncmp(s-10, "SWAP-SPACE", 10) == 0 || strncmp(s-10, "SWAPSPACE2", 10) == 0); } /* rather weak necessary condition */ static int may_be_adfs(const struct adfs_super_block *sb) { char *p; int sum; p = (char *)sb->s_checksum; sum = 0; while(--p != (char *)sb) sum = (sum >> 8) + (sum & 0xff) + *p; return (sum & 0xff) == sb->s_checksum[0]; } static int is_reiserfs_magic_string (struct reiserfs_super_block * rs) { return (!strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING, strlen ( REISERFS_SUPER_MAGIC_STRING)) || !strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, strlen ( REISER2FS_SUPER_MAGIC_STRING))); } char * fstype(const char *device) { <span style="color:#ff0000;">//获取设备的文件系统类型,没有则为NULL</span> int fd; char *type = NULL; union { struct minix_super_block ms; struct ext_super_block es; struct ext2_super_block e2s; struct vxfs_super_block vs; struct hfs_super_block hs; } sb; /* stuff at 1024 */ union { struct xiafs_super_block xiasb; char romfs_magic[8]; char qnx4fs_magic[10]; /* ignore first 4 bytes */ unsigned int bfs_magic; struct ntfs_super_block ntfssb; struct fat_super_block fatsb; struct xfs_super_block xfsb; struct cramfs_super_block cramfssb; } xsb; struct ufs_super_block ufssb; union { struct iso_volume_descriptor iso; struct hs_volume_descriptor hs; } isosb; struct reiserfs_super_block reiserfssb; /* block 64 or 8 */ struct jfs_super_block jfssb; /* block 32 */ struct hpfs_super_block hpfssb; struct adfs_super_block adfssb; struct sysv_super_block svsb; struct gfs2_sb gfs2sb; struct btrfs_super_block btrfssb; struct stat statbuf; /* opening and reading an arbitrary unknown path can have undesired side effects - first check that `device' refers to a block device or ordinary file */ if (stat (device, &statbuf) || !(S_ISBLK(statbuf.st_mode) || S_ISREG(statbuf.st_mode))) return NULL; fd = open(device, O_RDONLY); if (fd < 0) return NULL; /* do seeks and reads in disk order, otherwise a very short partition may cause a failure because of read error */ if (!type) { /* block 0 */ if (lseek(fd, 0, SEEK_SET) != 0 || read(fd, (char *) &xsb, sizeof(xsb)) != sizeof(xsb)) goto try_iso9660; /* Gyorgy Kovesdi: none of my photocds has a readable block 0 */ if (xiafsmagic(xsb.xiasb) == _XIAFS_SUPER_MAGIC) type = "xiafs"; else if(!strncmp(xsb.romfs_magic, "-rom1fs-", 8)) type = "romfs"; else if(!strncmp(xsb.xfsb.s_magic, XFS_SUPER_MAGIC, 4)) type = "xfs"; else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6)) type = "qnx4"; else if(xsb.bfs_magic == 0x1badface) type = "bfs"; else if(!strncmp(xsb.ntfssb.s_magic, NTFS_SUPER_MAGIC, sizeof(xsb.ntfssb.s_magic))) type = "ntfs"; else if(cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC || cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC_BE) type = "cramfs"; else if ((!strncmp(xsb.fatsb.s_os, "MSDOS", 5) || !strncmp(xsb.fatsb.s_os, "MSWIN", 5) || !strncmp(xsb.fatsb.s_os, "MTOOL", 5) || !strncmp(xsb.fatsb.s_os, "mkdosfs", 7) || !strncmp(xsb.fatsb.s_os, "kmkdosfs", 8) || /* Michal Svec: created by fdformat, old msdos utility for formatting large (1.7) floppy disks. */ !strncmp(xsb.fatsb.s_os, "CH-FOR18", 8)) && (!strncmp(xsb.fatsb.s_fs, "FAT12 ", 8) || !strncmp(xsb.fatsb.s_fs, "FAT16 ", 8) || !strncmp(xsb.fatsb.s_fs2, "FAT32 ", 8))) type = "vfat"; /* only guessing - might as well be fat or umsdos */ } if (!type) { /* sector 1 */ if (lseek(fd, 512 , SEEK_SET) != 512 || read(fd, (char *) &svsb, sizeof(svsb)) != sizeof(svsb)) goto io_error; if (sysvmagic(svsb) == SYSV_SUPER_MAGIC ) type = "sysv"; } if (!type) { /* block 1 */ if (lseek(fd, 1024, SEEK_SET) != 1024 || read(fd, (char *) &sb, sizeof(sb)) != sizeof(sb)) goto io_error; /* ext2 has magic in little-endian on disk, so "swapped" is superfluous; however, there have existed strange byteswapped PPC ext2 systems */ if (ext2magic(sb.e2s) == EXT2_SUPER_MAGIC || ext2magic(sb.e2s) == EXT2_PRE_02B_MAGIC || ext2magic(sb.e2s) == swapped(EXT2_SUPER_MAGIC)) { type = "ext2"; /* maybe even ext3? */ if ((assemble4le(sb.e2s.s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && assemble4le(sb.e2s.s_journal_inum) != 0) type = "ext3"; /* "ext3,ext2" */ if(assemble4le(sb.e2s.s_feature_ro_compat)&(EXT4_FEATURE_RO_COMPAT_HUGE_FILE|EXT4_FEATURE_RO_COMPAT_GDT_CSUM| EXT4_FEATURE_RO_COMPAT_DIR_NLINK| EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)) type="ext4"; } else if (minixmagic(sb.ms) == MINIX_SUPER_MAGIC || minixmagic(sb.ms) == MINIX_SUPER_MAGIC2 || minixmagic(sb.ms) == swapped(MINIX_SUPER_MAGIC2) || minixmagic(sb.ms) == MINIX2_SUPER_MAGIC || minixmagic(sb.ms) == MINIX2_SUPER_MAGIC2) type = "minix"; else if (extmagic(sb.es) == EXT_SUPER_MAGIC) type = "ext"; else if (vxfsmagic(sb.vs) == VXFS_SUPER_MAGIC) type = "vxfs"; else if (hfsmagic(sb.hs) == swapped(HFS_SUPER_MAGIC) || (hfsmagic(sb.hs) == swapped(HFSPLUS_SUPER_MAGIC) && hfsversion(sb.hs) == swapped(HFSPLUS_SUPER_VERSION))) type = "hfs"; } if (!type) { /* block 3 */ if (lseek(fd, 0xc00, SEEK_SET) != 0xc00 || read(fd, (char *) &adfssb, sizeof(adfssb)) != sizeof(adfssb)) goto io_error; /* only a weak test */ if (may_be_adfs(&adfssb) && (adfsblksize(adfssb) >= 8 && adfsblksize(adfssb) <= 10)) type = "adfs"; } if (!type) { int mag; /* block 8 */ if (lseek(fd, 8192, SEEK_SET) != 8192 || read(fd, (char *) &ufssb, sizeof(ufssb)) != sizeof(ufssb)) goto io_error; mag = ufsmagic(ufssb); if (mag == UFS_SUPER_MAGIC_LE || mag == UFS_SUPER_MAGIC_BE) type = "ufs"; } if (!type) { /* block 8 */ if (lseek(fd, REISERFS_OLD_DISK_OFFSET_IN_BYTES, SEEK_SET) != REISERFS_OLD_DISK_OFFSET_IN_BYTES || read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) != sizeof(reiserfssb)) goto io_error; if (is_reiserfs_magic_string(&reiserfssb)) type = "reiserfs"; } if (!type) { /* block 8 */ if (lseek(fd, 0x2000, SEEK_SET) != 0x2000 || read(fd, (char *) &hpfssb, sizeof(hpfssb)) != sizeof(hpfssb)) goto io_error; if (hpfsmagic(hpfssb) == HPFS_SUPER_MAGIC) type = "hpfs"; } if (!type) { /* block 32 */ if (lseek(fd, JFS_SUPER1_OFF, SEEK_SET) != JFS_SUPER1_OFF || read(fd, (char *) &jfssb, sizeof(jfssb)) != sizeof(jfssb)) goto io_error; if (!strncmp(jfssb.s_magic, JFS_MAGIC, 4)) type = "jfs"; } if (!type) { /* block 32 */ try_iso9660: if (lseek(fd, 0x8000, SEEK_SET) != 0x8000 || read(fd, (char *) &isosb, sizeof(isosb)) != sizeof(isosb)) goto io_error; if (strncmp(isosb.hs.id, HS_STANDARD_ID, sizeof(isosb.hs.id)) == 0) { /* "CDROM" */ type = "iso9660"; } else if (strncmp(isosb.iso.id, ISO_STANDARD_ID, sizeof(isosb.iso.id)) == 0) { /* CD001 */ type = "iso9660"; if (is_really_udf(fd)) type = "udf"; } else if (may_be_udf(isosb.iso.id)) type = "udf"; } if (!type) { /* block 64 */ if (lseek(fd, REISERFS_DISK_OFFSET_IN_BYTES, SEEK_SET) != REISERFS_DISK_OFFSET_IN_BYTES || read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) != sizeof(reiserfssb)) goto io_error; if (is_reiserfs_magic_string(&reiserfssb)) type = "reiserfs"; } if (!type) { /* block 64 */ if (lseek(fd, GFS_SUPERBLOCK_OFFSET, SEEK_SET) != GFS_SUPERBLOCK_OFFSET || read(fd, (char *) &gfs2sb, sizeof(gfs2sb)) != sizeof(gfs2sb)) goto io_error; if (gfsmagic(gfs2sb)) { if (gfsformat(gfs2sb) == GFS_FORMAT_FS && gfsmultiformat(gfs2sb) == GFS_FORMAT_MULTI) type = "gfs"; else if (gfsformat(gfs2sb) == GFS2_FORMAT_FS && gfsmultiformat(gfs2sb) == GFS2_FORMAT_MULTI) type = "gfs2"; } } if (!type) { /* block 64 */ if (lseek(fd, BTRFS_SUPER_INFO_OFFSET, SEEK_SET) != BTRFS_SUPER_INFO_OFFSET || read(fd, (char *) &btrfssb, sizeof(btrfssb)) != sizeof(btrfssb)) goto io_error; if (!strncmp((char *)(btrfssb.magic), BTRFS_MAGIC, sizeof(btrfssb.magic))) { type = "btrfs"; } } if (!type) { /* perhaps the user tries to mount the swap space on a new disk; warn her before she does mkfs on it */ int pagesize = getpagesize(); int rd; char buf[128 * 1024]; /* 64k is current max pagesize */ if (pagesize > sizeof(buf)) abort(); rd = pagesize; if (rd < 8192) rd = 8192; if (rd > sizeof(buf)) rd = sizeof(buf); if (lseek(fd, 0, SEEK_SET) != 0 || read(fd, buf, rd) != rd) goto io_error; if (may_be_swap(buf+pagesize) || may_be_swap(buf+4096) || may_be_swap(buf+8192)) type = "swap"; } close (fd); return(type); io_error: close(fd); return NULL; } int check_ismounted(char *devname){ <span style="color:#ff0000;">//检查设备是否已经挂载</span> struct ustat ust[2]; struct stat st; if(access(devname,F_OK)!=0) return -1; if (stat(devname, &st) < 0) return -1; if ((st.st_mode & S_IFMT) != S_IFBLK) return -1; if (ustat(st.st_rdev, ust) >= 0) { return 1; //mounted } return 0; // can mkfs }</span>