aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 09:36:37 -0500
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 09:36:37 -0500
commit2fc2991175bf77395e6b15fe6b2304d3bf72da40 (patch)
treeb0ff38c09240e7c00e1577d447ebe89143d752dc /fs/open.c
parent8b491d750885ebe8e7d385ce4186c85957d67123 (diff)
parent7015faa7df829876a0f931cd18aa6d7c24a1b581 (diff)
Merge branch 'master' of /home/tglx/work/mtd/git/linux-2.6.git/
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c215
1 files changed, 145 insertions, 70 deletions
diff --git a/fs/open.c b/fs/open.c
index 32bf05e2996d..8d06ec911fd9 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,16 @@ 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 int (*open)(struct inode *, struct file *))
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{
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{ 744{
776 struct file * f;
777 struct inode *inode; 745 struct inode *inode;
778 int error; 746 int error;
779 747
780 error = -ENFILE;
781 f = get_empty_filp();
782 if (!f)
783 goto cleanup_dentry;
784 f->f_flags = flags; 748 f->f_flags = flags;
785 f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; 749 f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK |
750 FMODE_PREAD | FMODE_PWRITE;
786 inode = dentry->d_inode; 751 inode = dentry->d_inode;
787 if (f->f_mode & FMODE_WRITE) { 752 if (f->f_mode & FMODE_WRITE) {
788 error = get_write_access(inode); 753 error = get_write_access(inode);
@@ -797,11 +762,14 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
797 f->f_op = fops_get(inode->i_fop); 762 f->f_op = fops_get(inode->i_fop);
798 file_move(f, &inode->i_sb->s_files); 763 file_move(f, &inode->i_sb->s_files);
799 764
800 if (f->f_op && f->f_op->open) { 765 if (!open && f->f_op)
801 error = f->f_op->open(inode,f); 766 open = f->f_op->open;
767 if (open) {
768 error = open(inode, f);
802 if (error) 769 if (error)
803 goto cleanup_all; 770 goto cleanup_all;
804 } 771 }
772
805 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); 773 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
806 774
807 file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); 775 file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
@@ -827,12 +795,110 @@ cleanup_all:
827 f->f_vfsmnt = NULL; 795 f->f_vfsmnt = NULL;
828cleanup_file: 796cleanup_file:
829 put_filp(f); 797 put_filp(f);
830cleanup_dentry:
831 dput(dentry); 798 dput(dentry);
832 mntput(mnt); 799 mntput(mnt);
833 return ERR_PTR(error); 800 return ERR_PTR(error);
834} 801}
835 802
803/*
804 * Note that while the flag value (low two bits) for sys_open means:
805 * 00 - read-only
806 * 01 - write-only
807 * 10 - read-write
808 * 11 - special
809 * it is changed into
810 * 00 - no permissions needed
811 * 01 - read-permission
812 * 10 - write-permission
813 * 11 - read-write
814 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
815 * used by symlinks.
816 */
817struct file *filp_open(const char * filename, int flags, int mode)
818{
819 int namei_flags, error;
820 struct nameidata nd;
821
822 namei_flags = flags;
823 if ((namei_flags+1) & O_ACCMODE)
824 namei_flags++;
825
826 error = open_namei(filename, namei_flags, mode, &nd);
827 if (!error)
828 return nameidata_to_filp(&nd, flags);
829
830 return ERR_PTR(error);
831}
832EXPORT_SYMBOL(filp_open);
833
834/**
835 * lookup_instantiate_filp - instantiates the open intent filp
836 * @nd: pointer to nameidata
837 * @dentry: pointer to dentry
838 * @open: open callback
839 *
840 * Helper for filesystems that want to use lookup open intents and pass back
841 * a fully instantiated struct file to the caller.
842 * This function is meant to be called from within a filesystem's
843 * lookup method.
844 * Note that in case of error, nd->intent.open.file is destroyed, but the
845 * path information remains valid.
846 * If the open callback is set to NULL, then the standard f_op->open()
847 * filesystem callback is substituted.
848 */
849struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
850 int (*open)(struct inode *, struct file *))
851{
852 if (IS_ERR(nd->intent.open.file))
853 goto out;
854 if (IS_ERR(dentry))
855 goto out_err;
856 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt),
857 nd->intent.open.flags - 1,
858 nd->intent.open.file,
859 open);
860out:
861 return nd->intent.open.file;
862out_err:
863 release_open_intent(nd);
864 nd->intent.open.file = (struct file *)dentry;
865 goto out;
866}
867EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
868
869/**
870 * nameidata_to_filp - convert a nameidata to an open filp.
871 * @nd: pointer to nameidata
872 * @flags: open flags
873 *
874 * Note that this function destroys the original nameidata
875 */
876struct file *nameidata_to_filp(struct nameidata *nd, int flags)
877{
878 struct file *filp;
879
880 /* Pick up the filp from the open intent */
881 filp = nd->intent.open.file;
882 /* Has the filesystem initialised the file for us? */
883 if (filp->f_dentry == NULL)
884 filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
885 else
886 path_release(nd);
887 return filp;
888}
889
890struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
891{
892 int error;
893 struct file *f;
894
895 error = -ENFILE;
896 f = get_empty_filp();
897 if (f == NULL)
898 return ERR_PTR(error);
899
900 return __dentry_open(dentry, mnt, flags, f, NULL);
901}
836EXPORT_SYMBOL(dentry_open); 902EXPORT_SYMBOL(dentry_open);
837 903
838/* 904/*
@@ -842,14 +908,16 @@ int get_unused_fd(void)
842{ 908{
843 struct files_struct * files = current->files; 909 struct files_struct * files = current->files;
844 int fd, error; 910 int fd, error;
911 struct fdtable *fdt;
845 912
846 error = -EMFILE; 913 error = -EMFILE;
847 spin_lock(&files->file_lock); 914 spin_lock(&files->file_lock);
848 915
849repeat: 916repeat:
850 fd = find_next_zero_bit(files->open_fds->fds_bits, 917 fdt = files_fdtable(files);
851 files->max_fdset, 918 fd = find_next_zero_bit(fdt->open_fds->fds_bits,
852 files->next_fd); 919 fdt->max_fdset,
920 fdt->next_fd);
853 921
854 /* 922 /*
855 * N.B. For clone tasks sharing a files structure, this test 923 * N.B. For clone tasks sharing a files structure, this test
@@ -872,14 +940,14 @@ repeat:
872 goto repeat; 940 goto repeat;
873 } 941 }
874 942
875 FD_SET(fd, files->open_fds); 943 FD_SET(fd, fdt->open_fds);
876 FD_CLR(fd, files->close_on_exec); 944 FD_CLR(fd, fdt->close_on_exec);
877 files->next_fd = fd + 1; 945 fdt->next_fd = fd + 1;
878#if 1 946#if 1
879 /* Sanity check */ 947 /* Sanity check */
880 if (files->fd[fd] != NULL) { 948 if (fdt->fd[fd] != NULL) {
881 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); 949 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
882 files->fd[fd] = NULL; 950 fdt->fd[fd] = NULL;
883 } 951 }
884#endif 952#endif
885 error = fd; 953 error = fd;
@@ -893,9 +961,10 @@ EXPORT_SYMBOL(get_unused_fd);
893 961
894static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) 962static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
895{ 963{
896 __FD_CLR(fd, files->open_fds); 964 struct fdtable *fdt = files_fdtable(files);
897 if (fd < files->next_fd) 965 __FD_CLR(fd, fdt->open_fds);
898 files->next_fd = fd; 966 if (fd < fdt->next_fd)
967 fdt->next_fd = fd;
899} 968}
900 969
901void fastcall put_unused_fd(unsigned int fd) 970void fastcall put_unused_fd(unsigned int fd)
@@ -924,25 +993,21 @@ EXPORT_SYMBOL(put_unused_fd);
924void fastcall fd_install(unsigned int fd, struct file * file) 993void fastcall fd_install(unsigned int fd, struct file * file)
925{ 994{
926 struct files_struct *files = current->files; 995 struct files_struct *files = current->files;
996 struct fdtable *fdt;
927 spin_lock(&files->file_lock); 997 spin_lock(&files->file_lock);
928 if (unlikely(files->fd[fd] != NULL)) 998 fdt = files_fdtable(files);
929 BUG(); 999 BUG_ON(fdt->fd[fd] != NULL);
930 files->fd[fd] = file; 1000 rcu_assign_pointer(fdt->fd[fd], file);
931 spin_unlock(&files->file_lock); 1001 spin_unlock(&files->file_lock);
932} 1002}
933 1003
934EXPORT_SYMBOL(fd_install); 1004EXPORT_SYMBOL(fd_install);
935 1005
936asmlinkage long sys_open(const char __user * filename, int flags, int mode) 1006long do_sys_open(const char __user *filename, int flags, int mode)
937{ 1007{
938 char * tmp; 1008 char *tmp = getname(filename);
939 int fd; 1009 int fd = PTR_ERR(tmp);
940
941 if (force_o_largefile())
942 flags |= O_LARGEFILE;
943 1010
944 tmp = getname(filename);
945 fd = PTR_ERR(tmp);
946 if (!IS_ERR(tmp)) { 1011 if (!IS_ERR(tmp)) {
947 fd = get_unused_fd(); 1012 fd = get_unused_fd();
948 if (fd >= 0) { 1013 if (fd >= 0) {
@@ -959,6 +1024,14 @@ asmlinkage long sys_open(const char __user * filename, int flags, int mode)
959 } 1024 }
960 return fd; 1025 return fd;
961} 1026}
1027
1028asmlinkage long sys_open(const char __user *filename, int flags, int mode)
1029{
1030 if (force_o_largefile())
1031 flags |= O_LARGEFILE;
1032
1033 return do_sys_open(filename, flags, mode);
1034}
962EXPORT_SYMBOL_GPL(sys_open); 1035EXPORT_SYMBOL_GPL(sys_open);
963 1036
964#ifndef __alpha__ 1037#ifndef __alpha__
@@ -1007,15 +1080,17 @@ asmlinkage long sys_close(unsigned int fd)
1007{ 1080{
1008 struct file * filp; 1081 struct file * filp;
1009 struct files_struct *files = current->files; 1082 struct files_struct *files = current->files;
1083 struct fdtable *fdt;
1010 1084
1011 spin_lock(&files->file_lock); 1085 spin_lock(&files->file_lock);
1012 if (fd >= files->max_fds) 1086 fdt = files_fdtable(files);
1087 if (fd >= fdt->max_fds)
1013 goto out_unlock; 1088 goto out_unlock;
1014 filp = files->fd[fd]; 1089 filp = fdt->fd[fd];
1015 if (!filp) 1090 if (!filp)
1016 goto out_unlock; 1091 goto out_unlock;
1017 files->fd[fd] = NULL; 1092 rcu_assign_pointer(fdt->fd[fd], NULL);
1018 FD_CLR(fd, files->close_on_exec); 1093 FD_CLR(fd, fdt->close_on_exec);
1019 __put_unused_fd(files, fd); 1094 __put_unused_fd(files, fd);
1020 spin_unlock(&files->file_lock); 1095 spin_unlock(&files->file_lock);
1021 return filp_close(filp, files); 1096 return filp_close(filp, files);