Some Loop Device Problems

Bruce Elliott (belliott@accessone.com)
Mon, 26 Feb 1996 00:14:56 PST


Some problems with the long-lost loop device:

loop.h should be in the normal include place, as it contains ioctl
definitions.

Loop needs its own real major number. I would suggest 10, as it
seems to be available now that character and block have gone their
separate ways. Note that 28 is not available.

The logic for "floating" major number should probably be removed,
as it was a work-around for the missing major number.

There is an apparent typing error in loop.h: a "5" should be "3".

The loop device length is not reset following "-d". This gives a
number of I/O errors if something like "wc /dev/loop0" is tried.

Buffer flushing is _very_ slow after a large number of loop writes.
Removing a call to ll_rw_block and some associated stuff seems to
fix this.

If the underlying file is unlinked while it is attached to a loop
device, the filesystem is corrupted. The problem is that the inode
and allocated blocks are not released when the file is eventually
detached.

My present diffs are below. They don't address the first three items
above.

======================================================================
--- linux.rels/drivers/block/loop.c Thu Feb 22 05:18:43 1996
+++ linux/drivers/block/loop.c Sat Feb 24 20:48:10 1996
@@ -29,7 +29,7 @@
#include "des.h"
#endif

-#define DEFAULT_MAJOR_NR 28
+#define DEFAULT_MAJOR_NR 10
int loop_major = DEFAULT_MAJOR_NR;
#define MAJOR_NR loop_major /* not necessarily constant */

@@ -225,15 +225,8 @@
brelse(bh);
goto error_out;
}
- if (CURRENT->cmd == WRITE) {
- set_bit(BH_Dirty, &bh->b_state);
- ll_rw_block(WRITE, 1, &bh);
- wait_on_buffer(bh);
- if (buffer_dirty(bh)) {
- brelse(bh);
- goto error_out;
- }
- }
+ if (CURRENT->cmd == WRITE)
+ mark_buffer_dirty(bh, 1);
brelse(bh);
dest_addr += size;
len -= size;
@@ -280,7 +273,7 @@
return -ENXIO;
if (lo->lo_refcnt > 1)
return -EBUSY;
- lo->lo_inode->i_count--;
+ iput(lo->lo_inode);
lo->lo_device = 0;
lo->lo_inode = NULL;
lo->lo_encrypt_type = 0;
@@ -288,6 +281,7 @@
lo->lo_encrypt_key_size = 0;
memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
memset(lo->lo_name, 0, LO_NAME_SIZE);
+ loop_sizes[lo->lo_number] = 0;
invalidate_buffers(dev);
return 0;
}
--- linux.rels/drivers/block/loop.h Thu Feb 22 04:40:01 1996
+++ linux/drivers/block/loop.h Fri Feb 23 01:09:48 1996
@@ -62,7 +62,7 @@
#define LO_CRYPT_NONE 0
#define LO_CRYPT_XOR 1
#define LO_CRYPT_DES 2
-#define LO_CRYPT_IDEA 5
+#define LO_CRYPT_IDEA 3
#define MAX_LO_CRYPT 4

/*
======================================================================

B. D. Elliott bde@accessone.com (Seattle)