2004-06-04 15:15:41

by Jinu M.

[permalink] [raw]
Subject: removable media support on 2.6.x

Hi All,

We are developing a storage driver (block driver) on 2.6.x kernel. The
hardware we are using supports media removal on the fly. We are facing
some problem when the media is removed while the disk is mounted. The
system freezes and the module count never goes to zero.

This is what we do when the disk is removed on the fly.

disk_removed(...)
{
/* invalidate disk */
if(gDisk->bdev) {
invalidate_bdev(gDisk->bdev, 1);
bdput(gDisk->bdev);
}

/* indicates that no disk present */
set_capacity(gDisk->gd, 0);

/* cleanup gendisk */
del_gendisk(gDisk->gd);
put_disk(gDisk->gd);

/* clean up blkqueue */
blk_cleanup_queue(gDisk->blkqueue);
}

disk_removed() is called from the workqueue that is initiated from the
tasklet()<=isr() on card removal.

We guess invalidate_bdev() is the culprit ;) but would like to know
from you all if we are doing some mistake. Is there something missing
or something wrong in the way we are trying to provide removable media
support?

Thanks in advance,

-Jinu


2004-06-05 04:48:47

by Andrew Morton

[permalink] [raw]
Subject: Re: removable media support on 2.6.x

"Jinu M." <[email protected]> wrote:
>
> Hi All,
>
> We are developing a storage driver (block driver) on 2.6.x kernel. The
> hardware we are using supports media removal on the fly. We are facing
> some problem when the media is removed while the disk is mounted. The
> system freezes and the module count never goes to zero.
>
> This is what we do when the disk is removed on the fly.
>
> disk_removed(...)
> {
> /* invalidate disk */
> if(gDisk->bdev) {
> invalidate_bdev(gDisk->bdev, 1);
> bdput(gDisk->bdev);
> }
>
> /* indicates that no disk present */
> set_capacity(gDisk->gd, 0);
>
> /* cleanup gendisk */
> del_gendisk(gDisk->gd);
> put_disk(gDisk->gd);
>
> /* clean up blkqueue */
> blk_cleanup_queue(gDisk->blkqueue);
> }
>
> disk_removed() is called from the workqueue that is initiated from the
> tasklet()<=isr() on card removal.
>
> We guess invalidate_bdev() is the culprit ;) but would like to know
> from you all if we are doing some mistake. Is there something missing
> or something wrong in the way we are trying to provide removable media
> support?
>

afaik we don't really support hot unplug like this.

Changes were made a few months ago (make the VFS use file->f_mapping rather
than file->f_dentry->d_inode->i_mapping) which set some of the pieces in
place but I think there's a way to go yet.

umm, the general idea is that when the disk vanishes your driver should
then return -EIO for all future I/O requests. The block_device, the queue,
the inode and all that stuff remains in-core.

After device hot unplug we need to do <something> to disassociate the
defunct blockdev inode from the /dev/hdXX node. I think <something> hasn't
been coded yet.

Later, someone puts in new media and you can then access that via /dev/hdXX
- you get a brand new inode, blockdev, queue, etc. The old defunct one is
still alive, returning -EIO.

Eventually, all references to the old inode/blockdev/queue go away (due to
applications hitting EIO, etc). The old mountpoint can be unmounted and
this drops the final ref, so the old inode/blockdev/queue get freed up.

As I say, I don't think all of this is implemented yet, but perhaps a lot
of it is.

2004-06-05 05:12:17

by Jinu M.

[permalink] [raw]
Subject: RE: removable media support on 2.6.x

>
> afaik we don't really support hot unplug like this.
>
> Changes were made a few months ago (make the VFS use file->f_mapping
> rather
> than file->f_dentry->d_inode->i_mapping) which set some of the
> pieces in
> place but I think there's a way to go yet.
>
> umm, the general idea is that when the disk vanishes your driver
> should
> then return -EIO for all future I/O requests. The block_device, the
> queue,
> the inode and all that stuff remains in-core.

What we do with our 2.4 version of the driver is something on this
lines. When the media is removed we invalidate the buffers and then
set the card absent bit. Now on when read/write requests arrive we
return error status to the file system since card is absent. This worked
for 2.4.x.

Is there some existing driver which addresses removable media on 2.6.x
Kernel? I would like to see how it addresses this.. then I will have
a better idea to address it with the kernel support we have now.

-Jinu

2004-06-05 10:52:49

by Matthias Urlichs

[permalink] [raw]
Subject: RE: removable media support on 2.6.x

Hi, Jinu M. wrote:

> Is there some existing driver which addresses removable media on 2.6.x
> Kernel?

SCSI. USB sticks are SCSI disks in disguise; hotplugging works quite
well for them.

--
Matthias Urlichs

2004-06-05 21:34:16

by Grzegorz Kulewski

[permalink] [raw]
Subject: modprobing ACPI(?) module gives oops (2.6.7-rc2-mm2)

Hi,

You ACPI people (with great support from the USB people of course) are
really extremly powerful: you can break any kernel for me... :-)

2.6.6-mm4 worked ok while with 2.6.7-rc2-mm2 my (Gentoo) startup scripts
got this:

