xfs文件系统:格式化以及挂载

本文详细介绍了XFS文件系统的格式化、挂载和卸载过程。从mkfs.xfs命令的源码分析开始,讲解了文件系统的初始化、设备拓扑结构获取和内存管理等内容。接着探讨了mount命令的实现,包括系统调用、挂载选项处理以及安全性检查。最后简要概述了umount操作的主要步骤,涉及挂载点查找、安全检查和资源释放。通过对内核源码的深入剖析,揭示了Linux系统中XFS文件系统管理的底层机制。
摘要由CSDN通过智能技术生成

引言

情景:
  <源码> linux:3.14.56 xfsprogs:3.2.0
  <命令> mkfs.xfs -f /dev/[sdx] ; mount /dev/[sdx]; umount /dev/[sdx]

如情景所示,来分析分析,mkfs.xfs mount 以及umount操作都做了些什么事情。下述内容均为本人随意跟踪,看到那说到哪!仅作参考。


MKFS.XFS

本例格式化xfs文件系统,有关xfs文件系统就不介绍了。倒是首先要分析mkfs.xfs命令,先得获取相应的源码,源码获取可到github搜索xfsprogs,之前找了一个util-linux的包,编译后才发觉不支持mkfs.xfs,其它的文件系统倒还支持一些的,可见xfs还是比较“特殊”的,值得了解一下。好吧,总之下载即可。

  • mkfs.xfs -f /dev/sdc
    • 源码分析
      1、进入 xfs_mkfs.c文件主函数main。对于一个提供给用户使用的终端命令(或说控制接口),它做的事情无非就是在接受用户指令后,对相应指令参数进行解析,而后下发给后端进/线程做进一步处理,当然最终会返回信息给当前主进程,处理完事务后(同步的话),进程也就退出了。
