• rename系统调用的实现浅析


         rename系统调用用于在同一个文件系统中做文件的rename操作。如果源和目的在不同mount点上,rename会返回错误EXDEV。

         rename系统调用的实现入口在./fs/namei.c中:

    SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname)
    {
            return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname);
    }
    

      可以看到,它实际上是转调用了renameat系统调用。renameat系统调用的实现也在./fs/namei.c中,它的函数定义是:

    SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
                    int, newdfd, const char __user *, newname);

    下面是它的具体实现:

    1,对oldname和newname分别做目录查找,得到它们对应的nameidata数据结构oldnd和newnd。这个过程会涉及到查找目录项缓存,如果目录不在目录项缓存中,需要将目录从磁盘读取到目录项缓存中,具体细节见这里:http://www.cnblogs.com/cobbliu/p/4888751.html。

    2,查看oldnd和newnd的mount点是否一样,不一样则返回EXDEV

    3,做一堆其他的验证和准备工作,这个过程中会找到oldname的old_dir的inode和old_dentry,newname的new_dir的inode和new_dentry

    4,调用VFS层的error = vfs_rename(old_dir->d_inode, old_dentry, new_dir->d_inode, new_dentry);

    int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)的实现:

    1,如果目的和源的inode一样,则返回0

    2,查看是否需要删除old_dentry和是否需要新建new_dentry

    3,如果old_dentry是个目录则调用vfs_rename_dir,否则调用vfs_rename_other

    static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,struct inode *new_dir, struct dentry *new_dentry)的实现:

    1,调用dget(new_dentry)

    2,调用old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);做真正的rename操作

    3,调用dput(new_dentry)

    ext4_rename函数真正实现了rename过程,ext4_rename实际上是讲旧目录文件中的文件项的refcount递减,然后在新目录文件中加入新文件名的目录项,并不会移动实际的数据文件,也不会修改数据文件的inode号。

    /proc/sys/fs/dentry_state显示目录项高速缓存的一些信息:

    • nr_dentry - number of dentries currently allocated
    • nr_unused - nuber of unused dentries
    • age_limit - seconds after the entry may be reclaimed, when memory is short
    • remaining - reserved.

    通常linux文件系统中目录项高速缓存的age_limit是45s,也就是说该目录项在目录项高速缓存中停留45s还无访问,就将它换出。

    http://www.linuxinsight.com/proc_sys_fs_dentry_state.html

  • 相关阅读:
    JS解析XML文件和XML字符串
    查询优化的方法
    Oracle 常用操作
    取得同一网段内的IP和MAC地址!
    域名知多少?
    Oracle 数据库链路 同义词
    提高查询速度的方法【百万级以上数据】
    ExtJs学习之路从Grid中得到数据
    一个左边停靠且可以展开和隐藏的菜单【Jquery插件】
    Go流程控制
  • 原文地址:https://www.cnblogs.com/cobbliu/p/5744078.html
Copyright © 2020-2023  润新知