diff options
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/open.c b/fs/open.c index 70510004d06e..c32c89d6d8db 100644 --- a/fs/open.c +++ b/fs/open.c @@ -896,6 +896,10 @@ EXPORT_SYMBOL(filp_open); * a fully instantiated struct file to the caller. * This function is meant to be called from within a filesystem's * lookup method. + * Beware of calling it for non-regular files! Those ->open methods might block + * (e.g. in fifo_open), leaving you with parent locked (and in case of fifo, + * leading to a deadlock, as nobody can open that fifo anymore, because + * another process to open fifo will block on locked parent when doing lookup). * Note that in case of error, nd->intent.open.file is destroyed, but the * path information remains valid. * If the open callback is set to NULL, then the standard f_op->open() @@ -979,7 +983,7 @@ repeat: fdt = files_fdtable(files); fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fdset, - fdt->next_fd); + files->next_fd); /* * N.B. For clone tasks sharing a files structure, this test @@ -1004,7 +1008,7 @@ repeat: FD_SET(fd, fdt->open_fds); FD_CLR(fd, fdt->close_on_exec); - fdt->next_fd = fd + 1; + files->next_fd = fd + 1; #if 1 /* Sanity check */ if (fdt->fd[fd] != NULL) { @@ -1025,8 +1029,8 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd) { struct fdtable *fdt = files_fdtable(files); __FD_CLR(fd, fdt->open_fds); - if (fd < fdt->next_fd) - fdt->next_fd = fd; + if (fd < files->next_fd) + files->next_fd = fd; } void fastcall put_unused_fd(unsigned int fd) |