📄 namei.c
字号:
return error;
}
inode->i_dirt = 1;
}
*res_inode = inode;
return 0;
}
int do_mknod(const char * filename, int mode, dev_t dev)
{
const char * basename;
int namelen, error;
struct inode * dir;
mode &= ~current->umask;
error = dir_namei(filename,&namelen,&basename, NULL, &dir);
if (error)
return error;
if (!namelen) {
iput(dir);
return -ENOENT;
}
if (IS_RDONLY(dir)) {
iput(dir);
return -EROFS;
}
if (!permission(dir,MAY_WRITE | MAY_EXEC)) {
iput(dir);
return -EACCES;
}
if (!dir->i_op || !dir->i_op->mknod) {
iput(dir);
return -EPERM;
}
down(&dir->i_sem);
error = dir->i_op->mknod(dir,basename,namelen,mode,dev);
up(&dir->i_sem);
return error;
}
asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev)
{
int error;
char * tmp;
if (S_ISDIR(mode) || (!S_ISFIFO(mode) && !suser()))
return -EPERM;
switch (mode & S_IFMT) {
case 0:
mode |= S_IFREG;
break;
case S_IFREG: case S_IFCHR: case S_IFBLK: case S_IFIFO:
break;
default:
return -EINVAL;
}
error = getname(filename,&tmp);
if (!error) {
error = do_mknod(tmp,mode,dev);
putname(tmp);
}
return error;
}
static int do_mkdir(const char * pathname, int mode)
{
const char * basename;
int namelen, error;
struct inode * dir;
error = dir_namei(pathname,&namelen,&basename,NULL,&dir);
if (error)
return error;
if (!namelen) {
iput(dir);
return -ENOENT;
}
if (IS_RDONLY(dir)) {
iput(dir);
return -EROFS;
}
if (!permission(dir,MAY_WRITE | MAY_EXEC)) {
iput(dir);
return -EACCES;
}
if (!dir->i_op || !dir->i_op->mkdir) {
iput(dir);
return -EPERM;
}
down(&dir->i_sem);
error = dir->i_op->mkdir(dir,basename,namelen,mode);
up(&dir->i_sem);
return error;
}
asmlinkage int sys_mkdir(const char * pathname, int mode)
{
int error;
char * tmp;
error = getname(pathname,&tmp);
if (!error) {
error = do_mkdir(tmp,mode);
putname(tmp);
}
return error;
}
static int do_rmdir(const char * name)
{
const char * basename;
int namelen, error;
struct inode * dir;
error = dir_namei(name,&namelen,&basename,NULL,&dir);
if (error)
return error;
if (!namelen) {
iput(dir);
return -ENOENT;
}
if (IS_RDONLY(dir)) {
iput(dir);
return -EROFS;
}
if (!permission(dir,MAY_WRITE | MAY_EXEC)) {
iput(dir);
return -EACCES;
}
if (!dir->i_op || !dir->i_op->rmdir) {
iput(dir);
return -EPERM;
}
return dir->i_op->rmdir(dir,basename,namelen);
}
asmlinkage int sys_rmdir(const char * pathname)
{
int error;
char * tmp;
error = getname(pathname,&tmp);
if (!error) {
error = do_rmdir(tmp);
putname(tmp);
}
return error;
}
static int do_unlink(const char * name)
{
const char * basename;
int namelen, error;
struct inode * dir;
error = dir_namei(name,&namelen,&basename,NULL,&dir);
if (error)
return error;
if (!namelen) {
iput(dir);
return -EPERM;
}
if (IS_RDONLY(dir)) {
iput(dir);
return -EROFS;
}
if (!permission(dir,MAY_WRITE | MAY_EXEC)) {
iput(dir);
return -EACCES;
}
if (!dir->i_op || !dir->i_op->unlink) {
iput(dir);
return -EPERM;
}
return dir->i_op->unlink(dir,basename,namelen);
}
asmlinkage int sys_unlink(const char * pathname)
{
int error;
char * tmp;
error = getname(pathname,&tmp);
if (!error) {
error = do_unlink(tmp);
putname(tmp);
}
return error;
}
static int do_symlink(const char * oldname, const char * newname)
{
struct inode * dir;
const char * basename;
int namelen, error;
error = dir_namei(newname,&namelen,&basename,NULL,&dir);
if (error)
return error;
if (!namelen) {
iput(dir);
return -ENOENT;
}
if (IS_RDONLY(dir)) {
iput(dir);
return -EROFS;
}
if (!permission(dir,MAY_WRITE | MAY_EXEC)) {
iput(dir);
return -EACCES;
}
if (!dir->i_op || !dir->i_op->symlink) {
iput(dir);
return -EPERM;
}
down(&dir->i_sem);
error = dir->i_op->symlink(dir,basename,namelen,oldname);
up(&dir->i_sem);
return error;
}
asmlinkage int sys_symlink(const char * oldname, const char * newname)
{
int error;
char * from, * to;
error = getname(oldname,&from);
if (!error) {
error = getname(newname,&to);
if (!error) {
error = do_symlink(from,to);
putname(to);
}
putname(from);
}
return error;
}
static int do_link(struct inode * oldinode, const char * newname)
{
struct inode * dir;
const char * basename;
int namelen, error;
error = dir_namei(newname,&namelen,&basename,NULL,&dir);
if (error) {
iput(oldinode);
return error;
}
if (!namelen) {
iput(oldinode);
iput(dir);
return -EPERM;
}
if (IS_RDONLY(dir)) {
iput(oldinode);
iput(dir);
return -EROFS;
}
if (dir->i_dev != oldinode->i_dev) {
iput(dir);
iput(oldinode);
return -EXDEV;
}
if (!permission(dir,MAY_WRITE | MAY_EXEC)) {
iput(dir);
iput(oldinode);
return -EACCES;
}
if (!dir->i_op || !dir->i_op->link) {
iput(dir);
iput(oldinode);
return -EPERM;
}
down(&dir->i_sem);
error = dir->i_op->link(oldinode, dir, basename, namelen);
up(&dir->i_sem);
return error;
}
asmlinkage int sys_link(const char * oldname, const char * newname)
{
int error;
char * to;
struct inode * oldinode;
error = namei(oldname, &oldinode);
if (error)
return error;
error = getname(newname,&to);
if (error) {
iput(oldinode);
return error;
}
error = do_link(oldinode,to);
putname(to);
return error;
}
static int do_rename(const char * oldname, const char * newname)
{
struct inode * old_dir, * new_dir;
const char * old_base, * new_base;
int old_len, new_len, error;
error = dir_namei(oldname,&old_len,&old_base,NULL,&old_dir);
if (error)
return error;
if (!permission(old_dir,MAY_WRITE | MAY_EXEC)) {
iput(old_dir);
return -EACCES;
}
if (!old_len || (old_base[0] == '.' &&
(old_len == 1 || (old_base[1] == '.' &&
old_len == 2)))) {
iput(old_dir);
return -EPERM;
}
error = dir_namei(newname,&new_len,&new_base,NULL,&new_dir);
if (error) {
iput(old_dir);
return error;
}
if (!permission(new_dir,MAY_WRITE | MAY_EXEC)) {
iput(old_dir);
iput(new_dir);
return -EACCES;
}
if (!new_len || (new_base[0] == '.' &&
(new_len == 1 || (new_base[1] == '.' &&
new_len == 2)))) {
iput(old_dir);
iput(new_dir);
return -EPERM;
}
if (new_dir->i_dev != old_dir->i_dev) {
iput(old_dir);
iput(new_dir);
return -EXDEV;
}
if (IS_RDONLY(new_dir) || IS_RDONLY(old_dir)) {
iput(old_dir);
iput(new_dir);
return -EROFS;
}
if (!old_dir->i_op || !old_dir->i_op->rename) {
iput(old_dir);
iput(new_dir);
return -EPERM;
}
down(&new_dir->i_sem);
error = old_dir->i_op->rename(old_dir, old_base, old_len,
new_dir, new_base, new_len);
up(&new_dir->i_sem);
return error;
}
asmlinkage int sys_rename(const char * oldname, const char * newname)
{
int error;
char * from, * to;
error = getname(oldname,&from);
if (!error) {
error = getname(newname,&to);
if (!error) {
error = do_rename(from,to);
putname(to);
}
putname(from);
}
return error;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -