Matthew Wilcox <willy@xxxxxxxxxxxxx> writes: > If we call page_mapping(page) and PageSwapCache is true, we do this: > > if (unlikely(PageSwapCache(page))) { > swp_entry_t entry; > > entry.val = page_private(page); > return swap_address_space(entry); > } > > #define swap_address_space(entry) \ > (&swapper_spaces[swp_type(entry)][swp_offset(entry) \ > >> SWAP_ADDRESS_SPACE_SHIFT]) > > (i think we could make that more readable by adding > #define swp_as(entry) (swp_offset(entry) >> SWAP_ADDRESS_SPACE_SHIFT) > but i digress) Yes. This sounds good. > If, instead, we call page_file_mapping(page) and PageSwapCache is true, > we do this: > > return page_swap_info(page)->swap_file->f_mapping; > > struct swap_info_struct *page_swap_info(struct page *page) > { > swp_entry_t entry = { .val = page_private(page) }; > return swp_swap_info(entry); > } > > struct swap_info_struct *swp_swap_info(swp_entry_t entry) > { > return swap_type_to_swap_info(swp_type(entry)); > } > > static struct swap_info_struct *swap_type_to_swap_info(int type) > { > if (type >= READ_ONCE(nr_swapfiles)) > return NULL; > > smp_rmb(); /* Pairs with smp_wmb in alloc_swap_info. */ > return READ_ONCE(swap_info[type]); > } > > So ... are these different address spaces from each other? Yes. They are different. The address space from page_mapping(page) is used to hold pages in swap cache, they are not associated with some inodes in fact. While the address space from page_file_mapping(page) is used to read/write swap pages sometimes (please check __swap_writepage()). But page_file_mapping() isn't called there. Best Regards, Huang, Ying > If not, why do we have such a complicated way of finding the address > space for page_file_mapping()?