diff options
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r-- | mm/swapfile.c | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c index 1f9cf0d073b8..39aa9d129612 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 | ||
@@ -116,7 +116,7 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si) | |||
116 | last_in_cluster = offset + SWAPFILE_CLUSTER; | 116 | last_in_cluster = offset + SWAPFILE_CLUSTER; |
117 | else if (offset == last_in_cluster) { | 117 | else if (offset == last_in_cluster) { |
118 | spin_lock(&swap_lock); | 118 | spin_lock(&swap_lock); |
119 | si->cluster_next = offset-SWAPFILE_CLUSTER-1; | 119 | si->cluster_next = offset-SWAPFILE_CLUSTER+1; |
120 | goto cluster; | 120 | goto cluster; |
121 | } | 121 | } |
122 | if (unlikely(--latency_ration < 0)) { | 122 | if (unlikely(--latency_ration < 0)) { |
@@ -417,6 +417,61 @@ 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 | spin_lock(&swap_lock); | ||
432 | for (i = 0; i < nr_swapfiles; i++) { | ||
433 | struct inode *inode; | ||
434 | |||
435 | if (!(swap_info[i].flags & SWP_WRITEOK)) | ||
436 | continue; | ||
437 | if (!device) { | ||
438 | spin_unlock(&swap_lock); | ||
439 | return i; | ||
440 | } | ||
441 | inode = swap_info->swap_file->f_dentry->d_inode; | ||
442 | if (S_ISBLK(inode->i_mode) && | ||
443 | device == MKDEV(imajor(inode), iminor(inode))) { | ||
444 | spin_unlock(&swap_lock); | ||
445 | return i; | ||
446 | } | ||
447 | } | ||
448 | spin_unlock(&swap_lock); | ||
449 | return -ENODEV; | ||
450 | } | ||
451 | |||
452 | /* | ||
453 | * Return either the total number of swap pages of given type, or the number | ||
454 | * of free pages of that type (depending on @free) | ||
455 | * | ||
456 | * This is needed for software suspend | ||
457 | */ | ||
458 | unsigned int count_swap_pages(int type, int free) | ||
459 | { | ||
460 | unsigned int n = 0; | ||
461 | |||
462 | if (type < nr_swapfiles) { | ||
463 | spin_lock(&swap_lock); | ||
464 | if (swap_info[type].flags & SWP_WRITEOK) { | ||
465 | n = swap_info[type].pages; | ||
466 | if (free) | ||
467 | n -= swap_info[type].inuse_pages; | ||
468 | } | ||
469 | spin_unlock(&swap_lock); | ||
470 | } | ||
471 | return n; | ||
472 | } | ||
473 | #endif | ||
474 | |||
420 | /* | 475 | /* |
421 | * No need to decide whether this PTE shares the swap entry with others, | 476 | * 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 | 477 | * just let do_wp_page work it out if a write is requested later - to |