lkml.org 
[lkml]   [1999]   [May]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: 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/

\
 
 \ /
  Last update: 2005-03-22 13:52    [W:0.048 / U:0.328 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site