📄 namei.c
字号:
/////////////////////////////////////////////////////////////////////
#include "general.h"
#include "s_isdirreg.h"
#include "hd_info_struct.h"
#include "dir_entry.h"
#include "msdos_dir_entry.h"
#include "d_inode.h"
#include "m_inode.h"
#include "buffer_head.h"
#include "fat_cache.h"
#include "file.h"
#include "hd_request_struct.h"
#include "super_block.h"
#include "common_head.h"
/////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
int match(int len,const char * name,struct dir_entry * de){ int same; if ((!de) || (!de->inode) || (len == 0) || (len > NAME_LEN)) return 0; if (len < NAME_LEN && de->name[len]) return 0; __asm__("cld\n\t" "gs ; repe ; cmpsb\n\t" "setz %%al" :"=a" (same) :"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len)); return same;}struct buffer_head * find_entry(struct m_inode * dir, const char * name, int namelen, struct dir_entry ** res_dir){ struct buffer_head * bh; struct dir_entry * de;
int entries,i,block,new_block_flag;
*res_dir = NULL;
if ((namelen == 0) || (namelen > NAME_LEN)) return NULL;
if (!(block = dir->i_zone[0])) return NULL; if (!(bh = bread(dir->i_dev,block,0))) return NULL;
de = (struct dir_entry *) bh->b_data;
new_block_flag = 0;
entries = dir->i_size / (sizeof (struct dir_entry));
i = 0; while (i < entries) { if ((new_block_flag) || ((char *)de >= (char *)(bh->b_data + BLOCK_SIZE))) { brelse(bh); bh = NULL; if (!(block = bmap(dir , i / DIR_ENTRIES_PER_BLOCK))){
i += DIR_ENTRIES_PER_BLOCK;
new_block_flag = 1;
continue;
}
if (!(bh = bread(dir->i_dev,block,0)))
return NULL;
de = (struct dir_entry *) bh->b_data;
new_block_flag = 0; } if (match(namelen,name,de)) { *res_dir = de; return bh; } de++; i++; } brelse(bh); return NULL;}struct buffer_head * add_entry(struct m_inode * dir, const char * name, int namelen, struct dir_entry ** res_dir){ struct buffer_head * bh; struct dir_entry * de; int i,block;
*res_dir = NULL; if ((namelen == 0) || (namelen > NAME_LEN)) return NULL; if (!(block = dir->i_zone[0])) return NULL; if (!(bh = bread(dir->i_dev,block,0))) return NULL;
de = (struct dir_entry *) bh->b_data;
i = 0; while (1) { if ((char *)de >= (char *)(bh->b_data + BLOCK_SIZE)) { brelse(bh); bh = NULL; block = create_block(dir,i / DIR_ENTRIES_PER_BLOCK); if (!block) return NULL;
if (!(bh = bread(dir->i_dev,block,0)))
return NULL; de = (struct dir_entry *) bh->b_data; } if (i * sizeof(struct dir_entry) >= dir->i_size) { de->inode=0; dir->i_size = (i + 1) * sizeof(struct dir_entry); dir->i_mtime = file_datetime;
dir->i_dirt = 1; } if (!de->inode) { for (i = 0; i < NAME_LEN ; i++) de->name[i] = (i < namelen)? get_gs_byte(name + i) : 0; bh->b_dirt = 1; *res_dir = de; return bh; } de++; i++; } brelse(bh); return NULL;}struct m_inode * get_dir(const char * pathname){
struct m_inode * inode; struct buffer_head * bh;
struct dir_entry * de;
const char * thisname;
char c; int idev,inr,namelen;
int i; if ((!current_root) || (!current_root->i_count) || (!current_pwd) || (!current_pwd->i_count)) return NULL; if ((c = get_gs_byte(pathname)) == '\\') { inode = current_root; pathname++;
for (i = 0; i <= current_root_pathlength; i++)
current_path[i] = current_root_path[i];
current_pathlength = current_root_pathlength; } else if (c) { inode = current_pwd;
for (i = 0; i <= current_pwd_pathlength; i++)
current_path[i] = current_pwd_path[i];
current_pathlength = current_pwd_pathlength;
} else return NULL;
inode->i_count++; while (1) { thisname = pathname; if (!S_ISDIR(inode->i_mode)) { iput(inode); return NULL; } for(namelen = 0 ; (c = get_gs_byte(pathname++)) && (c != '\\') ; namelen++)
current_path[current_pathlength + namelen + 1] = c;
current_path[current_pathlength + namelen + 1] = c;
if (!c) return inode; if (!(bh = find_entry(inode,thisname,namelen,&de))) { iput(inode); return NULL; } inr = de->inode; idev = inode->i_dev; brelse(bh); iput(inode);
if ((current_path[current_pathlength + 1] == '.') && (current_path[current_pathlength + 2] == '\\'))
{}
else if ((current_path[current_pathlength + 1] == '.') && (current_path[current_pathlength + 2] == '.') &&
(current_path[current_pathlength + 3] == '\\'))
current_pathlength = current_path[current_pathlength];
else
{
current_path[current_pathlength + namelen + 1] = current_pathlength;
current_pathlength = current_pathlength + namelen + 1;
}
if (!(inode = iget(idev,inr))) return NULL; }
return NULL;}struct m_inode * dir_namei(const char * pathname, int * namelen, const char ** name){ struct m_inode * dir;
const char * basename;
char c; if (!(dir = get_dir(pathname))) return NULL; basename = pathname; while ((c = get_gs_byte(pathname++)) != 0) if (c == '\\') basename = pathname;
*namelen = (int)(pathname - basename - 1); *name = basename; return dir;}struct m_inode * namei(const char * pathname){ struct m_inode * dir; struct buffer_head * bh; struct dir_entry * de; const char * basename;
int idev,inr,namelen;
if (!(dir = dir_namei(pathname,&namelen,&basename))) return NULL; if (!namelen) /* special case: '/usr/' etc */ return dir; bh = find_entry(dir,basename,namelen,&de); if (!bh) { iput(dir); return NULL; } idev = dir->i_dev;
inr = de->inode; brelse(bh); iput(dir);
if ((current_path[current_pathlength + 1] == '.') && (current_path[current_pathlength + 2] == 0))
{}
else if ((current_path[current_pathlength + 1] == '.') && (current_path[current_pathlength + 2] == '.') &&
(current_path[current_pathlength + 3] == 0))
current_pathlength = current_path[current_pathlength];
else
{
current_path[current_pathlength + namelen + 1] = current_pathlength;
current_pathlength = current_pathlength + namelen + 1;
}
dir = iget(idev,inr); return dir;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -