2002-08-13 12:52:52

by Adam J. Richter

[permalink] [raw]
Subject: Patch: linux-2.5.31/drivers/block/loop.c update



This is a newer version of the "big cleanup" for loop.c
that I previous posted for 2.5.30. This version has the following
new additions:

1. bio remapping works. It replaces the loop devices
queue->make_request_fn with a very function. The flag that was
previously used to try to implement this is gone now. However,
I'm thinking of deleting the bio remapping optimization from loop.c,
as it only applies to running a loop device that is backed by a
hardware block device, with not encryption or other data transformation.
I think the only thing that that might be useful for would be
eliminating disk partitions, and and that is something that I'd
rather look at after the lvm2 device mapper is integrated.

2. The max_loops module parameter is gone. loop.c now
has no pamaeters for sysadmins to worry about. Instead, loop
devices are creates as they are needed. /dev/loop/n+1 is created
when /dev/loop/n is opened. Loop devices that have been created
but are not configured use very little memory anyhow.

3. Fixed a bug involving a loop device backed by a file, where
the loop device had a file system with block size of smaller than a
page. This could cause the loop device to attempt to tell
address_space_operations->{prepare,commit}_write to write beyond the
end of a page. I found this bug after making script of a few simple
regression tests.

4. Changed structure initializers to C99 format.

Except for "to do" item #2, everything below this line is
basically a rehash of my notes from the previous loop.c patch
that I posted (for 2.5.30).
----------------------------------------------------------------------

This version also has the changes that were in the
previous loop.c patch that I posted:

5. Elminated a bug that caused the loop device to try
to transfer n*(n+1)/2 pages when given a bvec with n bios. I believe
this was what was causing loop.c to run out memory. bio_copy failures
should be much more rare, although I have yet to include code like
Jari's to actually work around bio failures.

6. Each /dev/loop device now exports the DMA parameters of
its underlying device. So, bio producers can submit bios at the
maximum size that the underlying device can handle.

7. Space for loop devices is kmalloc'ed as they are set up,
rather than space for a fixed number of devices being preallocated.

8. bio_copy never copies data, although there is one
data copy that occurs when a loop device is backed by a file,
without any data transformation. Previously loop.c would
ask bio_copy to copy the data, but would never use it. It was just
a waste of cpu time.

9. Deleted some unnecessary locking, and replaced lo_sem with
lo_thread_exited (a struct completion rather than a semaphore, making
it smaller and avoiding a potential problem with waiting on a
semaphore to deallocate memory that it occupies as described to me by
some nice people on irc.kernelnewbies.org whose names I don't
remember).


Known bug:

1. The module referencing counting in fs/block_dev.c does not
get along well with this. After creating and deleting
a loop device, the reference count of the modules is -1.
I think this is probably a bug in block_dev.c.

To do:

1. Accomodate bio_copy failures by reserving one page (or
q->hardsect_size, whichever is greater. I have not done
this yet because I want to at least make some changes to bio.c

2. Possibly integrate changes by Jari Ruusu and Andrew Morton
to support files that lack
address_space_operations->{prepare,commit}_write, by using
struct file_operations methods instead. I don't currently
understand if there is a 'legitimate" reason for a writeable
file system not to provide {prepare,commit}_write operations
for plane files. tmpfs is an example of this.

3. After the device mapper from lvm2 is integrated into 2.5,
consider porting the "transform" functionality to it and
seeing if we can the eliminate loop.c.

--
Adam J. Richter __ ______________ 575 Oroville Road
[email protected] \ / Milpitas, California 95035
+1 408 309-6081 | g g d r a s i l United States of America
"Free Software For The Rest Of Us."


Attachments:
(No filename) (4.20 kB)
loop.diffs (29.22 kB)
Download all attachments

2002-08-15 12:32:23

by Adam J. Richter

[permalink] [raw]
Subject: Re: Patch: linux-2.5.31/drivers/block/loop.c update

Here is another update to loop.c, as a patch against
pristine linux-2.5.31.

This patch adds support for loop devices backed by
files on file systems that do not provide
address_space_operations->{prepare,commit}_write, by using
file_operations->{read,write} instead. The change is based on patches
by Jari Ruusu and Andrew Morton. It includes an optimization,
pointed out by Andrew Morton, that avoids an extra data copy
in the common case of using a loop device that has no data
tranformation and is backed by a tmpfs file.

I've also dropped the "bio remapping" optimization that I
actually got working in my previous patch, because it only optimized
the case of a loop device backed by a block device with no data
transformation, in which case there isn't much need for the loop
device.

There is some code in this version to preallocate a page
for dealing with memory allocation failures in the IO path, but
I have not put in the IO path changes to make use of it yet.
The primary difference between this approach and Jari's is
that I want to reserve just one page (or queue->hardsect_size
bytes if that is more than a page) and be able to handle bio's
bigger than that (by splitting them up in the event of memory
allocation failure).

--
Adam J. Richter __ ______________ 575 Oroville Road
[email protected] \ / Milpitas, California 95035
+1 408 309-6081 | g g d r a s i l United States of America
"Free Software For The Rest Of Us."


Attachments:
(No filename) (1.48 kB)
loop.diff (37.02 kB)
Download all attachments