/*由文件名字得到文件的inode节点,如果成功解析则返回1,且相应节点数据写入m_inode中,解析失败则返回-1*/ int name_to_inode(char *path,struct inode *m_inode){ unsigned int cur_inode_num; char *ptoken; /*囧对路径,从根节点开始解析*/ if(*path == '/'){ ptoken = strtok(path,"/"); cur_inode_num = 0;/*从根节点开始*/ while(ptoken != NULL){ //printf("%s\n",ptoken); if((cur_inode_num=namei(ptoken,cur_inode_num)) == -1){ printf("no such file or dir!\n"); return -1; } ptoken = strtok(NULL,"/"); } get_inode_data(cur_inode_num,m_inode); return 1; } /*相对路径*/ else if((*path == '.' & *(path+1) == '/') || (*path != '.' && *path != '/')){ ptoken = strtok(path,"./"); cur_inode_num = pwd.i_number;/*从当前节点开始*/ while(ptoken != NULL){ //printf("%s\n",ptoken); if((cur_inode_num=namei(ptoken,cur_inode_num)) == -1){ printf("no such file or dir!\n"); return -1; } ptoken = strtok(NULL,"/"); } get_inode_data(cur_inode_num,m_inode); return 1; } }
/*寻找当前节点号中是否含有名字为name的项目,如果有则返回name项目的i节点号,没有则返回-1*/ int namei(char *name, unsigned int cur_inode_num){ struct ext2_inode *current_inode; if((current_inode=malloc(sizeof(struct ext2_inode))) == NULL){ perror("namei.c: fail to malloc inode\n"); exit(EXIT_FAILURE); } get_inode_data(cur_inode_num,current_inode); char buf[BLOCK_SIZE]; struct ext2_dir_entry_2 *pentry; int dir_datablocks = current_inode->i_blocks;/*数据块个数*/ int i = 1; while(i <= dir_datablocks){ /*取出目录节点中第i块逻辑块所在的物理块的数据,放入buf*/ get_block_data(current_inode->i_block[i],buf); pentry = (struct ext2_dir_entry_2 *)buf; int j = 0; int num = BLOCK_SIZE/sizeof(struct ext2_dir_entry_2); /*比较每一项*/ while(j<num){ /*比较pentry->inode不为0的每一项*/ if(pentry->inode && !strcmp(&(pentry->name[0]),name)){ return pentry->inode; } j++; pentry++; } i++; } free(current_inode); return -1; }
static int gfs_fill_super_info(struct gfs_super_info *si, u32 ino) { struct gfs_inode_info *inode; struct gfs_super *raw; struct buffer_head *bh; int err; mutex_init(&si->s_mutex); inode = gfs_iget_info(si->s_vfs_sb, ino); PDEBUG("ino=%d PTR_ERR=%li\n", (int) ino, (long)PTR_ERR(inode)); if (IS_ERR(inode)) return PTR_ERR(inode); si->s_super_inode = inode; bh = get_inode_data(inode,0); if(!bh) return -EIO; MARK(); raw = (struct gfs_super *) (bh->b_data + sizeof(struct gfs_inode)); err = init_super_from_raw(si, raw); put_inode_data(inode,0); return err; }
int gfs_write_inode(struct inode *inode, struct writeback_control *wbc) { struct gfs_inode_info *gfs_inode = GFS_INODE(inode); struct gfs_inode *raw_inode; struct buffer_head *bh = get_inode_data(gfs_inode, 1); if(!bh) { PDEBUG("-EIO\n"); return -EIO; } raw_inode = (struct gfs_inode *)bh->b_data; if(inode->i_ino == 0) { struct gfs_super *raw_super = (struct gfs_super *) (bh->b_data + sizeof(struct gfs_inode)); init_raw_from_super(raw_super, inode->i_sb->s_fs_info); } gfs_init_raw_from_inode(raw_inode, gfs_inode); PDEBUG("Writing inode %ld %o %o\n", inode->i_ino, le32_to_cpu(raw_inode->i_mode), inode ->i_mode); sync_inode_data(gfs_inode); put_inode_data(gfs_inode, 1); return 0; }
struct inode *gfs_iget_new(struct gfs_super_info *sb) { struct gfs_inode_info *inode; bool err = 0; u32 ino = grab_free_ino(sb, &err); if(err) { gfs_info("No more free space\n"); return ERR_PTR(-ENOMEM); /* TODO: Really ENOMEM ?*/ } BUG_ON(!__is_bit_used(sb->s_inode_map, ino)); inode = gfs_iget_info(sb->s_vfs_sb, ino); if(IS_ERR(inode)) { PDEBUG("get info\n"); return ERR_CAST(inode); } BUG_ON(inode->vfs_inode.i_state & I_NEW); if(!get_inode_data(inode,1)) goto err; RAW_INODE(inode)->i_flags = cpu_to_le32(GI_INO_USED); RAW_INODE(inode)->i_nlink = cpu_to_le32(1); set_nlink(VFS_INODE(inode), 1); put_inode_data(inode, 1); gfs_dbg("New ino: %ld %i\n",VFS_INODE(inode)->i_ino, VFS_INODE(inode)->i_nlink); return VFS_INODE(inode); err: gfs_put_inode(inode); return ERR_PTR(-EIO); }
int gfs_junk_inode(struct gfs_inode *inode) { if(!get_inode_data(inode, 1)) return -ENOMEM; BUG_ON(inode->i_flags & GI_INO_JUNK); inode->i_flags |= GI_INO_JUNK; mark_inode_dirty(VFS_INODE(inode)); put_inode_data(inode, 1); return 0; }
static struct gfs_inode_info *gfs_iget_info(struct super_block *sb, u32 ino) { struct gfs_inode_info *gfs_inode; struct gfs_inode *raw_inode; struct buffer_head *bh; struct inode *vfs_inode; PDEBUG("ino=%d\n", (int)ino); vfs_inode = iget_locked(sb, ino); if(!vfs_inode) return ERR_PTR(-ENOMEM); gfs_inode = GFS_INODE(vfs_inode); if(vfs_inode->i_state & I_NEW) { bh = get_inode_data(gfs_inode, 0); if(!bh) { PDEBUG("IO\n"); return ERR_PTR(-EIO); } raw_inode = (struct gfs_inode*)bh->b_data; PDEBUG("Raw Inode %o\n", raw_inode->i_mode); gfs_init_inode_from_raw(gfs_inode, RAW_INODE(gfs_inode)); gfs_inode->i_ex_inode = NULL; gfs_inode->i_exino = 0xabcd; put_inode_data(gfs_inode, 0); unlock_new_inode(vfs_inode); } print_inode(gfs_inode); return gfs_inode; }
int create(struct inode *dir, const char *name, int len, int mode, struct inode ** res_inode){ /*判断目录是否有效*/ if(dir->ext2_inode.i_block[0] != UINT_MAX){ perror("inode_operations.c: create error! dir is a file!\n"); return -1; } /*判断名字是否有效*/ if(checkname(name) == -1){ perror("inode_operations.c: create error! filename is illegal!\n"); return -1; } /*判断是否已存在*/ if(is_exist(dir,name) == 1){ perror("inode_operations.c: create error! file is alreay exists!\n"); return -1; } char buf[BLOCK_SIZE]; struct ext2_dir_entry_2 *pentry; int dir_datablocks = dir->ext2_inode.i_blocks;/*数据块个数*/ int i = 1; int num = BLOCK_SIZE/sizeof(struct ext2_dir_entry_2); while(i <= dir_datablocks){ /*取出目录节点中第i块逻辑块所在的物理块的数据,放入buf*/ get_block_data(dir->ext2_inode.i_block[i],buf); pentry = (struct ext2_dir_entry_2 *)buf; /*寻找pentry->inode为0的每一项,表示未使用,填写目录项*/ //printf("inode_operations.c: create : dir_datablocks: %d\n",i); int j = 0; while(j<num){ //printf("inode_operations.c: create : entry: %d\n",j); if(!pentry->inode){ pentry->name_len = len; strcpy(pentry->name,name); pentry->file_type = mode; pentry->rec_len = 8 + len; pentry->inode = new_inode(); write_block_data(dir->ext2_inode.i_block[i],buf);//更新该数据块 *res_inode=(struct inode *)malloc(sizeof(struct inode)); if(*res_inode != NULL){ get_inode_data(pentry->inode,*res_inode); return 1; } } j++; pentry++; } i++; } /*数据块表项已满,则需申请新的数据块来存放新的目录项*/ if(dir_datablocks>=14){ perror("inode_operations.c create error! dir_entry is full,no more sub_dir!\n"); return -1; } dir_datablocks = ++(dir->ext2_inode.i_blocks); dir->ext2_inode.i_block[dir_datablocks] = new_block(); write_inode_data(dir->i_number,dir);//因为申请了新块,inode节点及时更新 get_block_data(dir->ext2_inode.i_block[dir_datablocks],buf); pentry = (struct ext2_dir_entry_2 *)buf; pentry->name_len = len; strcpy(pentry->name,name); pentry->file_type = mode; pentry->rec_len = 8 + len; pentry->inode = new_inode(); write_block_data(dir->ext2_inode.i_block[dir_datablocks],buf);//更新该数据块 if((*res_inode=(struct inode *)malloc(sizeof(struct inode))) != NULL){ get_inode_data(pentry->inode,*res_inode); return 1; } return -1; }
int mkdir(struct inode *dir, const char *name, int len, int mode){ /*判断目录是否有效*/ if(dir->ext2_inode.i_block[0] != UINT_MAX){ perror("inode_operations.c: mkdir error! dir is a file!\n"); return -1; } /*判断名字是否有效*/ if(checkname(name) == -1){ perror("inode_operations.c: mkdir error! dirname is illegal!\n"); return -1; } /*判断是否已存在*/ if(is_exist(dir,name) == 1){ perror("inode_operations.c: mkdir error! dirname is alreay exists!\n"); return -1; } char buf[BLOCK_SIZE]; struct inode *m_inode; struct ext2_dir_entry_2 *pentry; int dir_datablocks = dir->ext2_inode.i_blocks;/*数据块个数*/ int i = 1; int num = BLOCK_SIZE/sizeof(struct ext2_dir_entry_2); while(i <= dir_datablocks){ /*取出目录节点中第i块逻辑块所在的物理块的数据,放入buf*/ get_block_data(dir->ext2_inode.i_block[i],buf); pentry = (struct ext2_dir_entry_2 *)buf; /*寻找pentry->inode为0的每一项,表示未使用*/ int j = 0; while(j<num){ if(!pentry->inode){ pentry->name_len = len; strcpy(pentry->name,name); pentry->file_type = mode; pentry->rec_len = 8 + len; pentry->inode = new_inode(); write_block_data(dir->ext2_inode.i_block[i],buf);//更新该数据块 /*下面更新为目录项(文件夹)申请的inode节点信息,并为其预分配一块数据块,用于存放子目录或文件*/ if((m_inode=(struct inode*)malloc(sizeof(struct inode))) != NULL){ get_inode_data(pentry->inode,m_inode); m_inode->ext2_inode.i_block[0] = UINT_MAX;//表示该节点是目录节点 m_inode->ext2_inode.i_block[1] = new_block();//为每个目录节点预分配一块数据块,存放目录项 m_inode->ext2_inode.i_blocks = 1; write_inode_data(pentry->inode,m_inode); free(m_inode); return 1; } } j++; pentry++; } i++; } /*数据块表项已满,则需申请新的数据块来存放新的目录项*/ if(dir_datablocks>=14){ perror("inode_operations.c mkdir error! dir_entry is full,no more sub_dir!\n"); return -1; } dir_datablocks = ++dir->ext2_inode.i_blocks; dir->ext2_inode.i_block[dir_datablocks] = new_block(); write_inode_data(dir->i_number,dir);//因为申请了新块,inode节点及时更新 get_block_data(dir->ext2_inode.i_block[dir_datablocks],buf); pentry = (struct ext2_dir_entry_2 *)buf; pentry->name_len = len; strcpy(pentry->name,name); pentry->file_type = mode; pentry->rec_len = 8 + len; pentry->inode = new_inode(); write_block_data(dir->ext2_inode.i_block[dir_datablocks],buf);//更新该数据块 if((m_inode=(struct inode*)malloc(sizeof(struct inode))) != NULL){ get_inode_data(pentry->inode,m_inode); m_inode->ext2_inode.i_block[0] = UINT_MAX;//表示该节点是目录节点 m_inode->ext2_inode.i_block[1] = new_block();//为每个目录节点预分配一块数据块,存放目录项 m_inode->ext2_inode.i_blocks = 1; write_inode_data(pentry->inode,m_inode); free(m_inode); return 1; } return -1; }
static int put_inode_data( struct m_inode *inode ) { struct buffer_head *bh = get_inode_data( inode->dev, inode->inode_num ); return bwrite( bh ); }