reproducible bug in "loop.c" or linux kernel 2.2.16 (and earlier)

From: Wilfried Philips (philips@telin.rug.ac.be)
Date: Mon Jul 24 2000 - 18:18:02 EST


Hello,

when playing around with the "loop" driver I stumbled upon a nasty
bug that can be reproduced as follows
1. connect any file "test.file" to /dev/loop0
2. read data DIRECTLY from "test.file" (not using /dev/loop0)
3. now write other data to /dev/loop0 (in such a way that it should
end up in the blocks of "test.file" that were read in step 2)

The bug is that the data written in step 3 never makes it into
"test.file" even after executing "losetup -d /dev/loop0". The bug is
present in the 2.2.12, 2.2.14 and 2.2.16 kernels (and probably earlier
ones as well). The little script at the end reproduces the error.

I scanned the www for other reports of this problem and I found a couple of
reports that could be related to this problem (one dating back to
1996).

Is anybody aware of this problem? Are there any quick fixes? Can
anybody test if the problem also occurs in the 2.3. and 2.4. kernel
series?

On a related matter: the "loop" driver accesses "test.file" by
accessing blocks through the buffer cache, except when "test.file" is
sparse; in this case loop.c (create_missing_block) uses the
filesystem driver (by calling the "write" function stored in the
file_operations structure of the file descriptor). Could this not
cause a deadlock? (bdflush calls do_lo_request in loop.c, which calls
"write", which might have to wait until a free buffer become available).

 

Please also reply to my email-address.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
script that reproduces the error
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sudo rm -f test.file out.*
#create a file containing 4096 'a's and map it to loop0
dd if=/dev/zero bs=4096 count=1 | tr '\0x00' 'a'> test.file
sudo losetup /dev/loop0 test.file
#now read "test.file"; this should have no effect but it messes things up!
cat test.file > /dev/null #correct result is obtained if this line is removed!

#now write test data (all 'b's) to the loop device
dd if=/dev/zero bs=4096 count=1 |tr '\0x00' 'b'| sudo dd of=/dev/loop0

#now read back the written 'b's in different ways;
sudo dd if=/dev/loop0 bs=1024 count=1 of=out.1 # out.1 contains all 'b's (CORRECT)
cat test.file > out.2 # out.2 contains all 'a's (WRONG)

#finally demonstrate that the 'b's never make it to "test.file"
#even when the loop device is disconnected
sudo losetup -d /dev/loop0
cat test.file > out.3 # out.3 contains all 'a's (WRONG)

----
Support the anti-Spam amendment. Join at http://www.cauce.org/

Wilfried Philips Vakgroep TELIN (Telecommunicatie en Informatieverwerking) RUG St.-Pietersnieuwstraat 41, B9000 Gent, Belgium

Tel: 32-9-264.33.85 Fax: 32-9-264.42.95 Web: http://telin.rug.ac.be/~philips E-mail: philips@telin.rug.ac.be

----

- 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/



This archive was generated by hypermail 2b29 : Mon Jul 31 2000 - 21:00:18 EST