ChangeSet 1.1276.8.4, 2004/01/28 12:28:51-08:00, zaitcev@redhat.com [PATCH] USB: fix 2.4 usbdevfs race > Date: Thu, 5 Jun 2003 02:15:06 -0400 > From: Johannes Erdfelt > The fix is to just move setting hub->children to later in the > enumeration process. This way usbdevfs_read_super won't see the device > before it has been through the usbdevfs_add_device path. > > I didn't see this on x86, but apparentely others have looking at the > RedHat 9 kernel sources. (RedHat bugzilla #81091) I am fully convinced that JE's fix is correct, but I'd like to keep this also: In Linux, type of a list head and a list element is the same, but functionally they are different. As we saw in 81091, it is advantageous to keep list element fields NULL to catch walking through unlinked elements and such. This is why list_del sets them to NULL. It differs from list heads, which are set to point to themselves, and this is what INIT_LIST_HEAD does. Essentially, we apply constructor of list heads to list elements, and it's incorrect, even though it works in inode.c. drivers/usb/inode.c | 4 ---- 1 files changed, 4 deletions(-) diff -Nru a/drivers/usb/inode.c b/drivers/usb/inode.c --- a/drivers/usb/inode.c Wed Jan 28 13:36:24 2004 +++ b/drivers/usb/inode.c Wed Jan 28 13:36:24 2004 @@ -158,9 +158,7 @@ inode->i_uid = inode->i_gid = 0; inode->i_size = 0; list_del(&inode->u.usbdev_i.slist); - INIT_LIST_HEAD(&inode->u.usbdev_i.slist); list_del(&inode->u.usbdev_i.dlist); - INIT_LIST_HEAD(&inode->u.usbdev_i.dlist); iput(inode); } @@ -512,8 +510,6 @@ inode->i_ctime = inode->i_mtime = inode->i_atime = CURRENT_TIME; inode->i_mode = S_IFREG; inode->i_gid = inode->i_uid = 0; - INIT_LIST_HEAD(&inode->u.usbdev_i.dlist); - INIT_LIST_HEAD(&inode->u.usbdev_i.slist); inode->u.usbdev_i.p.dev = NULL; inode->u.usbdev_i.p.bus = NULL; switch (ITYPE(inode->i_ino)) {