Linux操作系统中对于NTFS读取目录功能的实现

2023-05-16


   1: /*  

   2:  * We use the same basic approach as the old NTFS driver, i.e. we parse the  

   3:  * index root entries and then the index allocation entries that are marked  

   4:  * as in use in the index bitmap.  

   5:  *  

   6:  * While this will return the names in random order this doesn't matter for  

   7:  * ->readdir but OTOH results in a faster ->readdir.  

   8:  *  

   9:  * VFS calls ->readdir without BKL but with i_mutex held. This protects the VFS  

  10:  * parts (e.g. ->f_pos and ->i_size, and it also protects against directory  

  11:  * modifications).  

  12:  *  

  13:  * Locking:  - Caller must hold i_mutex on the directory.  

  14:  *         - Each page cache page in the index allocation mapping must be  

  15:  *           locked whilst being accessed otherwise we may find a corrupt  

  16:  *           page due to it being under ->writepage at the moment which  

  17:  *           applies the mst protection fixups before writing out and then  

  18:  *           removes them again after the write is complete after which it   

  19:  *           unlocks the page.  

  20:  */  

  21: static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)  

  22: {  

We use the same basic approach as the old NTFS driver, i.e. we parse the
index root entries and then the index allocation entries that are marked
as in use in the index bitmap.

根据这名注释,可以推测index bitmap是用来标注多个index allocation的使用情况的。

那么这些index allocation都存在哪里呢,因为通常一个File Record中只有一个index allocation属性。

 


   1: /*  

   2:      * Copy the index root attribute value to a buffer so that we can put  

   3:      * the search context and unmap the mft record before calling the  

   4:      * filldir() callback.  We need to do this because of NFSd which calls  

   5:      * ->lookup() from its filldir callback() and this causes NTFS to  

   6:      * deadlock as ntfs_lookup() maps the mft record of the directory and  

   7:      * we have got it mapped here already.  The only solution is for us to  

   8:      * unmap the mft record here so that a call to ntfs_lookup() is able to  

   9:      * map the mft record without deadlocking.  

  10:      */  

  11:     rc = le32_to_cpu(ctx->attr->data.resident.value_length);  

  12:     ir = kmalloc(rc, GFP_NOFS);  

  13:     if (unlikely(!ir)) {  

  14:         err = -ENOMEM;  

  15:         goto err_out;  

  16:     }  

  17:     /* Copy the index root value (it has been verified in read_inode). */  

  18:     memcpy(ir, (u8*)ctx->attr +  

  19:             le16_to_cpu(ctx->attr->data.resident.value_offset), rc);  

  20:     ntfs_attr_put_search_ctx(ctx);  

  21:     unmap_mft_record(ndir);  

  22:     ctx = NULL;  

  23:     m = NULL;  

  24:     index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);  

  25:     /* The first index entry. */  

  26:     ie = (INDEX_ENTRY*)((u8*)&ir->index +  

  27:             le32_to_cpu(ir->index.entries_offset));  

  28:     /*  

  29:      * Loop until we exceed valid memory (corruption case) or until we  

  30:      * reach the last entry or until filldir tells us it has had enough  

  31:      * or signals an error (both covered by the rc test).  

  32:      */  

  33:     for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {  

  34:         ntfs_debug("In index root, offset 0x%zx.", (u8*)ie - (u8*)ir);  

  35:         /* Bounds checks. */  

  36:         if (unlikely((u8*)ie < (u8*)ir || (u8*)ie +  

  37:                 sizeof(INDEX_ENTRY_HEADER) > index_end ||  

  38:                 (u8*)ie + le16_to_cpu(ie->key_length) >  

  39:                 index_end))  

  40:             goto err_out;  

  41:         /* The last entry cannot contain a name. */  

  42:         if (ie->flags & INDEX_ENTRY_END)  

  43:             break;  

  44:         /* Skip index root entry if continuing previous readdir. */  

  45:         if (ir_pos > (u8*)ie - (u8*)ir)  

  46:             continue;  

  47:         /* Advance the position even if going to skip the entry. */  

  48:         fpos = (u8*)ie - (u8*)ir;  

  49:         /* Submit the name to the filldir callback. */  

  50:         rc = ntfs_filldir(vol, fpos, ndir, NULL, ie, name, dirent,  

  51:                 filldir);  

  52:         if (rc) {  

  53:             kfree(ir);  

  54:             goto abort;  

  55:         }  

  56:     }  

