mm/swapfile.c
37811 /*
37812 * linux/mm/swapfile.c
37813 *
37814 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
37815 * Swap reorganised 29.12.95, Stephen Tweedie
37816 */
37817
37818 #include <linux/malloc.h>
37819 #include <linux/smp_lock.h>
37820 #include <linux/kernel_stat.h>
37821 #include <linux/swap.h>
37822 #include <linux/swapctl.h>
37823 #include <linux/blkdev.h> /* for blk_size */
37824 #include <linux/vmalloc.h>
37825 #include <linux/pagemap.h>
37826 #include <linux/shm.h>
37827
37828 #include <asm/pgtable.h>
37829
37830 unsigned int nr_swapfiles = 0;
37831
37832 struct swap_list_t swap_list = {-1, -1};
37833
37834 struct swap_info_struct swap_info[MAX_SWAPFILES];
37835
37836 #define SWAPFILE_CLUSTER 256
37837
37838 static inline int scan_swap_map(
37839 struct swap_info_struct *si)
37840 {
37841 unsigned long offset;
37842 /* We try to cluster swap pages by allocating them
37843 * sequentially in swap. Once we've allocated
37844 * SWAPFILE_CLUSTER pages this way, however, we resort
37845 * to first-free allocation, starting a new cluster.
37846 * This prevents us from scattering swap pages all over
37847 * the entire swap partition, so that we reduce overall
37848 * disk seek times between swap pages. -- sct */
37849 if (si->cluster_nr) {
37850 while (si->cluster_next <= si->highest_bit) {
37851 offset = si->cluster_next++;
37852 if (si->swap_map[offset])
37853 continue;
37854 if (test_bit(offset, si->swap_lockmap))
37855 continue;
37856 si->cluster_nr--;
37857 goto got_page;
37858 }
37859 }
37860 si->cluster_nr = SWAPFILE_CLUSTER;
37861 for (offset = si->lowest_bit;
37862 offset <= si->highest_bit ; offset++) {
37863 if (si->swap_map[offset])
37864 continue;
37865 if (test_bit(offset, si->swap_lockmap))
37866 continue;
37867 si->lowest_bit = offset;
37868 got_page:
37869 si->swap_map[offset] = 1;
37870 nr_swap_pages--;
37871 if (offset == si->highest_bit)
37872 si->highest_bit--;
37873 si->cluster_next = offset;
37874 return offset;
37875 }
37876 return 0;
37877 }
37878
37879 unsigned long get_swap_page(void)
37880 {
37881 struct swap_info_struct * p;
37882 unsigned long offset, entry;
37883 int type, wrapped = 0;
37884
37885 type = swap_list.next;
37886 if (type < 0)
37887 return 0;
37888 if (nr_swap_pages == 0)
37889 return 0;
37890
37891 while (1) {
37892 p = &swap_info[type];
37893 if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
37894 offset = scan_swap_map(p);
37895 if (offset) {
37896 entry = SWP_ENTRY(type,offset);
37897 type = swap_info[type].next;
37898 if (type < 0 ||
37899 p->prio != swap_info[type].prio)
37900 {
37901 swap_list.next = swap_list.head;
37902 }
37903 else
37904 {
37905 swap_list.next = type;
37906 }
37907 return entry;
37908 }
37909 }
37910 type = p->next;
37911 if (!wrapped) {
37912 if (type < 0 || p->prio != swap_info[type].prio) {
37913 type = swap_list.head;
37914 wrapped = 1;
37915 }
37916 } else if (type < 0) {
37917 return 0; /* out of swap space */
37918 }
37919 }
37920 }
37921
37922
37923 void swap_free(unsigned long entry)
37924 {
37925 struct swap_info_struct * p;
37926 unsigned long offset, type;
37927
37928 if (!entry)
37929 goto out;
37930
37931 type = SWP_TYPE(entry);
37932 if (type & SHM_SWP_TYPE)
37933 goto out;
37934 if (type >= nr_swapfiles)
37935 goto bad_nofile;
37936 p = & swap_info[type];
37937 if (!(p->flags & SWP_USED))
37938 goto bad_device;
37939 if (p->prio > swap_info[swap_list.next].prio)
37940 swap_list.next = swap_list.head;
37941 offset = SWP_OFFSET(entry);
37942 if (offset >= p->max)
37943 goto bad_offset;
37944 if (offset < p->lowest_bit)
37945 p->lowest_bit = offset;
37946 if (offset > p->highest_bit)
37947 p->highest_bit = offset;
37948 if (!p->swap_map[offset])
37949 goto bad_free;
37950 if (p->swap_map[offset] < SWAP_MAP_MAX) {
37951 if (!--p->swap_map[offset])
37952 nr_swap_pages++;
37953 }
37954 #ifdef DEBUG_SWAP
37955 printk("DebugVM: "
37956 "swap_free(entry %08lx, count now %d)\n",
37957 entry, p->swap_map[offset]);
37958 #endif
37959 out:
37960 return;
37961
37962 bad_nofile:
37963 printk("swap_free: "
37964 "Trying to free nonexistent swap-page\n");
37965 goto out;
37966 bad_device:
37967 printk("swap_free: "
37968 "Trying to free swap from unused swap-device\n");
37969 goto out;
37970 bad_offset:
37971 printk("swap_free: offset exceeds max\n");
37972 goto out;
37973 bad_free:
37974 printk("swap_free: "
37975 "swap-space map bad (entry %08lx)\n",entry);
37976 goto out;
37977 }
37978
37979 /* The swap entry has been read in advance, and we return
37980 * 1 to indicate that the page has been used or is no
37981 * longer needed.
37982 *
37983 * Always set the resulting pte to be nowrite (the same
37984 * as COW pages after one process has exited). We don't
37985 * know just how many PTEs will share this swap entry, so
37986 * be cautious and let do_wp_page work out what to do if
37987 * a write is requested later. */
37988 static inline void unuse_pte(struct vm_area_struct * vma,
37989 unsigned long address, pte_t *dir, unsigned long entry,
37990 unsigned long page)
37991 {
37992 pte_t pte = *dir;
37993
37994 if (pte_none(pte))
37995 return;
37996 if (pte_present(pte)) {
37997 /* If this entry is swap-cached, then page must
37998 * already hold the right address for any copies in
37999 * physical memory */
38000 if (pte_page(pte) != page)
38001 return;
38002 /* We will be removing the swap cache in a moment,
38003 * so... */
38004 set_pte(dir, pte_mkdirty(pte));
38005 return;
38006 }
38007 if (pte_val(pte) != entry)
38008 return;
38009 set_pte(dir, pte_mkdirty(mk_pte(page,
38010 vma->vm_page_prot)));
38011 swap_free(entry);
38012 atomic_inc(&mem_map[MAP_NR(page)].count);
38013 ++vma->vm_mm->rss;
38014 }
38015
38016 static inline void unuse_pmd(struct vm_area_struct * vma,
38017 pmd_t *dir, unsigned long address, unsigned long size,
38018 unsigned long offset, unsigned long entry,
38019 unsigned long page)
38020 {
38021 pte_t * pte;
38022 unsigned long end;
38023
38024 if (pmd_none(*dir))
38025 return;
38026 if (pmd_bad(*dir)) {
38027 printk("unuse_pmd: bad pmd (%08lx)\n",pmd_val(*dir));
38028 pmd_clear(dir);
38029 return;
38030 }
38031 pte = pte_offset(dir, address);
38032 offset += address & PMD_MASK;
38033 address &= ~PMD_MASK;
38034 end = address + size;
38035 if (end > PMD_SIZE)
38036 end = PMD_SIZE;
38037 do {
38038 unuse_pte(vma, offset+address-vma->vm_start, pte,
38039 entry, page);
38040 address += PAGE_SIZE;
38041 pte++;
38042 } while (address < end);
38043 }
38044
38045 static inline void unuse_pgd(struct vm_area_struct * vma,
38046 pgd_t *dir, unsigned long address, unsigned long size,
38047 unsigned long entry, unsigned long page)
38048 {
38049 pmd_t * pmd;
38050 unsigned long offset, end;
38051
38052 if (pgd_none(*dir))
38053 return;
38054 if (pgd_bad(*dir)) {
38055 printk("unuse_pgd: bad pgd (%08lx)\n",pgd_val(*dir));
38056 pgd_clear(dir);
38057 return;
38058 }
38059 pmd = pmd_offset(dir, address);
38060 offset = address & PGDIR_MASK;
38061 address &= ~PGDIR_MASK;
38062 end = address + size;
38063 if (end > PGDIR_SIZE)
38064 end = PGDIR_SIZE;
38065 do {
38066 unuse_pmd(vma, pmd, address, end - address, offset,
38067 entry, page);
38068 address = (address + PMD_SIZE) & PMD_MASK;
38069 pmd++;
38070 } while (address < end);
38071 }
38072
38073 static void unuse_vma(struct vm_area_struct * vma,
38074 pgd_t *pgdir, unsigned long entry, unsigned long page)
38075 {
38076 unsigned long start = vma->vm_start, end = vma->vm_end;
38077
38078 while (start < end) {
38079 unuse_pgd(vma, pgdir, start, end - start, entry,
38080 page);
38081 start = (start + PGDIR_SIZE) & PGDIR_MASK;
38082 pgdir++;
38083 }
38084 }
38085
38086 static void unuse_process(struct mm_struct * mm,
38087 unsigned long entry, unsigned long page)
38088 {
38089 struct vm_area_struct* vma;
38090
38091 /* Go through process's page directory. */
38092 if (!mm || mm == &init_mm)
38093 return;
38094 for (vma = mm->mmap; vma; vma = vma->vm_next) {
38095 pgd_t * pgd = pgd_offset(mm, vma->vm_start);
38096 unuse_vma(vma, pgd, entry, page);
38097 }
38098 return;
38099 }
38100
38101 /* We completely avoid races by reading each swap page in
38102 * advance, and then search for the process using it.
38103 * All the necessary page table adjustments can then be
38104 * made atomically. */
38105 static int try_to_unuse(unsigned int type)
38106 {
38107 struct swap_info_struct * si = &swap_info[type];
38108 struct task_struct *p;
38109 struct page *page_map;
38110 unsigned long entry, page;
38111 int i;
38112
38113 while (1) {
38114 /* Find a swap page in use and read it in. */
38115 for (i = 1; i < si->max ; i++) {
38116 if (si->swap_map[i] > 0 &&
38117 si->swap_map[i] != SWAP_MAP_BAD) {
38118 goto found_entry;
38119 }
38120 }
38121 break;
38122
38123 found_entry:
38124 entry = SWP_ENTRY(type, i);
38125
38126 /* Get a page for the entry, using the existing swap
38127 * cache page if there is one. Otherwise, get a
38128 * clean page and read the swap into it. */
38129 page_map = read_swap_cache(entry);
38130 if (!page_map) {
38131 /* Continue searching if entry became unused. */
38132 if (si->swap_map[i] == 0)
38133 continue;
38134 return -ENOMEM;
38135 }
38136 page = page_address(page_map);
38137 read_lock(&tasklist_lock);
38138 for_each_task(p)
38139 unuse_process(p->mm, entry, page);
38140 read_unlock(&tasklist_lock);
38141 shm_unuse(entry, page);
38142 /* Now get rid of the extra reference to the
38143 * temporary page we've been using. */
38144 if (PageSwapCache(page_map))
38145 delete_from_swap_cache(page_map);
38146 __free_page(page_map);
38147 /* Check for and clear any overflowed swap map
38148 * counts. */
38149 if (si->swap_map[i] != 0) {
38150 if (si->swap_map[i] != SWAP_MAP_MAX)
38151 printk(KERN_ERR
38152 "try_to_unuse: entry %08lx count=%d\n",
38153 entry, si->swap_map[i]);
38154 si->swap_map[i] = 0;
38155 nr_swap_pages++;
38156 }
38157 }
38158 return 0;
38159 }
38160
38161 asmlinkage int sys_swapoff(const char * specialfile)
38162 {
38163 struct swap_info_struct * p = NULL;
38164 struct dentry * dentry;
38165 struct file filp;
38166 int i, type, prev;
38167 int err = -EPERM;
38168
38169 lock_kernel();
38170 if (!capable(CAP_SYS_ADMIN))
38171 goto out;
38172
38173 dentry = namei(specialfile);
38174 err = PTR_ERR(dentry);
38175 if (IS_ERR(dentry))
38176 goto out;
38177
38178 prev = -1;
38179 for (type = swap_list.head; type >= 0;
38180 type = swap_info[type].next) {
38181 p = swap_info + type;
38182 if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
38183 if (p->swap_file) {
38184 if (p->swap_file == dentry)
38185 break;
38186 } else {
38187 if (S_ISBLK(dentry->d_inode->i_mode) &&
38188 (p->swap_device == dentry->d_inode->i_rdev))
38189 break;
38190 }
38191 }
38192 prev = type;
38193 }
38194 err = -EINVAL;
38195 if (type < 0)
38196 goto out_dput;
38197
38198 if (prev < 0) {
38199 swap_list.head = p->next;
38200 } else {
38201 swap_info[prev].next = p->next;
38202 }
38203 if (type == swap_list.next) {
38204 /* just pick something that's safe... */
38205 swap_list.next = swap_list.head;
38206 }
38207 p->flags = SWP_USED;
38208 err = try_to_unuse(type);
38209 if (err) {
38210 /* re-insert swap space back into swap_list */
38211 for (prev = -1, i = swap_list.head; i >= 0;
38212 prev = i, i = swap_info[i].next)
38213 if (p->prio >= swap_info[i].prio)
38214 break;
38215 p->next = i;
38216 if (prev < 0)
38217 swap_list.head = swap_list.next = p - swap_info;
38218 else
38219 swap_info[prev].next = p - swap_info;
38220 p->flags = SWP_WRITEOK;
38221 goto out_dput;
38222 }
38223 if(p->swap_device){
38224 memset(&filp, 0, sizeof(filp));
38225 filp.f_dentry = dentry;
38226 filp.f_mode = 3; /* read write */
38227 /* open it again to get fops */
38228 if( !blkdev_open(dentry->d_inode, &filp) &&
38229 filp.f_op && filp.f_op->release){
38230 filp.f_op->release(dentry->d_inode,&filp);
38231 filp.f_op->release(dentry->d_inode,&filp);
38232 }
38233 }
38234 dput(dentry);
38235
38236 dentry = p->swap_file;
38237 p->swap_file = NULL;
38238 nr_swap_pages -= p->pages;
38239 p->swap_device = 0;
38240 vfree(p->swap_map);
38241 p->swap_map = NULL;
38242 vfree(p->swap_lockmap);
38243 p->swap_lockmap = NULL;
38244 p->flags = 0;
38245 err = 0;
38246
38247 out_dput:
38248 dput(dentry);
38249 out:
38250 unlock_kernel();
38251 return err;
38252 }
38253
38254 int get_swaparea_info(char *buf)
38255 {
38256 char * page = (char *) __get_free_page(GFP_KERNEL);
38257 struct swap_info_struct *ptr = swap_info;
38258 int i, j, len = 0, usedswap;
38259
38260 if (!page)
38261 return -ENOMEM;
38262
38263 len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed"
38264 "\tPriority\n");
38265 for (i = 0 ; i < nr_swapfiles ; i++, ptr++) {
38266 if (ptr->flags & SWP_USED) {
38267 char * path = d_path(ptr->swap_file, page,
38268 PAGE_SIZE);
38269
38270 len += sprintf(buf + len, "%-31s ", path);
38271
38272 if (!ptr->swap_device)
38273 len += sprintf(buf + len, "file\t\t");
38274 else
38275 len += sprintf(buf + len, "partition\t");
38276
38277 usedswap = 0;
38278 for (j = 0; j < ptr->max; ++j)
38279 switch (ptr->swap_map[j]) {
38280 case SWAP_MAP_BAD:
38281 case 0:
38282 continue;
38283 default:
38284 usedswap++;
38285 }
38286 len +=
38287 sprintf(buf + len, "%d\t%d\t%d\n",
38288 ptr->pages << (PAGE_SHIFT - 10),
38289 usedswap << (PAGE_SHIFT - 10),ptr->prio);
38290 }
38291 }
38292 free_page((unsigned long) page);
38293 return len;
38294 }
38295
38296 /* Written 01/25/92 by Simmule Turner, heavily changed by
38297 * Linus.
38298 *
38299 * The swapon system call */
38300 asmlinkage int sys_swapon(const char * specialfile,
38301 int swap_flags)
38302 {
38303 struct swap_info_struct * p;
38304 struct dentry * swap_dentry;
38305 unsigned int type;
38306 int i, j, prev;
38307 int error = -EPERM;
38308 struct file filp;
38309 static int least_priority = 0;
38310 union swap_header *swap_header = 0;
38311 int swap_header_version;
38312 int lock_map_size = PAGE_SIZE;
38313 int nr_good_pages = 0;
38314 unsigned long tmp_lock_map = 0;
38315
38316 lock_kernel();
38317 if (!capable(CAP_SYS_ADMIN))
38318 goto out;
38319 memset(&filp, 0, sizeof(filp));
38320 p = swap_info;
38321 for (type = 0 ; type < nr_swapfiles ; type++,p++)
38322 if (!(p->flags & SWP_USED))
38323 break;
38324 if (type >= MAX_SWAPFILES)
38325 goto out;
38326 if (type >= nr_swapfiles)
38327 nr_swapfiles = type+1;
38328 p->flags = SWP_USED;
38329 p->swap_file = NULL;
38330 p->swap_device = 0;
38331 p->swap_map = NULL;
38332 p->swap_lockmap = NULL;
38333 p->lowest_bit = 0;
38334 p->highest_bit = 0;
38335 p->cluster_nr = 0;
38336 p->max = 1;
38337 p->next = -1;
38338 if (swap_flags & SWAP_FLAG_PREFER) {
38339 p->prio = (swap_flags & SWAP_FLAG_PRIO_MASK)
38340 >> SWAP_FLAG_PRIO_SHIFT;
38341 } else {
38342 p->prio = --least_priority;
38343 }
38344 swap_dentry = namei(specialfile);
38345 error = PTR_ERR(swap_dentry);
38346 if (IS_ERR(swap_dentry))
38347 goto bad_swap_2;
38348
38349 p->swap_file = swap_dentry;
38350 error = -EINVAL;
38351
38352 if (S_ISBLK(swap_dentry->d_inode->i_mode)) {
38353 p->swap_device = swap_dentry->d_inode->i_rdev;
38354 set_blocksize(p->swap_device, PAGE_SIZE);
38355
38356 filp.f_dentry = swap_dentry;
38357 filp.f_mode = 3; /* read write */
38358 error = blkdev_open(swap_dentry->d_inode, &filp);
38359 if (error)
38360 goto bad_swap_2;
38361 set_blocksize(p->swap_device, PAGE_SIZE);
38362 error = -ENODEV;
38363 if (!p->swap_device ||
38364 (blk_size[MAJOR(p->swap_device)] &&
38365 !blk_size[MAJOR(p->swap_device)]
38366 [MINOR(p->swap_device)]))
38367 goto bad_swap;
38368 error = -EBUSY;
38369 for (i = 0 ; i < nr_swapfiles ; i++) {
38370 if (i == type)
38371 continue;
38372 if (p->swap_device == swap_info[i].swap_device)
38373 goto bad_swap;
38374 }
38375 } else if (S_ISREG(swap_dentry->d_inode->i_mode)) {
38376 error = -EBUSY;
38377 for (i = 0 ; i < nr_swapfiles ; i++) {
38378 if (i == type)
38379 continue;
38380 if (swap_dentry->d_inode ==
38381 swap_info[i].swap_file->d_inode)
38382 goto bad_swap;
38383 }
38384 } else
38385 goto bad_swap;
38386
38387 swap_header = (void *) __get_free_page(GFP_USER);
38388 if (!swap_header) {
38389 printk("Unable to start swapping: "
38390 "out of memory :-)\n");
38391 error = -ENOMEM;
38392 goto bad_swap;
38393 }
38394
38395 p->swap_lockmap = (char *) &tmp_lock_map;
38396 rw_swap_page_nocache(READ, SWP_ENTRY(type,0),
38397 (char *) swap_header);
38398 p->swap_lockmap = NULL;
38399
38400 if (!memcmp("SWAP-SPACE", swap_header->magic.magic,10))
38401 swap_header_version = 1;
38402 else if (!memcmp("SWAPSPACE2",
38403 swap_header->magic.magic, 10))
38404 swap_header_version = 2;
38405 else {
38406 printk("Unable to find swap-space signature\n");
38407 error = -EINVAL;
38408 goto bad_swap;
38409 }
38410
38411 switch (swap_header_version) {
38412 case 1:
38413 memset(((char *) swap_header)+PAGE_SIZE-10,0,10);
38414 j = 0;
38415 p->lowest_bit = 0;
38416 p->highest_bit = 0;
38417 for (i = 1 ; i < 8*PAGE_SIZE ; i++) {
38418 if (test_bit(i,(char *) swap_header)) {
38419 if (!p->lowest_bit)
38420 p->lowest_bit = i;
38421 p->highest_bit = i;
38422 p->max = i+1;
38423 j++;
38424 }
38425 }
38426 nr_good_pages = j;
38427 p->swap_map = vmalloc(p->max * sizeof(short));
38428 if (!p->swap_map) {
38429 error = -ENOMEM;
38430 goto bad_swap;
38431 }
38432 for (i = 1 ; i < p->max ; i++) {
38433 if (test_bit(i,(char *) swap_header))
38434 p->swap_map[i] = 0;
38435 else
38436 p->swap_map[i] = SWAP_MAP_BAD;
38437 }
38438 break;
38439
38440 case 2:
38441 /* Check the swap header's sub-version and the size
38442 * of the swap file and bad block lists */
38443 if (swap_header->info.version != 1) {
38444 printk(KERN_WARNING
38445 "Unable to handle swap header version %d\n",
38446 swap_header->info.version);
38447 error = -EINVAL;
38448 goto bad_swap;
38449 }
38450
38451 p->lowest_bit = 1;
38452 p->highest_bit = swap_header->info.last_page - 1;
38453 p->max = swap_header->info.last_page;
38454
38455 error = -EINVAL;
38456 if (swap_header->info.nr_badpages >
38457 MAX_SWAP_BADPAGES)
38458 goto bad_swap;
38459 if (p->max >= SWP_OFFSET(SWP_ENTRY(0,~0UL)))
38460 goto bad_swap;
38461
38462 /* OK, set up the swap map and apply the bad block
38463 * list */
38464 if (!(p->swap_map =
38465 vmalloc(p->max * sizeof(short)))) {
38466 error = -ENOMEM;
38467 goto bad_swap;
38468 }
38469
38470 error = 0;
38471 memset(p->swap_map, 0, p->max * sizeof(short));
38472 for (i=0; i<swap_header->info.nr_badpages; i++) {
38473 int page = swap_header->info.badpages[i];
38474 if (page <= 0 ||
38475 page >= swap_header->info.last_page)
38476 error = -EINVAL;
38477 else
38478 p->swap_map[page] = SWAP_MAP_BAD;
38479 }
38480 nr_good_pages = swap_header->info.last_page - i;
38481 lock_map_size = (p->max + 7) / 8;
38482 if (error)
38483 goto bad_swap;
38484 }
38485
38486 if (!nr_good_pages) {
38487 printk(KERN_WARNING "Empty swap-file\n");
38488 error = -EINVAL;
38489 goto bad_swap;
38490 }
38491 p->swap_map[0] = SWAP_MAP_BAD;
38492 if (!(p->swap_lockmap = vmalloc (lock_map_size))) {
38493 error = -ENOMEM;
38494 goto bad_swap;
38495 }
38496 memset(p->swap_lockmap,0,lock_map_size);
38497 p->flags = SWP_WRITEOK;
38498 p->pages = nr_good_pages;
38499 nr_swap_pages += nr_good_pages;
38500 printk(KERN_INFO
38501 "Adding Swap: %dk swap-space (priority %d)\n",
38502 nr_good_pages<<(PAGE_SHIFT-10), p->prio);
38503
38504 /* insert swap space into swap_list: */
38505 prev = -1;
38506 for (i = swap_list.head; i >= 0;
38507 i = swap_info[i].next) {
38508 if (p->prio >= swap_info[i].prio) {
38509 break;
38510 }
38511 prev = i;
38512 }
38513 p->next = i;
38514 if (prev < 0) {
38515 swap_list.head = swap_list.next = p - swap_info;
38516 } else {
38517 swap_info[prev].next = p - swap_info;
38518 }
38519 error = 0;
38520 goto out;
38521 bad_swap:
38522 if(filp.f_op && filp.f_op->release)
38523 filp.f_op->release(filp.f_dentry->d_inode,&filp);
38524 bad_swap_2:
38525 if (p->swap_lockmap)
38526 vfree(p->swap_lockmap);
38527 if (p->swap_map)
38528 vfree(p->swap_map);
38529 dput(p->swap_file);
38530 p->swap_device = 0;
38531 p->swap_file = NULL;
38532 p->swap_map = NULL;
38533 p->swap_lockmap = NULL;
38534 p->flags = 0;
38535 if (!(swap_flags & SWAP_FLAG_PREFER))
38536 ++least_priority;
38537 out:
38538 if (swap_header)
38539 free_page((long) swap_header);
38540 unlock_kernel();
38541 return error;
38542 }
38543
38544 void si_swapinfo(struct sysinfo *val)
38545 {
38546 unsigned int i, j;
38547
38548 val->freeswap = val->totalswap = 0;
38549 for (i = 0; i < nr_swapfiles; i++) {
38550 if ((swap_info[i].flags & SWP_WRITEOK) !=
38551 SWP_WRITEOK)
38552 continue;
38553 for (j = 0; j < swap_info[i].max; ++j)
38554 switch (swap_info[i].swap_map[j]) {
38555 case SWAP_MAP_BAD:
38556 continue;
38557 case 0:
38558 ++val->freeswap;
38559 default:
38560 ++val->totalswap;
38561 }
38562 }
38563 val->freeswap <<= PAGE_SHIFT;
38564 val->totalswap <<= PAGE_SHIFT;
38565 return;
38566 }
Сайт управляется системой
uCoz