Here is a patch which makes usbdevfs use the mount options.

The problem was, the options were being parsed at super_block
read-time; for a non-single fs, a new super_block is created every mount,
thus the super_block read was happening every mount and the options got
parsed and used.  But with a FS_SINGLE, the super_block is only read at
kern_mount() time, which is usbdevfs_init().  Subsequent mounts are now
actually 'remounts' and unless remount_fs() is defined the options are
ignored.

This implements remount_fs(), which does nothing more than parse the
options and reset all inode's values.  The option parsing is moved out of
the usbdevfs_read_super() into its own function.

I noticed that fs/super.c, get_sb_single() calls do_remount_sb() but
doesn't care if it succeeds or fails.  Is this a bug?

Anyway here's the patch, against 2.4.4.



diff -ur 2.4.4-clean/drivers/usb/inode.c linux/drivers/usb/inode.c
--- 2.4.4-clean/drivers/usb/inode.c     Fri Mar  2 16:47:21 2001
+++ linux/drivers/usb/inode.c   Mon May 21 15:44:36 2001
@@ -43,6 +43,11 @@
 
 /* --------------------------------------------------------------------- */
 
+/*
+ * This list of superblocks is still used,
+ * but since usbdevfs became FS_SINGLE
+ * there is only one super_block.
+ */
 static LIST_HEAD(superlist);
 
 struct special {
@@ -159,6 +164,97 @@
        iput(inode);
 }
 
+static int parse_options(struct super_block *s, char *data)
+{
+       uid_t devuid = 0, busuid = 0, listuid = 0;
+       gid_t devgid = 0, busgid = 0, listgid = 0;
+       umode_t devmode = S_IWUSR | S_IRUGO, busmode = S_IXUGO | S_IRUGO, listmode = 
+S_IRUGO;
+       char *curopt = NULL, *value;
+
+       /* parse options */
+       if (data)
+               curopt = strtok(data, ",");
+       for (; curopt; curopt = strtok(NULL, ",")) {
+               if ((value = strchr(curopt, '=')) != NULL)
+                       *value++ = 0;
+               if (!strcmp(curopt, "devuid")) {
+                       if (!value || !value[0])
+                               return -EINVAL;
+                       devuid = simple_strtoul(value, &value, 0);
+                       if (*value)
+                               return -EINVAL;
+               }
+               if (!strcmp(curopt, "devgid")) {
+                       if (!value || !value[0])
+                               return -EINVAL;
+                       devgid = simple_strtoul(value, &value, 0);
+                       if (*value)
+                               return -EINVAL;
+               }
+               if (!strcmp(curopt, "devmode")) {
+                       if (!value || !value[0])
+                               return -EINVAL;
+                       devmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
+                       if (*value)
+                               return -EINVAL;
+               }
+               if (!strcmp(curopt, "busuid")) {
+                       if (!value || !value[0])
+                               return -EINVAL;
+                       busuid = simple_strtoul(value, &value, 0);
+                       if (*value)
+                               return -EINVAL;
+               }
+               if (!strcmp(curopt, "busgid")) {
+                       if (!value || !value[0])
+                               return -EINVAL;
+                       busgid = simple_strtoul(value, &value, 0);
+                       if (*value)
+                               return -EINVAL;
+               }
+               if (!strcmp(curopt, "busmode")) {
+                       if (!value || !value[0])
+                               return -EINVAL;
+                       busmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
+                       if (*value)
+                               return -EINVAL;
+               }
+               if (!strcmp(curopt, "listuid")) {
+                       if (!value || !value[0])
+                               return -EINVAL;
+                       listuid = simple_strtoul(value, &value, 0);
+                       if (*value)
+                               return -EINVAL;
+               }
+               if (!strcmp(curopt, "listgid")) {
+                       if (!value || !value[0])
+                               return -EINVAL;
+                       listgid = simple_strtoul(value, &value, 0);
+                       if (*value)
+                               return -EINVAL;
+               }
+               if (!strcmp(curopt, "listmode")) {
+                       if (!value || !value[0])
+                               return -EINVAL;
+                       listmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
+                       if (*value)
+                               return -EINVAL;
+               }
+       }
+
+       s->u.usbdevfs_sb.devuid = devuid;
+       s->u.usbdevfs_sb.devgid = devgid;
+       s->u.usbdevfs_sb.devmode = devmode;
+       s->u.usbdevfs_sb.busuid = busuid;
+       s->u.usbdevfs_sb.busgid = busgid;
+       s->u.usbdevfs_sb.busmode = busmode;
+       s->u.usbdevfs_sb.listuid = listuid;
+       s->u.usbdevfs_sb.listgid = listgid;
+       s->u.usbdevfs_sb.listmode = listmode;
+
+       return 0;
+}
+
 static struct usb_bus *usbdevfs_findbus(int busnr)
 {
         struct list_head *list;
@@ -460,10 +556,47 @@
         return 0;
 }
 
