📄
字号:
printk("VFS: iput: trying to free free inode\n");<br> printk("VFS: device %s, inode %lu, mode=0%07o\n",<br> kdevname(inode->i_rdev), inode->i_ino, inode->i_mode);<br> return;<br> }<br> if (inode->i_pipe)<br> wake_up_interruptible(&PIPE_WAIT(*inode));<br> repeat:<br> if (inode->i_count>1) {<br> inode->i_count--;<br> return;<br> }<br> wake_up(&inode_wait);<br> if (inode->i_pipe) {<br> unsigned long page = (unsigned long) PIPE_BASE(*inode);<br> PIPE_BASE(*inode) = NULL;<br> free_page(page);<br> }<br> if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {<br> inode->i_sb->s_op->put_inode(inode);<br> if (!inode->i_nlink)<br> return;<br> }<br> if (inode->i_dirt) {<br> write_inode(inode); /* we can sleep - so do again */<br> wait_on_inode(inode);<br> goto repeat;<br> }<br> if (IS_WRITABLE(inode)) {<br> if (inode->i_sb && inode->i_sb->dq_op) {<br> /* Here we can sleep also. Let's do it again<br> * Dmitry Gorodchanin 02/11/96 <br> */<br> inode->i_lock = 1;<br> inode->i_sb->dq_op->drop(inode);<br> unlock_inode(inode);<br> goto repeat;<br> }<br> }<br> inode->i_count--;<br> if (inode->i_count)<br> /*<br> * Huoh, we were supposed to be the last user, but someone has<br> * grabbed it while we were sleeping. Dont destroy inode VM<br> * mappings, it might cause a memory leak.<br> */<br> return;<br> if (inode->i_mmap) {<br> printk("iput: inode %lu on device %s still has mappings.\n",<br> inode->i_ino, kdevname(inode->i_dev));<br> inode->i_mmap = NULL;<br> }<br> nr_free_inodes++;<br> return;<br> }</p> <p> </p> <p>#define free_page(addr) free_pages((addr),0) </font><font face="宋体" size="2" color="#ff0000">/* In file linux/include/linux/mm.h */</p> <p>/* In file linux/mm/page_alloc.c */</font><br> <font FACE="宋体" SIZE="2">/*<br> * Free_page() adds the page to the free lists. This is optimized for<br> * fast normal cases (no error jumps taken normally).<br> *<br> * The way to optimize jumps for gcc-2.2.2 is to:<br> * - select the "normal" case and put it inside the if () { XXX }<br> * - no else-statements if you can avoid them<br> *<br> * With the above two rules, you get a straight-line execution path<br> * for the normal case, giving better asm-code.<br> *<br> * free_page() may sleep since the page being freed may be a buffer<br> * page or present in the swap cache. It will not sleep, however,<br> * for a freshly allocated page (get_free_page()).<br> */<br> /*<br> * Buddy system. Hairy. You really aren't expected to understand this<br> *<br> * Hint: -mask = 1+~mask<br> */<br> static inline void free_pages_ok(unsigned long map_nr, unsigned long order)<br> {<br> struct free_area_struct *area = free_area + order;<br> unsigned long index = map_nr >> (1 + order);<br> unsigned long mask = (~0UL) << order;<br> unsigned long flags;<br> save_flags(flags);<br> cli();<br> #define list(x) (mem_map+(x))<br> map_nr &= mask;<br> nr_free_pages -= mask;<br> while (mask + (1 << (NR_MEM_LISTS-1))) {<br> if (!change_bit(index, area->map))<br> break;<br> remove_mem_queue(list(map_nr ^ -mask));<br> mask <<= 1;<br> area++;<br> index >>= 1;<br> map_nr &= mask;<br> }<br> add_mem_queue(area, list(map_nr));<br> #undef list<br> restore_flags(flags);<br> }</p> <p>void __free_page(struct page *page)<br> {<br> if (!PageReserved(page) && atomic_dec_and_test(&page->count)) {<br> unsigned long map_nr = page->map_nr;<br> delete_from_swap_cache(map_nr);<br> free_pages_ok(map_nr, 0);<br> }</p> <p>}</p> <p>void free_pages(unsigned long addr, unsigned long order)<br> {<br> <br> unsigned long map_nr = MAP_NR(addr);<br> if (map_nr < MAP_NR(high_memory)) {<br> mem_map_t * map = mem_map + map_nr;<br> if (PageReserved(map))<br> return;<br> if (atomic_dec_and_test(&map->count)) {<br> delete_from_swap_cache(map_nr);<br> free_pages_ok(map_nr, order);<br> return;<br> }<br> }</p> <p>}</font><font FACE="宋体" SIZE="7" COLOR="#007f00"></p> <p></font> </p> <font face="隶书" size="5"><p>四 后记<br> <font face="宋体" size="3"><p> 限于时间关系及作者水平,本实验报告仅对EXECVE系统调用进行了比较粗浅地分析 ,有很多代
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -