国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

產(chǎn)品經(jīng)理如何做p2p網(wǎng)站改版短視頻矩陣seo系統(tǒng)源碼

產(chǎn)品經(jīng)理如何做p2p網(wǎng)站改版,短視頻矩陣seo系統(tǒng)源碼,wordpress改了ip,erp系統(tǒng)是什么意思14.7 實(shí)現(xiàn)文件寫入 這是一個(gè)網(wǎng)站有所有小節(jié)的代碼實(shí)現(xiàn),同時(shí)也包含了Bochs等文件 本節(jié)要實(shí)現(xiàn)的 sys_write 是系統(tǒng)調(diào)用 write 的內(nèi)核實(shí)現(xiàn),咱們之前的 write 是個(gè)簡易版,它是為了臨時(shí)完成輸出打印的功能,不支持文件描述符。如今要讓…

14.7 實(shí)現(xiàn)文件寫入

這是一個(gè)網(wǎng)站有所有小節(jié)的代碼實(shí)現(xiàn),同時(shí)也包含了Bochs等文件
本節(jié)要實(shí)現(xiàn)的 sys_write 是系統(tǒng)調(diào)用 write 的內(nèi)核實(shí)現(xiàn),咱們之前的 write 是個(gè)簡易版,它是為了臨時(shí)完成輸出打印的功能,不支持文件描述符。如今要讓 write 支持文件描述符的話,還要修改下周邊與此系統(tǒng)調(diào)用相關(guān)的內(nèi)容。

