ext2文件系统源代码之ioctl.c

来源:互联网 发布:签收后淘宝介入 编辑:程序博客网 时间:2024/06/14 19:45
今天,我来说一个ext2文件系统源代码里比较简单的一个文件,ioctl.c,里边是做一些对于硬件设备的io指令相关的文件,一般来说,硬件设备的ioctl应该是极其复杂的文件,但是由于这里是ext2,是文件系统层,所以对于ioctl的操作不是很多。好啦,我们开始看吧。
/* 日常作者,还是那个人 * linux/fs/ext2/ioctl.c * * Copyright (C) 1993, 1994, 1995 * Remy Card (card@masi.ibp.fr) * Laboratoire MASI - Institut Blaise Pascal * Universite Pierre et Marie Curie (Paris VI) */#include "ext2.h"#include <linux/capability.h>#include <linux/time.h>#include <linux/sched.h>#include <linux/compat.h>#include <linux/smp_lock.h>#include <asm/current.h>#include <asm/uaccess.h>/*对ext2文件系统的文件进行ioctl操作*/int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,unsigned long arg){/*从vfs层的inode结构体获得内存存储ext2的inode信息的ext2_inode_info结构体*/struct ext2_inode_info *ei = EXT2_I(inode);unsigned int flags;ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg);switch (cmd) {/*要获得文件的flag*/case EXT2_IOC_GETFLAGS:/*之前讲过,把vfs的inode信息转化成ext2_inode_info结构体的,存在ei里*/ext2_get_inode_flags(ei);/*再与上EXT2_FL_USER_VISIBLE标志位,它代表用户可见,但不可修改*/flags = ei->i_flags & EXT2_FL_USER_VISIBLE;/*把flags放到用户空间传入的参数arg里*/return put_user(flags, (int __user *) arg);/*设置文件的flag*/case EXT2_IOC_SETFLAGS: {unsigned int oldflags;/*只读不可以修改flag*/if (IS_RDONLY(inode))return -EROFS;/*当前进程的文件执行时id不等于uid,说明不是文件主。变换身份后还没有修改权力,就返回权限不够*/if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))return -EACCES;/*得到用户想修改的值*/if (get_user(flags, (int __user *) arg))return -EFAULT;/*不是目录的话,不允许设置EXT2_DIRSYNC_FL位,这是专门为目录位的*/if (!S_ISDIR(inode->i_mode))flags &= ~EXT2_DIRSYNC_FL;mutex_lock(&inode->i_mutex);/*oldflags保存原来的flag*/oldflags = ei->i_flags;/* IMMUTABLE和APPEND_ONLY的修改必须有相应的权限,*/if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {if (!capable(CAP_LINUX_IMMUTABLE)) {mutex_unlock(&inode->i_mutex);return -EPERM;}}/*与上EXT2_FL_USER_MODIFIABLE,用户可修改位*/flags = flags & EXT2_FL_USER_MODIFIABLE;flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;/*ei指向新的flag*/ei->i_flags = flags;mutex_unlock(&inode->i_mutex);/*设置inode的flag*/ext2_set_inode_flags(inode);/*更新修改时间,标记inode脏*/inode->i_ctime = CURRENT_TIME_SEC;mark_inode_dirty(inode);return 0;}/*获得inode的版本号*/case EXT2_IOC_GETVERSION:return put_user(inode->i_generation, (int __user *) arg);/*设置inode版本号*/case EXT2_IOC_SETVERSION:/*和之前的一样,权限检查*/if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))return -EPERM;/*只读不可以*/if (IS_RDONLY(inode))return -EROFS;/*获得用户希望修改的值*/if (get_user(inode->i_generation, (int __user *) arg))return -EFAULT;/*修改时间,标记inode为脏*/inode->i_ctime = CURRENT_TIME_SEC;mark_inode_dirty(inode);return 0;default:return -ENOTTY;}}#ifdef CONFIG_COMPAT/*兼容性的ioctl函数,兼容以前的内核版本,以前传入的第一个参数是file结构体而不是inode结构体*/long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg){/*从file结构体获得inode指针*/struct inode *inode = file->f_path.dentry->d_inode;int ret;/*根据用户传入的cmd,除了非法的返回错误,否则都调用上边的函数*/switch (cmd) {case EXT2_IOC32_GETFLAGS:cmd = EXT2_IOC_GETFLAGS;break;case EXT2_IOC32_SETFLAGS:cmd = EXT2_IOC_SETFLAGS;break;case EXT2_IOC32_GETVERSION:cmd = EXT2_IOC_GETVERSION;break;case EXT2_IOC32_SETVERSION:cmd = EXT2_IOC_SETVERSION;break;default:return -ENOIOCTLCMD;}lock_kernel();ret = ext2_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));unlock_kernel();return ret;}#endif

0 0