patch-2.4.5 linux/drivers/usb/inode.c

Next file: linux/drivers/usb/mdc800.c
Previous file: linux/drivers/usb/ibmcam.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.4/linux/drivers/usb/inode.c linux/drivers/usb/inode.c
@@ -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);
@@ -689,8 +743,10 @@
 	}
 	if ((ret = usb_register(&usbdevfs_driver)))
 		return ret;
-	if ((ret = register_filesystem(&usbdevice_fs_type)))
+	if ((ret = register_filesystem(&usbdevice_fs_type))) {
 		usb_deregister(&usbdevfs_driver);
+		return ret;
+	}
 	kern_mount(&usbdevice_fs_type);
 #ifdef CONFIG_PROC_FS		
 	/* create mount point for usbdevfs */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)