... ...
while ((c = getopt(argc, argv, "b:d:i:l:L:m:n:KNp:qr:s:CfV")) != EOF) {
        switch (c) {
        case 'C':
        case 'f':
            force_overwrite = 1;
            break;
... ...

跟踪force_overwrite标志:

    memset(&ft, 0, sizeof(ft));                                ----/1/
    get_topology(&xi, &ft, force_overwrite);        ----/2/

/1/ 首先初始化以ft为首地址的fs_topology结构体,那么不妨先来看看这个结构体的内容有哪些:

/*
 * Device topology information.
 */
struct fs_topology {
    int    dsunit;        /* stripe unit - data subvolume:*/
    int    dswidth;    /* stripe width - data subvolume */
    int    rtswidth;    /* stripe width - rt subvolume */
    int    lsectorsize;    /* logical sector size &*/
    int    psectorsize;    /* physical sector size */
    int    sectoralign;    //扇区对齐标志:该标志位置位1时,要求处理的块大小与扇区大小相同(老linux版本中),因而通常不会置位。
};

/2/ 若ENABLE_BLKID有定义,即安装有blkid源码,即可执行blkid命令,获取设备的拓扑结构如下:

static void get_topology(
    libxfs_init_t        *xi,
    struct fs_topology    *ft,
    int            force_overwrite)
{
    if (!xi->disfile) {                                        ----/2.1/
        const char *dfile = xi->volname ? xi->volname : xi->dname;

        blkid_get_topology(dfile, &ft->dsunit, &ft->dswidth,                ----/2.2/
                   &ft->lsectorsize, &ft->psectorsize,
                   force_overwrite);
    }

    if (xi->rtname && !xi->risfile) {
        int dummy;

        blkid_get_topology(xi->rtname, &dummy, &ft->rtswidth,
                   &dummy, &dummy, force_overwrite);
    }
}

/2.1/ libxfs_init_t函数memset初始化为0,其成员变量disfile可知其初始化为0,又当前mkfs.xfs命令未加-d选项,则进入该分支处理。下面分支同理。
/2.2/ 处理获取设备拓扑结构,这里不好追踪就不展开了,关键函数定义实现在blkid命令源码中如:当前函数中的blkid_new_probe_from_filename。

/2// 若ENABLE_BLKID无定义,获取设备的拓扑结构:

static void get_topology(
    libxfs_init_t        *xi,
    struct fs_topology    *ft,
    int            force_overwrite)
{

    char *dfile = xi->volname ? xi->volname : xi->dname;
    int bsz = BBSIZE;

    if (!xi->disfile) {
        int fd;
        long long dummy;

        get_subvol_stripe_wrapper(dfile, SVTYPE_DATA,                ----/2.1//
                &ft->dsunit, &ft->dswidth, &ft->sectoralign);
        fd = open(dfile, O_RDONLY);
        /* If this fails we just fall back to BBSIZE */
        if (fd >= 0) {
            platform_findsizes(dfile, fd, &dummy, &bsz);
            close(fd);
        }
    }

    ft->lsectorsize = bsz;
    ft->psectorsize = bsz;

    if (xi->rtname && !xi->risfile) {
        int dummy1;

        get_subvol_stripe_wrapper(dfile, SVTYPE_RT, &dummy1,
                      &ft->rtswidth, &dummy1);
    }
}

/2.1// 不妨进入该函数:

void
get_subvol_stripe_wrapper(
    char        *dev,
    sv_type_t    type,
    int        *sunit,
    int        *swidth,
    int        *sectalign)
{
    struct stat64    sb;

    if (dev == NULL)
        return;

    if (stat64(dev, &sb)) {
        fprintf(stderr, _("Cannot stat %s: %s\n"),
            dev, strerror(errno));
        exit(1);
    }

    if (  dm_get_subvol_stripe(dev, type, sunit, swidth, sectalign, &sb))
        return;
    if (  md_get_subvol_stripe(dev, type, sunit, swidth, sectalign, &sb))        ----/2.1.1//
        return;
    if ( lvm_get_subvol_stripe(dev, type, sunit, swidth, sectalign, &sb))
        return;
    if ( xvm_get_subvol_stripe(dev, type, sunit, swidth, sectalign, &sb))
        return;
    if (evms_get_subvol_stripe(dev, type, sunit, swidth, sectalign, &sb))
        return;
    //可添加其它类型的设备驱动,信息获取如上格式
    /* ... add new device drivers here */
}

/2.1.1// 分析它即可,其它的同理。顾名思义,即获取Multiple Devices相关的东西,也就是有关矩阵raid条带化的信息,因为mkfs.xfs命令未加-d选项,故而获取的是创建md设备时指定的条带信息。进入该函数可知,主要是对其参数进行赋值。
返回main主函数,调用libxfs_init函数进行xfs文件系统的初始化,主要关注一下函数:
 1、radix_tree_init
   基树初始化,主要用于内存管理,该树为典型的字典类型结构(有待研究)
 2、libxfs_device_open
   打开一个设备并且获取其设备号,即便不是真的设备亦返回一个伪设备号
 3、cache_init
   初始化缓存,返回cache结构体
 4、manage_zones
   manage_zones函数实现释放xfs分区或生成xfs分区。而生成启动xfs目录结构调用的是xfs_dir_startup函数,该函数定义在linux源码lib库中(可使得生成目录下”.”以及“..”文件)

回到main函数,进入判断force_overwrite标志位的分支结构,调用zero_old_xfs_structures函数,函数将置0初始化各个次要AG的sb超级块结构,通常128M至4T左右容量设的备,4个AG用于管理磁盘空间。当然若是raid阵列的话就另当别论了,相同容量需创建更多的AG。AG超级块结构参考:http://www.lenky.info/archives/2012/01/648

回到main函数,调用libxfs_mount —-/3/,该函数主要就是对结构体进行填充,不过却是非常重要的,不妨来看看:

/*
 * Mount structure initialization, provides a filled-in xfs_mount_t
 * such that the numerous XFS_* macros can be used. 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值