14.7.1 實(shí)現(xiàn)file_write
/*把buf中的count個(gè)字節(jié)寫入file,成功則返回寫入的字節(jié)數(shù),失敗則返回-1*/
int32_t file_write(struct file* file, const void* buf, uint32_t count){if((file->fd_inode->i_size +count)>(BLOCK_SIZE * 140)){ //文件目前最大只支持512*140=71680字節(jié)printk("exceed max file_size 71680 bytes,write file failed\n");return -1;}uint8_t* io_buf = sys_malloc(512);if(io_buf==NULL){printk("file_write:sys_malloc for io_buf failed\n");return -1;}uint32_t* all_blocks = (uint32_t*)sys_malloc(BLOCK_SIZE+48);    //用來記錄文件所有的塊地址,一個(gè)地址4字節(jié),一共有140個(gè)塊所以要560字節(jié)內(nèi)存if(all_blocks == NULL){printk("file_write: sys_malloc for all_blocks failed\n");return -1;}const uint8_t* src = buf;   //用src指向buf中待寫入的數(shù)據(jù)uint32_t bytes_written = 0;     //用來記錄已寫入數(shù)據(jù)大小uint32_t size_left = count;     //用來記錄未寫入數(shù)據(jù)大小int32_t block_lba = -1; //用來記錄塊地址uint32_t block_bitmap_idx = 0;  //用來記錄block對應(yīng)于block_bitmap中的索引,作為參數(shù)傳遞給bitmap_syncuint32_t sec_idx;   //用來索引扇區(qū)uint32_t sec_lba;   //扇區(qū)地址uint32_t sec_off_bytes; //扇區(qū)內(nèi)字節(jié)偏移量uint32_t sec_left_bytes;    //扇區(qū)內(nèi)剩余字節(jié)量uint32_t chunk_size;    //每次寫入硬盤的數(shù)據(jù)塊大小int32_t indirect_block_table;   //用來獲取一級(jí)間接表地址uint32_t block_idx; //塊索引//判斷文件是否是第一次寫,如果是,先為其分配一個(gè)塊if(file->fd_inode->i_sectors[0]==0){block_lba = block_bitmap_alloc(cur_part);if(block_lba == -1){printk("file_write:block_bitmap_alloc failed\n");return -1;}file->fd_inode->i_sectors[0]=block_lba;/*每分配一個(gè)塊就將位圖同步到磁盤*/block_bitmap_idx = block_lba-cur_part->sb->block_bitmap_lba;ASSERT(block_bitmap_idx!=0);bitmap_sync(cur_part,block_bitmap_idx,BLOCK_BITMAP);}/*寫入count字節(jié)前,改文件已經(jīng)占用的塊數(shù)*/uint32_t file_has_used_blocks = file->fd_inode->i_size / BLOCK_SIZE + 1;/*存儲(chǔ)count字節(jié)后該文件將占用的塊數(shù)*/uint32_t file_will_use_blocks = (file->fd_inode->i_size + count) / BLOCK_SIZE + 1;ASSERT(file_will_use_blocks <= 140);/*通過此增量判斷是否要分配扇區(qū),如果增量為0,表示原扇區(qū)夠用*/uint32_t add_blocks = file_will_use_blocks - file_has_used_blocks;/*將寫文件所用到的塊地址收集到all_blocks,系統(tǒng)中快大小等于扇區(qū)大小,后面都統(tǒng)一在all_blocks中獲取寫入扇區(qū)地址*/if(add_blocks==0){/*在同一扇區(qū)內(nèi)寫入數(shù)據(jù),不涉及到分配新扇區(qū)*/if(file_will_use_blocks<=12){//文件數(shù)據(jù)將在12塊之內(nèi)block_idx = file_has_used_blocks - 1;   //指向最后一個(gè)已有數(shù)據(jù)扇區(qū)all_blocks[block_idx] = file->fd_inode->i_sectors[block_idx];}else{/*未寫入新數(shù)據(jù)之前已經(jīng)占用了間接塊,需要將間接塊地址讀取出來*/ASSERT(file->fd_inode->i_sectors[12]!=0);indirect_block_table = file->fd_inode->i_sectors[12];ide_read(cur_part->my_disk,indirect_block_table,all_blocks+12,1);}}else{/*若是有增量,變涉及到分配新扇區(qū)及是否分配一級(jí)間接塊表,下面要分三種情況處理*//*第一種情況:12個(gè)塊直接夠用*/if(file_will_use_blocks <= 12){/*先將剩余空間的可繼續(xù)用的扇區(qū)地址寫入all_blocks*/block_idx = file_has_used_blocks - 1;ASSERT(file->fd_inode->i_sectors[block_idx]!=0);all_blocks[block_idx] = file->fd_inode->i_sectors[block_idx];/*再將未來要用的扇區(qū)分配好后寫入all_blocks*/block_idx = file_has_used_blocks;   //指向第一個(gè)要分配的扇區(qū)while(block_idx<file_will_use_blocks){block_lba = block_bitmap_alloc(cur_part);if(block_lba==-1){printk("file_write:block_bitmap_alloc for situation 1 failed\n");return -1;}/*寫文件時(shí),不應(yīng)該存在塊未使用但已經(jīng)分配扇區(qū)的情況,當(dāng)文件刪除時(shí),就會(huì)把塊地址清0*/ASSERT(file->fd_inode->i_sectors[block_idx]==0);    //確保尚未分配扇區(qū)地址file->fd_inode->i_sectors[block_idx] = all_blocks[block_idx] = block_lba;/*每分配一個(gè)塊就將位圖同步到磁盤*/block_bitmap_idx = block_lba-cur_part->sb->block_bitmap_lba;ASSERT(block_bitmap_idx!=0);bitmap_sync(cur_part,block_bitmap_idx,BLOCK_BITMAP);block_idx++;    //分配下一個(gè)扇區(qū)}}else if(file_has_used_blocks <= 12 && file_will_use_blocks > 12){/*第二種情況:舊數(shù)據(jù)在12個(gè)直接塊中,數(shù)據(jù)將使用間接塊*//*先將剩余空間的可繼續(xù)用的扇區(qū)地址寫入all_blocks*/block_idx = file_has_used_blocks - 1;   //指向舊數(shù)據(jù)所在的最后一個(gè)扇區(qū)ASSERT(file->fd_inode->i_sectors[block_idx]!=0);all_blocks[block_idx] = file->fd_inode->i_sectors[block_idx];/*創(chuàng)建一級(jí)間接塊表*/block_lba = block_bitmap_alloc(cur_part);if(block_lba==-1){printk("file_write:block_bitmap_alloc for situation 2 failed\n");return -1;}ASSERT(file->fd_inode->i_sectors[12]==0);//確保一級(jí)塊表未分配/*分配一級(jí)塊間接索引表*/indirect_block_table = file->fd_inode->i_sectors[12] = block_lba;block_idx = file_has_used_blocks;   //第-個(gè)未使用的塊,即本文件最后一個(gè)已經(jīng)使用的直接塊的下一塊while(block_idx < file_will_use_blocks){block_lba = block_bitmap_alloc(cur_part);if(block_lba==-1){printk("file_write:block_bitmap_alloc for situation 2 failed\n");return -1;}if(block_idx <  12){    //新創(chuàng)建的0-11快直接存入all_blocks數(shù)組中ASSERT(file->fd_inode->i_sectors[block_idx]==0);    //確保尚未分配扇區(qū)地址file->fd_inode->i_sectors[block_idx] = all_blocks[block_idx] = block_lba;}else{//間接塊只寫入到all_blocks數(shù)組中,待全部分配完成后一次同步到硬盤all_blocks[block_idx] = block_lba;}/*每分配一個(gè)塊就將文圖同步到硬盤*/block_bitmap_idx = block_lba - cur_part->sb->block_bitmap_lba;bitmap_sync(cur_part,block_bitmap_idx,BLOCK_BITMAP);block_idx++;}ide_write(cur_part->my_disk,indirect_block_table,all_blocks+12,1);   //同步一級(jí)間接塊表到硬盤}else if(file_has_used_blocks > 12){/*第三種情況:新數(shù)據(jù)占間接塊*/ASSERT(file->fd_inode->i_sectors[12]!=0);   //已經(jīng)具備了一級(jí)間接塊indirect_block_table = file->fd_inode->i_sectors[12];   //  獲取一級(jí)間接表地址/*已經(jīng)使用的間接塊也將被讀入all_blocks,無需單獨(dú)收錄*/ide_read(cur_part->my_disk,indirect_block_table,all_blocks+12,1);   //獲取所有間接塊地址block_idx = file_has_used_blocks;   //第一個(gè)為使用的間接塊,即已經(jīng)使用的間接塊的下一塊while(block_idx<file_will_use_blocks){block_lba = block_bitmap_alloc(cur_part);if(block_lba==-1){printk("file_write:block_bitmap_alloc for situation 3 failed\n");return -1;}all_blocks[block_idx] = block_lba;/*每分配一個(gè)塊就將文圖同步到硬盤*/block_bitmap_idx = block_lba - cur_part->sb->block_bitmap_lba;bitmap_sync(cur_part,block_bitmap_idx,BLOCK_BITMAP);block_idx++;}ide_write(cur_part->my_disk,indirect_block_table,all_blocks+12,1);//同步一級(jí)間接塊表到硬盤}}/*用到的塊地址已經(jīng)收集到了all_blocks中,下面開是寫數(shù)據(jù)*/bool first_write_block = true;  //含有剩余空間的塊標(biāo)識(shí)file->fd_pos = file->fd_inode->i_size - 1;  //置fd_pos為文件大小-1,下面在寫數(shù)據(jù)時(shí)隨時(shí)更新,這是文件內(nèi)偏移量while(bytes_written < count){   //直到數(shù)據(jù)寫完memset(io_buf,0,BLOCK_SIZE);sec_idx = file->fd_inode->i_size / BLOCK_SIZE;sec_lba = all_blocks[sec_idx];sec_off_bytes = file->fd_inode->i_size % BLOCK_SIZE;sec_left_bytes = BLOCK_SIZE - sec_off_bytes;/*判斷此寫入硬盤的大小數(shù)據(jù)*/chunk_size = size_left<sec_left_bytes ? size_left : sec_left_bytes;if(first_write_block){ide_read(cur_part->my_disk,sec_lba,io_buf,1);first_write_block = false;}memcpy(io_buf+sec_off_bytes,src,chunk_size);ide_write(cur_part->my_disk,sec_lba,io_buf,1);printk("file write at lba 0x%x\n",sec_lba); //調(diào)試,完成后去掉src+=chunk_size;    //將指針推移到下一個(gè)新數(shù)據(jù)file->fd_inode->i_size+=chunk_size; //更新文件大小file->fd_pos +=chunk_size;bytes_written+=chunk_size;size_left -= chunk_size;}inode_sync(cur_part,file->fd_inode,io_buf);sys_free(all_blocks);sys_free(io_buf);return bytes_written;
}

file_write:功能是把buf中的count個(gè)字節(jié)寫入file,成功則返回寫入的字節(jié)數(shù),失敗則返回-1。核心的原理是:傳進(jìn)函數(shù)的文件結(jié)構(gòu)struct file指針中有個(gè)指向操作文件inode的指針,通過這個(gè)inode中的i_sizei_sectors[ ],我們可以順利知道文件大小與存儲(chǔ)位置信息。先將文件已有數(shù)據(jù)的最后一塊數(shù)據(jù)讀出來并與將要寫入的數(shù)據(jù)在緩沖區(qū)中共同拼湊成一個(gè)完整的塊,然后寫入磁盤。剩下的數(shù)據(jù)以塊為單位繼續(xù)寫入磁盤即可。

流程:1.先判斷寫入的buf會(huì)不會(huì)超出文件的大小;2.申請緩沖區(qū);3.寫入count字節(jié)前,先計(jì)算該文件已經(jīng)占用的塊數(shù);4.計(jì)算存儲(chǔ)count字節(jié)后該文件將占用的塊數(shù);5.將寫文件所用到的塊地址收集到all_blocks,共分為三種情況討論;6.用到的塊地址已經(jīng)收集到了all_blocks中,開始寫數(shù)據(jù)。

14.7.2 改進(jìn)sys_write及write

因?yàn)橹拔覀儗?shí)現(xiàn)的sys_write,由于沒有實(shí)現(xiàn)file_write,所以它就是調(diào)用了console_put_str打印字符串,現(xiàn)在我們改進(jìn)sys_write。

如果傳入的fd表示標(biāo)準(zhǔn)輸出,直接調(diào)用console_put_str打印即可。否則就調(diào)用fd_local2global獲取文件描述符fd對應(yīng)于文件表中的下標(biāo)_fd,然后獲得待寫入文件的文件結(jié)構(gòu)指針wr_file,再判斷他的flag,最后做出判斷。

//fs.c
/*將buf中連續(xù)count個(gè)字節(jié)寫入文件描述符fd,成功則返回寫入的字節(jié)數(shù),失敗返回-1*/
int32_t sys_write(int32_t fd, const void* buf, uint32_t count){if(fd<0){printk("sys_write:fd error\n");return -1;}if(fd==stdout_no){char tmp_buf[1024] = {0};memcpy(tmp_buf,buf,count);console_put_str(tmp_buf);return count;}uint32_t _fd = fd_local2global(fd);struct file* wr_file = &file_table[_fd];if(wr_file->fd_flag & O_WRONLY || wr_file->fd_flag & O_RDWR){uint32_t bytes_written = file_write(wr_file,buf,count);return bytes_written;}else{console_put_str("sys_write: not allowed to write file without flag O_RDWR or O_WRONLY\n");return -1;}
}

同時(shí)修改write

/* 把buf中count個(gè)字符寫入文件描述符fd */
uint32_t write(int32_t fd, const void *buf, uint32_t count)
{return _syscall3(SYS_WRITE, fd, buf, count);//其實(shí)就是更改這里
}

