Loading drivers/usb/gadget/function/f_fs.c +29 −7 Original line number Diff line number Diff line Loading @@ -141,6 +141,7 @@ struct ffs_epfile { struct ffs_data *ffs; struct ffs_ep *ep; /* P: ffs->eps_lock */ atomic_t opened; struct dentry *dentry; Loading Loading @@ -207,7 +208,7 @@ struct ffs_epfile { unsigned char in; /* P: ffs->eps_lock */ unsigned char isoc; /* P: ffs->eps_lock */ unsigned char _pad; bool invalid; }; struct ffs_buffer { Loading Loading @@ -954,6 +955,16 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) if (file->f_flags & O_NONBLOCK) return -EAGAIN; /* * epfile->invalid is set when EPs are disabled. Userspace * might have stale threads continuing to do I/O and may be * unaware of that especially if we block here. Instead return * an error immediately here and don't allow any more I/O * until the epfile is reopened. */ if (epfile->invalid) return -ENODEV; ret = wait_event_interruptible( epfile->ffs->wait, (ep = epfile->ep)); if (ret) Loading Loading @@ -1131,15 +1142,16 @@ ffs_epfile_open(struct inode *inode, struct file *file) ENTER(); ffs_log("%s: state %d setup_state %d flag %lu", epfile->name, epfile->ffs->state, epfile->ffs->setup_state, epfile->ffs->flags); ffs_log("%s: state %d setup_state %d flag %lu opened %u", epfile->name, epfile->ffs->state, epfile->ffs->setup_state, epfile->ffs->flags, atomic_read(&epfile->opened)); if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) return -ENODEV; file->private_data = epfile; ffs_data_opened(epfile->ffs); atomic_inc(&epfile->opened); return 0; } Loading Loading @@ -1271,9 +1283,12 @@ ffs_epfile_release(struct inode *inode, struct file *file) ENTER(); __ffs_epfile_read_buffer_free(epfile); ffs_log("%s: state %d setup_state %d flag %lu", epfile->name, epfile->ffs->state, epfile->ffs->setup_state, epfile->ffs->flags); ffs_log("%s: state %d setup_state %d flag %lu opened %u", epfile->name, epfile->ffs->state, epfile->ffs->setup_state, epfile->ffs->flags, atomic_read(&epfile->opened)); if (atomic_dec_and_test(&epfile->opened)) epfile->invalid = false; ffs_data_closed(epfile->ffs); Loading Loading @@ -1302,6 +1317,10 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, if (file->f_flags & O_NONBLOCK) return -EAGAIN; /* don't allow any I/O until file is reopened */ if (epfile->invalid) return -ENODEV; ret = wait_event_interruptible( epfile->ffs->wait, (ep = epfile->ep)); if (ret) Loading Loading @@ -1950,6 +1969,8 @@ static int ffs_epfiles_create(struct ffs_data *ffs) ffs_epfiles_destroy(epfiles, i - 1); return -ENOMEM; } atomic_set(&epfile->opened, 0); } ffs->epfiles = epfiles; Loading Loading @@ -1995,6 +2016,7 @@ static void ffs_func_eps_disable(struct ffs_function *func) ++ep; if (epfile) { epfile->invalid = true; /* until file is reopened */ epfile->ep = NULL; __ffs_epfile_read_buffer_free(epfile); ++epfile; Loading Loading
drivers/usb/gadget/function/f_fs.c +29 −7 Original line number Diff line number Diff line Loading @@ -141,6 +141,7 @@ struct ffs_epfile { struct ffs_data *ffs; struct ffs_ep *ep; /* P: ffs->eps_lock */ atomic_t opened; struct dentry *dentry; Loading Loading @@ -207,7 +208,7 @@ struct ffs_epfile { unsigned char in; /* P: ffs->eps_lock */ unsigned char isoc; /* P: ffs->eps_lock */ unsigned char _pad; bool invalid; }; struct ffs_buffer { Loading Loading @@ -954,6 +955,16 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) if (file->f_flags & O_NONBLOCK) return -EAGAIN; /* * epfile->invalid is set when EPs are disabled. Userspace * might have stale threads continuing to do I/O and may be * unaware of that especially if we block here. Instead return * an error immediately here and don't allow any more I/O * until the epfile is reopened. */ if (epfile->invalid) return -ENODEV; ret = wait_event_interruptible( epfile->ffs->wait, (ep = epfile->ep)); if (ret) Loading Loading @@ -1131,15 +1142,16 @@ ffs_epfile_open(struct inode *inode, struct file *file) ENTER(); ffs_log("%s: state %d setup_state %d flag %lu", epfile->name, epfile->ffs->state, epfile->ffs->setup_state, epfile->ffs->flags); ffs_log("%s: state %d setup_state %d flag %lu opened %u", epfile->name, epfile->ffs->state, epfile->ffs->setup_state, epfile->ffs->flags, atomic_read(&epfile->opened)); if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) return -ENODEV; file->private_data = epfile; ffs_data_opened(epfile->ffs); atomic_inc(&epfile->opened); return 0; } Loading Loading @@ -1271,9 +1283,12 @@ ffs_epfile_release(struct inode *inode, struct file *file) ENTER(); __ffs_epfile_read_buffer_free(epfile); ffs_log("%s: state %d setup_state %d flag %lu", epfile->name, epfile->ffs->state, epfile->ffs->setup_state, epfile->ffs->flags); ffs_log("%s: state %d setup_state %d flag %lu opened %u", epfile->name, epfile->ffs->state, epfile->ffs->setup_state, epfile->ffs->flags, atomic_read(&epfile->opened)); if (atomic_dec_and_test(&epfile->opened)) epfile->invalid = false; ffs_data_closed(epfile->ffs); Loading Loading @@ -1302,6 +1317,10 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, if (file->f_flags & O_NONBLOCK) return -EAGAIN; /* don't allow any I/O until file is reopened */ if (epfile->invalid) return -ENODEV; ret = wait_event_interruptible( epfile->ffs->wait, (ep = epfile->ep)); if (ret) Loading Loading @@ -1950,6 +1969,8 @@ static int ffs_epfiles_create(struct ffs_data *ffs) ffs_epfiles_destroy(epfiles, i - 1); return -ENOMEM; } atomic_set(&epfile->opened, 0); } ffs->epfiles = epfiles; Loading Loading @@ -1995,6 +2016,7 @@ static void ffs_func_eps_disable(struct ffs_function *func) ++ep; if (epfile) { epfile->invalid = true; /* until file is reopened */ epfile->ep = NULL; __ffs_epfile_read_buffer_free(epfile); ++epfile; Loading