Hi.

This is a potential fix for http://bugme.osdl.org/show_bug.cgi?id=1418
(usbfs does not honor devgid and friends).

I created usb_apply_options, which does all the work. I am not too sure
about dentry locking (!), but mount/umount loop while pluging and
unpluging my webcam didn't do anything wierd.

I moved parse_options from usb_fill_super (called on first mount, which
is simple_pin_fs) to usb_get_sb.

Also reorganized usbfs_init a bit, but i can drop that, if it seems
unnecessary/too ugly to someone.

Signed-off-by: Domen Puncer <[EMAIL PROTECTED]>


diff -pruNX dontdiff c/drivers/usb/core/inode.c a/drivers/usb/core/inode.c
--- c/drivers/usb/core/inode.c  2004-06-16 07:18:57.000000000 +0200
+++ a/drivers/usb/core/inode.c  2004-07-14 17:36:00.000000000 +0200
@@ -83,6 +83,50 @@ static match_table_t tokens = {
        {Opt_err, NULL}
 };
 
+static void usb_apply_options(struct super_block *sb)
+{
+       struct list_head *list;
+
+       list_for_each(list, &sb->s_root->d_subdirs) {
+               struct iattr attr;
+               struct dentry *de;
+               struct list_head *list2;
+
+               de = list_entry(list, struct dentry, d_child);
+               attr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID;
+
+               if (S_ISDIR(de->d_inode->i_mode)) {
+                       attr.ia_mode = busmode | S_IFDIR;
+                       attr.ia_uid = busuid;
+                       attr.ia_gid = busgid;
+               } else {
+                       attr.ia_mode = listmode | S_IFREG;
+                       attr.ia_uid = listuid;
+                       attr.ia_gid = listgid;
+               }
+               down(&de->d_inode->i_sem);
+               notify_change(de, &attr);
+               up(&de->d_inode->i_sem);
+
+               if (!S_ISDIR(de->d_inode->i_mode))
+                       continue;
+               list_for_each(list2, &de->d_subdirs) {
+                       struct iattr attr2;
+                       struct dentry *de2;
+
+                       de2 = list_entry(list2, struct dentry, d_child);
+                       attr2.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID;
+                       attr2.ia_mode = devmode | S_IFREG;
+                       attr2.ia_uid = devuid;
+                       attr2.ia_gid = devgid;
+
+                       down(&de2->d_inode->i_sem);
+                       notify_change(de2, &attr2);
+                       up(&de2->d_inode->i_sem);
+               }
+       }
+}
+
 static int parse_options(struct super_block *s, char *data)
 {
        char *p;
@@ -147,6 +191,7 @@ static int parse_options(struct super_bl
                        return -EINVAL;
                }
        }
+       usb_apply_options(s);
 
        return 0;
 }
@@ -356,11 +401,6 @@ static int usbfs_fill_super(struct super
        struct inode *inode;
        struct dentry *root;
 
-       if (parse_options(sb, data)) {
-               warn("usbfs: mount parameter error:");
-               return -EINVAL;
-       }
-
        sb->s_blocksize = PAGE_CACHE_SIZE;
        sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
        sb->s_magic = USBDEVICE_SUPER_MAGIC;
@@ -499,7 +539,15 @@ static struct file_system_type usbdevice
 static struct super_block *usb_get_sb(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, usbfs_fill_super);
+       struct super_block *sb;
+
+       sb = get_sb_single(fs_type, flags, data, usbfs_fill_super);
+
+       if (parse_options(sb, data)) {
+               warn("usbfs: mount parameter error:");
+               return NULL;
+       }
+       return sb;
 }
 
 static struct file_system_type usbdevice_fs_type = {
@@ -732,7 +780,7 @@ void usbfs_remove_device(struct usb_devi
 /* --------------------------------------------------------------------- */
 
 #ifdef CONFIG_PROC_FS          
-static struct proc_dir_entry *usbdir = NULL;
+static struct proc_dir_entry *usbdir; /* = NULL */
 #endif 
 
 int __init usbfs_init(void)
@@ -744,16 +792,12 @@ int __init usbfs_init(void)
                return retval;
 
        retval = register_filesystem(&usb_fs_type);
-       if (retval) {
-               usb_deregister(&usbdevfs_driver);
-               return retval;
-       }
+       if (retval)
+               goto out_deregister;
+
        retval = register_filesystem(&usbdevice_fs_type);
-       if (retval) {
-               unregister_filesystem(&usb_fs_type);
-               usb_deregister(&usbdevfs_driver);
-               return retval;
-       }
+       if (retval)
+               goto out_unregister;
 
 #ifdef CONFIG_PROC_FS          
        /* create mount point for usbdevfs */
@@ -761,6 +805,12 @@ int __init usbfs_init(void)
 #endif 
 
        return 0;
+
+out_unregister:
+       unregister_filesystem(&usb_fs_type);
+out_deregister:
+       usb_deregister(&usbdevfs_driver);
+       return retval;
 }
 
 void usbfs_cleanup(void)


-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to