give swapper_space a set_page_dirty a_op
Subsystems (3)
PATCH 10/16 give swapper_space a set_page_dirty a_op
Give swapper_space a ->set_page_dirty() address_space_operation.
So swapcache pages do not need special-casing inset_page_dirty_buffers().
=====================================
mm/swap_state.c renamed from mm/swap_state.c~swap-set_page_dirty +4 -3
@@ -48,9 +48,10 @@ static int swap_vm_writeback(struct page }static struct address_space_operations swap_aops = { - vm_writeback: swap_vm_writeback, - writepage: swap_writepage, - sync_page: block_sync_page, + vm_writeback: swap_vm_writeback, + writepage: swap_writepage, + sync_page: block_sync_page, + set_page_dirty: __set_page_dirty_nobuffers, };/*
mm/page-writeback.c renamed from mm/page-writeback.c~swap-set_page_dirty +1 -1
@@ -497,7 +497,7 @@ int __set_page_dirty_buffers(struct pagespin_lock (&mapping->private_lock); -if (page_has_buffers (page) && !PageSwapCache (page)) { +if (page_has_buffers (page)) {struct buffer_head *head =page_buffers (page);struct buffer_head *bh = head;
-
Quoted 3 lines · Andrew Morton
Give
swapper_spacea ->set_page_dirty()address_space_operation.
Remember that we don't need swapper_space at all?
All the underlying inodes have their own address spaces, and the SWP_ENTRY tells us what we need to know, to find the underlying address spaces.
swapper_space is just a master address space that overlays the underlying multiple address spaces. We can just look directly at the underlying ones...
Jeff
Quoted 7 lines · Jeff Garzik
Quoted 3 lines · Andrew Morton
Give
swapper_spacea ->set_page_dirty()address_space_operation.Remember that we don't need
swapper_spaceat all?
swapper_space makes some sense...
Quoted 7 lines
All the underlying inodes have their own address spaces, and the
SWP_ENTRYtells us what we need to know, to find the underlying address spaces.
swapper_spaceis just a master address space that overlays the underlying multiple address spaces. We can just look directly at the underlying ones...
Nope. swapper_space is a single, standalone mapping which implements its own (striped) I/O direct to block devices. To locate the blockdev it goes:
swap_files[type]->f_dentry->d_inode->i_bdev
Swap never talks to d_inode->i_mapping. If someone else is accessing that device then their view of the device will be via bdinode->i_mapping and is not coherent with swapper_space.
swapper_space can get at the underlying device via its own block
mapping function or via a swapfile's bmap() function. But either
way, it goes direct to the blockdev via brw_page().
All those inodes and file*'s are just a way for swap to get directly at the blockdev, which is a good thing for swap to be doing.
Yes, possibly we could stripe swap at the address_space level, and switch anon pages in and out of the individual blockdev mappings.
But that's more complex, and means that swap would have to be able to deal with external agents coming in and randomly locking its buffers and pages (it'll oops at present if that happens, but it can't because nobody can get at swapper_space's pages and buffers).
Plus the blockdev mapping uses PAGE_CACHE_SIZE pages, and swap
uses PAGE_SIZE pages. I do think the design is OK as-is.
-