📄 inode.c
字号:
return -1; } return pos;}static int usbdevfs_bus_readdir(struct file *filp, void *dirent, filldir_t filldir){ struct inode *inode = filp->f_dentry->d_inode; unsigned long ino = inode->i_ino; struct usb_bus *bus; /* sanity check */ if (ITYPE(ino) != IBUS) return -EINVAL; switch ((unsigned int)filp->f_pos) { case 0: if (filldir(dirent, ".", 1, filp->f_pos, ino) < 0) return 0; filp->f_pos++; /* fall through */ case 1: if (filldir(dirent, "..", 2, filp->f_pos, IROOT) < 0) return 0; filp->f_pos++; /* fall through */ default: lock_kernel(); bus = usbdevfs_findbus(IBUSNR(ino)); bus_readdir(bus->root_hub, IDEVICE | ((bus->busnum & 0xff) << 8), filp->f_pos-2, filp, dirent, filldir); unlock_kernel(); return 0; }}static struct file_operations usbdevfs_root_file_operations = { readdir: usbdevfs_root_readdir,};static struct inode_operations usbdevfs_root_inode_operations = { lookup: usbdevfs_root_lookup,};static struct file_operations usbdevfs_bus_file_operations = { readdir: usbdevfs_bus_readdir,};static struct inode_operations usbdevfs_bus_inode_operations = { lookup: usbdevfs_bus_lookup,};static void usbdevfs_read_inode(struct inode *inode){ struct special *spec; 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)) { case ISPECIAL: if (inode->i_ino == IROOT) { inode->i_op = &usbdevfs_root_inode_operations; inode->i_fop = &usbdevfs_root_file_operations; inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; return; } if (inode->i_ino <= IROOT || inode->i_ino > IROOT+NRSPECIAL) return; spec = &special[inode->i_ino-(IROOT+1)]; inode->i_fop = spec->fops; return; case IDEVICE: return; case IBUS: return; default: return; }}static void usbdevfs_put_super(struct super_block *sb){ list_del(&sb->u.usbdevfs_sb.slist); INIT_LIST_HEAD(&sb->u.usbdevfs_sb.slist); while (!list_empty(&sb->u.usbdevfs_sb.ilist)) free_inode(list_entry(sb->u.usbdevfs_sb.ilist.next, struct inode, u.usbdev_i.slist)); MOD_DEC_USE_COUNT;}static int usbdevfs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz){ struct statfs tmp; tmp.f_type = USBDEVICE_SUPER_MAGIC; tmp.f_bsize = PAGE_SIZE/sizeof(long); /* ??? */ tmp.f_blocks = 0; tmp.f_bfree = 0; tmp.f_bavail = 0; tmp.f_files = 0; tmp.f_ffree = 0; tmp.f_namelen = NAME_MAX; return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;}static struct super_operations usbdevfs_sops = { read_inode: usbdevfs_read_inode, put_super: usbdevfs_put_super, statfs: usbdevfs_statfs,};struct super_block *usbdevfs_read_super(struct super_block *s, void *data, int silent){ struct inode *root_inode, *inode; 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; } } /* fill superblock */ MOD_INC_USE_COUNT; lock_super(s); s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = USBDEVICE_SUPER_MAGIC; 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; s->s_root = d_alloc_root(root_inode); if (!s->s_root) goto out_no_root; list_add_tail(&s->u.usbdevfs_sb.slist, &superlist); unlock_super(s); 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; list_add_tail(&inode->u.usbdev_i.slist, &s->u.usbdevfs_sb.ilist); list_add_tail(&inode->u.usbdev_i.dlist, &special[i].inodes); } lock_kernel(); for (blist = usb_bus_list.next; blist != &usb_bus_list; blist = blist->next) { bus = list_entry(blist, struct usb_bus, bus_list); new_bus_inode(bus, s); recurse_new_dev_inode(bus->root_hub, s); } unlock_kernel(); return s; out_no_root: printk("usbdevfs_read_super: get root inode failed\n"); iput(root_inode); s->s_dev = 0; unlock_super(s); MOD_DEC_USE_COUNT; return NULL; opterr: printk(KERN_WARNING "usbdevfs: mount parameter error\n"); s->s_dev = 0; return NULL;}static struct file_system_type usbdevice_fs_type = { "usbdevfs", 0, usbdevfs_read_super, NULL};/* --------------------------------------------------------------------- */void usbdevfs_add_bus(struct usb_bus *bus){ struct list_head *slist; lock_kernel(); for (slist = superlist.next; slist != &superlist; slist = slist->next) new_bus_inode(bus, list_entry(slist, struct super_block, u.usbdevfs_sb.slist)); unlock_kernel(); usbdevfs_conn_disc_event();}void usbdevfs_remove_bus(struct usb_bus *bus){ lock_kernel(); while (!list_empty(&bus->inodes)) free_inode(list_entry(bus->inodes.next, struct inode, u.usbdev_i.dlist)); unlock_kernel(); usbdevfs_conn_disc_event();}void usbdevfs_add_device(struct usb_device *dev){ struct list_head *slist; lock_kernel(); for (slist = superlist.next; slist != &superlist; slist = slist->next) new_dev_inode(dev, list_entry(slist, struct super_block, u.usbdevfs_sb.slist)); unlock_kernel(); usbdevfs_conn_disc_event();}void usbdevfs_remove_device(struct usb_device *dev){ struct dev_state *ds; struct siginfo sinfo; lock_kernel(); while (!list_empty(&dev->inodes)) free_inode(list_entry(dev->inodes.next, struct inode, u.usbdev_i.dlist)); while (!list_empty(&dev->filelist)) { ds = list_entry(dev->filelist.next, struct dev_state, list); list_del(&ds->list); INIT_LIST_HEAD(&ds->list); down_write(&ds->devsem); ds->dev = NULL; up_write(&ds->devsem); if (ds->discsignr) { sinfo.si_signo = SIGPIPE; sinfo.si_errno = EPIPE; sinfo.si_code = SI_ASYNCIO; sinfo.si_addr = ds->disccontext; send_sig_info(ds->discsignr, &sinfo, ds->disctask); } } unlock_kernel(); usbdevfs_conn_disc_event();}/* --------------------------------------------------------------------- */static struct proc_dir_entry *usbdir = NULL;int __init usbdevfs_init(void){ int ret; for (ret = 0; ret < NRSPECIAL; ret++) { INIT_LIST_HEAD(&special[ret].inodes); } if ((ret = usb_register(&usbdevfs_driver))) return ret; if ((ret = register_filesystem(&usbdevice_fs_type))) usb_deregister(&usbdevfs_driver); /* create mount point for usbdevfs */ usbdir = proc_mkdir("usb", proc_bus); return ret;}void __exit usbdevfs_cleanup(void){ usb_deregister(&usbdevfs_driver); unregister_filesystem(&usbdevice_fs_type); if (usbdir) remove_proc_entry("usb", proc_bus);}#if 0module_init(usbdevfs_init);module_exit(usbdevfs_cleanup);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -