Messages in this thread Patch in this message | | | From | Linus Torvalds <> | Date | Mon, 25 Nov 2019 14:55:22 -0800 | Subject | Re: Commit 0be0ee71 ("fs: properly and reliably lock f_pos in fdget_pos()") breaking userspace |
| |
On Mon, Nov 25, 2019 at 1:30 PM Kenneth R. Crudup <kenny@panix.com> wrote: > > FYI. Don't know if the fault lies with these subsystems or not, but I know > it's been a goal to keep things working. In both cases, reverting this commit > fixes both these issues. If you need additional information from me, please > let me know.
Do you have any way to figure out what file descriptor we have in those two cases?
It's almost certainly trivial to fix - if I were to know just what kind of file we're blocking on that just needs to be marked FMODE_STREAM.
The commit itself is also trivial enough to just revert if we can't figure it out, but that's why I applied it first thing in the merge window - to see the problems quickly and hopefully get them fixed. It obviously showed no problems on my machines, but I have neither vmware nor KDE upower...
Anyway, here's a TOTALLYT UNTESTED patch that may help pinpoint which thing it is that causes issues.
It might also be so noisy as to be useless, I didn't think it through a lot. Mind trying it out if you can't immediately see "ahh, vmware fd #N is a file of type XYZ"?
Linus fs/open.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/fs/open.c b/fs/open.c index 5c68282ea79e..5dfe7cde4ff5 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1075,6 +1075,21 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, } EXPORT_SYMBOL(file_open_root); +/* Hacky hack hack */ +static void check_if_stream(struct file *f, const char *name) +{ + /* Already marked as FMODE_STREAM */ + if (f->f_mode & FMODE_STREAM) + return; + + /* Does it have a real lseek implementation? Not a stream */ + if (f->f_op && f->f_op->llseek && f->f_op->llseek != no_llseek) + return; + + pr_info("%s: file '%s' with ops %lx (%pS) might be a stream file\n", + current->comm, name, (unsigned long)f->f_op, f->f_op); +} + long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; @@ -1097,6 +1112,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) } else { fsnotify_open(f); fd_install(fd, f); + check_if_stream(f, tmp->name); } } putname(tmp); | |