aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-09-14 08:01:25 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-14 08:01:25 -0400
commitd7f6884ae0ae6e406ec3500fcde16e8f51642460 (patch)
treeefceb246a4fa12921b7dbd3946a88fa257684405 /fs/open.c
parentcd28ab6a4e50a7601d22752aa7ce0c8197b10bdf (diff)
parent2f4ba45a75d6383b4a1201169a808ffea416ffa0 (diff)
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c62
1 files changed, 36 insertions, 26 deletions
diff --git a/fs/open.c b/fs/open.c
index 32bf05e2996d..2fac58c51910 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -24,6 +24,7 @@
24#include <linux/personality.h> 24#include <linux/personality.h>
25#include <linux/pagemap.h> 25#include <linux/pagemap.h>
26#include <linux/syscalls.h> 26#include <linux/syscalls.h>
27#include <linux/rcupdate.h>
27 28
28#include <asm/unistd.h> 29#include <asm/unistd.h>
29 30
@@ -842,14 +843,16 @@ int get_unused_fd(void)
842{ 843{
843 struct files_struct * files = current->files; 844 struct files_struct * files = current->files;
844 int fd, error; 845 int fd, error;
846 struct fdtable *fdt;
845 847
846 error = -EMFILE; 848 error = -EMFILE;
847 spin_lock(&files->file_lock); 849 spin_lock(&files->file_lock);
848 850
849repeat: 851repeat:
850 fd = find_next_zero_bit(files->open_fds->fds_bits, 852 fdt = files_fdtable(files);
851 files->max_fdset, 853 fd = find_next_zero_bit(fdt->open_fds->fds_bits,
852 files->next_fd); 854 fdt->max_fdset,
855 fdt->next_fd);
853 856
854 /* 857 /*
855 * N.B. For clone tasks sharing a files structure, this test 858 * N.B. For clone tasks sharing a files structure, this test
@@ -872,14 +875,14 @@ repeat:
872 goto repeat; 875 goto repeat;
873 } 876 }
874 877
875 FD_SET(fd, files->open_fds); 878 FD_SET(fd, fdt->open_fds);
876 FD_CLR(fd, files->close_on_exec); 879 FD_CLR(fd, fdt->close_on_exec);
877 files->next_fd = fd + 1; 880 fdt->next_fd = fd + 1;
878#if 1 881#if 1
879 /* Sanity check */ 882 /* Sanity check */
880 if (files->fd[fd] != NULL) { 883 if (fdt->fd[fd] != NULL) {
881 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); 884 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
882 files->fd[fd] = NULL; 885 fdt->fd[fd] = NULL;
883 } 886 }
884#endif 887#endif
885 error = fd; 888 error = fd;
@@ -893,9 +896,10 @@ EXPORT_SYMBOL(get_unused_fd);
893 896
894static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) 897static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
895{ 898{
896 __FD_CLR(fd, files->open_fds); 899 struct fdtable *fdt = files_fdtable(files);
897 if (fd < files->next_fd) 900 __FD_CLR(fd, fdt->open_fds);
898 files->next_fd = fd; 901 if (fd < fdt->next_fd)
902 fdt->next_fd = fd;
899} 903}
900 904
901void fastcall put_unused_fd(unsigned int fd) 905void fastcall put_unused_fd(unsigned int fd)
@@ -924,25 +928,21 @@ EXPORT_SYMBOL(put_unused_fd);
924void fastcall fd_install(unsigned int fd, struct file * file) 928void fastcall fd_install(unsigned int fd, struct file * file)
925{ 929{
926 struct files_struct *files = current->files; 930 struct files_struct *files = current->files;
931 struct fdtable *fdt;
927 spin_lock(&files->file_lock); 932 spin_lock(&files->file_lock);
928 if (unlikely(files->fd[fd] != NULL)) 933 fdt = files_fdtable(files);
929 BUG(); 934 BUG_ON(fdt->fd[fd] != NULL);
930 files->fd[fd] = file; 935 rcu_assign_pointer(fdt->fd[fd], file);
931 spin_unlock(&files->file_lock); 936 spin_unlock(&files->file_lock);
932} 937}
933 938
934EXPORT_SYMBOL(fd_install); 939EXPORT_SYMBOL(fd_install);
935 940
936asmlinkage long sys_open(const char __user * filename, int flags, int mode) 941long do_sys_open(const char __user *filename, int flags, int mode)
937{ 942{
938 char * tmp; 943 char *tmp = getname(filename);
939 int fd; 944 int fd = PTR_ERR(tmp);
940 945
941 if (force_o_largefile())
942 flags |= O_LARGEFILE;
943
944 tmp = getname(filename);
945 fd = PTR_ERR(tmp);
946 if (!IS_ERR(tmp)) { 946 if (!IS_ERR(tmp)) {
947 fd = get_unused_fd(); 947 fd = get_unused_fd();
948 if (fd >= 0) { 948 if (fd >= 0) {
@@ -959,6 +959,14 @@ asmlinkage long sys_open(const char __user * filename, int flags, int mode)
959 } 959 }
960 return fd; 960 return fd;
961} 961}
962
963asmlinkage long sys_open(const char __user *filename, int flags, int mode)
964{
965 if (force_o_largefile())
966 flags |= O_LARGEFILE;
967
968 return do_sys_open(filename, flags, mode);
969}
962EXPORT_SYMBOL_GPL(sys_open); 970EXPORT_SYMBOL_GPL(sys_open);
963 971
964#ifndef __alpha__ 972#ifndef __alpha__
@@ -1007,15 +1015,17 @@ asmlinkage long sys_close(unsigned int fd)
1007{ 1015{
1008 struct file * filp; 1016 struct file * filp;
1009 struct files_struct *files = current->files; 1017 struct files_struct *files = current->files;
1018 struct fdtable *fdt;
1010 1019
1011 spin_lock(&files->file_lock); 1020 spin_lock(&files->file_lock);
1012 if (fd >= files->max_fds) 1021 fdt = files_fdtable(files);
1022 if (fd >= fdt->max_fds)
1013 goto out_unlock; 1023 goto out_unlock;
1014 filp = files->fd[fd]; 1024 filp = fdt->fd[fd];
1015 if (!filp) 1025 if (!filp)
1016 goto out_unlock; 1026 goto out_unlock;
1017 files->fd[fd] = NULL; 1027 rcu_assign_pointer(fdt->fd[fd], NULL);
1018 FD_CLR(fd, files->close_on_exec); 1028 FD_CLR(fd, fdt->close_on_exec);
1019 __put_unused_fd(files, fd); 1029 __put_unused_fd(files, fd);
1020 spin_unlock(&files->file_lock); 1030 spin_unlock(&files->file_lock);
1021 return filp_close(filp, files); 1031 return filp_close(filp, files);