summaryrefslogtreecommitdiffstats
path: root/include/linux/file.h
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-10-09 00:00:47 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-10-09 00:00:47 +0000
commitd6434e1042f3b0a6dfe1b1f615af369486f9b1fa (patch)
treee2be02f33984c48ec019c654051d27964e42c441 /include/linux/file.h
parent609d1e803baf519487233b765eb487f9ec227a18 (diff)
Merge with 2.3.19.
Diffstat (limited to 'include/linux/file.h')
-rw-r--r--include/linux/file.h35
1 files changed, 22 insertions, 13 deletions
diff --git a/include/linux/file.h b/include/linux/file.h
index 1bdd56a0c..1a11904b6 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -5,7 +5,6 @@
#ifndef __LINUX_FILE_H
#define __LINUX_FILE_H
-extern void __fput(struct file *); /* goner? */
extern void _fput(struct file *);
/*
@@ -57,18 +56,6 @@ extern inline struct file * fget(unsigned int fd)
}
/*
- * Install a file pointer in the fd array.
- */
-extern inline void fd_install(unsigned int fd, struct file * file)
-{
- struct files_struct *files = current->files;
-
- write_lock(&files->file_lock);
- files->fd[fd] = file;
- write_unlock(&files->file_lock);
-}
-
-/*
* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
*
* Since those functions where calling other functions, it was compleatly
@@ -91,4 +78,26 @@ extern inline void fput(struct file * file)
}
extern void put_filp(struct file *);
+/*
+ * Install a file pointer in the fd array.
+ *
+ * The VFS is full of places where we drop the files lock between
+ * setting the open_fds bitmap and installing the file in the file
+ * array. At any such point, we are vulnerable to a dup2() race
+ * installing a file in the array before us. We need to detect this and
+ * fput() the struct file we are about to overwrite in this case.
+ */
+
+extern inline void fd_install(unsigned int fd, struct file * file)
+{
+ struct files_struct *files = current->files;
+ struct file * result;
+
+ write_lock(&files->file_lock);
+ result = xchg(&files->fd[fd], file);
+ write_unlock(&files->file_lock);
+ if (result)
+ fput(result);
+}
+
#endif /* __LINUX_FILE_H */