最近因项目需要,需要对块设备进行判断:是否有文件系统,以及文件系统的类型。
虽然linux下自带有几种命令可以知道文件系统:fdisk -l , blkid ,parted -l , df -T ,file -sL
但没有直接的函数调用来获取设备上的文件系统。
下面用C语言实现一个函数:char * fstype(char*device); 返回 指定设备上的文件系统,没有返回NULL
参考自mkfs.xfs的源代码
#include
#include
#include
#include
#include
#include
#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 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 ; made into a function
for mount(8) by Mike Grupenhoff .
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
Added cramfs, hfs, hpfs, adfs - Sepp Wijnands
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) { //获取设备的文件系统类型,没有则为NULL
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){ //检查设备是否已经挂载
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
}