diff options
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 45 |
1 files changed, 18 insertions, 27 deletions
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/vfs.h> | 21 | #include <linux/vfs.h> |
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/personality.h> | ||
24 | #include <linux/pagemap.h> | 25 | #include <linux/pagemap.h> |
25 | #include <linux/syscalls.h> | 26 | #include <linux/syscalls.h> |
26 | 27 | ||
@@ -807,7 +808,9 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) | |||
807 | 808 | ||
808 | /* NB: we're sure to have correct a_ops only after f_op->open */ | 809 | /* NB: we're sure to have correct a_ops only after f_op->open */ |
809 | if (f->f_flags & O_DIRECT) { | 810 | if (f->f_flags & O_DIRECT) { |
810 | if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) { | 811 | if (!f->f_mapping->a_ops || |
812 | ((!f->f_mapping->a_ops->direct_IO) && | ||
813 | (!f->f_mapping->a_ops->get_xip_page))) { | ||
811 | fput(f); | 814 | fput(f); |
812 | f = ERR_PTR(-EINVAL); | 815 | f = ERR_PTR(-EINVAL); |
813 | } | 816 | } |
@@ -933,31 +936,27 @@ EXPORT_SYMBOL(fd_install); | |||
933 | asmlinkage long sys_open(const char __user * filename, int flags, int mode) | 936 | asmlinkage long sys_open(const char __user * filename, int flags, int mode) |
934 | { | 937 | { |
935 | char * tmp; | 938 | char * tmp; |
936 | int fd, error; | 939 | int fd; |
940 | |||
941 | if (force_o_largefile()) | ||
942 | flags |= O_LARGEFILE; | ||
937 | 943 | ||
938 | #if BITS_PER_LONG != 32 | ||
939 | flags |= O_LARGEFILE; | ||
940 | #endif | ||
941 | tmp = getname(filename); | 944 | tmp = getname(filename); |
942 | fd = PTR_ERR(tmp); | 945 | fd = PTR_ERR(tmp); |
943 | if (!IS_ERR(tmp)) { | 946 | if (!IS_ERR(tmp)) { |
944 | fd = get_unused_fd(); | 947 | fd = get_unused_fd(); |
945 | if (fd >= 0) { | 948 | if (fd >= 0) { |
946 | struct file *f = filp_open(tmp, flags, mode); | 949 | struct file *f = filp_open(tmp, flags, mode); |
947 | error = PTR_ERR(f); | 950 | if (IS_ERR(f)) { |
948 | if (IS_ERR(f)) | 951 | put_unused_fd(fd); |
949 | goto out_error; | 952 | fd = PTR_ERR(f); |
950 | fd_install(fd, f); | 953 | } else { |
954 | fd_install(fd, f); | ||
955 | } | ||
951 | } | 956 | } |
952 | out: | ||
953 | putname(tmp); | 957 | putname(tmp); |
954 | } | 958 | } |
955 | return fd; | 959 | return fd; |
956 | |||
957 | out_error: | ||
958 | put_unused_fd(fd); | ||
959 | fd = error; | ||
960 | goto out; | ||
961 | } | 960 | } |
962 | EXPORT_SYMBOL_GPL(sys_open); | 961 | EXPORT_SYMBOL_GPL(sys_open); |
963 | 962 | ||
@@ -980,23 +979,15 @@ asmlinkage long sys_creat(const char __user * pathname, int mode) | |||
980 | */ | 979 | */ |
981 | int filp_close(struct file *filp, fl_owner_t id) | 980 | int filp_close(struct file *filp, fl_owner_t id) |
982 | { | 981 | { |
983 | int retval; | 982 | int retval = 0; |
984 | |||
985 | /* Report and clear outstanding errors */ | ||
986 | retval = filp->f_error; | ||
987 | if (retval) | ||
988 | filp->f_error = 0; | ||
989 | 983 | ||
990 | if (!file_count(filp)) { | 984 | if (!file_count(filp)) { |
991 | printk(KERN_ERR "VFS: Close: file count is 0\n"); | 985 | printk(KERN_ERR "VFS: Close: file count is 0\n"); |
992 | return retval; | 986 | return 0; |
993 | } | 987 | } |
994 | 988 | ||
995 | if (filp->f_op && filp->f_op->flush) { | 989 | if (filp->f_op && filp->f_op->flush) |
996 | int err = filp->f_op->flush(filp); | 990 | retval = filp->f_op->flush(filp); |
997 | if (!retval) | ||
998 | retval = err; | ||
999 | } | ||
1000 | 991 | ||
1001 | dnotify_flush(filp, id); | 992 | dnotify_flush(filp, id); |
1002 | locks_remove_posix(filp, id); | 993 | locks_remove_posix(filp, id); |