void hd_str(char *str) { for(; *str != '\0'; str++)// while character on given address is not EQ \0, send it, increase address and iterate! { if (*str == '\n') hd_newline(); hd_write(*str);//send character which is located on address called str here, *str gives valu (char) stored there } }
/** * \ingroup hashtable_private * * Writes the bucket list at its appropriate place in the dbm. * * \param hd Non-NULL pointer to an initialized hd_t structure. * \param buckets The bucket list of at least hd->header.nbuckets * sizeof(unsigned) bytes long. * * \returns Zero on success, or non-zero on error. */ int hd_write_buckets (hd_t* hd, unsigned* buckets) { CHECK( hd_write( hd, hd->header.off_b, (char*)buckets, hd->header.nbuckets * sizeof(unsigned) ) ); return 0; }
void hd_num(int32_t num,uint8_t min) { if(num<0)//sign { hd_write('-'); num=-num; } if(num>1000000000 || min>10) hd_write('0'+num/1000000000); if(num>100000000 || min>9) hd_write('0'+num/100000000%10); if(num>10000000 || min>8) hd_write('0'+num/10000000%10); if(num>1000000 || min>7) hd_write('0'+num/1000000%10); if(num>100000 || min>6) hd_write('0'+num/100000%10); if(num>10000 || min>5) hd_write('0'+num/10000%10); if(num>1000 || min>3) hd_write('0'+num/1000%10); if(num>100 || min>2) hd_write('0'+num/100%10); if(num>10 || min>1) hd_write('0'+num/10%10); hd_write('0'+num%10); //done }
/* 函数功能:删除普通文件 输入参数:文件名 pathname 删除方式 flags 输出参数:成功返回0,失败返回-1 */ int fs_delete(char * pathname,int flags) { DEV_Inode* p_devinode; int inode_nr; Inode* p_inode; Dir_Entry* p_de; int i,j,k; // 读目录文件,获取Dir_Entry 和 inode_nr int file_offset = 0; int de_nr = 0; for(i = 0,inode_nr = 0;i < ROOT_SECTS;i++,file_offset += SECTOR_SIZE) { file_buff_read(fsbuf,p_inode_de,file_offset,SECTOR_SIZE); for(j = 0,p_de = (Dir_Entry*)fsbuf;j < DIR_ENT_PER_SECT;j++,p_de++) { if(strcmp(p_de->name,pathname) == 0) { inode_nr = p_de->inode_nr; de_nr += j; break; } } if(inode_nr != 0) break; de_nr += DIR_ENT_PER_SECT; } // 目录中寻找结束 if(inode_nr == 0) { printk("can not find the file for delete ! %s\n",pathname); return -1; // 待删除的文件不存在 } if(inode_nr < 5) { printk("can not delete this file! %s\n",pathname); return -1; // 前4个文件不能删除。1:"." 2-4:tty0-tty2 } // 检测inode_table中是否有inode_nr,如果没有,则表示没有进程在使用该文件,可以删除 for(p_inode = inode_table;p_inode < inode_table + MAX_ALL_INODE;p_inode++) { if(p_inode->i_num == inode_nr && p_inode->i_cnt != 0) { printk("can not delete the file ! %s\n",pathname); return -1; // 当前有进程在使用该文件,所以不能删除 } } // 设备中释放imap,smap,Dir_Entry // imap int sect = IMAP_1ST_SECTS + inode_nr / 8 / SECTOR_SIZE; hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * sect,1); fsbuf[inode_nr / 8 % SECTOR_SIZE] &= (U8)~(1 << (inode_nr % 8) ); hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * sect,1); // smap sect = INODE_1ST_SECTS + inode_nr / INODE_PER_SECT; // 获取devinode hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * sect,1); p_devinode = (DEV_Inode*)fsbuf; p_devinode += inode_nr % INODE_PER_SECT; int start_sect = p_devinode->i_start_sect; int nr_sects = p_devinode->i_nr_sects; i = start_sect / 8 / SECTOR_SIZE; // 所在扇区号 j = start_sect / 8 % SECTOR_SIZE; // 扇区内字节号 k = start_sect % 8; // 字内位号 //printk("start_sect:%d,i:%d,j:%d,k:%d\n",start_sect + DAT_1ST_SECT,i,j,k); while(nr_sects > 0) // 释放smap { hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1); while(j < SECTOR_SIZE && nr_sects >0) { if(8 - k >= nr_sects) // 该字节内解决问题 { while(nr_sects-- > 0) { fsbuf[j] &= (char)~(1 << k++); } break; } else // 该字节内解决不了问题 { if(k == 0) // 全0 { fsbuf[j] = 0; nr_sects -= 8; } else // 非全0 { while(k < 8) { fsbuf[j] &= (char)~(1 << k++); nr_sects--; } } j++; k = 0; } } //printk("i:%d,j:%d,k:%d\n",i,j,k); hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1); i++; j = 0; } // Dir_Entry Dir_Entry de; de.inode_nr = 0; //printk("de_nr:%d ",de_nr); file_buff_write(&de,p_inode_de,de_nr * sizeof(Dir_Entry),sizeof(Dir_Entry)); sync_buff(p_inode_de,0); // 0:不释放缓冲 1:同步之后释放缓冲 // 成功返回0 return 0; }
//--------------------------------------------------------------------------------------------------*/ // 创建文件系统 void fs_make(void) { // 超级块 Super_Block sb; sb.magic = MAGIC; // 魔数 sb.imap_1st_sects = IMAP_1ST_SECTS; // imap第一个扇区号 sb.nr_inodes = NR_INODES; // inodes总数 sb.nr_imap_sects = NR_IMAP_SECTS; // inode-map 占用扇区数 sb.smap_1st_sects = SMAP_1ST_SECTS; // smap第一个扇区号 sb.nr_sects = NR_SECTS; // 扇区总数 sb.nr_smap_sects = NR_SMAP_SECTS; // sector-map占用扇区数 sb.inode_1st_sects = INODE_1ST_SECTS; // inode_array第一个扇区号 sb.inode_size = INODE_SIZE; // inode 大小 sb.inode_per_sect = INODE_PER_SECT; // 每扇区能容纳的inode数 sb.nr_inode_sects = NR_INODE_SECTS; // inode占用扇区数 sb.dat_1st_sect = DAT_1ST_SECT; // 第一个数据扇区号 sb.dir_ent_size = DIR_ENT_SIZE; // dir_entry的大小 sb.dir_ent_inode_off = DIR_ENT_INODE_OFF; // dir_entry结构中inode_nr的偏移 sb.dir_ent_fname_off = DIR_ENT_FNAME_OFF; // dir_entry结构中name的偏移 sb.dir_ent_per_sect = DIR_ENT_PER_SECT; // 每个root扇区能容纳的dir_entry数 sb.root_sects = ROOT_SECTS; // root占用扇区数 sb.root_inode = ROOT_INODE; // root directory 的inode号 sb.inode_isize_off = INODE_ISEZE_OFF; // inode结构中i_size的偏移 sb.inode_start_off = INODE_START_OFF; // inode结构中i_start_sect的偏移 printk("super block lba: %x,sects: %x\n",1,1); printk("i_node map lba: %x,sects: %x\n",IMAP_1ST_SECTS ,NR_IMAP_SECTS); printk("sector map lba: %x,sects: %x\n",SMAP_1ST_SECTS ,NR_SMAP_SECTS); printk("inode_array lba: %x,sects: %x\n",INODE_1ST_SECTS ,NR_INODE_SECTS); printk("data_root lba: %x,sects: %x\n",DAT_1ST_SECT ,NR_SECTS); mset(fsbuf,0x11,SECTOR_SIZE * 1); memcopy(fsbuf,(char*)&sb,SUPER_BLOCK_SIZE); hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * 1,1); // 超级块放在第 1 个扇区(从0开始数) //---------------------------------------------------------- // imap int i; for(i = 0;i < NR_IMAP_SECTS;i++) { mset(fsbuf,0,SECTOR_SIZE); if(i == 0) *fsbuf = 0x1f; // 0:保留,1:root,2-4:tty0-tty2。总共5位 hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * ( IMAP_1ST_SECTS + i),1); } //---------------------------------------------------------- // smap mset(fsbuf,0,SECTOR_SIZE * NR_SMAP_SECTS); int j; for(i = 0 ;i < (ROOT_SECTS + 1) / 8;i++) // 0:保留,此时只有root占用了硬盘扇区 // +1 是因为根目录区从第1扇区开始(从0开始数) fsbuf[i] = 0xff; for(j = 0 ;j < (ROOT_SECTS + 1) % 8;j++) fsbuf[i] |= 1 << j; hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * SMAP_1ST_SECTS,NR_SMAP_SECTS); int ints = (ROOT_SECTS + 1) / 32; // 以4字节为最小单位操作 int bits = (ROOT_SECTS + 1) % 32; for(i = 0;i < NR_SMAP_SECTS;i++) { mset(fsbuf,0,SECTOR_SIZE); int* p_int = (int*)fsbuf; for(j = 0;j < SECTOR_SIZE / 4;j++,p_int++) // 以4字节为最小单位操作 { if(ints > 0) { *p_int = 0xffffffff; ints--; continue; } // ints为0时,程序才能运行到这里 *p_int = 0x00000000; if(bits > 0) { while(bits > 0) { bits--; *p_int |= 1 << bits; } } } hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (SMAP_1ST_SECTS + i),1); } //---------------------------------------------------------- // inode_array DEV_Inode* p_inode = (DEV_Inode*)fsbuf; // 0:保留,1:root,2-4:tty0-tty2。总共5个 mset(fsbuf,0,SECTOR_SIZE); p_inode++; // 0:保留 p_inode->i_mode = I_MODE_ROOT; // 1:root p_inode->i_size = SECTOR_SIZE * ROOT_SECTS; p_inode->i_start_sect = 1; p_inode->i_nr_sects = ROOT_SECTS; p_inode++; for(i = 0 ;i < NR_TTY ;i++,p_inode++) // 2-4:tty { p_inode->i_mode = I_MODE_CHAR; p_inode->i_size = 0; p_inode->i_start_sect = DEVICE(MAJAR_TTY,i); // 设为tty的设备号 p_inode->i_nr_sects = 0; } hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * INODE_1ST_SECTS,1); //---------------------------------------------------------- // root(dir_entry) 0:保留,".",tty0-tty2。总共5个 Dir_Entry* p_dir; for(i = 0;i < ROOT_SECTS;i++) // 其余的清零 { p_dir = (Dir_Entry*)fsbuf; for(j = 0;j < DIR_ENT_PER_SECT;j++,p_dir++) p_dir->inode_nr = 0; hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (DAT_1ST_SECT + 1 + i),1); // +1 是因为根目录区从第1扇区开始(从0开始数) } p_dir = (Dir_Entry*)fsbuf; p_dir++; // 0:保留 p_dir->inode_nr = 1; // 1:"." root memcopy(p_dir->name,".",2); p_dir++; for(i = 0;i < NR_TTY;i++,p_dir++) // tty { p_dir->inode_nr = 2 + i; memcopy(p_dir->name,"tty0",5); p_dir->name[3] = '0' + i; } hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (DAT_1ST_SECT + 1),1); // +1 是因为根目录区从第1扇区开始(从0开始数) }
/* 函数功能:创建普通文件 输入参数:文件名 pathname 输出参数:0 创建失败,非0 新文件在设备中的inode_nr */ int create_file(char * pathname) { int inode_nr = 0; int start_sect = 0; int i,j,k; // 在imap中找一个空位 for(i = 0;i < NR_IMAP_SECTS ;i++) { hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (IMAP_1ST_SECTS + i),1); for(j = 0;j < SECTOR_SIZE;j++) { if(fsbuf[j] == (char)0xff) continue; for(k = 0;k < 8;k++) { if(( fsbuf[j] & (1<<k) ) == 0) { // 此时第i扇区,第j字节,第k位为待找的空位 //printk("imap find3\n"); inode_nr = SECTOR_SIZE * i * 8 + j * 8 + k; if(inode_nr == 0) continue; //printk("imap find4,inode_nr: %d\n",inode_nr); fsbuf[j] |= (1 << k); hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (IMAP_1ST_SECTS + i),1); break; } } if(inode_nr != 0) break; } if(inode_nr != 0) break; } if(inode_nr == 0) { printk("imap full----"); return 0; // 没有空位 } // 在smap中找 inode_nr对应的 SECTS_PER_FILE 个连续空位,然后全部置1 for(i = 0;i < NR_SMAP_SECTS;i++) // { hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (SMAP_1ST_SECTS + i),1); for(j = 0;j < SECTOR_SIZE;j++) { if(fsbuf[j] == (char)0xff) continue; for(k = 0;k < 8;k++) { if((fsbuf[j] & (1 << k)) == 0) { // 此时第i扇区,第j字节,第k位为待找的空位 //printk("i:%d j:%d k:%d\n",i,j,k); start_sect = SECTOR_SIZE * i * 8 + j * 8 + k; int nr_sects = SECTS_PER_FILE; while(nr_sects > 0) // 填充smap { hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1); while(j < SECTOR_SIZE && nr_sects >0) { if(8 - k >= nr_sects) // 该字节内解决问题 { while(nr_sects-- > 0) { if(fsbuf[j] & (char)(1 << k)) { printk("i:%d j:%d k:%d\n",i,j,k); printk("OMG retry1!\n"); goto repeat; } fsbuf[j] |= (char)(1 << k++); } hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1); goto smapOK; } else // 该字节内解决不了问题 { if(k == 0) // 全1 { if(fsbuf[j] != 0) { printk("i:%d j:%d k:%d\n",i,j,k); printk("OMG retry2!\n"); goto repeat; } fsbuf[j] = 0xff; nr_sects -= 8; } else // 非全1 { while(k < 8) { if(fsbuf[j] & (char)(1 << k)) { printk("i:%d j:%d k:%d\n",i,j,k); printk("OMG retry3!\n"); goto repeat; } fsbuf[j] |= (char)(1 << k++); nr_sects--; } } j++; k = 0; } } hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1); i++; j = 0; } } repeat: ; } } } smapOK: if(start_sect == 0) { printk("smap full2----"); return 0; // 没有空位 } // devinode赋值 int offset = (SECTOR_SIZE * INODE_1ST_SECTS + inode_nr * INODE_SIZE) & ~0x1ff; hd_read(ROOT_DEV,fsbuf,offset,1); DEV_Inode* p_devinode = (DEV_Inode*)fsbuf; p_devinode += inode_nr % INODE_PER_SECT; p_devinode->i_mode = I_MODE_FILE; p_devinode->i_size = FILE_MAX_SIZE; p_devinode->i_start_sect = start_sect; p_devinode->i_nr_sects = SECTS_PER_FILE; printk("new file %s start_sect :%d sects: %d\n",pathname,start_sect,SECTS_PER_FILE); hd_write(ROOT_DEV,fsbuf,offset,1); // Dir_Entry // 在root中找一个空位 Dir_Entry* p_de; int file_offset = 0; int de_nr = 0; for(i = 0;i < ROOT_SECTS;i++,file_offset += SECTOR_SIZE) { file_buff_read(fsbuf,p_inode_de,file_offset,SECTOR_SIZE); for(j = 0,p_de = (Dir_Entry*)fsbuf;j < DIR_ENT_PER_SECT;j++,p_de++) { if(p_de->inode_nr == 0 && (i !=0 || j != 0)) // 第0号位置保留 { de_nr += j; //printk("de_nr:%d ",de_nr); Dir_Entry de; de.inode_nr = inode_nr; memcopy(de.name,pathname,MAX_FILENAME_LEN); file_buff_write(&de,p_inode_de,de_nr * sizeof(Dir_Entry),sizeof(Dir_Entry)); sync_buff(p_inode_de,0); // 0:不释放缓冲 1:同步之后释放缓冲 // 返回inode_nr printk("create file success: %s\n",pathname); return inode_nr; // 返回inode_nr 0:失败,非0:成功 } } de_nr += DIR_ENT_PER_SECT; } printk("Dir_Entry empty\n"); return 0; // 没有找到Dir_Entry }