Loading drivers/usb/gadget/function/f_fs.c +29 −7 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ struct ffs_epfile { struct ffs_data *ffs; struct ffs_ep *ep; /* P: ffs->eps_lock */ atomic_t opened; struct dentry *dentry; Loading Loading @@ -205,7 +206,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 @@ -956,6 +957,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 @@ -1152,15 +1163,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 @@ -1301,9 +1313,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 @@ -1333,6 +1348,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 @@ -1998,6 +2017,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 @@ -2045,6 +2066,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 @@ -139,6 +139,7 @@ struct ffs_epfile { struct ffs_data *ffs; struct ffs_ep *ep; /* P: ffs->eps_lock */ atomic_t opened; struct dentry *dentry; Loading Loading @@ -205,7 +206,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 @@ -956,6 +957,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 @@ -1152,15 +1163,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 @@ -1301,9 +1313,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 @@ -1333,6 +1348,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 @@ -1998,6 +2017,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 @@ -2045,6 +2066,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