• linux文件系统初探--Day7


    今天的主要内容很少,昨天我们把目录的处理换成我们指定的sfs之类的操作,今天则是涉及自定义文件操作。

    源码解析

    新增的代码只有inode.c中的一部分:

    struct inode_operations sfs_file_inode_ops = {
    	.getattr 	= simple_getattr,
    };
    

    之后在super.c中也仅仅是加上了对sfs_file_inode_ops的声明,同时在samplefs_get_inode中,当mode为S_IFREG即处理常规文件时,将i_op替换为sfs_file_inode_ops

    不妨来看一看libfs.c中的simple_getattr函数:

    int simple_getattr(const struct path *path, struct kstat *stat,
    		   u32 request_mask, unsigned int query_flags)
    {
    	struct inode *inode = d_inode(path->dentry);
    	generic_fillattr(inode, stat);
    	stat->blocks = inode->i_mapping->nrpages << (PAGE_SHIFT - 9);
    	return 0;
    }
    EXPORT_SYMBOL(simple_getattr);
    

    代码很短,不妨逐行解释。

    d_inode的解释是:

    Get the actual inode of this dentry

    很简单,就是获取某个dentry的inode,dcache.h中对d_inode的实现为:

    static inline struct inode *d_inode(const struct dentry *dentry)
    {
    	return dentry->d_inode;
    }
    

    在fs/stat.c中,generic_fillattr定义如下:

    /**
     * generic_fillattr - Fill in the basic attributes from the inode struct
     * @inode: Inode to use as the source
     * @stat: Where to fill in the attributes
     *
     * Fill in the basic attributes in the kstat structure from data that's to be
     * found on the VFS inode structure.  This is the default if no getattr inode
     * operation is supplied.
     */
    void generic_fillattr(struct inode *inode, struct kstat *stat)
    {
    	stat->dev = inode->i_sb->s_dev;
    	stat->ino = inode->i_ino;
    	stat->mode = inode->i_mode;
    	stat->nlink = inode->i_nlink;
    	stat->uid = inode->i_uid;
    	stat->gid = inode->i_gid;
    	stat->rdev = inode->i_rdev;
    	stat->size = i_size_read(inode);
    	stat->atime = inode->i_atime;
    	stat->mtime = inode->i_mtime;
    	stat->ctime = inode->i_ctime;
    	stat->blksize = i_blocksize(inode);
    	stat->blocks = inode->i_blocks;
    
    	if (IS_NOATIME(inode))
    		stat->result_mask &= ~STATX_ATIME;
    	if (IS_AUTOMOUNT(inode))
    		stat->attributes |= STATX_ATTR_AUTOMOUNT;
    }
    EXPORT_SYMBOL(generic_fillattr);
    

    注释写的很清楚,就是把inode中的一些属性复制到kstat中,kstat定义在stat.h中,初步看来是inode的一个小副本,包含了一些inode的基本信息。

    struct kstat {
    	u32		result_mask;	/* What fields the user got */
    	umode_t		mode;
    	unsigned int	nlink;
    	uint32_t	blksize;	/* Preferred I/O size */
    	u64		attributes;
    	u64		attributes_mask;
    #define KSTAT_ATTR_FS_IOC_FLAGS				
    	(STATX_ATTR_COMPRESSED |			
    	 STATX_ATTR_IMMUTABLE |				
    	 STATX_ATTR_APPEND |				
    	 STATX_ATTR_NODUMP |				
    	 STATX_ATTR_ENCRYPTED				
    	 )/* Attrs corresponding to FS_*_FL flags */
    	u64		ino;
    	dev_t		dev;
    	dev_t		rdev;
    	kuid_t		uid;
    	kgid_t		gid;
    	loff_t		size;
    	struct timespec64 atime;
    	struct timespec64 mtime;
    	struct timespec64 ctime;
    	struct timespec64 btime;			/* File creation time */
    	u64		blocks;
    };
    

    在inode中i_mapping指向该inode相关的页缓存的地址空间,内核中用address_space结构表示地址空间这一概念,nrpages成员表示缓存页的总数,PAGE_SHIFT在page.h中,页大小为4KB,PAGE_SHIFT为12,这行代码修改了一下stat->blocks的值,可能的意思是,stat->blocks表示的是文件用块表示的最大长度,但是这个9具体指什么还暂时不清楚。

    以上就是getattr成员的函数解析,总体上来看就是填充了一个kstat结构,根据ppt上给出的预期结果,ls命令涉及的系统调用很可能需要getattrkstat结构的支持。

    结果和问题

    可见,ls命令可以正常使用。

    问题:touch命令有时会出现问题,而且与材料给出的预期结果不一致,touch命令也可以正常使用。而且时间戳的获取还是存在问题,目前使用的是:

    struct timespec64 ts;
    ktime_get_ts64(&ts);
    inode->i_mtime = ts;
    

    还是不能获取正确的时间戳。

  • 相关阅读:
    ASP.NET MVC案例——————拦截器
    Windows Azure Virtual Network (10) 使用Azure Access Control List(ACL)设置客户端访问权限
    Windows Azure Storage (20) 使用Azure File实现共享文件夹
    Windows Azure HandBook (5) Azure混合云解决方案
    Windows Azure Service Bus (6) 中继(Relay On) 使用VS2013开发Service Bus Relay On
    Azure PowerShell (9) 使用PowerShell导出订阅下所有的Azure VM的Public IP和Private IP
    Windows Azure Service Bus (5) 主题(Topic) 使用VS2013开发Service Bus Topic
    Azure China (9) 在Azure China配置CDN服务
    Windows Azure Storage (19) 再谈Azure Block Blob和Page Blob
    Windows Azure HandBook (4) 分析Windows Azure如何处理Session
  • 原文地址:https://www.cnblogs.com/LuoboLiam/p/14361588.html
Copyright © 2020-2023  润新知