Esempio n. 1
0
/*
 * Trying to stop swapping from a file is fraught with races, so
 * we repeat quite a bit here when we have to pause. swapoff()
 * isn't exactly timing-critical, so who cares (but this is /really/
 * inefficient, ugh).
 *
 * We return 1 after having slept, which makes the process start over
 * from the beginning for this process..
 */
static inline int unuse_pte(struct vm_area_struct * vma, unsigned long address,
	pte_t *dir, unsigned int type, unsigned long page)
{
	pte_t pte = *dir;

	if (pte_none(pte))
		return 0;
	if (pte_present(pte)) {
		unsigned long page_nr = MAP_NR(pte_page(pte));
		if (page_nr >= MAP_NR(high_memory))
			return 0;
		if (!in_swap_cache(page_nr))
			return 0;
		if (SWP_TYPE(in_swap_cache(page_nr)) != type)
			return 0;
		delete_from_swap_cache(page_nr);
		set_pte(dir, pte_mkdirty(pte));
		return 0;
	}
	if (SWP_TYPE(pte_val(pte)) != type)
		return 0;
	read_swap_page(pte_val(pte), (char *) page);
#if 0 /* Is this really needed here, hasn't it been solved elsewhere? */
	flush_page_to_ram(page);
#endif
	if (pte_val(*dir) != pte_val(pte)) {
		free_page(page);
		return 1;
	}
	set_pte(dir, pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))));
	flush_tlb_page(vma, address);
	++vma->vm_mm->rss;
	swap_free(pte_val(pte));
	return 1;
}
Esempio n. 2
0
void swap_in(unsigned long *table_ptr)
{
	int swap_nr;
	unsigned long page;

	if (!swap_bitmap) {
		printk("Trying to swap in without swap bit-map");
		return;
	}
	if (1 & *table_ptr) {
		printk("trying to swap in present page\n\r");
		return;
	}
	swap_nr = *table_ptr >> 1;
	if (!swap_nr) {
		printk("No swap page in swap_in\n\r");
		return;
	}
	if (!(page = get_free_page()))
		oom();
	read_swap_page(swap_nr, (char *) page);
	if (setbit(swap_bitmap,swap_nr))
		printk("swapping in multiply from same page\n\r");
	*table_ptr = page | (PAGE_DIRTY | 7);
}
Esempio n. 3
0
int sys_swapon(const char * specialfile)
{
	struct inode * swap_inode;
	int i,j;

	if (!suser())
		return -EPERM;
	if (!(swap_inode  = namei(specialfile)))
		return -ENOENT;
	if (swap_file || swap_device || swap_bitmap) {
		iput(swap_inode);
		return -EBUSY;
	}
	if (S_ISBLK(swap_inode->i_mode)) {
		swap_device = swap_inode->i_rdev;
		iput(swap_inode);
	} else if (S_ISREG(swap_inode->i_mode))
		swap_file = swap_inode;
	else {
		iput(swap_inode);
		return -EINVAL;
	}
	swap_bitmap = (char *) get_free_page();
	if (!swap_bitmap) {
		iput(swap_file);
		swap_device = 0;
		swap_file = NULL;
		printk("Unable to start swapping: out of memory :-)\n");
		return -ENOMEM;
	}
	read_swap_page(0,swap_bitmap);
	if (strncmp("SWAP-SPACE",swap_bitmap+4086,10)) {
		printk("Unable to find swap-space signature\n\r");
		free_page((long) swap_bitmap);
		iput(swap_file);
		swap_device = 0;
		swap_file = NULL;
		swap_bitmap = NULL;
		return -EINVAL;
	}
	memset(swap_bitmap+4086,0,10);
	j = 0;
	for (i = 1 ; i < SWAP_BITS ; i++)
		if (bit(swap_bitmap,i))
			j++;
	if (!j) {
		printk("Empty swap-file\n");
		free_page((long) swap_bitmap);
		iput(swap_file);
		swap_device = 0;
		swap_file = NULL;
		swap_bitmap = NULL;
		return -EINVAL;
	}
	printk("Adding Swap: %d pages (%d bytes) swap-space\n\r",j,j*4096);
	return 0;
}
Esempio n. 4
0
void swap_in(struct vm_area_struct * vma, pte_t * page_table,
        swap_entry_t entry, int write_access)
{
    unsigned long page;

    if(pte_val(*page_table) != entry.val)
    {
        return;
    }
    page = get_free_page(GFP_KERNEL);
    if(!page)
    {
        pte_val(*page_table) = PAGE_BAD;
        swap_free(entry);
        oom();
    }

    read_swap_page(entry,(char *)page);
    if(pte_val(*page_table) != entry.val)
    {
        return;
    }
    return ;
}