/* Copy the index root value (it has been verified in read_inode). */
    memcpy(ir, (u8*)ctx->attr +
            le16_to_cpu(ctx->attr->data.resident.value_offset), rc);

这段代码是从index root属性中提取文件名信息,如果遇到index entry的flags被设置了INDEX_ENTRY_END标志,就跳出循环。

index root是存放于resident,即File Record本地的index entry集合。

 

/* If there is no index allocation attribute we are finished. */
if (!NInoIndexAllocPresent(ndir))
    goto EOD;

如果没有Index Allocation属性,我们就已经遍历完了所有的目录项,结束。

 

读取到Bitmap的内容


   1: bmp = (u8*)page_address(bmp_page);  

   2:     /* Find next index block in use. */  

   3:     while (!(bmp[cur_bmp_pos >> 3] & (1 << (cur_bmp_pos & 7)))) {  

   4: find_next_index_buffer:  

   5:         cur_bmp_pos++;  

   6:         /*  

   7:          * If we have reached the end of the bitmap page, get the next  

   8:          * page, and put away the old one.  

   9:          */  

  10:         if (unlikely((cur_bmp_pos >> 3) >= PAGE_CACHE_SIZE)) {  

  11:             ntfs_unmap_page(bmp_page);  

  12:             bmp_pos += PAGE_CACHE_SIZE * 8;  

  13:             cur_bmp_pos = 0;  

  14:             goto get_next_bmp_page;  

  15:         }  

  16:         /* If we have reached the end of the bitmap, we are done. */  

  17:         if (unlikely(((bmp_pos + cur_bmp_pos) >> 3) >= i_size))  

  18:             goto unm_EOD;  

  19:         ia_pos = (bmp_pos + cur_bmp_pos) <<  

  20:                 ndir->itype.index.block_size_bits;  

  21:     }  

 

Bitmap里面的每一位,代表着index allocation中的一个cluster是否有效。

如果Bitmap中某一比特位为0,则其对应的index allocation中的数据就要越过相应的cluster去读下一个cluster的内容。

转载于:https://www.cnblogs.com/long123king/p/3544221.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux操作系统中对于NTFS读取目录功能的实现 的相关文章

