int nr_good_pages = 0; int nr_extents; 
unsigned int nr_good_pages = 0; int nr_extents = 0; 
asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags){	struct swap_info_struct * p;	char *name = NULL;	struct block_device *bdev = NULL;	struct file *swap_file = NULL;	struct address_space *mapping;	unsigned int type;	int i, prev;	int error;	static int least_priority;	union swap_header *swap_header = NULL;	int swap_header_version;	int nr_good_pages = 0;	int nr_extents;	sector_t span;	unsigned long maxpages = 1;	int swapfilesize;	unsigned short *swap_map;	struct page *page = NULL;	struct inode *inode = NULL;	int did_down = 0;	if (!capable(CAP_SYS_ADMIN))		return -EPERM;	swap_list_lock();	p = swap_info;	for (type = 0 ; type < nr_swapfiles ; type++,p++)		if (!(p->flags & SWP_USED))			break;	error = -EPERM;	/*	 * Test if adding another swap device is possible. There are	 * two limiting factors: 1) the number of bits for the swap	 * type swp_entry_t definition and 2) the number of bits for	 * the swap type in the swap ptes as defined by the different	 * architectures. To honor both limitations a swap entry	 * with swap offset 0 and swap type ~0UL is created, encoded	 * to a swap pte, decoded to a swp_entry_t again and finally	 * the swap type part is extracted. This will mask all bits	 * from the initial ~0UL that can't be encoded in either the	 * swp_entry_t or the architecture definition of a swap pte.	 */	if (type > swp_type(pte_to_swp_entry(swp_entry_to_pte(swp_entry(~0UL,0))))) {		swap_list_unlock();		goto out;	}	if (type >= nr_swapfiles)		nr_swapfiles = type+1;	INIT_LIST_HEAD(&p->extent_list);	p->flags = SWP_USED;	p->swap_file = NULL;	p->old_block_size = 0;	p->swap_map = NULL;	p->lowest_bit = 0;	p->highest_bit = 0;	p->cluster_nr = 0;	p->inuse_pages = 0;	spin_lock_init(&p->sdev_lock);	p->next = -1;	if (swap_flags & SWAP_FLAG_PREFER) {		p->prio =		  (swap_flags & SWAP_FLAG_PRIO_MASK)>>SWAP_FLAG_PRIO_SHIFT;	} else {		p->prio = --least_priority;	}	swap_list_unlock();	name = getname(specialfile);	error = PTR_ERR(name);	if (IS_ERR(name)) {		name = NULL;		goto bad_swap_2;	}	swap_file = filp_open(name, O_RDWR|O_LARGEFILE, 0);	error = PTR_ERR(swap_file);	if (IS_ERR(swap_file)) {		swap_file = NULL;		goto bad_swap_2;	}	p->swap_file = swap_file;	mapping = swap_file->f_mapping;	inode = mapping->host;	error = -EBUSY;	for (i = 0; i < nr_swapfiles; i++) {		struct swap_info_struct *q = &swap_info[i];		if (i == type || !q->swap_file)			continue;		if (mapping == q->swap_file->f_mapping)			goto bad_swap;	}	error = -EINVAL;	if (S_ISBLK(inode->i_mode)) {		bdev = I_BDEV(inode);		error = bd_claim(bdev, sys_swapon);		if (error < 0) {			bdev = NULL;			goto bad_swap;		}		p->old_block_size = block_size(bdev);		error = set_blocksize(bdev, PAGE_SIZE);		if (error < 0)			goto bad_swap;		p->bdev = bdev;	} else if (S_ISREG(inode->i_mode)) {		p->bdev = inode->i_sb->s_bdev;		down(&inode->i_sem);		did_down = 1;		if (IS_SWAPFILE(inode)) {			error = -EBUSY;			goto bad_swap;		}	} else {		goto bad_swap;	}	swapfilesize = i_size_read(inode) >> PAGE_SHIFT;	/*	 * Read the swap header.	 */	if (!mapping->a_ops->readpage) {		error = -EINVAL;		goto bad_swap;	}	page = read_cache_page(mapping, 0,			(filler_t *)mapping->a_ops->readpage, swap_file);	if (IS_ERR(page)) {		error = PTR_ERR(page);		goto bad_swap;	}	wait_on_page_locked(page);	if (!PageUptodate(page))		goto bad_swap;	kmap(page);	swap_header = page_address(page);	if (!memcmp("SWAP-SPACE",swap_header->magic.magic,10))		swap_header_version = 1;	else if (!memcmp("SWAPSPACE2",swap_header->magic.magic,10))		swap_header_version = 2;	else {		printk("Unable to find swap-space signature\n");		error = -EINVAL;		goto bad_swap;	}		switch (swap_header_version) {	case 1:		printk(KERN_ERR "version 0 swap is no longer supported. "			"Use mkswap -v1 %s\n", name);		error = -EINVAL;		goto bad_swap;	case 2:		/* Check the swap header's sub-version and the size of                   the swap file and bad block lists */		if (swap_header->info.version != 1) {			printk(KERN_WARNING			       "Unable to handle swap header version %d\n",			       swap_header->info.version);			error = -EINVAL;			goto bad_swap;		}		p->lowest_bit  = 1;		/*		 * Find out how many pages are allowed for a single swap		 * device. There are two limiting factors: 1) the number of		 * bits for the swap offset in the swp_entry_t type and		 * 2) the number of bits in the a swap pte as defined by		 * the different architectures. In order to find the		 * largest possible bit mask a swap entry with swap type 0		 * and swap offset ~0UL is created, encoded to a swap pte,		 * decoded to a swp_entry_t again and finally the swap		 * offset is extracted. This will mask all the bits from		 * the initial ~0UL mask that can't be encoded in either		 * the swp_entry_t or the architecture definition of a		 * swap pte.		 */		maxpages = swp_offset(pte_to_swp_entry(swp_entry_to_pte(swp_entry(0,~0UL)))) - 1;		if (maxpages > swap_header->info.last_page)			maxpages = swap_header->info.last_page;		p->highest_bit = maxpages - 1;		error = -EINVAL;		if (!maxpages)			goto bad_swap;		if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode))			goto bad_swap;		if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)			goto bad_swap;				/* OK, set up the swap map and apply the bad block list */		if (!(p->swap_map = vmalloc(maxpages * sizeof(short)))) {			error = -ENOMEM;			goto bad_swap;		}		error = 0;		memset(p->swap_map, 0, maxpages * sizeof(short));		for (i=0; i<swap_header->info.nr_badpages; i++) {			int page = swap_header->info.badpages[i];			if (page <= 0 || page >= swap_header->info.last_page)				error = -EINVAL;			else				p->swap_map[page] = SWAP_MAP_BAD;		}		nr_good_pages = swap_header->info.last_page -				swap_header->info.nr_badpages -				1 /* header page */;		if (error) 			goto bad_swap;	}	if (swapfilesize && maxpages > swapfilesize) {		printk(KERN_WARNING		       "Swap area shorter than signature indicates\n");		error = -EINVAL;		goto bad_swap;	}	if (nr_good_pages) {		p->swap_map[0] = SWAP_MAP_BAD;		p->max = maxpages;		p->pages = nr_good_pages;		nr_extents = setup_swap_extents(p, &span);		if (nr_extents < 0) {			error = nr_extents;			goto bad_swap;		}		nr_good_pages = p->pages;	}	if (!nr_good_pages) {		printk(KERN_WARNING "Empty swap-file\n");		error = -EINVAL;		goto bad_swap;	}	down(&swapon_sem);	swap_list_lock();	swap_device_lock(p);	p->flags = SWP_ACTIVE;	nr_swap_pages += nr_good_pages;	total_swap_pages += nr_good_pages;	printk(KERN_INFO "Adding %dk swap on %s.  "			"Priority:%d extents:%d across:%lluk\n",		nr_good_pages<<(PAGE_SHIFT-10), name, p->prio,		nr_extents, (unsigned long long)span<<(PAGE_SHIFT-10));	/* insert swap space into swap_list: */	prev = -1;	for (i = swap_list.head; i >= 0; i = swap_info[i].next) {		if (p->prio >= swap_info[i].prio) {			break;		}		prev = i;	}	p->next = i;	if (prev < 0) {		swap_list.head = swap_list.next = p - swap_info;	} else {		swap_info[prev].next = p - swap_info;	}	swap_device_unlock(p);	swap_list_unlock();	up(&swapon_sem);	error = 0;	goto out;bad_swap:	if (bdev) {		set_blocksize(bdev, p->old_block_size);		bd_release(bdev);	}	destroy_swap_extents(p);bad_swap_2:	swap_list_lock();	swap_map = p->swap_map;	p->swap_file = NULL;	p->swap_map = NULL;	p->flags = 0;	if (!(swap_flags & SWAP_FLAG_PREFER))		++least_priority;	swap_list_unlock();	vfree(swap_map);	if (swap_file)		filp_close(swap_file, NULL);out:	if (page && !IS_ERR(page)) {		kunmap(page);		page_cache_release(page);	}	if (name)		putname(name);	if (did_down) {		if (!error)			inode->i_flags |= S_SWAPFILE;		up(&inode->i_sem);	}	return error;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/6eb396dc4a9781c5e7951143ab56ce5710687ab3/swapfile.c/clean/mm/swapfile.c