Linux下mknod的作用,你需要了解linux中的mknod

一、源码分析:

mknod->系统调用->

/fs/namei.c

SYSCALL_DEFINE3(mknod, const char __user *, filename, int, mode, unsigned, dev)

{

return sys_mknodat(AT_FDCWD, filename, mode, dev);

}

SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, unsigned, dev)

{

int error;

char *tmp;

struct dentry *dentry;

struct nameidata nd;

...

error = user_path_parent(dfd, filename, &nd, &tmp);

...

dentry = lookup_create(&nd, 0);

...

if (!IS_POSIXACL(nd.path.dentry->d_inode)) mode &= ~current_umask();

error = may_mknod(mode);

...

error = mnt_want_write(nd.path.mnt);

...

error = security_path_mknod(&nd.path, dentry, mode, dev);

...

switch (mode & S_IFMT)

{

case 0: case S_IFREG:

error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);

break;

case S_IFCHR: case S_IFBLK:

error = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, new_decode_dev(dev));

break;

case S_IFIFO: case S_IFSOCK:

error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);

break;

}

...

}

使用new_decode_dev(dev)创建设备号

static inline dev_t new_decode_dev(u32 dev)

{

unsigned major = (dev & 0xfff00) >> 8;

unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);

return MKDEV(major, minor);

}

include\linux\types.h

typedef __kernel_dev_t  dev_t;

typedef __u32 __kernel_dev_t;

vfs_create():用于普通文件创建

vfs_mkdir():用于目录节点创建

vfs_mknod():用于特殊文件(FIFO、插口、字符设备文件、块设备文件)创建

/proc目录下的特殊文件,则由内核生成,非用户创建。

int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)

{

int error = may_create(dir, dentry);

...

if ((S_ISCHR(mode) || S_ISBLK(mode)) && !ns_capable(inode_userns(dir), CAP_MKNOD)) return -EPERM;

...

error = devcgroup_inode_mknod(mode, dev);

error = security_inode_mknod(dir, dentry, mode, dev);

error = dir->i_op->mknod(dir, dentry, mode, dev);

...

}

dir : innode结构指针,指向待创建设备文件的父节点,由path_walk()找到的。

dentry:指向代表着或将要代表待创建设备文件节点的目录项dentry结构,sys_mknod中lookup_create在内核dentry结构杂凑表中找到或创建

vfs_mknod是虚拟文件系统的mknod

下面还有诸如ext2、ext3、ext4、jffs、yaffs等实际文件系统,对应struct inode_operaTIons jfs_dir_inode_operaTIons

中的.mknod  = jfs_mknod,

staTIc int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)

{

...

struct inode *ip;

...

ip = ialloc(dir, mode);

...

init_special_inode(ip, ip->i_mode, rdev);

...

}

ialloc分配inode结构体,init_special_inode进行填充

/fs/inode.c

void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)

{

inode->i_mode = mode;

if (S_ISCHR(mode)) //字符设备

{

inode->i_fop = &def_chr_fops;

inode->i_rdev = rdev;

}

else if (S_ISBLK(mode)) //块设备

{

inode->i_fop = &def_blk_fops;

inode->i_rdev = rdev;

}

else if (S_ISFIFO(mode))//FIFO流设备

inode->i_fop = &def_fifo_fops;

else if (S_ISSOCK(mode))//网络设备

inode->i_fop = &bad_sock_fops;

else//未知设备提示

printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for inode %s:%lu\n", mode, inode->i_sb->s_id,inode->i_ino);

}

EXPORT_SYMBOL(init_special_inode);

函数设置file_operaTIon的i_fop和设备号i_rdev

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值