+static int usbdevfs_remount(struct super_block *s, int *flags, char *data)
+{
+       struct list_head *ilist = s->u.usbdevfs_sb.ilist.next;
+       struct inode *inode;
+       int ret;
+
+       if ((ret = parse_options(s, data))) {
+               printk(KERN_WARNING "usbdevfs: remount parameter error\n");
+               return ret;
+       }
+
+       for (; ilist != &s->u.usbdevfs_sb.ilist; ilist = ilist->next) {
+               inode = list_entry(ilist, struct inode, u.usbdev_i.slist);
+
+               switch (ITYPE(inode->i_ino)) {
+                       case ISPECIAL :
+                               inode->i_uid = s->u.usbdevfs_sb.listuid;
+                               inode->i_gid = s->u.usbdevfs_sb.listgid;
+                               inode->i_mode = s->u.usbdevfs_sb.listmode | S_IFREG;
+                               break;
+                       case IBUS :
+                               inode->i_uid = s->u.usbdevfs_sb.busuid;
+                               inode->i_gid = s->u.usbdevfs_sb.busgid;
+                               inode->i_mode = s->u.usbdevfs_sb.busmode | S_IFDIR;
+                               break;
+                       case IDEVICE :
+                               inode->i_uid = s->u.usbdevfs_sb.devuid;
+                               inode->i_gid = s->u.usbdevfs_sb.devgid;
+                               inode->i_mode = s->u.usbdevfs_sb.devmode | S_IFREG;
+                               break;
+               }
+       }
+
+       return 0;
+}
+
 static struct super_operations usbdevfs_sops = { 
        read_inode:     usbdevfs_read_inode,
        put_super:      usbdevfs_put_super,
        statfs:         usbdevfs_statfs,
+       remount_fs:     usbdevfs_remount,
 };
 
 struct super_block *usbdevfs_read_super(struct super_block *s, void *data, int silent)
@@ -472,81 +605,12 @@
        struct list_head *blist;
        struct usb_bus *bus;
        unsigned int i;
-       uid_t devuid = 0, busuid = 0, listuid = 0;
-       gid_t devgid = 0, busgid = 0, listgid = 0;
-       umode_t devmode = S_IWUSR | S_IRUGO, busmode = S_IXUGO | S_IRUGO, listmode = 
S_IRUGO;
-       char *curopt = NULL, *value;
 
