diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-08-19 18:04:24 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-27 03:08:56 +0200 |
commit | 483ce1d4b8c3b82bc9c9a1dd9dbc44f50b3aaf5a (patch) | |
tree | 46a43df814fc7f7bb0c22d0c47fabb7db95d7ada /fs/file.c | |
parent | take fget() and friends to fs/file.c (diff) | |
download | linux-483ce1d4b8c3b82bc9c9a1dd9dbc44f50b3aaf5a.tar.xz linux-483ce1d4b8c3b82bc9c9a1dd9dbc44f50b3aaf5a.zip |
take descriptor-related part of close() to file.c
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/file.c')
-rw-r--r-- | fs/file.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/fs/file.c b/fs/file.c index 6eef55ce30c9..fd4694e688ab 100644 --- a/fs/file.c +++ b/fs/file.c @@ -626,6 +626,32 @@ void fd_install(unsigned int fd, struct file *file) EXPORT_SYMBOL(fd_install); +/* + * The same warnings as for __alloc_fd()/__fd_install() apply here... + */ +int __close_fd(struct files_struct *files, unsigned fd) +{ + struct file *file; + struct fdtable *fdt; + + spin_lock(&files->file_lock); + fdt = files_fdtable(files); + if (fd >= fdt->max_fds) + goto out_unlock; + file = fdt->fd[fd]; + if (!file) + goto out_unlock; + rcu_assign_pointer(fdt->fd[fd], NULL); + __clear_close_on_exec(fd, fdt); + __put_unused_fd(files, fd); + spin_unlock(&files->file_lock); + return filp_close(file, files); + +out_unlock: + spin_unlock(&files->file_lock); + return -EBADF; +} + struct file *fget(unsigned int fd) { struct file *file; |