• 技术文章 >后端开发 >php教程

    如何写一个简易的文件系统(4):umount_PHP教程

    2016-07-12 08:55:57原创439

    如何写一个简易的文件系统(4):umount


    哈哈,时隔几年,又从磁盘深处找出了原始代码myfs.zip。
    -----------------------------------------无敌分割线------------------------------

    最近准备从新写一个基于block设备的小文件系统来完成这个系列的博客。 这次是基于3.10的kernel来写的。可能跟前3篇稍有差异。
    umount就是将文件系统卸载掉。那么卸载文件系统需要做什么事情呢?需要将所有的数据全部更新的设备上(不管是文件数据 ,还是文件系统数据)
    以后我会将文件数据称为media data,而将文件系统数据(inode,superblock等等)称为meta data。
    前一篇的mount的fill super中看到下面一行代码:
    sb->s_op = &dfs_sops;
    就是给sb一个super block的操作结构体。当然如果你不给的话,暂时不影响umount操作,但是所有的数据都不会更新设备上去。
    const struct super_operations dfs_sops = {
    .alloc_inode = dfs_alloc_inode,
    .put_super = dfs_put_super,
    .sync_fs = dfs_sync_fs,
    };
    除了mount过程中要用到的alloc_inode之外,这边又添加了两个函数,一个叫put_super,另外一个叫sync_fs.
    其中put_super用于更新设备上的super block,而sync_fs用于同步文件系统,也就是将所有的dirty文件全部更新到设备上去。
    暂时我们还没有做好创建/更新文件的准备,所以这边只实现了put_super函数。
    static void dfs_put_super(struct super_block *sb)
    {
    struct dfs_sb_info *sbi = DFS_SB(sb);


    dfs_trace("%s\n", __func__);
    if (sbi->dirty)
    return dfs_write_super(sb);
    kfree(sbi);
    }


    static int dfs_sync_fs(struct super_block *sb, int wait)
    {
    dfs_trace("%s\n", __func__);
    dfs_put_super(sb);
    /* todo: sync files as well*/
    return 0;
    }

    static void dfs_write_super(struct super_block *sb)
    {
    struct dfs_sb_info *sbi = DFS_SB(sb);
    struct buffer_head *bh;
    struct dfs_super_block ds;

    dfs_trace("%s\n", __func__);
    #defineDFS_SB_BLOCK 0
    if (!(bh = sb_bread(sb, DFS_SB_BLOCK)))
    return;
    /* update super block */
    ds.inode_count = sbi->inode_count;
    ds.block_size = sbi->block_size;
    ds.total_blocks = sbi->total_blocks;
    ds.free_blocks = sbi->free_blocks;
    ds.used_blocks = sbi->used_blocks;
    ds.bad_blocks = sbi->bad_blocks;
    ds.inode_size = sbi->inode_size;
    ds.magic = sbi->magic;
    ds.max_inode_no = sbi->max_inode_no;
    memcpy((void*)(bh->b_data), &ds, sizeof(struct dfs_super_block));
    mark_buffer_dirty(bh);
    sync_dirty_buffer(bh);
    return brelse(bh);
    }

    root:/ # mount -t dfs /dev/block/bootdevice/by-name/oem /oem
    mount -t dfs /dev/block/bootdevice/by-name/oem /oem
    root/ # mount
    rootfs / rootfs ro,seclabel 0 0
    tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,mode=755 0 0
    devpts /dev/pts devpts rw,seclabel,relatime,mode=600 0 0
    proc /proc proc rw,relatime 0 0
    sysfs /sys sysfs rw,seclabel,relatime 0 0
    selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0
    debugfs /sys/kernel/debug debugfs rw,seclabel,relatime 0 0
    none /acct cgroup rw,relatime,cpuacct 0 0
    none /sys/fs/cgroup tmpfs rw,seclabel,relatime,mode=750,gid=1000 0 0
    tmpfs /mnt tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0
    none /dev/cpuctl cgroup rw,relatime,cpu 0 0
    adb /dev/usb-ffs/adb functionfs rw,relatime 0 0
    /dev/block/dm-0 /system ext4 ro,seclabel,relatime,discard,data=ordered 0 0
    /dev/block/bootdevice/by-name/cache /cache ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
    /dev/block/bootdevice/by-name/persist /persist ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
    /dev/block/bootdevice/by-name/dsp /dsp ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
    /dev/block/bootdevice/by-name/modem /firmware vfat ro,context=u:object_r:firmware_file:s0,relatime,uid=1000,gid=1000,fmask=0337,dmask=0227,codepage=437,iocharset=iso8859-1,shortname=lower,errors=remount-ro 0 0
    tmpfs /storage tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0
    /dev/block/dm-1 /data ext4 rw,seclabel,nosuid,nodev,relatime,discard,noauto_da_alloc,data=ordered 0 0
    /dev/fuse /mnt/runtime/default/emulated fuse rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
    /dev/fuse /storage/emulated fuse rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
    /dev/fuse /mnt/runtime/read/emulated fuse rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
    /dev/fuse /mnt/runtime/write/emulated fuse rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
    /dev/block/bootdevice/by-name/oem /oem dfs rw,relatime 0 0
    root:/ # umount /oem
    umount /oem

    尝试cd /oem的时候发现一个问题。
    root/ # cd oem
    cd oem
    /system/bin/sh: cd: /oem: Not a directory

    原来内核没有实现lookup功能,添加如下
    static struct dentry *dfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
    {
    return NULL;//暂时为空,没啥好找的。
    }

    const struct inode_operations dfs_inode_operations = {
    .getattr = dfs_getattr,
    .lookup = dfs_lookup,
    };

    www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1114326.htmlTechArticle如何写一个简易的文件系统(4):umount 哈哈,时隔几年,又从磁盘深处找出了原始代码 myfs.zip。 -----------------------------------------无敌分割...

    声明:本文原创发布php中文网,转载请注明出处,感谢您的尊重!如有疑问,请联系admin@php.cn处理
    专题推荐:android
    上一篇:搭建自己的PHP框架心得(一),搭建php框架心得_PHP教程 下一篇:golang错误处理之error_PHP教程
    大前端线上培训班

    相关文章推荐

    • 你必须了解PHP中什么是抽象类和抽象方法• 怎样使用PHP中的spl_autoload_register() 和 __autoload() 函数?• PHP中怎样去判断对象是否属于一个类?• PHP中怎样完成Cookie的创建、读取和删除?• 五分钟带你看PHP中的接口interface声明与应用(实例详解)

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网