lkml.org 
[lkml]   [2004]   [Nov]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectTest patch for ub and double registration
Hello,

here's a patch to fix the double kobject registration problem with the ub.
One little problem here is that I do not have a device which fails this
way, so I would like owners of such devices to give it a try.

The latest victim of this is Fabio Coatti. It should be noted that this
fix only (supposed to) prevents oopses on deregistration. If the device
doesn't work generally (for example, requires START STOP UNIT), it won't
help that.

Clemens' bug report wasn't clear enough. It may be this, may be something
else.

The flash key given on KS does the same, but we worked around that
particular units with Ben Herrenschmidt, so they are not good test cases
anymore.

-- Pete

diff -urp -X dontdiff linux-2.6.10-rc1/drivers/block/ub.c linux-2.6.10-rc1-ub/drivers/block/ub.c
--- linux-2.6.10-rc1/drivers/block/ub.c 2004-10-28 09:46:38.000000000 -0700
+++ linux-2.6.10-rc1-ub/drivers/block/ub.c 2004-11-01 12:35:10.000000000 -0800
@@ -188,7 +188,7 @@ struct ub_capacity {
*/

#define SCMD_ST_HIST_SZ 8
-#define SCMD_TRACE_SZ 15 /* No more than 256 (trace_index) */
+#define SCMD_TRACE_SZ 63 /* Less than 4KB of 61-byte lines */

struct ub_scsi_cmd_trace {
int hcur;
@@ -267,6 +267,7 @@ struct ub_dev {
int changed; /* Media was changed */
int removable;
int readonly;
+ int first_open; /* Kludge. See ub_bd_open. */
char name[8];
struct usb_device *dev;
struct usb_interface *intf;
@@ -959,9 +957,12 @@ static void ub_scsi_urb_compl(struct ub_
ub_cmdtr_state(sc, cmd);
return;
}
- if (urb->status != 0)
+ if (urb->status != 0) {
+ printk("ub: cmd #%d cmd status (%d)\n", cmd->tag, urb->status); /* P3 */
goto Bad_End;
+ }
if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
+ printk("ub: cmd #%d xferred %d\n", cmd->tag, urb->actual_length); /* P3 */
/* XXX Must do reset here to unconfuse the device */
goto Bad_End;
}
@@ -1428,6 +1424,26 @@ static int ub_bd_open(struct inode *inod
sc->openc++;
spin_unlock_irqrestore(&ub_lock, flags);

+ /*
+ * This is a workaround for a specific problem in our block layer.
+ * In 2.6.9, register_disk duplicates the code from rescan_partitions.
+ * However, if we do add_disk with a device which persistently reports
+ * a changed media, add_disk calls register_disk, which does do_open,
+ * which will call rescan_paritions for changed media. After that,
+ * register_disk attempts to do it all again and causes double kobject
+ * registration and a eventually an oops on module removal.
+ *
+ * The bottom line is, Al Viro says that we should not allow
+ * bdev->bd_invalidated to be set when doing add_disk no matter what.
+ */
+ if (sc->first_open) {
+ if (sc->changed) {
+ sc->first_open = 0;
+ rc = -ENOMEDIUM;
+ goto err_open;
+ }
+ }
+
if (sc->removable || sc->readonly)
check_disk_change(inode->i_bdev);

@@ -1467,6 +1483,8 @@ static int ub_bd_release(struct inode *i

spin_lock_irqsave(&ub_lock, flags);
--sc->openc;
+ if (sc->openc == 0)
+ sc->first_open = 0;
if (sc->openc == 0 && atomic_read(&sc->poison))
ub_cleanup(sc);
spin_unlock_irqrestore(&ub_lock, flags);
@@ -1919,6 +1933,8 @@ static int ub_probe(struct usb_interface
}
sc->removable = 1; /* XXX Query this from the device */
+ sc->changed = 1; /* ub_revalidate clears only */
+ sc->first_open = 1;
ub_revalidate(sc);
/* This is pretty much a long term P3 */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 14:07    [W:0.055 / U:0.040 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site