Messages in this thread | | | Date | Tue, 1 Jun 1999 02:38:08 +0200 | From | Michel Kaempf <> | Subject | Re: errors/oopses when turning off a swap file |
| |
On Sat, May 29, 1999, Michel Kaempf wrote: > [6.] A small shell script or example program which triggers the problem : > ------------------------------------------------------------------------- > #! /bin/sh > > cd /usr/local > dd if=/dev/zero of=swap bs=1024 count=1024 > mkswap swap > swapon swap > swapon swap > swapoff swap > swapon swap
I found out, in the sys_swapon() function (mm/swapfile.c), where the problem comes from :
1/ Before the first `swapon' command :
* nr_swapfiles == 2
2/ When `swapon' is called for the first time, sys_swapon() looks for a free `swap_info_struct' :
* type == 1 * nr_swapfiles == 2
3/ When `swapon' is called for the second time, sys_swapon() has to increase `nr_swapfiles' in order to find a free `swap_info_struct' :
>> if (type >= nr_swapfiles) >> nr_swapfiles = type+1;
* type == 2 * nr_swapfiles == 3
But after having found this free structure, sys_swapon() returns the error `-EBUSY' because it founds out that the swapfile `/usr/local/swap' was already beeing used.
4/ Then `swapoff' is called, it frees the `type == 2' structure and leaves `nr_swapfiles' untouched :
* nr_swapfiles == 3
5/ When `swapon' is called for the last time, it founds out that the `type == 1' structure is free :
* type == 1 * nr_swapfiles == 3
But sys_swapon() checks whether this swapfile is already used or not :
>> error = -EBUSY; >> for (i = 0 ; i < nr_swapfiles ; i++) >> { >> if (i == type) >> continue; >> if (swap_dentry->d_inode == swap_info[i].swap_file->d_inode) >> goto bad_swap; >> }
And here is the problem : when `i == (nr_swapfiles-1) == 2', `swap_info[i].swap_file == NULL' because this structure was freed by the `swapoff' command => `swap_info[i].swap_file->d_inode' triggers an oops.
This could solve the problem :
>> if ( (i == type) || (swap_info[i].swap_file == NULL) ) >> continue;
but the fact that there are free structures below the `nr_swapfiles' limit also produces oopses in the get_swaparea_info() function : sometimes we have `ptr->swap_map == NULL' in the following loop :
>> for (j = 0; j < ptr->max; ++j) >> { >> switch (ptr->swap_map[j]) >> { >> case SWAP_MAP_BAD: >> case 0: >> continue; >> default: >> usedswap++; >> } >> }
I hope that this will help solving the problem.
-- Michel "MaXX" Kaempf
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |