aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c160
1 files changed, 92 insertions, 68 deletions
diff --git a/fs/open.c b/fs/open.c
index 32bf05e2996d..f0d90cf0495c 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
@@ -737,52 +738,15 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
737 return error; 738 return error;
738} 739}
739 740
740/* 741static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
741 * Note that while the flag value (low two bits) for sys_open means: 742 int flags, struct file *f)
742 * 00 - read-only
743 * 01 - write-only
744 * 10 - read-write
745 * 11 - special
746 * it is changed into
747 * 00 - no permissions needed
748 * 01 - read-permission
749 * 10 - write-permission
750 * 11 - read-write
751 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
752 * used by symlinks.
753 */
754struct file *filp_open(const char * filename, int flags, int mode)
755{ 743{
756 int namei_flags, error;
757 struct nameidata nd;
758
759 namei_flags = flags;
760 if ((namei_flags+1) & O_ACCMODE)
761 namei_flags++;
762 if (namei_flags & O_TRUNC)
763 namei_flags |= 2;
764
765 error = open_namei(filename, namei_flags, mode, &nd);
766 if (!error)
767 return dentry_open(nd.dentry, nd.mnt, flags);
768
769 return ERR_PTR(error);
770}
771
772EXPORT_SYMBOL(filp_open);
773
774struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
775{
776 struct file * f;
777 struct inode *inode; 744 struct inode *inode;
778 int error; 745 int error;
779 746
780 error = -ENFILE;
781 f = get_empty_filp();
782 if (!f)
783 goto cleanup_dentry;
784 f->f_flags = flags; 747 f->f_flags = flags;
785 f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; 748 f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK |
749 FMODE_PREAD | FMODE_PWRITE;
786 inode = dentry->d_inode; 750 inode = dentry->d_inode;
787 if (f->f_mode & FMODE_WRITE) { 751 if (f->f_mode & FMODE_WRITE) {
788 error = get_write_access(inode); 752 error = get_write_access(inode);
@@ -827,12 +791,63 @@ cleanup_all:
827 f->f_vfsmnt = NULL; 791 f->f_vfsmnt = NULL;
828cleanup_file: 792cleanup_file:
829 put_filp(f); 793 put_filp(f);
830cleanup_dentry:
831 dput(dentry); 794 dput(dentry);
832 mntput(mnt); 795 mntput(mnt);
833 return ERR_PTR(error); 796 return ERR_PTR(error);
834} 797}
835 798
799/*
800 * Note that while the flag value (low two bits) for sys_open means:
801 * 00 - read-only
802 * 01 - write-only
803 * 10 - read-write
804 * 11 - special
805 * it is changed into
806 * 00 - no permissions needed
807 * 01 - read-permission
808 * 10 - write-permission
809 * 11 - read-write
810 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
811 * used by symlinks.
812 */
813struct file *filp_open(const char * filename, int flags, int mode)
814{
815 int namei_flags, error;
816 struct nameidata nd;
817 struct file *f;
818
819 namei_flags = flags;
820 if ((namei_flags+1) & O_ACCMODE)
821 namei_flags++;
822 if (namei_flags & O_TRUNC)
823 namei_flags |= 2;
824
825 error = -ENFILE;
826 f = get_empty_filp();
827 if (f == NULL)
828 return ERR_PTR(error);
829
830 error = open_namei(filename, namei_flags, mode, &nd);
831 if (!error)
832 return __dentry_open(nd.dentry, nd.mnt, flags, f);
833
834 put_filp(f);
835 return ERR_PTR(error);
836}
837EXPORT_SYMBOL(filp_open);
838
839struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
840{
841 int error;
842 struct file *f;
843
844 error = -ENFILE;
845 f = get_empty_filp();
846 if (f == NULL)
847 return ERR_PTR(error);
848
849 return __dentry_open(dentry, mnt, flags, f);
850}
836EXPORT_SYMBOL(dentry_open); 851EXPORT_SYMBOL(dentry_open);
837 852
838/* 853/*
@@ -842,14 +857,16 @@ int get_unused_fd(void)
842{ 857{
843 struct files_struct * files = current->files; 858 struct files_struct * files = current->files;
844 int fd, error; 859 int fd, error;
860 struct fdtable *fdt;
845 861
846 error = -EMFILE; 862 error = -EMFILE;
847 spin_lock(&files->file_lock); 863 spin_lock(&files->file_lock);
848 864
849repeat: 865repeat:
850 fd = find_next_zero_bit(files->open_fds->fds_bits, 866 fdt = files_fdtable(files);
851 files->max_fdset, 867 fd = find_next_zero_bit(fdt->open_fds->fds_bits,
852 files->next_fd); 868 fdt->max_fdset,
869 fdt->next_fd);
853 870
854 /* 871 /*
855 * N.B. For clone tasks sharing a files structure, this test 872 * N.B. For clone tasks sharing a files structure, this test
@@ -872,14 +889,14 @@ repeat:
872 goto repeat; 889 goto repeat;
873 } 890 }
874 891
875 FD_SET(fd, files->open_fds); 892 FD_SET(fd, fdt->open_fds);
876 FD_CLR(fd, files->close_on_exec); 893 FD_CLR(fd, fdt->close_on_exec);
877 files->next_fd = fd + 1; 894 fdt->next_fd = fd + 1;
878#if 1 895#if 1
879 /* Sanity check */ 896 /* Sanity check */
880 if (files->fd[fd] != NULL) { 897 if (fdt->fd[fd] != NULL) {
881 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); 898 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
882 files->fd[fd] = NULL; 899 fdt->fd[fd] = NULL;
883 } 900 }
884#endif 901#endif
885 error = fd; 902 error = fd;
@@ -893,9 +910,10 @@ EXPORT_SYMBOL(get_unused_fd);
893 910
894static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) 911static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
895{ 912{
896 __FD_CLR(fd, files->open_fds); 913 struct fdtable *fdt = files_fdtable(files);
897 if (fd < files->next_fd) 914 __FD_CLR(fd, fdt->open_fds);
898 files->next_fd = fd; 915 if (fd < fdt->next_fd)
916 fdt->next_fd = fd;
899} 917}
900 918
901void fastcall put_unused_fd(unsigned int fd) 919void fastcall put_unused_fd(unsigned int fd)
@@ -924,25 +942,21 @@ EXPORT_SYMBOL(put_unused_fd);
924void fastcall fd_install(unsigned int fd, struct file * file) 942void fastcall fd_install(unsigned int fd, struct file * file)
925{ 943{
926 struct files_struct *files = current->files; 944 struct files_struct *files = current->files;
945 struct fdtable *fdt;
927 spin_lock(&files->file_lock); 946 spin_lock(&files->file_lock);
928 if (unlikely(files->fd[fd] != NULL)) 947 fdt = files_fdtable(files);
929 BUG(); 948 BUG_ON(fdt->fd[fd] != NULL);
930 files->fd[fd] = file; 949 rcu_assign_pointer(fdt->fd[fd], file);
931 spin_unlock(&files->file_lock); 950 spin_unlock(&files->file_lock);
932} 951}
933 952
934EXPORT_SYMBOL(fd_install); 953EXPORT_SYMBOL(fd_install);
935 954
936asmlinkage long sys_open(const char __user * filename, int flags, int mode) 955long do_sys_open(const char __user *filename, int flags, int mode)
937{ 956{
938 char * tmp; 957 char *tmp = getname(filename);
939 int fd; 958 int fd = PTR_ERR(tmp);
940
941 if (force_o_largefile())
942 flags |= O_LARGEFILE;
943 959
944 tmp = getname(filename);
945 fd = PTR_ERR(tmp);
946 if (!IS_ERR(tmp)) { 960 if (!IS_ERR(tmp)) {
947 fd = get_unused_fd(); 961 fd = get_unused_fd();
948 if (fd >= 0) { 962 if (fd >= 0) {
@@ -959,6 +973,14 @@ asmlinkage long sys_open(const char __user * filename, int flags, int mode)
959 } 973 }
960 return fd; 974 return fd;
961} 975}
976
977asmlinkage long sys_open(const char __user *filename, int flags, int mode)
978{
979 if (force_o_largefile())
980 flags |= O_LARGEFILE;
981
982 return do_sys_open(filename, flags, mode);
983}
962EXPORT_SYMBOL_GPL(sys_open); 984EXPORT_SYMBOL_GPL(sys_open);
963 985
964#ifndef __alpha__ 986#ifndef __alpha__
@@ -1007,15 +1029,17 @@ asmlinkage long sys_close(unsigned int fd)
1007{ 1029{
1008 struct file * filp; 1030 struct file * filp;
1009 struct files_struct *files = current->files; 1031 struct files_struct *files = current->files;
1032 struct fdtable *fdt;
1010 1033
1011 spin_lock(&files->file_lock); 1034 spin_lock(&files->file_lock);
1012 if (fd >= files->max_fds) 1035 fdt = files_fdtable(files);
1036 if (fd >= fdt->max_fds)
1013 goto out_unlock; 1037 goto out_unlock;
1014 filp = files->fd[fd]; 1038 filp = fdt->fd[fd];
1015 if (!filp) 1039 if (!filp)
1016 goto out_unlock; 1040 goto out_unlock;
1017 files->fd[fd] = NULL; 1041 rcu_assign_pointer(fdt->fd[fd], NULL);
1018 FD_CLR(fd, files->close_on_exec); 1042 FD_CLR(fd, fdt->close_on_exec);
1019 __put_unused_fd(files, fd); 1043 __put_unused_fd(files, fd);
1020 spin_unlock(&files->file_lock); 1044 spin_unlock(&files->file_lock);
1021 return filp_close(filp, files); 1045 return filp_close(filp, files);