BUG_ON(subdir->nr_swapped > offset); 
BUG_ON(page_private(subdir) > offset); 
static void shmem_truncate(struct inode *inode){	struct shmem_inode_info *info = SHMEM_I(inode);	unsigned long idx;	unsigned long size;	unsigned long limit;	unsigned long stage;	unsigned long diroff;	struct page **dir;	struct page *topdir;	struct page *middir;	struct page *subdir;	swp_entry_t *ptr;	LIST_HEAD(pages_to_free);	long nr_pages_to_free = 0;	long nr_swaps_freed = 0;	int offset;	int freed;	inode->i_ctime = inode->i_mtime = CURRENT_TIME;	idx = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;	if (idx >= info->next_index)		return;	spin_lock(&info->lock);	info->flags |= SHMEM_TRUNCATE;	limit = info->next_index;	info->next_index = idx;	topdir = info->i_indirect;	if (topdir && idx <= SHMEM_NR_DIRECT) {		info->i_indirect = NULL;		nr_pages_to_free++;		list_add(&topdir->lru, &pages_to_free);	}	spin_unlock(&info->lock);	if (info->swapped && idx < SHMEM_NR_DIRECT) {		ptr = info->i_direct;		size = limit;		if (size > SHMEM_NR_DIRECT)			size = SHMEM_NR_DIRECT;		nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size);	}	if (!topdir)		goto done2;	BUG_ON(limit <= SHMEM_NR_DIRECT);	limit -= SHMEM_NR_DIRECT;	idx = (idx > SHMEM_NR_DIRECT)? (idx - SHMEM_NR_DIRECT): 0;	offset = idx % ENTRIES_PER_PAGE;	idx -= offset;	dir = shmem_dir_map(topdir);	stage = ENTRIES_PER_PAGEPAGE/2;	if (idx < ENTRIES_PER_PAGEPAGE/2) {		middir = topdir;		diroff = idx/ENTRIES_PER_PAGE;	} else {		dir += ENTRIES_PER_PAGE/2;		dir += (idx - ENTRIES_PER_PAGEPAGE/2)/ENTRIES_PER_PAGEPAGE;		while (stage <= idx)			stage += ENTRIES_PER_PAGEPAGE;		middir = *dir;		if (*dir) {			diroff = ((idx - ENTRIES_PER_PAGEPAGE/2) %				ENTRIES_PER_PAGEPAGE) / ENTRIES_PER_PAGE;			if (!diroff && !offset) {				*dir = NULL;				nr_pages_to_free++;				list_add(&middir->lru, &pages_to_free);			}			shmem_dir_unmap(dir);			dir = shmem_dir_map(middir);		} else {			diroff = 0;			offset = 0;			idx = stage;		}	}	for (; idx < limit; idx += ENTRIES_PER_PAGE, diroff++) {		if (unlikely(idx == stage)) {			shmem_dir_unmap(dir);			dir = shmem_dir_map(topdir) +			    ENTRIES_PER_PAGE/2 + idx/ENTRIES_PER_PAGEPAGE;			while (!*dir) {				dir++;				idx += ENTRIES_PER_PAGEPAGE;				if (idx >= limit)					goto done1;			}			stage = idx + ENTRIES_PER_PAGEPAGE;			middir = *dir;			*dir = NULL;			nr_pages_to_free++;			list_add(&middir->lru, &pages_to_free);			shmem_dir_unmap(dir);			cond_resched();			dir = shmem_dir_map(middir);			diroff = 0;		}		subdir = dir[diroff];		if (subdir && subdir->nr_swapped) {			size = limit - idx;			if (size > ENTRIES_PER_PAGE)				size = ENTRIES_PER_PAGE;			freed = shmem_map_and_free_swp(subdir,						offset, size, &dir);			if (!dir)				dir = shmem_dir_map(middir);			nr_swaps_freed += freed;			if (offset)				spin_lock(&info->lock);			subdir->nr_swapped -= freed;			if (offset)				spin_unlock(&info->lock);			BUG_ON(subdir->nr_swapped > offset);		}		if (offset)			offset = 0;		else if (subdir) {			dir[diroff] = NULL;			nr_pages_to_free++;			list_add(&subdir->lru, &pages_to_free);		}	}done1:	shmem_dir_unmap(dir);done2:	if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) {		/*		 * Call truncate_inode_pages again: racing shmem_unuse_inode		 * may have swizzled a page in from swap since vmtruncate or		 * generic_delete_inode did it, before we lowered next_index.		 * Also, though shmem_getpage checks i_size before adding to		 * cache, no recheck after: so fix the narrow window there too.		 */		truncate_inode_pages(inode->i_mapping, inode->i_size);	}	spin_lock(&info->lock);	info->flags &= ~SHMEM_TRUNCATE;	info->swapped -= nr_swaps_freed;	if (nr_pages_to_free)		shmem_free_blocks(inode, nr_pages_to_free);	shmem_recalc_inode(inode);	spin_unlock(&info->lock);	/*	 * Empty swap vector directory pages to be freed?	 */	if (!list_empty(&pages_to_free)) {		pages_to_free.prev->next = NULL;		shmem_free_pages(pages_to_free.next);	}}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/4c21e2f2441dc5fbb957b030333f5a3f2d02dea7/shmem.c/clean/mm/shmem.c