#include <linux/namei.h>
//filename: "/dev/rtc"
char * getname(const char __user * filename)
{
char *tmp, *result;
result = ERR_PTR(-ENOMEM);
tmp = __getname(); //分配内存用于存储文件的路径名
if (tmp) {
int retval = do_getname(filename, tmp);//调完后:tmp="/dev/rtc"
result = tmp;
if (retval < 0) {
__putname(tmp);
result = ERR_PTR(retval);
}
}
//... ...
return result;
}
static int do_getname(const char __user *filename, char *page)
{
int retval;
unsigned long len = PATH_MAX;
//... ...
retval = strncpy_from_user(page, filename, len);//filename ==>page
if (retval > 0) {
if (retval < len)
return 0;
return -ENAMETOOLONG;
} else if (!retval)
retval = -ENOENT;
return retval;
}
/*
* open_namei()
*
* namei for open - this is in fact almost the whole open-routine.
*
* Note that the low bits of "flag" aren't the same as in the open
* system call - they are 00 - no permissions needed
* 01 - read permission needed
* 10 - write permission needed
* 11 - read/write permissions needed
* which is a lot more logical, and also allows the "no perm" needed
* for symlinks (where the permissions are checked later).
* SMP-safe
*/
int open_namei(..., const char *pathname, int flag, int mode, struct nameidata *nd)
{
int acc_mode, error;
struct path path;
struct dentry *dir;
int count = 0;
//... ...
if (flag & O_TRUNC)
acc_mode |= MAY_WRITE;
if (flag & O_APPEND)
acc_mode |= MAY_APPEND;
/*
* The simplest case - just a plain lookup.
*/
if (!(flag & O_CREAT)) {//若文件存在则打开,不存在则出错而不创建
// 找到此文件 后,将相关信息写入nd
error = path_lookup_open(..., pathname, lookup_flags(flag), nd, flag);
if (error)
return error;
goto ok;
}
//若文件存在则打开,不存在则创建,找到后或创建了
//将相关信息写入nd
error = path_lookup_create(...,pathname,LOOKUP_PARENT,nd,flag,mode);
if (error)
return error;
error = -EISDIR;
if (nd->last_type != LAST_NORM || ...) //打开的是个目录而非文件
goto exit;
dir = nd->dentry;
nd->flags &= ~LOOKUP_PARENT;
mutex_lock(&dir->d_inode->i_mutex);//文件 已找到或已创建,对其加锁开始操作
path.dentry = lookup_hash(nd);
path.mnt = nd->mnt;
//... ...
/*
* It already exists.
*/
mutex_unlock(&dir->d_inode->i_mutex);
//... ...
ok:
error = may_open(nd, acc_mode, flag);
if (error)
goto exit;
return 0;
// ... ...
exit:
//... ...
return error;
// ... ...
}
int may_open(struct nameidata *nd, int acc_mode, int flag)
{
struct dentry *dentry = nd->dentry;
struct inode *inode = dentry->d_inode;
int error;
if (!inode)
return -ENOENT;
if (S_ISLNK(inode->i_mode))
return -ELOOP;
if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)) //目录无法本身是无法写入
return -EISDIR;
error = vfs_permission(nd, acc_mode);
if (error)
return error;
/*
* FIFO's, sockets and device files are special: they don't
* actually live on the filesystem itself, and as such you
* can write to them even if the filesystem is read-only.
*/
if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
flag &= ~O_TRUNC;
} else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
if (nd->mnt->mnt_flags & MNT_NODEV)
return -EACCES;
flag &= ~O_TRUNC;
} else if (IS_RDONLY(inode) && (flag & FMODE_WRITE)) //只读文件 不能写
return -EROFS;
/*
* An append-only file must be opened in append mode for writing.
*/
if (IS_APPEND(inode)) {
//... ...
if (flag & O_TRUNC)
return -EPERM;
}
//... ...
if (flag & O_TRUNC) {
error = get_write_access(inode);
if (error)
return error;
//... ...
} else
//... ...
return 0;
}
//首先nd设置为起始目录的相关信息,路径以/号分隔,从路径中
//分享出一个目录项,然后到nd->dentry的子目录项中去搜索
//如果找到了调用path_to_nameidata()让nd前进一步
static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
{
dput(nd->dentry);//老的释放
//... ...
nd->mnt = path->mnt;
nd->dentry = path->dentry;//推进一步
}
static inline int lookup_flags(unsigned int f)
{
unsigned long retval = LOOKUP_FOLLOW;
if (f & O_NOFOLLOW)
retval &= ~LOOKUP_FOLLOW;
if (f & O_DIRECTORY)
retval |= LOOKUP_DIRECTORY;
return retval;
}
int get_write_access(struct inode * inode)
{
spin_lock(&inode->i_lock);
if (atomic_read(&inode->i_writecount) < 0) {
spin_unlock(&inode->i_lock);
return -ETXTBSY;
}
atomic_inc(&inode->i_writecount);
spin_unlock(&inode->i_lock);
return 0;
}
int vfs_permission(struct nameidata *nd, int mask)
{
return permission(nd->dentry->d_inode, mask, nd);
}
int permission(struct inode *inode, int mask, struct nameidata *nd)
{
int retval;
//... ...
if (inode->i_op && inode->i_op->permission)
retval = inode->i_op->permission(inode, ..., nd);
else
retval = generic_permission(inode, ..., NULL);
if (retval)
return retval;
... ...
}
/**
* path_lookup_open - lookup a file path with open intent
* @dfd: the directory to use as base, or AT_FDCWD
* @name: pointer to file name
* @lookup_flags: lookup intent flags
* @nd: pointer to nameidata
* @open_flags: open intent flags
*/
//name: "/dev/rtc"
//open_flags: O_RDONLY
int path_lookup_open(..., const char *name, unsigned int lookup_flags,
struct nameidata *nd, int open_flags)
{
return __path_lookup_intent_open(..., name, lookup_flags, nd, open_flags, 0);
}
static int __path_lookup_intent_open(..., const char *name,
unsigned int lookup_flags, struct nameidata *nd,
int open_flags, int create_mode)
{
int err;
//... ...
err = do_path_lookup(..., name, lookup_flags|LOOKUP_OPEN, nd);
if (IS_ERR(nd->intent.open.file)) {
//处理错误
}
//...
return err;
}
/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
//name: "/dev/rtc"
//flags: O_RDONLY|LOOKUP_OPEN
static int fastcall do_path_lookup(..., const char *name,
unsigned int flags, struct nameidata *nd)
{
int retval = 0;
int fput_needed;
struct file *file;
struct fs_struct *fs = current->fs;//拿到当前进程所在的文件系统数据结构
//init nd{}
nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags;
nd->depth = 0;
if (*name=='/') {//"/dev/rtc" ==>以"/"开头的是绝对路径
read_lock(&fs->lock);
//... ...
nd->mnt = mntget(fs->rootmnt);
nd->dentry = dget(fs->root);
read_unlock(&fs->lock);
} else if (dfd == AT_FDCWD) { //"./rtc" |"rtc/"==>用相对当前路径
read_lock(&fs->lock);
nd->mnt = mntget(fs->pwdmnt);
nd->dentry = dget(fs->pwd);
read_unlock(&fs->lock);
} else {
//... ...
}
current->total_link_count = 0;
retval = link_path_walk(name, nd);
//... ...
}
int fastcall link_path_walk(const char *name, struct nameidata *nd)
{
struct nameidata save = *nd;
int result;
//... ...
result = __link_path_walk(name, nd);
//... ...
return result;
}
/*
* Name resolution.
* This is the basic name resolution function, turning a pathname into
* the final dentry. We expect 'base' to be positive and a directory.
*
* Returns 0 and nd will have valid dentry and mnt on success.
* Returns error and drops reference to input namei data on failure.
*/
//name:/dev/rtc
//nd:当前进程所在的文件系统的绝对路径对应的信息:目录项及挂载点
static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
{
struct path next;
struct inode *inode;
int err;
unsigned int lookup_flags = nd->flags;
while (*name=='/') // ==>//////dev/rtc ==> OK
name++;
if (!*name) //==>//////////
goto return_reval;
inode = nd->dentry->d_inode;
//... ...
没有合适的资源?快使用搜索试试~ 我知道了~
file-open-driver.rar_linux 打开 文件_open
共92个文件
h:42个
c:17个
sample:10个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 174 浏览量
2022-09-24
02:33:57
上传
评论
收藏 66KB RAR 举报
温馨提示
linux kernel 文件打开与驱动的关联微架构
资源详情
资源评论
资源推荐
收起资源包目录
file-open-driver.rar (92个子文件)
文件打开架构
schdule.c 6KB
.git
index 959B
hooks
prepare-commit-msg.sample 1KB
post-receive.sample 552B
applypatch-msg.sample 452B
pre-commit.sample 2KB
post-commit.sample 160B
pre-applypatch.sample 398B
commit-msg.sample 894B
pre-rebase.sample 5KB
update.sample 4KB
post-update.sample 189B
config 215B
description 73B
refs
tags
heads
master 41B
logs
refs
heads
master 145B
HEAD 145B
objects
4b
825dc642cb6eb9a060e54bf8d69288fbee4904 15B
71
15a8f210ff9897d345c5bdfdbe1ff3e928ab5a 211B
5c
b1d780f56466be044831626f755c9a9f3a255a 691B
a8
152301036e5141e8d6a4da3fcc9152ad7134fb 731B
6d
51b7ed64d81f71874fb30df2d30f0e33a61587 87B
info
2e
49957766bb6267d3d6df3268749a9a2eb7d963 144B
d8
dec641f0298c98b6366e81c34dc9207ed6b3ce 86B
pack
25
ca2917b93cd684bb86fc427b0091c796b1fd44 3KB
63
7217586d9b6dbcf5450d251e6e2721216ab28c 363B
c3
ce61e74f81186091ea52a98cce85691683f3e5 763B
3a
a913725920eb86344553f6c0f6c7848a875696 249B
93
50c33a4ff0122ecd592fdb2d43142beeac406b 204B
1d
77c406a3df597ec26383df3683e2798b9d22a2 118B
32
a77aa75bba4aee68bea373a778bc4091a5b848 154B
f1
00edb491626e9d7176810d96af8bc7185642e1 78B
info
exclude 240B
HEAD 23B
drivers
base
bus.c 987B
core.c 6KB
char
misc.c 2KB
mm
vmstat.c 49B
include
asm-arm
thread_info.h 2KB
page.h 356B
types.h 959B
posix_types.h 499B
param.h 902B
fcntl.h 186B
errno.h 430B
current.h 334B
asm-generic
errno-base.h 2KB
resource.h 93B
fcntl.h 519B
errno.h 5KB
linux
namei.h 1006B
mount.h 808B
vmstat.h 157B
hash.h 924B
file.h 713B
preempt.h 625B
ext2_fs.h 2KB
kernel.h 366B
cdev.h 165B
kdev_t.h 316B
fs.h 8KB
fs_struct.h 215B
types.h 814B
compiler-gcc4.h 476B
err.h 751B
rtc.h 611B
compiler-gcc.h 802B
limits.h 248B
smp.h 179B
irqreturn.h 594B
miscdevice.h 303B
errno.h 432B
linkage.h 257B
mmzone.h 575B
swap.h 60B
sched.h 2KB
stat.h 958B
dcache.h 2KB
time.h 347B
compiler.h 4KB
fs
inode.c 7KB
open.c 5KB
ioctl.c 1KB
file_table.c 249B
namei.c 16KB
dcache.c 7KB
file.c 2KB
arch
arm
mach-s3c6410
plat-s3c6410.c 393B
mach-s3c6410.c 98B
time-s3c64xx.c 497B
kernel
time.c 499B
kernel
time.c 2KB
共 92 条
- 1
局外狗
- 粉丝: 64
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- tensorflow-gpu-2.7.4-cp37-cp37m-manylinux2010-x86-64.whl
- 多段线、 圆、弧转多段线(仅我可见)
- tensorflow-2.7.2-cp38-cp38-manylinux2010-x86-64.whl
- yeyue-p8Yi4-ve4a83792.apk
- tensorflow-gpu-2.7.3-cp38-cp38-manylinux2010-x86-64.whl
- 五相感应电机矢量控制模型MATLAB
- RGLED (1) (1).circ
- IMG_20240427_215747.jpg
- python下前端WEB学习笔记
- 田间种植行排号自动生成工具
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0