(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) |