-       /* parse options */
-       if (data)
-               curopt = strtok(data, ",");
-       for (; curopt; curopt = strtok(NULL, ",")) {
-               if ((value = strchr(curopt, '=')) != NULL)
-                       *value++ = 0;
-               if (!strcmp(curopt, "devuid")) {
-                       if (!value || !value[0])
-                               goto opterr;
-                       devuid = simple_strtoul(value, &value, 0);
-                       if (*value)
-                               goto opterr;
-               }
-               if (!strcmp(curopt, "devgid")) {
-                       if (!value || !value[0])
-                               goto opterr;
-                       devgid = simple_strtoul(value, &value, 0);
-                       if (*value)
-                               goto opterr;
-               }
-               if (!strcmp(curopt, "devmode")) {
-                       if (!value || !value[0])
-                               goto opterr;
-                       devmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
-                       if (*value)
-                               goto opterr;
-               }
-               if (!strcmp(curopt, "busuid")) {
-                       if (!value || !value[0])
-                               goto opterr;
-                       busuid = simple_strtoul(value, &value, 0);
-                       if (*value)
-                               goto opterr;
-               }
-               if (!strcmp(curopt, "busgid")) {
-                       if (!value || !value[0])
-                               goto opterr;
-                       busgid = simple_strtoul(value, &value, 0);
-                       if (*value)
-                               goto opterr;
-               }
-               if (!strcmp(curopt, "busmode")) {
-                       if (!value || !value[0])
-                               goto opterr;
-                       busmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
-                       if (*value)
-                               goto opterr;
-               }
-               if (!strcmp(curopt, "listuid")) {
-                       if (!value || !value[0])
-                               goto opterr;
-                       listuid = simple_strtoul(value, &value, 0);
-                       if (*value)
-                               goto opterr;
-               }
-               if (!strcmp(curopt, "listgid")) {
-                       if (!value || !value[0])
-                               goto opterr;
-                       listgid = simple_strtoul(value, &value, 0);
-                       if (*value)
-                               goto opterr;
-               }
-               if (!strcmp(curopt, "listmode")) {
-                       if (!value || !value[0])
-                               goto opterr;
-                       listmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;
-                       if (*value)
-                               goto opterr;
-               }
+       if (parse_options(s, data)) {
+               printk(KERN_WARNING "usbdevfs: mount parameter error\n");
+               return NULL;
        }
+
        /* fill superblock */
         s->s_blocksize = 1024;
         s->s_blocksize_bits = 10;
@@ -554,12 +618,6 @@
         s->s_op = &usbdevfs_sops;
        INIT_LIST_HEAD(&s->u.usbdevfs_sb.slist);
        INIT_LIST_HEAD(&s->u.usbdevfs_sb.ilist);
-       s->u.usbdevfs_sb.devuid = devuid;
-       s->u.usbdevfs_sb.devgid = devgid;
-       s->u.usbdevfs_sb.devmode = devmode;
-       s->u.usbdevfs_sb.busuid = busuid;
-       s->u.usbdevfs_sb.busgid = busgid;
-       s->u.usbdevfs_sb.busmode = busmode;
        root_inode = iget(s, IROOT);
         if (!root_inode)
                 goto out_no_root;
@@ -570,9 +628,9 @@
        for (i = 0; i < NRSPECIAL; i++) {
                if (!(inode = iget(s, IROOT+1+i)))
                        continue;
-               inode->i_uid = listuid;
-               inode->i_gid = listgid;
-               inode->i_mode = listmode | S_IFREG;
+               inode->i_uid = s->u.usbdevfs_sb.listuid;
+               inode->i_gid = s->u.usbdevfs_sb.listgid;
+               inode->i_mode = s->u.usbdevfs_sb.listmode | S_IFREG;
                special[i].inode = inode;
                list_add_tail(&inode->u.usbdev_i.slist, &s->u.usbdevfs_sb.ilist);
                list_add_tail(&inode->u.usbdev_i.dlist, &special[i].inodes);
@@ -590,10 +648,6 @@
         printk("usbdevfs_read_super: get root inode failed\n");
         iput(root_inode);
         return NULL;
-
- opterr:
-        printk(KERN_WARNING "usbdevfs: mount parameter error\n");
-       return NULL;
 }
 
 static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, FS_SINGLE);
diff -ur 2.4.4-clean/include/linux/usbdev_fs_sb.h linux/include/linux/usbdev_fs_sb.h
--- 2.4.4-clean/include/linux/usbdev_fs_sb.h    Mon Jan 10 14:32:48 2000
+++ linux/include/linux/usbdev_fs_sb.h  Mon May 21 03:23:31 2001
@@ -7,4 +7,7 @@
        uid_t busuid;
        gid_t busgid;
        umode_t busmode;
+       uid_t listuid;
+       gid_t listgid;
+       umode_t listmode;
 };



_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
http://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to