Chinaunix首页 | 论坛 | 博客
  • 博客访问: 38940
  • 博文数量: 5
  • 博客积分: 70
  • 博客等级: 民兵
  • 技术积分: 106
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-01 11:42
文章分类
文章存档

2017年(2)

2013年(2)

2012年(1)

我的朋友

分类: LINUX

2017-04-06 22:22:27

(1)调用路径:sys_symlink->vfs_symlink->ext2_symlink
(2)代码
asmlinkage long sys_symlink(const char * oldname, const char * newname)
{
    int error = 0;
    char * from;
    char * to;

    from = getname(oldname);//原文件名
    if(IS_ERR(from))
        return PTR_ERR(from);
    to = getname(newname); //新文件名
    error = PTR_ERR(to);
    if (!IS_ERR(to)) {
        struct dentry *dentry;
        struct nameidata nd;

        if (path_init(to, LOOKUP_PARENT, &nd))
            error = path_walk(to, &nd); //新文件路径
        if (error)
            goto out;
        dentry = lookup_create(&nd, 0); //创建目录项结构
        error = PTR_ERR(dentry);
        if (!IS_ERR(dentry)) {
            error = vfs_symlink(nd.dentry->d_inode, dentry, from); //建立符号链接
            dput(dentry);
        }
        up(&nd.dentry->d_inode->i_sem);
        path_release(&nd);
out:
        putname(to);
    }
    putname(from);
    return error;
}
//dir:目标目录节点  dentry:目标文件目录项  oldname:源文件名(包含路径)
int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
{
    int error;

    down(&dir->i_zombie);
    error = may_create(dir, dentry);
    if (error)
        goto exit_lock;

    error = -EPERM;
    if (!dir->i_op || !dir->i_op->symlink)
        goto exit_lock;

    DQUOT_INIT(dir);
    lock_kernel();
    error = dir->i_op->symlink(dir, dentry, oldname);//调用ext2_symlink
    unlock_kernel();

exit_lock:
    up(&dir->i_zombie);
    if (!error)
        inode_dir_notify(dir, DN_CREATE);
    return error;
}
//创建ext2文件系统的符号链接
static int ext2_symlink (struct inode * dir, struct dentry * dentry,
    const char * symname)
{
    struct super_block * sb = dir->i_sb;
    int err = -ENAMETOOLONG;
    unsigned l = strlen(symname)+1; //符号链接字符串长度
    struct inode * inode;

    if (l > sb->s_blocksize)
        goto out;
         //创建i节点
    inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
    err = PTR_ERR(inode);
    if (IS_ERR(inode))
        goto out;
        //如果i节点的数据块号数组(15项,60字节)中放不下符号链接指向的路径,就放在前n个数据块中,n=ceil((路径长度+1)/4096)
    if (l > sizeof (inode->u.ext2_i.i_data)) {
        /* slow symlink */
        inode->i_op = &page_symlink_inode_operations;
        inode->i_mapping->a_ops = &ext2_aops;
        err = block_symlink(inode, symname, l);
        if (err)
            goto out_fail;
    } else { //否则放在数据块号数组中
        /* fast symlink */
        inode->i_op = &ext2_fast_symlink_inode_operations;
//inode->u.ext2_i.i_data指向的数组用来指示文件数据块分布,共15项,每项4字节。前12项是文件的前12个块的块号,第13项是1级块表的块号、第14项是2级间接块表块号,第15项是3级间接块表的块号。
        memcpy((char*)&inode->u.ext2_i.i_data,symname,l);
        inode->i_size = l-1;
    }
    mark_inode_dirty(inode); //节点置为脏

    err = ext2_add_nondir(dentry, inode);
out:
    return err;

out_fail:
    ext2_dec_count(inode);
    iput (inode);
    goto out;
}

阅读(2568) | 评论(0) | 转发(0) |
0

上一篇:Linux内核2.4.18创建硬链接的系统调用sys_link

下一篇:没有了

给主人留下些什么吧!~~