[lc-checkins] CVS: linux/mm/comp_cache free.c,1.39,1.40 main.c,1.57,1.58 swapout.c,1.63,1.64
Status: Beta
Brought to you by:
nitin_sf
From: Rodrigo S. de C. <rc...@us...> - 2002-07-17 21:45:17
|
Update of /cvsroot/linuxcompressed/linux/mm/comp_cache In directory usw-pr-cvs1:/tmp/cvs-serv9378/mm/comp_cache Modified Files: free.c main.c swapout.c Log Message: Bug fixes o Fix bug introduced in the last changes into compress_clean_page() function. It wasn't retuning any value. o Completed fix for the case where no swap buffer is freed. The fix was incomplete, so it would mess up the lists, discard dirty fragments, what would end up corrupting memory. Now, writeout_fragments() checks the error value of decompress_to_swp_buffer() and handles accordingly for the case where the error == -ENOMEM (no swap buffer available). Index: free.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/free.c,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -r1.39 -r1.40 *** free.c 17 Jul 2002 20:44:36 -0000 1.39 --- free.c 17 Jul 2002 21:45:12 -0000 1.40 *************** *** 2,6 **** * linux/mm/comp_cache/free.c * ! * Time-stamp: <2002-07-17 16:06:56 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache/free.c * ! * Time-stamp: <2002-07-17 17:51:14 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 331,336 **** BUG(); - page_cache_release(swap_cache_page); UnlockPage(swap_cache_page); } --- 331,336 ---- BUG(); UnlockPage(swap_cache_page); + page_cache_release(swap_cache_page); } Index: main.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/main.c,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -r1.57 -r1.58 *** main.c 17 Jul 2002 20:44:36 -0000 1.57 --- main.c 17 Jul 2002 21:45:12 -0000 1.58 *************** *** 2,6 **** * linux/mm/comp_cache/main.c * ! * Time-stamp: <2002-07-17 15:14:43 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache/main.c * ! * Time-stamp: <2002-07-17 18:28:09 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 103,106 **** --- 103,108 ---- ret = compress_page(page, 0, gfp_mask, priority); spin_unlock(&comp_cache_lock); + + return ret; } Index: swapout.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/swapout.c,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -r1.63 -r1.64 *** swapout.c 17 Jul 2002 20:44:36 -0000 1.63 --- swapout.c 17 Jul 2002 21:45:12 -0000 1.64 *************** *** 2,6 **** * /mm/comp_cache/swapout.c * ! * Time-stamp: <2002-07-17 12:34:20 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * /mm/comp_cache/swapout.c * ! * Time-stamp: <2002-07-17 18:26:45 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 125,135 **** * */ ! static struct swp_buffer * ! find_free_swp_buffer(struct comp_cache_fragment * fragment, unsigned int gfp_mask) { struct page * buffer_page; ! struct list_head * swp_buffer_lh; struct swp_buffer * swp_buffer; ! int priority = 6; if (!fragment) --- 125,135 ---- * */ ! static int ! find_free_swp_buffer(struct comp_cache_fragment * fragment, unsigned int gfp_mask, struct swp_buffer ** swp_buffer_out) { struct page * buffer_page; ! struct list_head * swp_buffer_lh; struct swp_buffer * swp_buffer; ! int priority = 6, error = 0; if (!fragment) *************** *** 146,154 **** /* Failed to get a free swap buffer. Probably gfp_mask does * not allow buffer sync in refill_swp_buffer() function. */ ! if (list_empty(&swp_free_buffer_head)) goto failed; /* Fragment totally freed. Free its struct to avoid leakage. */ if (!CompFragmentIO(fragment)) { kmem_cache_free(fragment_cachep, (fragment)); goto failed; --- 146,157 ---- /* Failed to get a free swap buffer. Probably gfp_mask does * not allow buffer sync in refill_swp_buffer() function. */ ! if (list_empty(&swp_free_buffer_head)) { ! error = -ENOMEM; goto failed; + } /* Fragment totally freed. Free its struct to avoid leakage. */ if (!CompFragmentIO(fragment)) { + error = -ENOENT; kmem_cache_free(fragment_cachep, (fragment)); goto failed; *************** *** 156,161 **** /* Fragment partially freed (to be merged). Nothing to do. */ ! if (CompFragmentFreed(fragment)) goto failed; get_free_buffer: --- 159,166 ---- /* Fragment partially freed (to be merged). Nothing to do. */ ! if (CompFragmentFreed(fragment)) { ! error = -ENOENT; goto failed; + } get_free_buffer: *************** *** 176,201 **** list_add(&buffer_page->list, &fragment->mapping->locked_comp_pages); ! ! return (swp_buffer); ! failed: CompFragmentClearIO(fragment); ! return NULL; } extern void decompress_fragment(struct comp_cache_fragment *, struct page *); ! static struct swp_buffer * ! decompress_to_swp_buffer(struct comp_cache_fragment * fragment, unsigned int gfp_mask) { struct page * buffer_page; struct swp_buffer * swp_buffer; if (fragment->comp_page->page->buffers) BUG(); - swp_buffer = find_free_swp_buffer(fragment, gfp_mask); ! /* no need for IO any longer */ ! if (!swp_buffer) ! return NULL; buffer_page = swp_buffer->page; --- 181,207 ---- list_add(&buffer_page->list, &fragment->mapping->locked_comp_pages); ! (*swp_buffer_out) = swp_buffer; ! out: ! return error; ! failed: CompFragmentClearIO(fragment); ! goto out; } extern void decompress_fragment(struct comp_cache_fragment *, struct page *); ! static int ! decompress_to_swp_buffer(struct comp_cache_fragment * fragment, unsigned int gfp_mask, struct swp_buffer ** swp_buffer_out) { struct page * buffer_page; struct swp_buffer * swp_buffer; + int error; if (fragment->comp_page->page->buffers) BUG(); ! error = find_free_swp_buffer(fragment, gfp_mask, &swp_buffer); ! if (error) ! goto out; buffer_page = swp_buffer->page; *************** *** 210,214 **** UnlockPage(fragment->comp_page->page); ! return swp_buffer; } --- 216,222 ---- UnlockPage(fragment->comp_page->page); ! (*swp_buffer_out) = swp_buffer; ! out: ! return error; } *************** *** 221,225 **** int (*writepage)(struct page *); struct list_head * fragment_lh; ! int maxscan, nrpages, swap_cache_page; struct comp_cache_fragment * fragment; struct swp_buffer * swp_buffer; --- 229,233 ---- int (*writepage)(struct page *); struct list_head * fragment_lh; ! int maxscan, nrpages, swap_cache_page, error; struct comp_cache_fragment * fragment; struct swp_buffer * swp_buffer; *************** *** 308,316 **** spin_unlock(&comp_cache_lock); - swp_buffer = decompress_to_swp_buffer(fragment, gfp_mask); ! /* no need for IO */ ! if (!swp_buffer) ! goto out; if (!swp_buffer->page->mapping) --- 316,323 ---- spin_unlock(&comp_cache_lock); ! error = decompress_to_swp_buffer(fragment, gfp_mask, &swp_buffer); ! if (error) ! goto failed; if (!swp_buffer->page->mapping) *************** *** 334,337 **** --- 341,359 ---- continue; break; + + failed: + /* ok, freed in the meanwhile */ + if (error == -ENOENT) + goto out; + + /* -ENOMEM - couldn't find a buffer (gfp_mask) */ + if (TryLockPage(fragment->comp_page->page)) + BUG(); + add_fragment_to_lru_queue(fragment); + list_del(&fragment->mapping_list); + list_add(&fragment->mapping_list, &fragment->mapping->dirty_comp_pages); + CompFragmentSetDirty(fragment); + UnlockPage(fragment->comp_page->page); + goto out; } |