diff options
| author | Rafael J. Wysocki <rjw@sisk.pl> | 2006-03-23 05:59:59 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-23 10:38:07 -0500 |
| commit | f577eb30afdc68233f25d4d82b04102129262365 (patch) | |
| tree | 25d3c2fa8dfbf42fd0d4776a36166736fcc1446a /mm | |
| parent | 2b322ce210aec74ae0d02938d3a01e29fe079469 (diff) | |
[PATCH] swsusp: low level interface
Introduce the low level interface that can be used for handling the
snapshot of the system memory by the in-kernel swap-writing/reading code of
swsusp and the userland interface code (to be introduced shortly).
Also change the way in which swsusp records the allocated swap pages and,
consequently, simplifies the in-kernel swap-writing/reading code (this is
necessary for the userland interface too). To this end, it introduces two
helper functions in mm/swapfile.c, so that the swsusp code does not refer
directly to the swap internals.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/swapfile.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c index 365ed6ff182d..4d11f9d84666 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
| @@ -45,7 +45,7 @@ static const char Unused_offset[] = "Unused swap offset entry "; | |||
| 45 | 45 | ||
| 46 | struct swap_list_t swap_list = {-1, -1}; | 46 | struct swap_list_t swap_list = {-1, -1}; |
| 47 | 47 | ||
| 48 | struct swap_info_struct swap_info[MAX_SWAPFILES]; | 48 | static struct swap_info_struct swap_info[MAX_SWAPFILES]; |
| 49 | 49 | ||
| 50 | static DEFINE_MUTEX(swapon_mutex); | 50 | static DEFINE_MUTEX(swapon_mutex); |
| 51 | 51 | ||
| @@ -417,6 +417,59 @@ void free_swap_and_cache(swp_entry_t entry) | |||
| 417 | } | 417 | } |
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | #ifdef CONFIG_SOFTWARE_SUSPEND | ||
| 421 | /* | ||
| 422 | * Find the swap type that corresponds to given device (if any) | ||
| 423 | * | ||
| 424 | * This is needed for software suspend and is done in such a way that inode | ||
| 425 | * aliasing is allowed. | ||
| 426 | */ | ||
| 427 | int swap_type_of(dev_t device) | ||
| 428 | { | ||
| 429 | int i; | ||
| 430 | |||
| 431 | if (!device) | ||
| 432 | return -EINVAL; | ||
| 433 | spin_lock(&swap_lock); | ||
| 434 | for (i = 0; i < nr_swapfiles; i++) { | ||
| 435 | struct inode *inode; | ||
| 436 | |||
| 437 | if (!(swap_info[i].flags & SWP_WRITEOK)) | ||
| 438 | continue; | ||
| 439 | inode = swap_info->swap_file->f_dentry->d_inode; | ||
| 440 | if (S_ISBLK(inode->i_mode) && | ||
| 441 | device == MKDEV(imajor(inode), iminor(inode))) { | ||
| 442 | spin_unlock(&swap_lock); | ||
| 443 | return i; | ||
| 444 | } | ||
| 445 | } | ||
| 446 | spin_unlock(&swap_lock); | ||
| 447 | return -ENODEV; | ||
| 448 | } | ||
| 449 | |||
| 450 | /* | ||
| 451 | * Return either the total number of swap pages of given type, or the number | ||
| 452 | * of free pages of that type (depending on @free) | ||
| 453 | * | ||
| 454 | * This is needed for software suspend | ||
| 455 | */ | ||
| 456 | unsigned int count_swap_pages(int type, int free) | ||
| 457 | { | ||
| 458 | unsigned int n = 0; | ||
| 459 | |||
| 460 | if (type < nr_swapfiles) { | ||
| 461 | spin_lock(&swap_lock); | ||
| 462 | if (swap_info[type].flags & SWP_WRITEOK) { | ||
| 463 | n = swap_info[type].pages; | ||
| 464 | if (free) | ||
| 465 | n -= swap_info[type].inuse_pages; | ||
| 466 | } | ||
| 467 | spin_unlock(&swap_lock); | ||
| 468 | } | ||
| 469 | return n; | ||
| 470 | } | ||
| 471 | #endif | ||
| 472 | |||
| 420 | /* | 473 | /* |
| 421 | * No need to decide whether this PTE shares the swap entry with others, | 474 | * No need to decide whether this PTE shares the swap entry with others, |
| 422 | * just let do_wp_page work it out if a write is requested later - to | 475 | * just let do_wp_page work it out if a write is requested later - to |