随机推荐

  • linux分区btrfs,linux btrfs文件系统及管理

    什么是btrfs xff1f Btrfs B tree文件系统 xff0c 通常念成Butter FS xff0c Better FS或B tree FS xff0c linux文件系统 xff0c 具有写时复制COW copy on wr
  • AJAX的post提交数组数据

    2019独角兽企业重金招聘Python工程师标准 gt gt gt code 前端js代码 xff1a function AlarmCondition id alarmLevel defaultOverValue isEnabled thi
  • linux 网络命令ethtool与mii-tool及nm-tool

    1 ethtool Ethtool是Linux下用于查询及设置网卡参数的命令 概要 xff1a ethtool ethX 查询ethX网口基本设置 ethtool h 显示ethtool的命令帮助 help ethtool i ethX 查
  • 使用lxc提供轻量级虚拟化

    lxc linux containers 是一种基于容器的操作系统层级的虚拟化技术 xff0c 一个容器就是一个虚拟的执行环境 xff0c 容器有效地将由单个操作系统管理的资源划分到孤立的组中 xff0c 以更好地在孤立的组之间平衡有冲突的
  • debian更新源时找不到公钥的解决办法

    W GPG error http mirrors 163 com jessie updates InRelease The following signatures couldn 39 t be verified because the p
  • esxi在线添加硬盘,系统没有识别到怎么办(重启除外)

    esxi在线添加虚拟磁盘 xff0c fdisk l没发现 xff0c 一般情况下重启服务器就可以 但是我服务器不能影响业务 xff0c 为什么新增磁盘或磁盘扩容后 xff0c Linux系统识别不到呢 xff1f 因为连接存储设备的SCS
  • CentOS 7更改阿里云源

    1 备份原镜像文件 xff0c 便于后期恢复 mv etc yum repos d CentOS Base repo etc yum repos d CentOS Base repo backup 2 下载新的CentOS Base rep
  • Ubuntu有线网络与无线网线自由切换方法

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 有的时候办公环境安全要求较高 xff0c 严格区分了工作网络 xff08 内部网络 xff09 和生活网络 xff08 Internet xff09 xff0c 通常生活网
  • 如何查看连接mysql的ip地址

    select SUBSTRING INDEX host 39 39 1 as ip count from information schema processlist group by ip
  • AutoCAD 许可管理器不起作用,或未正确安装,现在将关闭

    问题描述 重新安装了也还是这样 xff0c 而且第二次打开都跳不出申请码界面就关闭了 问题原因 xff0c 初步认为 xff1a AutoCAD 在首次弹出申请激活类型的类型时 xff0c 直接选择了网络激活 xff0c 而且没有激活成功
  • #ifndef详解

    ifndef 是 34 if not defined 34 的简写 xff0c 是预处理功能 xff08 宏定义 文件包含 条件编译 xff09 当中的条件编译 xff0c 可以根据是否已经定义了一个变量来进行分支选择 xff0c 其作用是
  • vue中watch的用法总结以及报错处理Error in callback for watcher "checkList"

    首先确认 watch是一个对象 xff0c 一定要当成对象来用 对象就有键 xff0c 有值 键 xff1a 就是你要监控的那个家伙 xff0c 比如说 route xff0c 这个就是要监控路由的变化 xff0c 或者是data中的某个变
  • 京东物流青龙系统分享

    QQ空间 腾讯朋友 新浪微博 人人网 开心网 微信 QQ好友 腾讯微博 浏览 xff1a 1102 2015年 xff0c 中国的大电商平台格局已定 xff0c 各大平台开始重视的方向已经从过去的价格战转向最后一公里和O2O的布局了 移动电
  • 彻底解决DZ大附件上传问题

    2012 4 13日更新 xff1a 因为这篇文章是很早以前写的了 xff0c 很多朋友看到了之后向我咨询大附件的问题 xff0c 但是以下部分信息已经失效 xff0c 如需了解这个问题的最新解决方案 xff0c 可以加我的QQ群 xff1
  • 前端经典面试题CSS三栏布局

    对于前端来说 xff0c 布局也是必须掌握的 xff0c 一个好的布局可以让页面看起来更美观 提到布局 xff0c 那就不得不说CSS三栏布局 这是前端面试经常会问到的一个问题 xff0c 算是基础题 所谓的三栏布局 xff0c 一般是指左
  • xmanager 注册码及评估期已过的解决办法

    注册信息 用户 xff1a admin 企业 xff1a microsoft Xshell4 0注册码 xff1a 690313 111999 999313 Xftp 4 0注册码 xff1a 101210 450789 147200 Xs
  • ntoj 808 蚂蚁的难题(八)

    蚂蚁的难题 八 时间限制 xff1a 2000 ms 内存限制 xff1a 65535 KB 难度 xff1a 5 描述 蚂蚁是一个古玩爱好者 xff0c 他收藏了很多瓶瓶罐罐 有一天 xff0c 他要将他的宝贝们一字排开 xff0c 摆放
  • CentOS 7尝试安装 phpstudy

    安装方法 xff08 phpstudy for linux V0 2公测版 xff09 使用 SSH 连接工具 连接到您的 Linux服务器后 xff0c 根据系统执行相应命令开始安装 xff08 大约2分钟完成面板安装 xff09 xff
  • asp.net 2.0中傻瓜式使用soap header

    在websevrice 中 soap header是十分重要的哦 xff0c 主要是安全性的考虑 xff0c 在asp net 2 0中 可以简单地应用soap header来 进行傻瓜式的应用 xff0c 更复杂的应用当然要更深入地去看了
  • Linux操作系统中对于NTFS读取目录功能的实现

    1 2 We use the same basic approach as the old NTFS driver i e we parse the 3 index root entries and then the index alloc