aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorPeter Staubach <staubach@redhat.com>2005-09-13 04:25:12 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-13 11:22:28 -0400
commita1a5b3d93ca45613ec1d920fdb131b69b6553882 (patch)
tree19b5a05aca27f3f2ef1dc2169ce6c521ddfa8468 /fs/open.c
parent873d3469db66ea08e94b0d04a96b1a4507684824 (diff)
[PATCH] open returns ENFILE but creates file anyway
When open(O_CREAT) is called and the error, ENFILE, is returned, the file may be created anyway. This is counter intuitive, against the SUS V3 specification, and may cause applications to misbehave if they are not coded correctly to handle this semantic. The SUS V3 specification explicitly states "No files shall be created or modified if the function returns -1.". The error, ENFILE, is used to indicate the system wide open file table is full and no more file structs can be allocated. This is due to an ordering problem. The entry in the directory is created before the file struct is allocated. If the allocation for the file struct fails, then the system call must return an error, but the directory entry was already created and can not be safely removed. The solution to this situation is relatively easy. The file struct should be allocated before the directory entry is created. If the allocation fails, then the error can be returned directly. If the creation of the directory entry fails, then the file struct can be easily freed. Signed-off-by: Peter Staubach <staubach@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c98
1 files changed, 56 insertions, 42 deletions
diff --git a/fs/open.c b/fs/open.c
index 2fac58c51910..f0d90cf0495c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -738,52 +738,15 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
738 return error; 738 return error;
739} 739}
740 740
741/* 741static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
742 * Note that while the flag value (low two bits) for sys_open means: 742 int flags, struct file *f)
743 * 00 - read-only
744 * 01 - write-only
745 * 10 - read-write
746 * 11 - special
747 * it is changed into
748 * 00 - no permissions needed
749 * 01 - read-permission
750 * 10 - write-permission
751 * 11 - read-write
752 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
753 * used by symlinks.
754 */
755struct file *filp_open(const char * filename, int flags, int mode)
756{
757 int namei_flags, error;
758 struct nameidata nd;
759
760 namei_flags = flags;
761 if ((namei_flags+1) & O_ACCMODE)
762 namei_flags++;
763 if (namei_flags & O_TRUNC)
764 namei_flags |= 2;
765
766 error = open_namei(filename, namei_flags, mode, &nd);
767 if (!error)
768 return dentry_open(nd.dentry, nd.mnt, flags);
769
770 return ERR_PTR(error);
771}
772
773EXPORT_SYMBOL(filp_open);
774
775struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
776{ 743{
777 struct file * f;
778 struct inode *inode; 744 struct inode *inode;
779 int error; 745 int error;
780 746
781 error = -ENFILE;
782 f = get_empty_filp();
783 if (!f)
784 goto cleanup_dentry;
785 f->f_flags = flags; 747 f->f_flags = flags;
786 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;
787 inode = dentry->d_inode; 750 inode = dentry->d_inode;
788 if (f->f_mode & FMODE_WRITE) { 751 if (f->f_mode & FMODE_WRITE) {
789 error = get_write_access(inode); 752 error = get_write_access(inode);
@@ -828,12 +791,63 @@ cleanup_all:
828 f->f_vfsmnt = NULL; 791 f->f_vfsmnt = NULL;
829cleanup_file: 792cleanup_file:
830 put_filp(f); 793 put_filp(f);
831cleanup_dentry:
832 dput(dentry); 794 dput(dentry);
833 mntput(mnt); 795 mntput(mnt);
834 return ERR_PTR(error); 796 return ERR_PTR(error);
835} 797}
836 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}
837EXPORT_SYMBOL(dentry_open); 851EXPORT_SYMBOL(dentry_open);
838 852
839/* 853/*