最后再把printf修改一下:

/* 格式化輸出字符串format */
uint32_t printf(const char *format, ...)
{va_list args;va_start(args, format); // 使args指向formatchar buf[1024] = {0};   // 用于存儲(chǔ)拼接后的字符串vsprintf(buf, format, args);va_end(args);return write(1, buf, strlen(buf));//其實(shí)就是更改這里
}
http://www.aloenet.com.cn/news/32280.html

相關(guān)文章:

  • 長沙手機(jī)網(wǎng)站設(shè)計(jì)公司百度瀏覽官網(wǎng)
  • 最簡單的網(wǎng)站制作360指數(shù)官網(wǎng)
  • 做網(wǎng)站文章要一篇一篇的寫嗎獲客
  • wordpress全站登陸可見教育培訓(xùn)機(jī)構(gòu)加盟十大排名
  • 防止網(wǎng)站流量被刷seo數(shù)據(jù)是什么
  • 微信小程序代運(yùn)營長沙排名優(yōu)化公司
  • 橙色網(wǎng)站欣賞百度一下百度搜索
  • 網(wǎng)站布局如何修改重慶網(wǎng)站制作公司
  • 2015做啥網(wǎng)站能致富百度官方網(wǎng)頁
  • 做一手房用什么網(wǎng)站百度競價(jià)開戶需要多少錢
  • 南通網(wǎng)站建設(shè)優(yōu)化公司網(wǎng)站優(yōu)化排名公司
  • 網(wǎng)站建設(shè)頁面設(shè)計(jì)規(guī)格全國31省市疫情最新消息今天
  • 正規(guī)網(wǎng)站建設(shè)定制學(xué)電商出來一般干什么工作
  • 莒縣網(wǎng)站設(shè)計(jì)免費(fèi)百度seo引流
  • 微信登錄界面相城seo網(wǎng)站優(yōu)化軟件
  • 青海省高速公路建設(shè)管理局網(wǎng)站百度知道網(wǎng)頁版入口
  • 外包項(xiàng)目刷seo快速排名
  • 品牌網(wǎng)站建設(shè)有哪兩種模式百度問問
  • 網(wǎng)頁設(shè)計(jì)作業(yè)報(bào)告范文成都網(wǎng)站優(yōu)化
  • 設(shè)計(jì)培訓(xùn)網(wǎng)頁版草根seo視頻大全網(wǎng)站
  • 黃石企業(yè)網(wǎng)站建設(shè)開發(fā)阿里云com域名注冊
  • 龍華哪有做網(wǎng)站設(shè)計(jì)網(wǎng)站關(guān)鍵詞優(yōu)化排名推薦
  • 蘭州關(guān)鍵詞優(yōu)化效果西安seo服務(wù)培訓(xùn)
  • wordpress技術(shù)類主題關(guān)鍵詞長尾詞優(yōu)化
  • 用什么做網(wǎng)站最簡單百度招商加盟
  • 建站工具官網(wǎng)小程序開發(fā)流程
  • 網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司品牌營銷推廣策劃公司
  • 華為云怎么做網(wǎng)站域名停靠網(wǎng)頁app推廣大全
  • 汽車app網(wǎng)站建設(shè)優(yōu)化關(guān)鍵詞規(guī)則
  • 《網(wǎng)站建設(shè)與維護(hù)》講義基本seo