Jun 4 19:17:02 polb01 Unable to handle kernel paging request at virtual
address c04e8840
Jun 4 19:17:02 polb01 printing eip:
Jun 4 19:17:02 polb01 c03129ab
Jun 4 19:17:02 polb01 *pde = 00533027
Jun 4 19:17:02 polb01 *pte = 004e8000
Jun 4 19:17:02 polb01 Oops: 0002 [#1]
Jun 4 19:17:02 polb01 PREEMPT DEBUG_PAGEALLOC
Jun 4 19:17:02 polb01 Modules linked in: ac psmouse pppoatm atm
ppp_deflate zlib_deflate zlib_inflate ppp_generic slhc capability
commoncap unix
Jun 4 19:17:02 polb01 CPU: 0
Jun 4 19:17:02 polb01 EIP: 0060:[<c03129ab>] Not tainted VLI
Jun 4 19:17:02 polb01 EFLAGS: 00010246 (2.6.7-rc2-mm2)
Jun 4 19:17:02 polb01 EIP is at acpi_bus_register_driver+0xd3/0x173
Jun 4 19:17:02 polb01 eax: c04e8840 ebx: e5909160 ecx: 000001e2
edx: ffffffed
Jun 4 19:17:02 polb01 esi: 00000000 edi: e59092c0 ebp: de5bdf84
esp: de5bdf7c
Jun 4 19:17:02 polb01 ds: 007b es: 007b ss: 0068
Jun 4 19:17:02 polb01 Process modprobe (pid: 4996, threadinfo=de5bc000
task=de5ee9f0)
Jun 4 19:17:02 polb01 Stack: c044a9a0 de5bc000 de5bdf8c e590f032 de5bdfbc
c0140645 dd9b8f4c dee08eb0
Jun 4 19:17:02 polb01 dee08910 de3e0d4c de3e0d6c 00000000 de5bdfbc
4014b008 0805b168 40096b7b
Jun 4 19:17:02 polb01 de5bc000 c010583d 4014b008 0002e917 0805b168
0805b168 40096b7b 0805b168
Jun 4 19:17:02 polb01 Call Trace:
Jun 4 19:17:02 polb01 [<c0105e4a>] show_stack+0x7a/0x90
Jun 4 19:17:02 polb01 [<c0105fcd>] show_registers+0x14d/0x1b0
Jun 4 19:17:02 polb01 [<c01061c9>] die+0xf9/0x250
Jun 4 19:17:02 polb01 [<c01184e3>] do_page_fault+0x1d3/0x55b
Jun 4 19:17:02 polb01 [<c0105abd>] error_code+0x2d/0x38
Jun 4 19:17:02 polb01 [<e590f032>] init_module+0x32/0x51 [ac]
Jun 4 19:17:02 polb01 [<c0140645>] sys_init_module+0x1c5/0x390
Jun 4 19:17:02 polb01 [<c010583d>] sysenter_past_esp+0x52/0x71
Jun 4 19:17:02 polb01
Jun 4 19:17:02 polb01 Code: ac 89 45 c0 01 00 00 00 c7 05 b8 89 45 c0 1e
7d 42 c0 c7 05 bc 89 45 c0 59 01 00 00 89 1d 2c 8a 45 c0 c7 03 28 8a 45 c0
89 43 04 <89> 18 81 3d a8 89 45 c0 3c 4b 24 1d 74 1c 68 a8 89 45 c0 68 5b
Jun 4 19:17:02 polb01 <6>note: modprobe[4996] exited with preempt_count 1
Jun 4 19:17:02 polb01 Debug: sleeping function called from invalid
context at include/linux/rwsem.h:43
Jun 4 19:17:02 polb01 in_atomic():1, irqs_disabled():0
Jun 4 19:17:02 polb01 [<c0105e77>] dump_stack+0x17/0x20
Jun 4 19:17:02 polb01 [<c011c934>] __might_sleep+0xb4/0xe0
Jun 4 19:17:02 polb01 [<c012419f>] do_exit+0xaf/0x980
Jun 4 19:17:02 polb01 [<c010631b>] die+0x24b/0x250
Jun 4 19:17:02 polb01 [<c01184e3>] do_page_fault+0x1d3/0x55b
Jun 4 19:17:02 polb01 [<c0105abd>] error_code+0x2d/0x38
Jun 4 19:17:02 polb01 [<e590f032>] init_module+0x32/0x51 [ac]
Jun 4 19:17:02 polb01 [<c0140645>] sys_init_module+0x1c5/0x390
Jun 4 19:17:02 polb01 [<c010583d>] sysenter_past_esp+0x52/0x71
Jun 4 19:17:02 polb01
Jun 4 19:17:02 polb01 bad: scheduling while atomic!
Jun 4 19:17:02 polb01 [<c0105e77>] dump_stack+0x17/0x20
Jun 4 19:17:02 polb01 [<c03f2e57>] schedule+0x717/0x720
Jun 4 19:17:02 polb01 [<c015b0c0>] unmap_vmas+0x1f0/0x2e0
Jun 4 19:17:02 polb01 [<c0160ba8>] exit_mmap+0xc8/0x270
Jun 4 19:17:02 polb01 [<c011d7fe>] mmput+0xbe/0x140
Jun 4 19:17:02 polb01 [<c01242c4>] do_exit+0x1d4/0x980
Jun 4 19:17:02 polb01 [<c010631b>] die+0x24b/0x250
Jun 4 19:17:02 polb01 [<c01184e3>] do_page_fault+0x1d3/0x55b
Jun 4 19:17:02 polb01 [<c0105abd>] error_code+0x2d/0x38
Jun 4 19:17:02 polb01 [<e590f032>] init_module+0x32/0x51 [ac]
Jun 4 19:17:02 polb01 [<c0140645>] sys_init_module+0x1c5/0x390
Jun 4 19:17:02 polb01 [<c010583d>] sysenter_past_esp+0x52/0x71
Jun 4 19:17:02 polb01
Jun 4 19:17:02 polb01 drivers/acpi/scan.c:345:
spin_lock(drivers/acpi/scan.c:c04589a8) already locked by
drivers/acpi/scan.c/345


What can cause this? Is this a known problem or something new? What can I
do to help track this down?


Thanks in advance,

Grzegorz Kulewski