diff options
44 files changed, 633 insertions, 763 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index d6c49e67d3fc..f1daf7ae42e9 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -144,28 +144,25 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd, | |||
144 | struct osf_dirent __user *, dirent, unsigned int, count, | 144 | struct osf_dirent __user *, dirent, unsigned int, count, |
145 | long __user *, basep) | 145 | long __user *, basep) |
146 | { | 146 | { |
147 | int error, fput_needed; | 147 | int error; |
148 | struct file *file; | 148 | struct fd arg = fdget(fd); |
149 | struct osf_dirent_callback buf; | 149 | struct osf_dirent_callback buf; |
150 | 150 | ||
151 | error = -EBADF; | 151 | if (!arg.file) |
152 | file = fget_light(fd, &fput_needed); | 152 | return -EBADF; |
153 | if (!file) | ||
154 | goto out; | ||
155 | 153 | ||
156 | buf.dirent = dirent; | 154 | buf.dirent = dirent; |
157 | buf.basep = basep; | 155 | buf.basep = basep; |
158 | buf.count = count; | 156 | buf.count = count; |
159 | buf.error = 0; | 157 | buf.error = 0; |
160 | 158 | ||
161 | error = vfs_readdir(file, osf_filldir, &buf); | 159 | error = vfs_readdir(arg.file, osf_filldir, &buf); |
162 | if (error >= 0) | 160 | if (error >= 0) |
163 | error = buf.error; | 161 | error = buf.error; |
164 | if (count != buf.count) | 162 | if (count != buf.count) |
165 | error = count - buf.count; | 163 | error = count - buf.count; |
166 | 164 | ||
167 | fput_light(file, fput_needed); | 165 | fdput(arg); |
168 | out: | ||
169 | return error; | 166 | return error; |
170 | } | 167 | } |
171 | 168 | ||
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index ff5d4e4c3733..e3bd7b8aceab 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -4780,7 +4780,7 @@ recheck: | |||
4780 | asmlinkage long | 4780 | asmlinkage long |
4781 | sys_perfmonctl (int fd, int cmd, void __user *arg, int count) | 4781 | sys_perfmonctl (int fd, int cmd, void __user *arg, int count) |
4782 | { | 4782 | { |
4783 | struct file *file = NULL; | 4783 | struct fd f = {NULL, 0}; |
4784 | pfm_context_t *ctx = NULL; | 4784 | pfm_context_t *ctx = NULL; |
4785 | unsigned long flags = 0UL; | 4785 | unsigned long flags = 0UL; |
4786 | void *args_k = NULL; | 4786 | void *args_k = NULL; |
@@ -4789,7 +4789,6 @@ sys_perfmonctl (int fd, int cmd, void __user *arg, int count) | |||
4789 | int narg, completed_args = 0, call_made = 0, cmd_flags; | 4789 | int narg, completed_args = 0, call_made = 0, cmd_flags; |
4790 | int (*func)(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); | 4790 | int (*func)(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); |
4791 | int (*getsize)(void *arg, size_t *sz); | 4791 | int (*getsize)(void *arg, size_t *sz); |
4792 | int fput_needed; | ||
4793 | #define PFM_MAX_ARGSIZE 4096 | 4792 | #define PFM_MAX_ARGSIZE 4096 |
4794 | 4793 | ||
4795 | /* | 4794 | /* |
@@ -4878,17 +4877,17 @@ restart_args: | |||
4878 | 4877 | ||
4879 | ret = -EBADF; | 4878 | ret = -EBADF; |
4880 | 4879 | ||
4881 | file = fget_light(fd, &fput_needed); | 4880 | f = fdget(fd); |
4882 | if (unlikely(file == NULL)) { | 4881 | if (unlikely(f.file == NULL)) { |
4883 | DPRINT(("invalid fd %d\n", fd)); | 4882 | DPRINT(("invalid fd %d\n", fd)); |
4884 | goto error_args; | 4883 | goto error_args; |
4885 | } | 4884 | } |
4886 | if (unlikely(PFM_IS_FILE(file) == 0)) { | 4885 | if (unlikely(PFM_IS_FILE(f.file) == 0)) { |
4887 | DPRINT(("fd %d not related to perfmon\n", fd)); | 4886 | DPRINT(("fd %d not related to perfmon\n", fd)); |
4888 | goto error_args; | 4887 | goto error_args; |
4889 | } | 4888 | } |
4890 | 4889 | ||
4891 | ctx = file->private_data; | 4890 | ctx = f.file->private_data; |
4892 | if (unlikely(ctx == NULL)) { | 4891 | if (unlikely(ctx == NULL)) { |
4893 | DPRINT(("no context for fd %d\n", fd)); | 4892 | DPRINT(("no context for fd %d\n", fd)); |
4894 | goto error_args; | 4893 | goto error_args; |
@@ -4918,8 +4917,8 @@ abort_locked: | |||
4918 | if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT; | 4917 | if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT; |
4919 | 4918 | ||
4920 | error_args: | 4919 | error_args: |
4921 | if (file) | 4920 | if (f.file) |
4922 | fput_light(file, fput_needed); | 4921 | fdput(f); |
4923 | 4922 | ||
4924 | kfree(args_k); | 4923 | kfree(args_k); |
4925 | 4924 | ||
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index 41e01832cb21..6785de7bd2a0 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c | |||
@@ -109,33 +109,32 @@ Efault: | |||
109 | 109 | ||
110 | int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count) | 110 | int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count) |
111 | { | 111 | { |
112 | struct file * file; | 112 | struct fd arg; |
113 | struct hpux_dirent __user * lastdirent; | 113 | struct hpux_dirent __user * lastdirent; |
114 | struct getdents_callback buf; | 114 | struct getdents_callback buf; |
115 | int error = -EBADF, fput_needed; | 115 | int error; |
116 | 116 | ||
117 | file = fget_light(fd, &fput_needed); | 117 | arg = fdget(fd); |
118 | if (!file) | 118 | if (!arg.file) |
119 | goto out; | 119 | return -EBADF; |
120 | 120 | ||
121 | buf.current_dir = dirent; | 121 | buf.current_dir = dirent; |
122 | buf.previous = NULL; | 122 | buf.previous = NULL; |
123 | buf.count = count; | 123 | buf.count = count; |
124 | buf.error = 0; | 124 | buf.error = 0; |
125 | 125 | ||
126 | error = vfs_readdir(file, filldir, &buf); | 126 | error = vfs_readdir(arg.file, filldir, &buf); |
127 | if (error >= 0) | 127 | if (error >= 0) |
128 | error = buf.error; | 128 | error = buf.error; |
129 | lastdirent = buf.previous; | 129 | lastdirent = buf.previous; |
130 | if (lastdirent) { | 130 | if (lastdirent) { |
131 | if (put_user(file->f_pos, &lastdirent->d_off)) | 131 | if (put_user(arg.file->f_pos, &lastdirent->d_off)) |
132 | error = -EFAULT; | 132 | error = -EFAULT; |
133 | else | 133 | else |
134 | error = count - buf.count; | 134 | error = count - buf.count; |
135 | } | 135 | } |
136 | 136 | ||
137 | fput_light(file, fput_needed); | 137 | fdput(arg); |
138 | out: | ||
139 | return error; | 138 | return error; |
140 | } | 139 | } |
141 | 140 | ||
diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c index 714bbfc3162c..db4e638cf408 100644 --- a/arch/powerpc/platforms/cell/spu_syscalls.c +++ b/arch/powerpc/platforms/cell/spu_syscalls.c | |||
@@ -69,8 +69,6 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags, | |||
69 | umode_t, mode, int, neighbor_fd) | 69 | umode_t, mode, int, neighbor_fd) |
70 | { | 70 | { |
71 | long ret; | 71 | long ret; |
72 | struct file *neighbor; | ||
73 | int fput_needed; | ||
74 | struct spufs_calls *calls; | 72 | struct spufs_calls *calls; |
75 | 73 | ||
76 | calls = spufs_calls_get(); | 74 | calls = spufs_calls_get(); |
@@ -78,11 +76,11 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags, | |||
78 | return -ENOSYS; | 76 | return -ENOSYS; |
79 | 77 | ||
80 | if (flags & SPU_CREATE_AFFINITY_SPU) { | 78 | if (flags & SPU_CREATE_AFFINITY_SPU) { |
79 | struct fd neighbor = fdget(neighbor_fd); | ||
81 | ret = -EBADF; | 80 | ret = -EBADF; |
82 | neighbor = fget_light(neighbor_fd, &fput_needed); | 81 | if (neighbor.file) { |
83 | if (neighbor) { | 82 | ret = calls->create_thread(name, flags, mode, neighbor.file); |
84 | ret = calls->create_thread(name, flags, mode, neighbor); | 83 | fdput(neighbor); |
85 | fput_light(neighbor, fput_needed); | ||
86 | } | 84 | } |
87 | } else | 85 | } else |
88 | ret = calls->create_thread(name, flags, mode, NULL); | 86 | ret = calls->create_thread(name, flags, mode, NULL); |
@@ -94,8 +92,7 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags, | |||
94 | asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus) | 92 | asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus) |
95 | { | 93 | { |
96 | long ret; | 94 | long ret; |
97 | struct file *filp; | 95 | struct fd arg; |
98 | int fput_needed; | ||
99 | struct spufs_calls *calls; | 96 | struct spufs_calls *calls; |
100 | 97 | ||
101 | calls = spufs_calls_get(); | 98 | calls = spufs_calls_get(); |
@@ -103,10 +100,10 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus) | |||
103 | return -ENOSYS; | 100 | return -ENOSYS; |
104 | 101 | ||
105 | ret = -EBADF; | 102 | ret = -EBADF; |
106 | filp = fget_light(fd, &fput_needed); | 103 | arg = fdget(fd); |
107 | if (filp) { | 104 | if (arg.file) { |
108 | ret = calls->spu_run(filp, unpc, ustatus); | 105 | ret = calls->spu_run(arg.file, unpc, ustatus); |
109 | fput_light(filp, fput_needed); | 106 | fdput(arg); |
110 | } | 107 | } |
111 | 108 | ||
112 | spufs_calls_put(calls); | 109 | spufs_calls_put(calls); |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 6b2ae729de92..6f28da9f4cad 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
@@ -1184,20 +1184,20 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file, | |||
1184 | struct rdma_ucm_migrate_id cmd; | 1184 | struct rdma_ucm_migrate_id cmd; |
1185 | struct rdma_ucm_migrate_resp resp; | 1185 | struct rdma_ucm_migrate_resp resp; |
1186 | struct ucma_context *ctx; | 1186 | struct ucma_context *ctx; |
1187 | struct file *filp; | 1187 | struct fd f; |
1188 | struct ucma_file *cur_file; | 1188 | struct ucma_file *cur_file; |
1189 | int ret = 0, fput_needed; | 1189 | int ret = 0; |
1190 | 1190 | ||
1191 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 1191 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
1192 | return -EFAULT; | 1192 | return -EFAULT; |
1193 | 1193 | ||
1194 | /* Get current fd to protect against it being closed */ | 1194 | /* Get current fd to protect against it being closed */ |
1195 | filp = fget_light(cmd.fd, &fput_needed); | 1195 | f = fdget(cmd.fd); |
1196 | if (!filp) | 1196 | if (!f.file) |
1197 | return -ENOENT; | 1197 | return -ENOENT; |
1198 | 1198 | ||
1199 | /* Validate current fd and prevent destruction of id. */ | 1199 | /* Validate current fd and prevent destruction of id. */ |
1200 | ctx = ucma_get_ctx(filp->private_data, cmd.id); | 1200 | ctx = ucma_get_ctx(f.file->private_data, cmd.id); |
1201 | if (IS_ERR(ctx)) { | 1201 | if (IS_ERR(ctx)) { |
1202 | ret = PTR_ERR(ctx); | 1202 | ret = PTR_ERR(ctx); |
1203 | goto file_put; | 1203 | goto file_put; |
@@ -1231,7 +1231,7 @@ response: | |||
1231 | 1231 | ||
1232 | ucma_put_ctx(ctx); | 1232 | ucma_put_ctx(ctx); |
1233 | file_put: | 1233 | file_put: |
1234 | fput_light(filp, fput_needed); | 1234 | fdput(f); |
1235 | return ret; | 1235 | return ret; |
1236 | } | 1236 | } |
1237 | 1237 | ||
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 402679bd30a3..0cb0007724a2 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -705,9 +705,9 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file, | |||
705 | struct ib_udata udata; | 705 | struct ib_udata udata; |
706 | struct ib_uxrcd_object *obj; | 706 | struct ib_uxrcd_object *obj; |
707 | struct ib_xrcd *xrcd = NULL; | 707 | struct ib_xrcd *xrcd = NULL; |
708 | struct file *f = NULL; | 708 | struct fd f = {NULL, 0}; |
709 | struct inode *inode = NULL; | 709 | struct inode *inode = NULL; |
710 | int ret = 0, fput_needed; | 710 | int ret = 0; |
711 | int new_xrcd = 0; | 711 | int new_xrcd = 0; |
712 | 712 | ||
713 | if (out_len < sizeof resp) | 713 | if (out_len < sizeof resp) |
@@ -724,13 +724,13 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file, | |||
724 | 724 | ||
725 | if (cmd.fd != -1) { | 725 | if (cmd.fd != -1) { |
726 | /* search for file descriptor */ | 726 | /* search for file descriptor */ |
727 | f = fget_light(cmd.fd, &fput_needed); | 727 | f = fdget(cmd.fd); |
728 | if (!f) { | 728 | if (!f.file) { |
729 | ret = -EBADF; | 729 | ret = -EBADF; |
730 | goto err_tree_mutex_unlock; | 730 | goto err_tree_mutex_unlock; |
731 | } | 731 | } |
732 | 732 | ||
733 | inode = f->f_dentry->d_inode; | 733 | inode = f.file->f_path.dentry->d_inode; |
734 | xrcd = find_xrcd(file->device, inode); | 734 | xrcd = find_xrcd(file->device, inode); |
735 | if (!xrcd && !(cmd.oflags & O_CREAT)) { | 735 | if (!xrcd && !(cmd.oflags & O_CREAT)) { |
736 | /* no file descriptor. Need CREATE flag */ | 736 | /* no file descriptor. Need CREATE flag */ |
@@ -795,8 +795,8 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file, | |||
795 | goto err_copy; | 795 | goto err_copy; |
796 | } | 796 | } |
797 | 797 | ||
798 | if (f) | 798 | if (f.file) |
799 | fput_light(f, fput_needed); | 799 | fdput(f); |
800 | 800 | ||
801 | mutex_lock(&file->mutex); | 801 | mutex_lock(&file->mutex); |
802 | list_add_tail(&obj->uobject.list, &file->ucontext->xrcd_list); | 802 | list_add_tail(&obj->uobject.list, &file->ucontext->xrcd_list); |
@@ -825,8 +825,8 @@ err: | |||
825 | put_uobj_write(&obj->uobject); | 825 | put_uobj_write(&obj->uobject); |
826 | 826 | ||
827 | err_tree_mutex_unlock: | 827 | err_tree_mutex_unlock: |
828 | if (f) | 828 | if (f.file) |
829 | fput_light(f, fput_needed); | 829 | fdput(f); |
830 | 830 | ||
831 | mutex_unlock(&file->device->xrcd_tree_mutex); | 831 | mutex_unlock(&file->device->xrcd_tree_mutex); |
832 | 832 | ||
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index acf75c2cf7ef..6f2ce6fa98f8 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -541,17 +541,15 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, | |||
541 | struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd) | 541 | struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd) |
542 | { | 542 | { |
543 | struct ib_uverbs_event_file *ev_file = NULL; | 543 | struct ib_uverbs_event_file *ev_file = NULL; |
544 | struct file *filp; | 544 | struct fd f = fdget(fd); |
545 | int fput_needed; | ||
546 | 545 | ||
547 | filp = fget_light(fd, &fput_needed); | 546 | if (!f.file) |
548 | if (!filp) | ||
549 | return NULL; | 547 | return NULL; |
550 | 548 | ||
551 | if (filp->f_op != &uverbs_event_fops) | 549 | if (f.file->f_op != &uverbs_event_fops) |
552 | goto out; | 550 | goto out; |
553 | 551 | ||
554 | ev_file = filp->private_data; | 552 | ev_file = f.file->private_data; |
555 | if (ev_file->is_async) { | 553 | if (ev_file->is_async) { |
556 | ev_file = NULL; | 554 | ev_file = NULL; |
557 | goto out; | 555 | goto out; |
@@ -560,7 +558,7 @@ struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd) | |||
560 | kref_get(&ev_file->ref); | 558 | kref_get(&ev_file->ref); |
561 | 559 | ||
562 | out: | 560 | out: |
563 | fput_light(filp, fput_needed); | 561 | fdput(f); |
564 | return ev_file; | 562 | return ev_file; |
565 | } | 563 | } |
566 | 564 | ||
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 91bcd97d3061..56097c6d072d 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c | |||
@@ -1014,25 +1014,25 @@ static void vfio_group_try_dissolve_container(struct vfio_group *group) | |||
1014 | 1014 | ||
1015 | static int vfio_group_set_container(struct vfio_group *group, int container_fd) | 1015 | static int vfio_group_set_container(struct vfio_group *group, int container_fd) |
1016 | { | 1016 | { |
1017 | struct file *filep; | 1017 | struct fd f; |
1018 | struct vfio_container *container; | 1018 | struct vfio_container *container; |
1019 | struct vfio_iommu_driver *driver; | 1019 | struct vfio_iommu_driver *driver; |
1020 | int ret = 0, fput_needed; | 1020 | int ret = 0; |
1021 | 1021 | ||
1022 | if (atomic_read(&group->container_users)) | 1022 | if (atomic_read(&group->container_users)) |
1023 | return -EINVAL; | 1023 | return -EINVAL; |
1024 | 1024 | ||
1025 | filep = fget_light(container_fd, &fput_needed); | 1025 | f = fdget(container_fd); |
1026 | if (!filep) | 1026 | if (!f.file) |
1027 | return -EBADF; | 1027 | return -EBADF; |
1028 | 1028 | ||
1029 | /* Sanity check, is this really our fd? */ | 1029 | /* Sanity check, is this really our fd? */ |
1030 | if (filep->f_op != &vfio_fops) { | 1030 | if (f.file->f_op != &vfio_fops) { |
1031 | fput_light(filep, fput_needed); | 1031 | fdput(f); |
1032 | return -EINVAL; | 1032 | return -EINVAL; |
1033 | } | 1033 | } |
1034 | 1034 | ||
1035 | container = filep->private_data; | 1035 | container = f.file->private_data; |
1036 | WARN_ON(!container); /* fget ensures we don't race vfio_release */ | 1036 | WARN_ON(!container); /* fget ensures we don't race vfio_release */ |
1037 | 1037 | ||
1038 | mutex_lock(&container->group_lock); | 1038 | mutex_lock(&container->group_lock); |
@@ -1054,8 +1054,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) | |||
1054 | 1054 | ||
1055 | unlock_out: | 1055 | unlock_out: |
1056 | mutex_unlock(&container->group_lock); | 1056 | mutex_unlock(&container->group_lock); |
1057 | fput_light(filep, fput_needed); | 1057 | fdput(f); |
1058 | |||
1059 | return ret; | 1058 | return ret; |
1060 | } | 1059 | } |
1061 | 1060 | ||
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c index cb2ddf164c98..07c9d8ab2c3b 100644 --- a/drivers/video/msm/mdp.c +++ b/drivers/video/msm/mdp.c | |||
@@ -257,19 +257,17 @@ int get_img(struct mdp_img *img, struct fb_info *info, | |||
257 | unsigned long *start, unsigned long *len, | 257 | unsigned long *start, unsigned long *len, |
258 | struct file **filep) | 258 | struct file **filep) |
259 | { | 259 | { |
260 | int put_needed, ret = 0; | 260 | int ret = 0; |
261 | struct file *file; | 261 | struct fd f = fdget(img->memory_id); |
262 | 262 | if (f.file == NULL) | |
263 | file = fget_light(img->memory_id, &put_needed); | ||
264 | if (file == NULL) | ||
265 | return -1; | 263 | return -1; |
266 | 264 | ||
267 | if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) { | 265 | if (MAJOR(f.file->f_dentry->d_inode->i_rdev) == FB_MAJOR) { |
268 | *start = info->fix.smem_start; | 266 | *start = info->fix.smem_start; |
269 | *len = info->fix.smem_len; | 267 | *len = info->fix.smem_len; |
270 | } else | 268 | } else |
271 | ret = -1; | 269 | ret = -1; |
272 | fput_light(file, put_needed); | 270 | fdput(f); |
273 | 271 | ||
274 | return ret; | 272 | return ret; |
275 | } | 273 | } |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 3494f2f44167..0a4f0c8bc58f 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1397,7 +1397,6 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file, | |||
1397 | u64 *transid, bool readonly, | 1397 | u64 *transid, bool readonly, |
1398 | struct btrfs_qgroup_inherit **inherit) | 1398 | struct btrfs_qgroup_inherit **inherit) |
1399 | { | 1399 | { |
1400 | struct file *src_file; | ||
1401 | int namelen; | 1400 | int namelen; |
1402 | int ret = 0; | 1401 | int ret = 0; |
1403 | 1402 | ||
@@ -1421,15 +1420,14 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file, | |||
1421 | ret = btrfs_mksubvol(&file->f_path, name, namelen, | 1420 | ret = btrfs_mksubvol(&file->f_path, name, namelen, |
1422 | NULL, transid, readonly, inherit); | 1421 | NULL, transid, readonly, inherit); |
1423 | } else { | 1422 | } else { |
1423 | struct fd src = fdget(fd); | ||
1424 | struct inode *src_inode; | 1424 | struct inode *src_inode; |
1425 | int fput_needed; | 1425 | if (!src.file) { |
1426 | src_file = fget_light(fd, &fput_needed); | ||
1427 | if (!src_file) { | ||
1428 | ret = -EINVAL; | 1426 | ret = -EINVAL; |
1429 | goto out_drop_write; | 1427 | goto out_drop_write; |
1430 | } | 1428 | } |
1431 | 1429 | ||
1432 | src_inode = src_file->f_path.dentry->d_inode; | 1430 | src_inode = src.file->f_path.dentry->d_inode; |
1433 | if (src_inode->i_sb != file->f_path.dentry->d_inode->i_sb) { | 1431 | if (src_inode->i_sb != file->f_path.dentry->d_inode->i_sb) { |
1434 | printk(KERN_INFO "btrfs: Snapshot src from " | 1432 | printk(KERN_INFO "btrfs: Snapshot src from " |
1435 | "another FS\n"); | 1433 | "another FS\n"); |
@@ -1439,7 +1437,7 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file, | |||
1439 | BTRFS_I(src_inode)->root, | 1437 | BTRFS_I(src_inode)->root, |
1440 | transid, readonly, inherit); | 1438 | transid, readonly, inherit); |
1441 | } | 1439 | } |
1442 | fput_light(src_file, fput_needed); | 1440 | fdput(src); |
1443 | } | 1441 | } |
1444 | out_drop_write: | 1442 | out_drop_write: |
1445 | mnt_drop_write_file(file); | 1443 | mnt_drop_write_file(file); |
@@ -2341,7 +2339,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
2341 | { | 2339 | { |
2342 | struct inode *inode = fdentry(file)->d_inode; | 2340 | struct inode *inode = fdentry(file)->d_inode; |
2343 | struct btrfs_root *root = BTRFS_I(inode)->root; | 2341 | struct btrfs_root *root = BTRFS_I(inode)->root; |
2344 | struct file *src_file; | 2342 | struct fd src_file; |
2345 | struct inode *src; | 2343 | struct inode *src; |
2346 | struct btrfs_trans_handle *trans; | 2344 | struct btrfs_trans_handle *trans; |
2347 | struct btrfs_path *path; | 2345 | struct btrfs_path *path; |
@@ -2350,7 +2348,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
2350 | struct btrfs_key key; | 2348 | struct btrfs_key key; |
2351 | u32 nritems; | 2349 | u32 nritems; |
2352 | int slot; | 2350 | int slot; |
2353 | int ret, fput_needed; | 2351 | int ret; |
2354 | u64 len = olen; | 2352 | u64 len = olen; |
2355 | u64 bs = root->fs_info->sb->s_blocksize; | 2353 | u64 bs = root->fs_info->sb->s_blocksize; |
2356 | u64 hint_byte; | 2354 | u64 hint_byte; |
@@ -2376,24 +2374,24 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
2376 | if (ret) | 2374 | if (ret) |
2377 | return ret; | 2375 | return ret; |
2378 | 2376 | ||
2379 | src_file = fget_light(srcfd, &fput_needed); | 2377 | src_file = fdget(srcfd); |
2380 | if (!src_file) { | 2378 | if (!src_file.file) { |
2381 | ret = -EBADF; | 2379 | ret = -EBADF; |
2382 | goto out_drop_write; | 2380 | goto out_drop_write; |
2383 | } | 2381 | } |
2384 | 2382 | ||
2385 | ret = -EXDEV; | 2383 | ret = -EXDEV; |
2386 | if (src_file->f_path.mnt != file->f_path.mnt) | 2384 | if (src_file.file->f_path.mnt != file->f_path.mnt) |
2387 | goto out_fput; | 2385 | goto out_fput; |
2388 | 2386 | ||
2389 | src = src_file->f_dentry->d_inode; | 2387 | src = src_file.file->f_dentry->d_inode; |
2390 | 2388 | ||
2391 | ret = -EINVAL; | 2389 | ret = -EINVAL; |
2392 | if (src == inode) | 2390 | if (src == inode) |
2393 | goto out_fput; | 2391 | goto out_fput; |
2394 | 2392 | ||
2395 | /* the src must be open for reading */ | 2393 | /* the src must be open for reading */ |
2396 | if (!(src_file->f_mode & FMODE_READ)) | 2394 | if (!(src_file.file->f_mode & FMODE_READ)) |
2397 | goto out_fput; | 2395 | goto out_fput; |
2398 | 2396 | ||
2399 | /* don't make the dst file partly checksummed */ | 2397 | /* don't make the dst file partly checksummed */ |
@@ -2724,7 +2722,7 @@ out_unlock: | |||
2724 | vfree(buf); | 2722 | vfree(buf); |
2725 | btrfs_free_path(path); | 2723 | btrfs_free_path(path); |
2726 | out_fput: | 2724 | out_fput: |
2727 | fput_light(src_file, fput_needed); | 2725 | fdput(src_file); |
2728 | out_drop_write: | 2726 | out_drop_write: |
2729 | mnt_drop_write_file(file); | 2727 | mnt_drop_write_file(file); |
2730 | return ret; | 2728 | return ret; |
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index bd2313d106e5..d315c6c5891a 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
@@ -107,9 +107,9 @@ static const struct super_operations coda_super_operations = | |||
107 | 107 | ||
108 | static int get_device_index(struct coda_mount_data *data) | 108 | static int get_device_index(struct coda_mount_data *data) |
109 | { | 109 | { |
110 | struct file *file; | 110 | struct fd f; |
111 | struct inode *inode; | 111 | struct inode *inode; |
112 | int idx, fput_needed; | 112 | int idx; |
113 | 113 | ||
114 | if (data == NULL) { | 114 | if (data == NULL) { |
115 | printk("coda_read_super: Bad mount data\n"); | 115 | printk("coda_read_super: Bad mount data\n"); |
@@ -121,17 +121,17 @@ static int get_device_index(struct coda_mount_data *data) | |||
121 | return -1; | 121 | return -1; |
122 | } | 122 | } |
123 | 123 | ||
124 | file = fget_light(data->fd, &fput_needed); | 124 | f = fdget(data->fd); |
125 | if (!file) | 125 | if (!f.file) |
126 | goto Ebadf; | 126 | goto Ebadf; |
127 | inode = file->f_path.dentry->d_inode; | 127 | inode = f.file->f_path.dentry->d_inode; |
128 | if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) { | 128 | if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) { |
129 | fput_light(file, fput_needed); | 129 | fdput(f); |
130 | goto Ebadf; | 130 | goto Ebadf; |
131 | } | 131 | } |
132 | 132 | ||
133 | idx = iminor(inode); | 133 | idx = iminor(inode); |
134 | fput_light(file, fput_needed); | 134 | fdput(f); |
135 | 135 | ||
136 | if (idx < 0 || idx >= MAX_CODADEVS) { | 136 | if (idx < 0 || idx >= MAX_CODADEVS) { |
137 | printk("coda_read_super: Bad minor number\n"); | 137 | printk("coda_read_super: Bad minor number\n"); |
diff --git a/fs/compat.c b/fs/compat.c index 1bdb350ea5d3..d72d51e19025 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -870,22 +870,20 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd, | |||
870 | struct compat_old_linux_dirent __user *dirent, unsigned int count) | 870 | struct compat_old_linux_dirent __user *dirent, unsigned int count) |
871 | { | 871 | { |
872 | int error; | 872 | int error; |
873 | struct file *file; | 873 | struct fd f = fdget(fd); |
874 | int fput_needed; | ||
875 | struct compat_readdir_callback buf; | 874 | struct compat_readdir_callback buf; |
876 | 875 | ||
877 | file = fget_light(fd, &fput_needed); | 876 | if (!f.file) |
878 | if (!file) | ||
879 | return -EBADF; | 877 | return -EBADF; |
880 | 878 | ||
881 | buf.result = 0; | 879 | buf.result = 0; |
882 | buf.dirent = dirent; | 880 | buf.dirent = dirent; |
883 | 881 | ||
884 | error = vfs_readdir(file, compat_fillonedir, &buf); | 882 | error = vfs_readdir(f.file, compat_fillonedir, &buf); |
885 | if (buf.result) | 883 | if (buf.result) |
886 | error = buf.result; | 884 | error = buf.result; |
887 | 885 | ||
888 | fput_light(file, fput_needed); | 886 | fdput(f); |
889 | return error; | 887 | return error; |
890 | } | 888 | } |
891 | 889 | ||
@@ -949,17 +947,16 @@ efault: | |||
949 | asmlinkage long compat_sys_getdents(unsigned int fd, | 947 | asmlinkage long compat_sys_getdents(unsigned int fd, |
950 | struct compat_linux_dirent __user *dirent, unsigned int count) | 948 | struct compat_linux_dirent __user *dirent, unsigned int count) |
951 | { | 949 | { |
952 | struct file * file; | 950 | struct fd f; |
953 | struct compat_linux_dirent __user * lastdirent; | 951 | struct compat_linux_dirent __user * lastdirent; |
954 | struct compat_getdents_callback buf; | 952 | struct compat_getdents_callback buf; |
955 | int fput_needed; | ||
956 | int error; | 953 | int error; |
957 | 954 | ||
958 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 955 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
959 | return -EFAULT; | 956 | return -EFAULT; |
960 | 957 | ||
961 | file = fget_light(fd, &fput_needed); | 958 | f = fdget(fd); |
962 | if (!file) | 959 | if (!f.file) |
963 | return -EBADF; | 960 | return -EBADF; |
964 | 961 | ||
965 | buf.current_dir = dirent; | 962 | buf.current_dir = dirent; |
@@ -967,17 +964,17 @@ asmlinkage long compat_sys_getdents(unsigned int fd, | |||
967 | buf.count = count; | 964 | buf.count = count; |
968 | buf.error = 0; | 965 | buf.error = 0; |
969 | 966 | ||
970 | error = vfs_readdir(file, compat_filldir, &buf); | 967 | error = vfs_readdir(f.file, compat_filldir, &buf); |
971 | if (error >= 0) | 968 | if (error >= 0) |
972 | error = buf.error; | 969 | error = buf.error; |
973 | lastdirent = buf.previous; | 970 | lastdirent = buf.previous; |
974 | if (lastdirent) { | 971 | if (lastdirent) { |
975 | if (put_user(file->f_pos, &lastdirent->d_off)) | 972 | if (put_user(f.file->f_pos, &lastdirent->d_off)) |
976 | error = -EFAULT; | 973 | error = -EFAULT; |
977 | else | 974 | else |
978 | error = count - buf.count; | 975 | error = count - buf.count; |
979 | } | 976 | } |
980 | fput_light(file, fput_needed); | 977 | fdput(f); |
981 | return error; | 978 | return error; |
982 | } | 979 | } |
983 | 980 | ||
@@ -1035,17 +1032,16 @@ efault: | |||
1035 | asmlinkage long compat_sys_getdents64(unsigned int fd, | 1032 | asmlinkage long compat_sys_getdents64(unsigned int fd, |
1036 | struct linux_dirent64 __user * dirent, unsigned int count) | 1033 | struct linux_dirent64 __user * dirent, unsigned int count) |
1037 | { | 1034 | { |
1038 | struct file * file; | 1035 | struct fd f; |
1039 | struct linux_dirent64 __user * lastdirent; | 1036 | struct linux_dirent64 __user * lastdirent; |
1040 | struct compat_getdents_callback64 buf; | 1037 | struct compat_getdents_callback64 buf; |
1041 | int fput_needed; | ||
1042 | int error; | 1038 | int error; |
1043 | 1039 | ||
1044 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 1040 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
1045 | return -EFAULT; | 1041 | return -EFAULT; |
1046 | 1042 | ||
1047 | file = fget_light(fd, &fput_needed); | 1043 | f = fdget(fd); |
1048 | if (!file) | 1044 | if (!f.file) |
1049 | return -EBADF; | 1045 | return -EBADF; |
1050 | 1046 | ||
1051 | buf.current_dir = dirent; | 1047 | buf.current_dir = dirent; |
@@ -1053,18 +1049,18 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, | |||
1053 | buf.count = count; | 1049 | buf.count = count; |
1054 | buf.error = 0; | 1050 | buf.error = 0; |
1055 | 1051 | ||
1056 | error = vfs_readdir(file, compat_filldir64, &buf); | 1052 | error = vfs_readdir(f.file, compat_filldir64, &buf); |
1057 | if (error >= 0) | 1053 | if (error >= 0) |
1058 | error = buf.error; | 1054 | error = buf.error; |
1059 | lastdirent = buf.previous; | 1055 | lastdirent = buf.previous; |
1060 | if (lastdirent) { | 1056 | if (lastdirent) { |
1061 | typeof(lastdirent->d_off) d_off = file->f_pos; | 1057 | typeof(lastdirent->d_off) d_off = f.file->f_pos; |
1062 | if (__put_user_unaligned(d_off, &lastdirent->d_off)) | 1058 | if (__put_user_unaligned(d_off, &lastdirent->d_off)) |
1063 | error = -EFAULT; | 1059 | error = -EFAULT; |
1064 | else | 1060 | else |
1065 | error = count - buf.count; | 1061 | error = count - buf.count; |
1066 | } | 1062 | } |
1067 | fput_light(file, fput_needed); | 1063 | fdput(f); |
1068 | return error; | 1064 | return error; |
1069 | } | 1065 | } |
1070 | #endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */ | 1066 | #endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */ |
@@ -1152,18 +1148,16 @@ asmlinkage ssize_t | |||
1152 | compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, | 1148 | compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, |
1153 | unsigned long vlen) | 1149 | unsigned long vlen) |
1154 | { | 1150 | { |
1155 | struct file *file; | 1151 | struct fd f = fdget(fd); |
1156 | int fput_needed; | ||
1157 | ssize_t ret; | 1152 | ssize_t ret; |
1158 | loff_t pos; | 1153 | loff_t pos; |
1159 | 1154 | ||
1160 | file = fget_light(fd, &fput_needed); | 1155 | if (!f.file) |
1161 | if (!file) | ||
1162 | return -EBADF; | 1156 | return -EBADF; |
1163 | pos = file->f_pos; | 1157 | pos = f.file->f_pos; |
1164 | ret = compat_readv(file, vec, vlen, &pos); | 1158 | ret = compat_readv(f.file, vec, vlen, &pos); |
1165 | file->f_pos = pos; | 1159 | f.file->f_pos = pos; |
1166 | fput_light(file, fput_needed); | 1160 | fdput(f); |
1167 | return ret; | 1161 | return ret; |
1168 | } | 1162 | } |
1169 | 1163 | ||
@@ -1171,19 +1165,18 @@ asmlinkage ssize_t | |||
1171 | compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec, | 1165 | compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec, |
1172 | unsigned long vlen, loff_t pos) | 1166 | unsigned long vlen, loff_t pos) |
1173 | { | 1167 | { |
1174 | struct file *file; | 1168 | struct fd f; |
1175 | int fput_needed; | ||
1176 | ssize_t ret; | 1169 | ssize_t ret; |
1177 | 1170 | ||
1178 | if (pos < 0) | 1171 | if (pos < 0) |
1179 | return -EINVAL; | 1172 | return -EINVAL; |
1180 | file = fget_light(fd, &fput_needed); | 1173 | f = fdget(fd); |
1181 | if (!file) | 1174 | if (!f.file) |
1182 | return -EBADF; | 1175 | return -EBADF; |
1183 | ret = -ESPIPE; | 1176 | ret = -ESPIPE; |
1184 | if (file->f_mode & FMODE_PREAD) | 1177 | if (f.file->f_mode & FMODE_PREAD) |
1185 | ret = compat_readv(file, vec, vlen, &pos); | 1178 | ret = compat_readv(f.file, vec, vlen, &pos); |
1186 | fput_light(file, fput_needed); | 1179 | fdput(f); |
1187 | return ret; | 1180 | return ret; |
1188 | } | 1181 | } |
1189 | 1182 | ||
@@ -1221,18 +1214,16 @@ asmlinkage ssize_t | |||
1221 | compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, | 1214 | compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, |
1222 | unsigned long vlen) | 1215 | unsigned long vlen) |
1223 | { | 1216 | { |
1224 | struct file *file; | 1217 | struct fd f = fdget(fd); |
1225 | int fput_needed; | ||
1226 | ssize_t ret; | 1218 | ssize_t ret; |
1227 | loff_t pos; | 1219 | loff_t pos; |
1228 | 1220 | ||
1229 | file = fget_light(fd, &fput_needed); | 1221 | if (!f.file) |
1230 | if (!file) | ||
1231 | return -EBADF; | 1222 | return -EBADF; |
1232 | pos = file->f_pos; | 1223 | pos = f.file->f_pos; |
1233 | ret = compat_writev(file, vec, vlen, &pos); | 1224 | ret = compat_writev(f.file, vec, vlen, &pos); |
1234 | file->f_pos = pos; | 1225 | f.file->f_pos = pos; |
1235 | fput_light(file, fput_needed); | 1226 | fdput(f); |
1236 | return ret; | 1227 | return ret; |
1237 | } | 1228 | } |
1238 | 1229 | ||
@@ -1240,19 +1231,18 @@ asmlinkage ssize_t | |||
1240 | compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec, | 1231 | compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec, |
1241 | unsigned long vlen, loff_t pos) | 1232 | unsigned long vlen, loff_t pos) |
1242 | { | 1233 | { |
1243 | struct file *file; | 1234 | struct fd f; |
1244 | int fput_needed; | ||
1245 | ssize_t ret; | 1235 | ssize_t ret; |
1246 | 1236 | ||
1247 | if (pos < 0) | 1237 | if (pos < 0) |
1248 | return -EINVAL; | 1238 | return -EINVAL; |
1249 | file = fget_light(fd, &fput_needed); | 1239 | f = fdget(fd); |
1250 | if (!file) | 1240 | if (!f.file) |
1251 | return -EBADF; | 1241 | return -EBADF; |
1252 | ret = -ESPIPE; | 1242 | ret = -ESPIPE; |
1253 | if (file->f_mode & FMODE_PWRITE) | 1243 | if (f.file->f_mode & FMODE_PWRITE) |
1254 | ret = compat_writev(file, vec, vlen, &pos); | 1244 | ret = compat_writev(f.file, vec, vlen, &pos); |
1255 | fput_light(file, fput_needed); | 1245 | fdput(f); |
1256 | return ret; | 1246 | return ret; |
1257 | } | 1247 | } |
1258 | 1248 | ||
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index debdfe0fc809..48f1987bec34 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -1531,16 +1531,13 @@ static int compat_ioctl_check_table(unsigned int xcmd) | |||
1531 | asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | 1531 | asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, |
1532 | unsigned long arg) | 1532 | unsigned long arg) |
1533 | { | 1533 | { |
1534 | struct file *filp; | 1534 | struct fd f = fdget(fd); |
1535 | int error = -EBADF; | 1535 | int error = -EBADF; |
1536 | int fput_needed; | 1536 | if (!f.file) |
1537 | |||
1538 | filp = fget_light(fd, &fput_needed); | ||
1539 | if (!filp) | ||
1540 | goto out; | 1537 | goto out; |
1541 | 1538 | ||
1542 | /* RED-PEN how should LSM module know it's handling 32bit? */ | 1539 | /* RED-PEN how should LSM module know it's handling 32bit? */ |
1543 | error = security_file_ioctl(filp, cmd, arg); | 1540 | error = security_file_ioctl(f.file, cmd, arg); |
1544 | if (error) | 1541 | if (error) |
1545 | goto out_fput; | 1542 | goto out_fput; |
1546 | 1543 | ||
@@ -1560,30 +1557,30 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | |||
1560 | #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) | 1557 | #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) |
1561 | case FS_IOC_RESVSP_32: | 1558 | case FS_IOC_RESVSP_32: |
1562 | case FS_IOC_RESVSP64_32: | 1559 | case FS_IOC_RESVSP64_32: |
1563 | error = compat_ioctl_preallocate(filp, compat_ptr(arg)); | 1560 | error = compat_ioctl_preallocate(f.file, compat_ptr(arg)); |
1564 | goto out_fput; | 1561 | goto out_fput; |
1565 | #else | 1562 | #else |
1566 | case FS_IOC_RESVSP: | 1563 | case FS_IOC_RESVSP: |
1567 | case FS_IOC_RESVSP64: | 1564 | case FS_IOC_RESVSP64: |
1568 | error = ioctl_preallocate(filp, compat_ptr(arg)); | 1565 | error = ioctl_preallocate(f.file, compat_ptr(arg)); |
1569 | goto out_fput; | 1566 | goto out_fput; |
1570 | #endif | 1567 | #endif |
1571 | 1568 | ||
1572 | case FIBMAP: | 1569 | case FIBMAP: |
1573 | case FIGETBSZ: | 1570 | case FIGETBSZ: |
1574 | case FIONREAD: | 1571 | case FIONREAD: |
1575 | if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) | 1572 | if (S_ISREG(f.file->f_path.dentry->d_inode->i_mode)) |
1576 | break; | 1573 | break; |
1577 | /*FALL THROUGH*/ | 1574 | /*FALL THROUGH*/ |
1578 | 1575 | ||
1579 | default: | 1576 | default: |
1580 | if (filp->f_op && filp->f_op->compat_ioctl) { | 1577 | if (f.file->f_op && f.file->f_op->compat_ioctl) { |
1581 | error = filp->f_op->compat_ioctl(filp, cmd, arg); | 1578 | error = f.file->f_op->compat_ioctl(f.file, cmd, arg); |
1582 | if (error != -ENOIOCTLCMD) | 1579 | if (error != -ENOIOCTLCMD) |
1583 | goto out_fput; | 1580 | goto out_fput; |
1584 | } | 1581 | } |
1585 | 1582 | ||
1586 | if (!filp->f_op || !filp->f_op->unlocked_ioctl) | 1583 | if (!f.file->f_op || !f.file->f_op->unlocked_ioctl) |
1587 | goto do_ioctl; | 1584 | goto do_ioctl; |
1588 | break; | 1585 | break; |
1589 | } | 1586 | } |
@@ -1591,7 +1588,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | |||
1591 | if (compat_ioctl_check_table(XFORM(cmd))) | 1588 | if (compat_ioctl_check_table(XFORM(cmd))) |
1592 | goto found_handler; | 1589 | goto found_handler; |
1593 | 1590 | ||
1594 | error = do_ioctl_trans(fd, cmd, arg, filp); | 1591 | error = do_ioctl_trans(fd, cmd, arg, f.file); |
1595 | if (error == -ENOIOCTLCMD) | 1592 | if (error == -ENOIOCTLCMD) |
1596 | error = -ENOTTY; | 1593 | error = -ENOTTY; |
1597 | 1594 | ||
@@ -1600,9 +1597,9 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | |||
1600 | found_handler: | 1597 | found_handler: |
1601 | arg = (unsigned long)compat_ptr(arg); | 1598 | arg = (unsigned long)compat_ptr(arg); |
1602 | do_ioctl: | 1599 | do_ioctl: |
1603 | error = do_vfs_ioctl(filp, fd, cmd, arg); | 1600 | error = do_vfs_ioctl(f.file, fd, cmd, arg); |
1604 | out_fput: | 1601 | out_fput: |
1605 | fput_light(filp, fput_needed); | 1602 | fdput(f); |
1606 | out: | 1603 | out: |
1607 | return error; | 1604 | return error; |
1608 | } | 1605 | } |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 567ae72e155d..cd96649bfe62 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -1809,8 +1809,8 @@ error_return: | |||
1809 | SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events, | 1809 | SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events, |
1810 | int, maxevents, int, timeout) | 1810 | int, maxevents, int, timeout) |
1811 | { | 1811 | { |
1812 | int error, fput_needed; | 1812 | int error; |
1813 | struct file *file; | 1813 | struct fd f; |
1814 | struct eventpoll *ep; | 1814 | struct eventpoll *ep; |
1815 | 1815 | ||
1816 | /* The maximum number of event must be greater than zero */ | 1816 | /* The maximum number of event must be greater than zero */ |
@@ -1818,38 +1818,33 @@ SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events, | |||
1818 | return -EINVAL; | 1818 | return -EINVAL; |
1819 | 1819 | ||
1820 | /* Verify that the area passed by the user is writeable */ | 1820 | /* Verify that the area passed by the user is writeable */ |
1821 | if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))) { | 1821 | if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))) |
1822 | error = -EFAULT; | 1822 | return -EFAULT; |
1823 | goto error_return; | ||
1824 | } | ||
1825 | 1823 | ||
1826 | /* Get the "struct file *" for the eventpoll file */ | 1824 | /* Get the "struct file *" for the eventpoll file */ |
1827 | error = -EBADF; | 1825 | f = fdget(epfd); |
1828 | file = fget_light(epfd, &fput_needed); | 1826 | if (!f.file) |
1829 | if (!file) | 1827 | return -EBADF; |
1830 | goto error_return; | ||
1831 | 1828 | ||
1832 | /* | 1829 | /* |
1833 | * We have to check that the file structure underneath the fd | 1830 | * We have to check that the file structure underneath the fd |
1834 | * the user passed to us _is_ an eventpoll file. | 1831 | * the user passed to us _is_ an eventpoll file. |
1835 | */ | 1832 | */ |
1836 | error = -EINVAL; | 1833 | error = -EINVAL; |
1837 | if (!is_file_epoll(file)) | 1834 | if (!is_file_epoll(f.file)) |
1838 | goto error_fput; | 1835 | goto error_fput; |
1839 | 1836 | ||
1840 | /* | 1837 | /* |
1841 | * At this point it is safe to assume that the "private_data" contains | 1838 | * At this point it is safe to assume that the "private_data" contains |
1842 | * our own data structure. | 1839 | * our own data structure. |
1843 | */ | 1840 | */ |
1844 | ep = file->private_data; | 1841 | ep = f.file->private_data; |
1845 | 1842 | ||
1846 | /* Time to fish for events ... */ | 1843 | /* Time to fish for events ... */ |
1847 | error = ep_poll(ep, events, maxevents, timeout); | 1844 | error = ep_poll(ep, events, maxevents, timeout); |
1848 | 1845 | ||
1849 | error_fput: | 1846 | error_fput: |
1850 | fput_light(file, fput_needed); | 1847 | fdput(f); |
1851 | error_return: | ||
1852 | |||
1853 | return error; | 1848 | return error; |
1854 | } | 1849 | } |
1855 | 1850 | ||
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 39646f224514..5439d6a56e99 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -233,8 +233,8 @@ group_extend_out: | |||
233 | 233 | ||
234 | case EXT4_IOC_MOVE_EXT: { | 234 | case EXT4_IOC_MOVE_EXT: { |
235 | struct move_extent me; | 235 | struct move_extent me; |
236 | struct file *donor_filp; | 236 | struct fd donor; |
237 | int err, fput_needed; | 237 | int err; |
238 | 238 | ||
239 | if (!(filp->f_mode & FMODE_READ) || | 239 | if (!(filp->f_mode & FMODE_READ) || |
240 | !(filp->f_mode & FMODE_WRITE)) | 240 | !(filp->f_mode & FMODE_WRITE)) |
@@ -245,11 +245,11 @@ group_extend_out: | |||
245 | return -EFAULT; | 245 | return -EFAULT; |
246 | me.moved_len = 0; | 246 | me.moved_len = 0; |
247 | 247 | ||
248 | donor_filp = fget_light(me.donor_fd, &fput_needed); | 248 | donor = fdget(me.donor_fd); |
249 | if (!donor_filp) | 249 | if (!donor.file) |
250 | return -EBADF; | 250 | return -EBADF; |
251 | 251 | ||
252 | if (!(donor_filp->f_mode & FMODE_WRITE)) { | 252 | if (!(donor.file->f_mode & FMODE_WRITE)) { |
253 | err = -EBADF; | 253 | err = -EBADF; |
254 | goto mext_out; | 254 | goto mext_out; |
255 | } | 255 | } |
@@ -266,7 +266,7 @@ group_extend_out: | |||
266 | if (err) | 266 | if (err) |
267 | goto mext_out; | 267 | goto mext_out; |
268 | 268 | ||
269 | err = ext4_move_extents(filp, donor_filp, me.orig_start, | 269 | err = ext4_move_extents(filp, donor.file, me.orig_start, |
270 | me.donor_start, me.len, &me.moved_len); | 270 | me.donor_start, me.len, &me.moved_len); |
271 | mnt_drop_write_file(filp); | 271 | mnt_drop_write_file(filp); |
272 | 272 | ||
@@ -274,7 +274,7 @@ group_extend_out: | |||
274 | &me, sizeof(me))) | 274 | &me, sizeof(me))) |
275 | err = -EFAULT; | 275 | err = -EFAULT; |
276 | mext_out: | 276 | mext_out: |
277 | fput_light(donor_filp, fput_needed); | 277 | fdput(donor); |
278 | return err; | 278 | return err; |
279 | } | 279 | } |
280 | 280 | ||
diff --git a/fs/fcntl.c b/fs/fcntl.c index 40a5bfb72cca..91af39a33af7 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -348,25 +348,23 @@ static int check_fcntl_cmd(unsigned cmd) | |||
348 | 348 | ||
349 | SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) | 349 | SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) |
350 | { | 350 | { |
351 | struct file *filp; | 351 | struct fd f = fdget_raw(fd); |
352 | int fput_needed; | ||
353 | long err = -EBADF; | 352 | long err = -EBADF; |
354 | 353 | ||
355 | filp = fget_raw_light(fd, &fput_needed); | 354 | if (!f.file) |
356 | if (!filp) | ||
357 | goto out; | 355 | goto out; |
358 | 356 | ||
359 | if (unlikely(filp->f_mode & FMODE_PATH)) { | 357 | if (unlikely(f.file->f_mode & FMODE_PATH)) { |
360 | if (!check_fcntl_cmd(cmd)) | 358 | if (!check_fcntl_cmd(cmd)) |
361 | goto out1; | 359 | goto out1; |
362 | } | 360 | } |
363 | 361 | ||
364 | err = security_file_fcntl(filp, cmd, arg); | 362 | err = security_file_fcntl(f.file, cmd, arg); |
365 | if (!err) | 363 | if (!err) |
366 | err = do_fcntl(fd, cmd, arg, filp); | 364 | err = do_fcntl(fd, cmd, arg, f.file); |
367 | 365 | ||
368 | out1: | 366 | out1: |
369 | fput_light(filp, fput_needed); | 367 | fdput(f); |
370 | out: | 368 | out: |
371 | return err; | 369 | return err; |
372 | } | 370 | } |
@@ -375,38 +373,36 @@ out: | |||
375 | SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, | 373 | SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, |
376 | unsigned long, arg) | 374 | unsigned long, arg) |
377 | { | 375 | { |
378 | struct file * filp; | 376 | struct fd f = fdget_raw(fd); |
379 | long err = -EBADF; | 377 | long err = -EBADF; |
380 | int fput_needed; | ||
381 | 378 | ||
382 | filp = fget_raw_light(fd, &fput_needed); | 379 | if (!f.file) |
383 | if (!filp) | ||
384 | goto out; | 380 | goto out; |
385 | 381 | ||
386 | if (unlikely(filp->f_mode & FMODE_PATH)) { | 382 | if (unlikely(f.file->f_mode & FMODE_PATH)) { |
387 | if (!check_fcntl_cmd(cmd)) | 383 | if (!check_fcntl_cmd(cmd)) |
388 | goto out1; | 384 | goto out1; |
389 | } | 385 | } |
390 | 386 | ||
391 | err = security_file_fcntl(filp, cmd, arg); | 387 | err = security_file_fcntl(f.file, cmd, arg); |
392 | if (err) | 388 | if (err) |
393 | goto out1; | 389 | goto out1; |
394 | 390 | ||
395 | switch (cmd) { | 391 | switch (cmd) { |
396 | case F_GETLK64: | 392 | case F_GETLK64: |
397 | err = fcntl_getlk64(filp, (struct flock64 __user *) arg); | 393 | err = fcntl_getlk64(f.file, (struct flock64 __user *) arg); |
398 | break; | 394 | break; |
399 | case F_SETLK64: | 395 | case F_SETLK64: |
400 | case F_SETLKW64: | 396 | case F_SETLKW64: |
401 | err = fcntl_setlk64(fd, filp, cmd, | 397 | err = fcntl_setlk64(fd, f.file, cmd, |
402 | (struct flock64 __user *) arg); | 398 | (struct flock64 __user *) arg); |
403 | break; | 399 | break; |
404 | default: | 400 | default: |
405 | err = do_fcntl(fd, cmd, arg, filp); | 401 | err = do_fcntl(fd, cmd, arg, f.file); |
406 | break; | 402 | break; |
407 | } | 403 | } |
408 | out1: | 404 | out1: |
409 | fput_light(filp, fput_needed); | 405 | fdput(f); |
410 | out: | 406 | out: |
411 | return err; | 407 | return err; |
412 | } | 408 | } |
diff --git a/fs/fhandle.c b/fs/fhandle.c index a48e4a139be1..f775bfdd6e4a 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c | |||
@@ -113,24 +113,21 @@ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name, | |||
113 | 113 | ||
114 | static struct vfsmount *get_vfsmount_from_fd(int fd) | 114 | static struct vfsmount *get_vfsmount_from_fd(int fd) |
115 | { | 115 | { |
116 | struct path path; | 116 | struct vfsmount *mnt; |
117 | 117 | ||
118 | if (fd == AT_FDCWD) { | 118 | if (fd == AT_FDCWD) { |
119 | struct fs_struct *fs = current->fs; | 119 | struct fs_struct *fs = current->fs; |
120 | spin_lock(&fs->lock); | 120 | spin_lock(&fs->lock); |
121 | path = fs->pwd; | 121 | mnt = mntget(fs->pwd.mnt); |
122 | mntget(path.mnt); | ||
123 | spin_unlock(&fs->lock); | 122 | spin_unlock(&fs->lock); |
124 | } else { | 123 | } else { |
125 | int fput_needed; | 124 | struct fd f = fdget(fd); |
126 | struct file *file = fget_light(fd, &fput_needed); | 125 | if (!f.file) |
127 | if (!file) | ||
128 | return ERR_PTR(-EBADF); | 126 | return ERR_PTR(-EBADF); |
129 | path = file->f_path; | 127 | mnt = mntget(f.file->f_path.mnt); |
130 | mntget(path.mnt); | 128 | fdput(f); |
131 | fput_light(file, fput_needed); | ||
132 | } | 129 | } |
133 | return path.mnt; | 130 | return mnt; |
134 | } | 131 | } |
135 | 132 | ||
136 | static int vfs_dentry_acceptable(void *context, struct dentry *dentry) | 133 | static int vfs_dentry_acceptable(void *context, struct dentry *dentry) |
diff --git a/fs/ioctl.c b/fs/ioctl.c index 29167bebe874..3bdad6d1f268 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -603,21 +603,14 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, | |||
603 | 603 | ||
604 | SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) | 604 | SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) |
605 | { | 605 | { |
606 | struct file *filp; | 606 | int error; |
607 | int error = -EBADF; | 607 | struct fd f = fdget(fd); |
608 | int fput_needed; | 608 | |
609 | 609 | if (!f.file) | |
610 | filp = fget_light(fd, &fput_needed); | 610 | return -EBADF; |
611 | if (!filp) | 611 | error = security_file_ioctl(f.file, cmd, arg); |
612 | goto out; | 612 | if (!error) |
613 | 613 | error = do_vfs_ioctl(f.file, fd, cmd, arg); | |
614 | error = security_file_ioctl(filp, cmd, arg); | 614 | fdput(f); |
615 | if (error) | ||
616 | goto out_fput; | ||
617 | |||
618 | error = do_vfs_ioctl(filp, fd, cmd, arg); | ||
619 | out_fput: | ||
620 | fput_light(filp, fput_needed); | ||
621 | out: | ||
622 | return error; | 615 | return error; |
623 | } | 616 | } |
diff --git a/fs/locks.c b/fs/locks.c index 7e81bfc75164..abc7dc6c490b 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1625,15 +1625,13 @@ EXPORT_SYMBOL(flock_lock_file_wait); | |||
1625 | */ | 1625 | */ |
1626 | SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) | 1626 | SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) |
1627 | { | 1627 | { |
1628 | struct file *filp; | 1628 | struct fd f = fdget(fd); |
1629 | int fput_needed; | ||
1630 | struct file_lock *lock; | 1629 | struct file_lock *lock; |
1631 | int can_sleep, unlock; | 1630 | int can_sleep, unlock; |
1632 | int error; | 1631 | int error; |
1633 | 1632 | ||
1634 | error = -EBADF; | 1633 | error = -EBADF; |
1635 | filp = fget_light(fd, &fput_needed); | 1634 | if (!f.file) |
1636 | if (!filp) | ||
1637 | goto out; | 1635 | goto out; |
1638 | 1636 | ||
1639 | can_sleep = !(cmd & LOCK_NB); | 1637 | can_sleep = !(cmd & LOCK_NB); |
@@ -1641,31 +1639,31 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) | |||
1641 | unlock = (cmd == LOCK_UN); | 1639 | unlock = (cmd == LOCK_UN); |
1642 | 1640 | ||
1643 | if (!unlock && !(cmd & LOCK_MAND) && | 1641 | if (!unlock && !(cmd & LOCK_MAND) && |
1644 | !(filp->f_mode & (FMODE_READ|FMODE_WRITE))) | 1642 | !(f.file->f_mode & (FMODE_READ|FMODE_WRITE))) |
1645 | goto out_putf; | 1643 | goto out_putf; |
1646 | 1644 | ||
1647 | error = flock_make_lock(filp, &lock, cmd); | 1645 | error = flock_make_lock(f.file, &lock, cmd); |
1648 | if (error) | 1646 | if (error) |
1649 | goto out_putf; | 1647 | goto out_putf; |
1650 | if (can_sleep) | 1648 | if (can_sleep) |
1651 | lock->fl_flags |= FL_SLEEP; | 1649 | lock->fl_flags |= FL_SLEEP; |
1652 | 1650 | ||
1653 | error = security_file_lock(filp, lock->fl_type); | 1651 | error = security_file_lock(f.file, lock->fl_type); |
1654 | if (error) | 1652 | if (error) |
1655 | goto out_free; | 1653 | goto out_free; |
1656 | 1654 | ||
1657 | if (filp->f_op && filp->f_op->flock) | 1655 | if (f.file->f_op && f.file->f_op->flock) |
1658 | error = filp->f_op->flock(filp, | 1656 | error = f.file->f_op->flock(f.file, |
1659 | (can_sleep) ? F_SETLKW : F_SETLK, | 1657 | (can_sleep) ? F_SETLKW : F_SETLK, |
1660 | lock); | 1658 | lock); |
1661 | else | 1659 | else |
1662 | error = flock_lock_file_wait(filp, lock); | 1660 | error = flock_lock_file_wait(f.file, lock); |
1663 | 1661 | ||
1664 | out_free: | 1662 | out_free: |
1665 | locks_free_lock(lock); | 1663 | locks_free_lock(lock); |
1666 | 1664 | ||
1667 | out_putf: | 1665 | out_putf: |
1668 | fput_light(filp, fput_needed); | 1666 | fdput(f); |
1669 | out: | 1667 | out: |
1670 | return error; | 1668 | return error; |
1671 | } | 1669 | } |
diff --git a/fs/namei.c b/fs/namei.c index c5b85b3523c0..e1c7072c7afa 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1797,8 +1797,6 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
1797 | struct nameidata *nd, struct file **fp) | 1797 | struct nameidata *nd, struct file **fp) |
1798 | { | 1798 | { |
1799 | int retval = 0; | 1799 | int retval = 0; |
1800 | int fput_needed; | ||
1801 | struct file *file; | ||
1802 | 1800 | ||
1803 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ | 1801 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ |
1804 | nd->flags = flags | LOOKUP_JUMPED; | 1802 | nd->flags = flags | LOOKUP_JUMPED; |
@@ -1850,44 +1848,41 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
1850 | get_fs_pwd(current->fs, &nd->path); | 1848 | get_fs_pwd(current->fs, &nd->path); |
1851 | } | 1849 | } |
1852 | } else { | 1850 | } else { |
1851 | struct fd f = fdget_raw(dfd); | ||
1853 | struct dentry *dentry; | 1852 | struct dentry *dentry; |
1854 | 1853 | ||
1855 | file = fget_raw_light(dfd, &fput_needed); | 1854 | if (!f.file) |
1856 | retval = -EBADF; | 1855 | return -EBADF; |
1857 | if (!file) | ||
1858 | goto out_fail; | ||
1859 | 1856 | ||
1860 | dentry = file->f_path.dentry; | 1857 | dentry = f.file->f_path.dentry; |
1861 | 1858 | ||
1862 | if (*name) { | 1859 | if (*name) { |
1863 | retval = -ENOTDIR; | 1860 | if (!S_ISDIR(dentry->d_inode->i_mode)) { |
1864 | if (!S_ISDIR(dentry->d_inode->i_mode)) | 1861 | fdput(f); |
1865 | goto fput_fail; | 1862 | return -ENOTDIR; |
1863 | } | ||
1866 | 1864 | ||
1867 | retval = inode_permission(dentry->d_inode, MAY_EXEC); | 1865 | retval = inode_permission(dentry->d_inode, MAY_EXEC); |
1868 | if (retval) | 1866 | if (retval) { |
1869 | goto fput_fail; | 1867 | fdput(f); |
1868 | return retval; | ||
1869 | } | ||
1870 | } | 1870 | } |
1871 | 1871 | ||
1872 | nd->path = file->f_path; | 1872 | nd->path = f.file->f_path; |
1873 | if (flags & LOOKUP_RCU) { | 1873 | if (flags & LOOKUP_RCU) { |
1874 | if (fput_needed) | 1874 | if (f.need_put) |
1875 | *fp = file; | 1875 | *fp = f.file; |
1876 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); | 1876 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); |
1877 | lock_rcu_walk(); | 1877 | lock_rcu_walk(); |
1878 | } else { | 1878 | } else { |
1879 | path_get(&file->f_path); | 1879 | path_get(&nd->path); |
1880 | fput_light(file, fput_needed); | 1880 | fdput(f); |
1881 | } | 1881 | } |
1882 | } | 1882 | } |
1883 | 1883 | ||
1884 | nd->inode = nd->path.dentry->d_inode; | 1884 | nd->inode = nd->path.dentry->d_inode; |
1885 | return 0; | 1885 | return 0; |
1886 | |||
1887 | fput_fail: | ||
1888 | fput_light(file, fput_needed); | ||
1889 | out_fail: | ||
1890 | return retval; | ||
1891 | } | 1886 | } |
1892 | 1887 | ||
1893 | static inline int lookup_last(struct nameidata *nd, struct path *path) | 1888 | static inline int lookup_last(struct nameidata *nd, struct path *path) |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index ea48693940f1..721d692fa8d4 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -451,24 +451,22 @@ static int fanotify_find_path(int dfd, const char __user *filename, | |||
451 | dfd, filename, flags); | 451 | dfd, filename, flags); |
452 | 452 | ||
453 | if (filename == NULL) { | 453 | if (filename == NULL) { |
454 | struct file *file; | 454 | struct fd f = fdget(dfd); |
455 | int fput_needed; | ||
456 | 455 | ||
457 | ret = -EBADF; | 456 | ret = -EBADF; |
458 | file = fget_light(dfd, &fput_needed); | 457 | if (!f.file) |
459 | if (!file) | ||
460 | goto out; | 458 | goto out; |
461 | 459 | ||
462 | ret = -ENOTDIR; | 460 | ret = -ENOTDIR; |
463 | if ((flags & FAN_MARK_ONLYDIR) && | 461 | if ((flags & FAN_MARK_ONLYDIR) && |
464 | !(S_ISDIR(file->f_path.dentry->d_inode->i_mode))) { | 462 | !(S_ISDIR(f.file->f_path.dentry->d_inode->i_mode))) { |
465 | fput_light(file, fput_needed); | 463 | fdput(f); |
466 | goto out; | 464 | goto out; |
467 | } | 465 | } |
468 | 466 | ||
469 | *path = file->f_path; | 467 | *path = f.file->f_path; |
470 | path_get(path); | 468 | path_get(path); |
471 | fput_light(file, fput_needed); | 469 | fdput(f); |
472 | } else { | 470 | } else { |
473 | unsigned int lookup_flags = 0; | 471 | unsigned int lookup_flags = 0; |
474 | 472 | ||
@@ -748,9 +746,9 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags, | |||
748 | struct inode *inode = NULL; | 746 | struct inode *inode = NULL; |
749 | struct vfsmount *mnt = NULL; | 747 | struct vfsmount *mnt = NULL; |
750 | struct fsnotify_group *group; | 748 | struct fsnotify_group *group; |
751 | struct file *filp; | 749 | struct fd f; |
752 | struct path path; | 750 | struct path path; |
753 | int ret, fput_needed; | 751 | int ret; |
754 | 752 | ||
755 | pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n", | 753 | pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n", |
756 | __func__, fanotify_fd, flags, dfd, pathname, mask); | 754 | __func__, fanotify_fd, flags, dfd, pathname, mask); |
@@ -784,15 +782,15 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags, | |||
784 | #endif | 782 | #endif |
785 | return -EINVAL; | 783 | return -EINVAL; |
786 | 784 | ||
787 | filp = fget_light(fanotify_fd, &fput_needed); | 785 | f = fdget(fanotify_fd); |
788 | if (unlikely(!filp)) | 786 | if (unlikely(!f.file)) |
789 | return -EBADF; | 787 | return -EBADF; |
790 | 788 | ||
791 | /* verify that this is indeed an fanotify instance */ | 789 | /* verify that this is indeed an fanotify instance */ |
792 | ret = -EINVAL; | 790 | ret = -EINVAL; |
793 | if (unlikely(filp->f_op != &fanotify_fops)) | 791 | if (unlikely(f.file->f_op != &fanotify_fops)) |
794 | goto fput_and_out; | 792 | goto fput_and_out; |
795 | group = filp->private_data; | 793 | group = f.file->private_data; |
796 | 794 | ||
797 | /* | 795 | /* |
798 | * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF. These are not | 796 | * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF. These are not |
@@ -839,7 +837,7 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags, | |||
839 | 837 | ||
840 | path_put(&path); | 838 | path_put(&path); |
841 | fput_and_out: | 839 | fput_and_out: |
842 | fput_light(filp, fput_needed); | 840 | fdput(f); |
843 | return ret; | 841 | return ret; |
844 | } | 842 | } |
845 | 843 | ||
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 8445fbc8985c..c311dda054a3 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -757,16 +757,16 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, | |||
757 | struct fsnotify_group *group; | 757 | struct fsnotify_group *group; |
758 | struct inode *inode; | 758 | struct inode *inode; |
759 | struct path path; | 759 | struct path path; |
760 | struct file *filp; | 760 | struct fd f; |
761 | int ret, fput_needed; | 761 | int ret; |
762 | unsigned flags = 0; | 762 | unsigned flags = 0; |
763 | 763 | ||
764 | filp = fget_light(fd, &fput_needed); | 764 | f = fdget(fd); |
765 | if (unlikely(!filp)) | 765 | if (unlikely(!f.file)) |
766 | return -EBADF; | 766 | return -EBADF; |
767 | 767 | ||
768 | /* verify that this is indeed an inotify instance */ | 768 | /* verify that this is indeed an inotify instance */ |
769 | if (unlikely(filp->f_op != &inotify_fops)) { | 769 | if (unlikely(f.file->f_op != &inotify_fops)) { |
770 | ret = -EINVAL; | 770 | ret = -EINVAL; |
771 | goto fput_and_out; | 771 | goto fput_and_out; |
772 | } | 772 | } |
@@ -782,13 +782,13 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, | |||
782 | 782 | ||
783 | /* inode held in place by reference to path; group by fget on fd */ | 783 | /* inode held in place by reference to path; group by fget on fd */ |
784 | inode = path.dentry->d_inode; | 784 | inode = path.dentry->d_inode; |
785 | group = filp->private_data; | 785 | group = f.file->private_data; |
786 | 786 | ||
787 | /* create/update an inode mark */ | 787 | /* create/update an inode mark */ |
788 | ret = inotify_update_watch(group, inode, mask); | 788 | ret = inotify_update_watch(group, inode, mask); |
789 | path_put(&path); | 789 | path_put(&path); |
790 | fput_and_out: | 790 | fput_and_out: |
791 | fput_light(filp, fput_needed); | 791 | fdput(f); |
792 | return ret; | 792 | return ret; |
793 | } | 793 | } |
794 | 794 | ||
@@ -796,19 +796,19 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd) | |||
796 | { | 796 | { |
797 | struct fsnotify_group *group; | 797 | struct fsnotify_group *group; |
798 | struct inotify_inode_mark *i_mark; | 798 | struct inotify_inode_mark *i_mark; |
799 | struct file *filp; | 799 | struct fd f; |
800 | int ret = 0, fput_needed; | 800 | int ret = 0; |
801 | 801 | ||
802 | filp = fget_light(fd, &fput_needed); | 802 | f = fdget(fd); |
803 | if (unlikely(!filp)) | 803 | if (unlikely(!f.file)) |
804 | return -EBADF; | 804 | return -EBADF; |
805 | 805 | ||
806 | /* verify that this is indeed an inotify instance */ | 806 | /* verify that this is indeed an inotify instance */ |
807 | ret = -EINVAL; | 807 | ret = -EINVAL; |
808 | if (unlikely(filp->f_op != &inotify_fops)) | 808 | if (unlikely(f.file->f_op != &inotify_fops)) |
809 | goto out; | 809 | goto out; |
810 | 810 | ||
811 | group = filp->private_data; | 811 | group = f.file->private_data; |
812 | 812 | ||
813 | ret = -EINVAL; | 813 | ret = -EINVAL; |
814 | i_mark = inotify_idr_find(group, wd); | 814 | i_mark = inotify_idr_find(group, wd); |
@@ -823,7 +823,7 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd) | |||
823 | fsnotify_put_mark(&i_mark->fsn_mark); | 823 | fsnotify_put_mark(&i_mark->fsn_mark); |
824 | 824 | ||
825 | out: | 825 | out: |
826 | fput_light(filp, fput_needed); | 826 | fdput(f); |
827 | return ret; | 827 | return ret; |
828 | } | 828 | } |
829 | 829 | ||
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 61c28ae266f5..f7c648d7d6bf 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -1746,11 +1746,10 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1746 | long fd; | 1746 | long fd; |
1747 | int sectsize; | 1747 | int sectsize; |
1748 | char *p = (char *)page; | 1748 | char *p = (char *)page; |
1749 | struct file *filp = NULL; | 1749 | struct fd f; |
1750 | struct inode *inode = NULL; | 1750 | struct inode *inode; |
1751 | ssize_t ret = -EINVAL; | 1751 | ssize_t ret = -EINVAL; |
1752 | int live_threshold; | 1752 | int live_threshold; |
1753 | int fput_needed; | ||
1754 | 1753 | ||
1755 | if (reg->hr_bdev) | 1754 | if (reg->hr_bdev) |
1756 | goto out; | 1755 | goto out; |
@@ -1767,26 +1766,26 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1767 | if (fd < 0 || fd >= INT_MAX) | 1766 | if (fd < 0 || fd >= INT_MAX) |
1768 | goto out; | 1767 | goto out; |
1769 | 1768 | ||
1770 | filp = fget_light(fd, &fput_needed); | 1769 | f = fdget(fd); |
1771 | if (filp == NULL) | 1770 | if (f.file == NULL) |
1772 | goto out; | 1771 | goto out; |
1773 | 1772 | ||
1774 | if (reg->hr_blocks == 0 || reg->hr_start_block == 0 || | 1773 | if (reg->hr_blocks == 0 || reg->hr_start_block == 0 || |
1775 | reg->hr_block_bytes == 0) | 1774 | reg->hr_block_bytes == 0) |
1776 | goto out; | 1775 | goto out2; |
1777 | 1776 | ||
1778 | inode = igrab(filp->f_mapping->host); | 1777 | inode = igrab(f.file->f_mapping->host); |
1779 | if (inode == NULL) | 1778 | if (inode == NULL) |
1780 | goto out; | 1779 | goto out2; |
1781 | 1780 | ||
1782 | if (!S_ISBLK(inode->i_mode)) | 1781 | if (!S_ISBLK(inode->i_mode)) |
1783 | goto out; | 1782 | goto out3; |
1784 | 1783 | ||
1785 | reg->hr_bdev = I_BDEV(filp->f_mapping->host); | 1784 | reg->hr_bdev = I_BDEV(f.file->f_mapping->host); |
1786 | ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, NULL); | 1785 | ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, NULL); |
1787 | if (ret) { | 1786 | if (ret) { |
1788 | reg->hr_bdev = NULL; | 1787 | reg->hr_bdev = NULL; |
1789 | goto out; | 1788 | goto out3; |
1790 | } | 1789 | } |
1791 | inode = NULL; | 1790 | inode = NULL; |
1792 | 1791 | ||
@@ -1798,7 +1797,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1798 | "blocksize %u incorrect for device, expected %d", | 1797 | "blocksize %u incorrect for device, expected %d", |
1799 | reg->hr_block_bytes, sectsize); | 1798 | reg->hr_block_bytes, sectsize); |
1800 | ret = -EINVAL; | 1799 | ret = -EINVAL; |
1801 | goto out; | 1800 | goto out3; |
1802 | } | 1801 | } |
1803 | 1802 | ||
1804 | o2hb_init_region_params(reg); | 1803 | o2hb_init_region_params(reg); |
@@ -1812,13 +1811,13 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1812 | ret = o2hb_map_slot_data(reg); | 1811 | ret = o2hb_map_slot_data(reg); |
1813 | if (ret) { | 1812 | if (ret) { |
1814 | mlog_errno(ret); | 1813 | mlog_errno(ret); |
1815 | goto out; | 1814 | goto out3; |
1816 | } | 1815 | } |
1817 | 1816 | ||
1818 | ret = o2hb_populate_slot_data(reg); | 1817 | ret = o2hb_populate_slot_data(reg); |
1819 | if (ret) { | 1818 | if (ret) { |
1820 | mlog_errno(ret); | 1819 | mlog_errno(ret); |
1821 | goto out; | 1820 | goto out3; |
1822 | } | 1821 | } |
1823 | 1822 | ||
1824 | INIT_DELAYED_WORK(®->hr_write_timeout_work, o2hb_write_timeout); | 1823 | INIT_DELAYED_WORK(®->hr_write_timeout_work, o2hb_write_timeout); |
@@ -1848,7 +1847,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1848 | if (IS_ERR(hb_task)) { | 1847 | if (IS_ERR(hb_task)) { |
1849 | ret = PTR_ERR(hb_task); | 1848 | ret = PTR_ERR(hb_task); |
1850 | mlog_errno(ret); | 1849 | mlog_errno(ret); |
1851 | goto out; | 1850 | goto out3; |
1852 | } | 1851 | } |
1853 | 1852 | ||
1854 | spin_lock(&o2hb_live_lock); | 1853 | spin_lock(&o2hb_live_lock); |
@@ -1864,7 +1863,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1864 | 1863 | ||
1865 | if (reg->hr_aborted_start) { | 1864 | if (reg->hr_aborted_start) { |
1866 | ret = -EIO; | 1865 | ret = -EIO; |
1867 | goto out; | 1866 | goto out3; |
1868 | } | 1867 | } |
1869 | 1868 | ||
1870 | /* Ok, we were woken. Make sure it wasn't by drop_item() */ | 1869 | /* Ok, we were woken. Make sure it wasn't by drop_item() */ |
@@ -1883,11 +1882,11 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1883 | printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%s)\n", | 1882 | printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%s)\n", |
1884 | config_item_name(®->hr_item), reg->hr_dev_name); | 1883 | config_item_name(®->hr_item), reg->hr_dev_name); |
1885 | 1884 | ||
1885 | out3: | ||
1886 | iput(inode); | ||
1887 | out2: | ||
1888 | fdput(f); | ||
1886 | out: | 1889 | out: |
1887 | if (filp) | ||
1888 | fput_light(filp, fput_needed); | ||
1889 | if (inode) | ||
1890 | iput(inode); | ||
1891 | if (ret < 0) { | 1890 | if (ret < 0) { |
1892 | if (reg->hr_bdev) { | 1891 | if (reg->hr_bdev) { |
1893 | blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE); | 1892 | blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE); |
@@ -134,25 +134,25 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small) | |||
134 | { | 134 | { |
135 | struct inode *inode; | 135 | struct inode *inode; |
136 | struct dentry *dentry; | 136 | struct dentry *dentry; |
137 | struct file *file; | 137 | struct fd f; |
138 | int error, fput_needed; | 138 | int error; |
139 | 139 | ||
140 | error = -EINVAL; | 140 | error = -EINVAL; |
141 | if (length < 0) | 141 | if (length < 0) |
142 | goto out; | 142 | goto out; |
143 | error = -EBADF; | 143 | error = -EBADF; |
144 | file = fget_light(fd, &fput_needed); | 144 | f = fdget(fd); |
145 | if (!file) | 145 | if (!f.file) |
146 | goto out; | 146 | goto out; |
147 | 147 | ||
148 | /* explicitly opened as large or we are on 64-bit box */ | 148 | /* explicitly opened as large or we are on 64-bit box */ |
149 | if (file->f_flags & O_LARGEFILE) | 149 | if (f.file->f_flags & O_LARGEFILE) |
150 | small = 0; | 150 | small = 0; |
151 | 151 | ||
152 | dentry = file->f_path.dentry; | 152 | dentry = f.file->f_path.dentry; |
153 | inode = dentry->d_inode; | 153 | inode = dentry->d_inode; |
154 | error = -EINVAL; | 154 | error = -EINVAL; |
155 | if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE)) | 155 | if (!S_ISREG(inode->i_mode) || !(f.file->f_mode & FMODE_WRITE)) |
156 | goto out_putf; | 156 | goto out_putf; |
157 | 157 | ||
158 | error = -EINVAL; | 158 | error = -EINVAL; |
@@ -165,14 +165,14 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small) | |||
165 | goto out_putf; | 165 | goto out_putf; |
166 | 166 | ||
167 | sb_start_write(inode->i_sb); | 167 | sb_start_write(inode->i_sb); |
168 | error = locks_verify_truncate(inode, file, length); | 168 | error = locks_verify_truncate(inode, f.file, length); |
169 | if (!error) | 169 | if (!error) |
170 | error = security_path_truncate(&file->f_path); | 170 | error = security_path_truncate(&f.file->f_path); |
171 | if (!error) | 171 | if (!error) |
172 | error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); | 172 | error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, f.file); |
173 | sb_end_write(inode->i_sb); | 173 | sb_end_write(inode->i_sb); |
174 | out_putf: | 174 | out_putf: |
175 | fput_light(file, fput_needed); | 175 | fdput(f); |
176 | out: | 176 | out: |
177 | return error; | 177 | return error; |
178 | } | 178 | } |
@@ -276,15 +276,13 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
276 | 276 | ||
277 | SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) | 277 | SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) |
278 | { | 278 | { |
279 | struct file *file; | 279 | struct fd f = fdget(fd); |
280 | int error = -EBADF, fput_needed; | 280 | int error = -EBADF; |
281 | 281 | ||
282 | file = fget_light(fd, &fput_needed); | 282 | if (f.file) { |
283 | if (file) { | 283 | error = do_fallocate(f.file, mode, offset, len); |
284 | error = do_fallocate(file, mode, offset, len); | 284 | fdput(f); |
285 | fput_light(file, fput_needed); | ||
286 | } | 285 | } |
287 | |||
288 | return error; | 286 | return error; |
289 | } | 287 | } |
290 | 288 | ||
@@ -400,16 +398,15 @@ out: | |||
400 | 398 | ||
401 | SYSCALL_DEFINE1(fchdir, unsigned int, fd) | 399 | SYSCALL_DEFINE1(fchdir, unsigned int, fd) |
402 | { | 400 | { |
403 | struct file *file; | 401 | struct fd f = fdget_raw(fd); |
404 | struct inode *inode; | 402 | struct inode *inode; |
405 | int error, fput_needed; | 403 | int error = -EBADF; |
406 | 404 | ||
407 | error = -EBADF; | 405 | error = -EBADF; |
408 | file = fget_raw_light(fd, &fput_needed); | 406 | if (!f.file) |
409 | if (!file) | ||
410 | goto out; | 407 | goto out; |
411 | 408 | ||
412 | inode = file->f_path.dentry->d_inode; | 409 | inode = f.file->f_path.dentry->d_inode; |
413 | 410 | ||
414 | error = -ENOTDIR; | 411 | error = -ENOTDIR; |
415 | if (!S_ISDIR(inode->i_mode)) | 412 | if (!S_ISDIR(inode->i_mode)) |
@@ -417,9 +414,9 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd) | |||
417 | 414 | ||
418 | error = inode_permission(inode, MAY_EXEC | MAY_CHDIR); | 415 | error = inode_permission(inode, MAY_EXEC | MAY_CHDIR); |
419 | if (!error) | 416 | if (!error) |
420 | set_fs_pwd(current->fs, &file->f_path); | 417 | set_fs_pwd(current->fs, &f.file->f_path); |
421 | out_putf: | 418 | out_putf: |
422 | fput_light(file, fput_needed); | 419 | fdput(f); |
423 | out: | 420 | out: |
424 | return error; | 421 | return error; |
425 | } | 422 | } |
@@ -582,21 +579,20 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group | |||
582 | 579 | ||
583 | SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) | 580 | SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) |
584 | { | 581 | { |
585 | struct file *file; | 582 | struct fd f = fdget(fd); |
586 | int error = -EBADF, fput_needed; | 583 | int error = -EBADF; |
587 | 584 | ||
588 | file = fget_light(fd, &fput_needed); | 585 | if (!f.file) |
589 | if (!file) | ||
590 | goto out; | 586 | goto out; |
591 | 587 | ||
592 | error = mnt_want_write_file(file); | 588 | error = mnt_want_write_file(f.file); |
593 | if (error) | 589 | if (error) |
594 | goto out_fput; | 590 | goto out_fput; |
595 | audit_inode(NULL, file->f_path.dentry); | 591 | audit_inode(NULL, f.file->f_path.dentry); |
596 | error = chown_common(&file->f_path, user, group); | 592 | error = chown_common(&f.file->f_path, user, group); |
597 | mnt_drop_write_file(file); | 593 | mnt_drop_write_file(f.file); |
598 | out_fput: | 594 | out_fput: |
599 | fput_light(file, fput_needed); | 595 | fdput(f); |
600 | out: | 596 | out: |
601 | return error; | 597 | return error; |
602 | } | 598 | } |
diff --git a/fs/read_write.c b/fs/read_write.c index 1adfb691e4f1..28b38279a219 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -232,23 +232,18 @@ EXPORT_SYMBOL(vfs_llseek); | |||
232 | SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, origin) | 232 | SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, origin) |
233 | { | 233 | { |
234 | off_t retval; | 234 | off_t retval; |
235 | struct file * file; | 235 | struct fd f = fdget(fd); |
236 | int fput_needed; | 236 | if (!f.file) |
237 | 237 | return -EBADF; | |
238 | retval = -EBADF; | ||
239 | file = fget_light(fd, &fput_needed); | ||
240 | if (!file) | ||
241 | goto bad; | ||
242 | 238 | ||
243 | retval = -EINVAL; | 239 | retval = -EINVAL; |
244 | if (origin <= SEEK_MAX) { | 240 | if (origin <= SEEK_MAX) { |
245 | loff_t res = vfs_llseek(file, offset, origin); | 241 | loff_t res = vfs_llseek(f.file, offset, origin); |
246 | retval = res; | 242 | retval = res; |
247 | if (res != (loff_t)retval) | 243 | if (res != (loff_t)retval) |
248 | retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */ | 244 | retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */ |
249 | } | 245 | } |
250 | fput_light(file, fput_needed); | 246 | fdput(f); |
251 | bad: | ||
252 | return retval; | 247 | return retval; |
253 | } | 248 | } |
254 | 249 | ||
@@ -258,20 +253,17 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high, | |||
258 | unsigned int, origin) | 253 | unsigned int, origin) |
259 | { | 254 | { |
260 | int retval; | 255 | int retval; |
261 | struct file * file; | 256 | struct fd f = fdget(fd); |
262 | loff_t offset; | 257 | loff_t offset; |
263 | int fput_needed; | ||
264 | 258 | ||
265 | retval = -EBADF; | 259 | if (!f.file) |
266 | file = fget_light(fd, &fput_needed); | 260 | return -EBADF; |
267 | if (!file) | ||
268 | goto bad; | ||
269 | 261 | ||
270 | retval = -EINVAL; | 262 | retval = -EINVAL; |
271 | if (origin > SEEK_MAX) | 263 | if (origin > SEEK_MAX) |
272 | goto out_putf; | 264 | goto out_putf; |
273 | 265 | ||
274 | offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low, | 266 | offset = vfs_llseek(f.file, ((loff_t) offset_high << 32) | offset_low, |
275 | origin); | 267 | origin); |
276 | 268 | ||
277 | retval = (int)offset; | 269 | retval = (int)offset; |
@@ -281,8 +273,7 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high, | |||
281 | retval = 0; | 273 | retval = 0; |
282 | } | 274 | } |
283 | out_putf: | 275 | out_putf: |
284 | fput_light(file, fput_needed); | 276 | fdput(f); |
285 | bad: | ||
286 | return retval; | 277 | return retval; |
287 | } | 278 | } |
288 | #endif | 279 | #endif |
@@ -461,34 +452,29 @@ static inline void file_pos_write(struct file *file, loff_t pos) | |||
461 | 452 | ||
462 | SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) | 453 | SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) |
463 | { | 454 | { |
464 | struct file *file; | 455 | struct fd f = fdget(fd); |
465 | ssize_t ret = -EBADF; | 456 | ssize_t ret = -EBADF; |
466 | int fput_needed; | ||
467 | 457 | ||
468 | file = fget_light(fd, &fput_needed); | 458 | if (f.file) { |
469 | if (file) { | 459 | loff_t pos = file_pos_read(f.file); |
470 | loff_t pos = file_pos_read(file); | 460 | ret = vfs_read(f.file, buf, count, &pos); |
471 | ret = vfs_read(file, buf, count, &pos); | 461 | file_pos_write(f.file, pos); |
472 | file_pos_write(file, pos); | 462 | fdput(f); |
473 | fput_light(file, fput_needed); | ||
474 | } | 463 | } |
475 | |||
476 | return ret; | 464 | return ret; |
477 | } | 465 | } |
478 | 466 | ||
479 | SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, | 467 | SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, |
480 | size_t, count) | 468 | size_t, count) |
481 | { | 469 | { |
482 | struct file *file; | 470 | struct fd f = fdget(fd); |
483 | ssize_t ret = -EBADF; | 471 | ssize_t ret = -EBADF; |
484 | int fput_needed; | ||
485 | 472 | ||
486 | file = fget_light(fd, &fput_needed); | 473 | if (f.file) { |
487 | if (file) { | 474 | loff_t pos = file_pos_read(f.file); |
488 | loff_t pos = file_pos_read(file); | 475 | ret = vfs_write(f.file, buf, count, &pos); |
489 | ret = vfs_write(file, buf, count, &pos); | 476 | file_pos_write(f.file, pos); |
490 | file_pos_write(file, pos); | 477 | fdput(f); |
491 | fput_light(file, fput_needed); | ||
492 | } | 478 | } |
493 | 479 | ||
494 | return ret; | 480 | return ret; |
@@ -497,19 +483,18 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, | |||
497 | SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf, | 483 | SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf, |
498 | size_t count, loff_t pos) | 484 | size_t count, loff_t pos) |
499 | { | 485 | { |
500 | struct file *file; | 486 | struct fd f; |
501 | ssize_t ret = -EBADF; | 487 | ssize_t ret = -EBADF; |
502 | int fput_needed; | ||
503 | 488 | ||
504 | if (pos < 0) | 489 | if (pos < 0) |
505 | return -EINVAL; | 490 | return -EINVAL; |
506 | 491 | ||
507 | file = fget_light(fd, &fput_needed); | 492 | f = fdget(fd); |
508 | if (file) { | 493 | if (f.file) { |
509 | ret = -ESPIPE; | 494 | ret = -ESPIPE; |
510 | if (file->f_mode & FMODE_PREAD) | 495 | if (f.file->f_mode & FMODE_PREAD) |
511 | ret = vfs_read(file, buf, count, &pos); | 496 | ret = vfs_read(f.file, buf, count, &pos); |
512 | fput_light(file, fput_needed); | 497 | fdput(f); |
513 | } | 498 | } |
514 | 499 | ||
515 | return ret; | 500 | return ret; |
@@ -526,19 +511,18 @@ SYSCALL_ALIAS(sys_pread64, SyS_pread64); | |||
526 | SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf, | 511 | SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf, |
527 | size_t count, loff_t pos) | 512 | size_t count, loff_t pos) |
528 | { | 513 | { |
529 | struct file *file; | 514 | struct fd f; |
530 | ssize_t ret = -EBADF; | 515 | ssize_t ret = -EBADF; |
531 | int fput_needed; | ||
532 | 516 | ||
533 | if (pos < 0) | 517 | if (pos < 0) |
534 | return -EINVAL; | 518 | return -EINVAL; |
535 | 519 | ||
536 | file = fget_light(fd, &fput_needed); | 520 | f = fdget(fd); |
537 | if (file) { | 521 | if (f.file) { |
538 | ret = -ESPIPE; | 522 | ret = -ESPIPE; |
539 | if (file->f_mode & FMODE_PWRITE) | 523 | if (f.file->f_mode & FMODE_PWRITE) |
540 | ret = vfs_write(file, buf, count, &pos); | 524 | ret = vfs_write(f.file, buf, count, &pos); |
541 | fput_light(file, fput_needed); | 525 | fdput(f); |
542 | } | 526 | } |
543 | 527 | ||
544 | return ret; | 528 | return ret; |
@@ -789,16 +773,14 @@ EXPORT_SYMBOL(vfs_writev); | |||
789 | SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, | 773 | SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, |
790 | unsigned long, vlen) | 774 | unsigned long, vlen) |
791 | { | 775 | { |
792 | struct file *file; | 776 | struct fd f = fdget(fd); |
793 | ssize_t ret = -EBADF; | 777 | ssize_t ret = -EBADF; |
794 | int fput_needed; | ||
795 | 778 | ||
796 | file = fget_light(fd, &fput_needed); | 779 | if (f.file) { |
797 | if (file) { | 780 | loff_t pos = file_pos_read(f.file); |
798 | loff_t pos = file_pos_read(file); | 781 | ret = vfs_readv(f.file, vec, vlen, &pos); |
799 | ret = vfs_readv(file, vec, vlen, &pos); | 782 | file_pos_write(f.file, pos); |
800 | file_pos_write(file, pos); | 783 | fdput(f); |
801 | fput_light(file, fput_needed); | ||
802 | } | 784 | } |
803 | 785 | ||
804 | if (ret > 0) | 786 | if (ret > 0) |
@@ -810,16 +792,14 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, | |||
810 | SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, | 792 | SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, |
811 | unsigned long, vlen) | 793 | unsigned long, vlen) |
812 | { | 794 | { |
813 | struct file *file; | 795 | struct fd f = fdget(fd); |
814 | ssize_t ret = -EBADF; | 796 | ssize_t ret = -EBADF; |
815 | int fput_needed; | ||
816 | 797 | ||
817 | file = fget_light(fd, &fput_needed); | 798 | if (f.file) { |
818 | if (file) { | 799 | loff_t pos = file_pos_read(f.file); |
819 | loff_t pos = file_pos_read(file); | 800 | ret = vfs_writev(f.file, vec, vlen, &pos); |
820 | ret = vfs_writev(file, vec, vlen, &pos); | 801 | file_pos_write(f.file, pos); |
821 | file_pos_write(file, pos); | 802 | fdput(f); |
822 | fput_light(file, fput_needed); | ||
823 | } | 803 | } |
824 | 804 | ||
825 | if (ret > 0) | 805 | if (ret > 0) |
@@ -838,19 +818,18 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec, | |||
838 | unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) | 818 | unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) |
839 | { | 819 | { |
840 | loff_t pos = pos_from_hilo(pos_h, pos_l); | 820 | loff_t pos = pos_from_hilo(pos_h, pos_l); |
841 | struct file *file; | 821 | struct fd f; |
842 | ssize_t ret = -EBADF; | 822 | ssize_t ret = -EBADF; |
843 | int fput_needed; | ||
844 | 823 | ||
845 | if (pos < 0) | 824 | if (pos < 0) |
846 | return -EINVAL; | 825 | return -EINVAL; |
847 | 826 | ||
848 | file = fget_light(fd, &fput_needed); | 827 | f = fdget(fd); |
849 | if (file) { | 828 | if (f.file) { |
850 | ret = -ESPIPE; | 829 | ret = -ESPIPE; |
851 | if (file->f_mode & FMODE_PREAD) | 830 | if (f.file->f_mode & FMODE_PREAD) |
852 | ret = vfs_readv(file, vec, vlen, &pos); | 831 | ret = vfs_readv(f.file, vec, vlen, &pos); |
853 | fput_light(file, fput_needed); | 832 | fdput(f); |
854 | } | 833 | } |
855 | 834 | ||
856 | if (ret > 0) | 835 | if (ret > 0) |
@@ -863,19 +842,18 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, | |||
863 | unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) | 842 | unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) |
864 | { | 843 | { |
865 | loff_t pos = pos_from_hilo(pos_h, pos_l); | 844 | loff_t pos = pos_from_hilo(pos_h, pos_l); |
866 | struct file *file; | 845 | struct fd f; |
867 | ssize_t ret = -EBADF; | 846 | ssize_t ret = -EBADF; |
868 | int fput_needed; | ||
869 | 847 | ||
870 | if (pos < 0) | 848 | if (pos < 0) |
871 | return -EINVAL; | 849 | return -EINVAL; |
872 | 850 | ||
873 | file = fget_light(fd, &fput_needed); | 851 | f = fdget(fd); |
874 | if (file) { | 852 | if (f.file) { |
875 | ret = -ESPIPE; | 853 | ret = -ESPIPE; |
876 | if (file->f_mode & FMODE_PWRITE) | 854 | if (f.file->f_mode & FMODE_PWRITE) |
877 | ret = vfs_writev(file, vec, vlen, &pos); | 855 | ret = vfs_writev(f.file, vec, vlen, &pos); |
878 | fput_light(file, fput_needed); | 856 | fdput(f); |
879 | } | 857 | } |
880 | 858 | ||
881 | if (ret > 0) | 859 | if (ret > 0) |
@@ -887,28 +865,28 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, | |||
887 | static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | 865 | static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, |
888 | size_t count, loff_t max) | 866 | size_t count, loff_t max) |
889 | { | 867 | { |
890 | struct file * in_file, * out_file; | 868 | struct fd in, out; |
891 | struct inode * in_inode, * out_inode; | 869 | struct inode *in_inode, *out_inode; |
892 | loff_t pos; | 870 | loff_t pos; |
893 | ssize_t retval; | 871 | ssize_t retval; |
894 | int fput_needed_in, fput_needed_out, fl; | 872 | int fl; |
895 | 873 | ||
896 | /* | 874 | /* |
897 | * Get input file, and verify that it is ok.. | 875 | * Get input file, and verify that it is ok.. |
898 | */ | 876 | */ |
899 | retval = -EBADF; | 877 | retval = -EBADF; |
900 | in_file = fget_light(in_fd, &fput_needed_in); | 878 | in = fdget(in_fd); |
901 | if (!in_file) | 879 | if (!in.file) |
902 | goto out; | 880 | goto out; |
903 | if (!(in_file->f_mode & FMODE_READ)) | 881 | if (!(in.file->f_mode & FMODE_READ)) |
904 | goto fput_in; | 882 | goto fput_in; |
905 | retval = -ESPIPE; | 883 | retval = -ESPIPE; |
906 | if (!ppos) | 884 | if (!ppos) |
907 | ppos = &in_file->f_pos; | 885 | ppos = &in.file->f_pos; |
908 | else | 886 | else |
909 | if (!(in_file->f_mode & FMODE_PREAD)) | 887 | if (!(in.file->f_mode & FMODE_PREAD)) |
910 | goto fput_in; | 888 | goto fput_in; |
911 | retval = rw_verify_area(READ, in_file, ppos, count); | 889 | retval = rw_verify_area(READ, in.file, ppos, count); |
912 | if (retval < 0) | 890 | if (retval < 0) |
913 | goto fput_in; | 891 | goto fput_in; |
914 | count = retval; | 892 | count = retval; |
@@ -917,15 +895,15 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
917 | * Get output file, and verify that it is ok.. | 895 | * Get output file, and verify that it is ok.. |
918 | */ | 896 | */ |
919 | retval = -EBADF; | 897 | retval = -EBADF; |
920 | out_file = fget_light(out_fd, &fput_needed_out); | 898 | out = fdget(out_fd); |
921 | if (!out_file) | 899 | if (!out.file) |
922 | goto fput_in; | 900 | goto fput_in; |
923 | if (!(out_file->f_mode & FMODE_WRITE)) | 901 | if (!(out.file->f_mode & FMODE_WRITE)) |
924 | goto fput_out; | 902 | goto fput_out; |
925 | retval = -EINVAL; | 903 | retval = -EINVAL; |
926 | in_inode = in_file->f_path.dentry->d_inode; | 904 | in_inode = in.file->f_path.dentry->d_inode; |
927 | out_inode = out_file->f_path.dentry->d_inode; | 905 | out_inode = out.file->f_path.dentry->d_inode; |
928 | retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); | 906 | retval = rw_verify_area(WRITE, out.file, &out.file->f_pos, count); |
929 | if (retval < 0) | 907 | if (retval < 0) |
930 | goto fput_out; | 908 | goto fput_out; |
931 | count = retval; | 909 | count = retval; |
@@ -949,10 +927,10 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
949 | * and the application is arguably buggy if it doesn't expect | 927 | * and the application is arguably buggy if it doesn't expect |
950 | * EAGAIN on a non-blocking file descriptor. | 928 | * EAGAIN on a non-blocking file descriptor. |
951 | */ | 929 | */ |
952 | if (in_file->f_flags & O_NONBLOCK) | 930 | if (in.file->f_flags & O_NONBLOCK) |
953 | fl = SPLICE_F_NONBLOCK; | 931 | fl = SPLICE_F_NONBLOCK; |
954 | #endif | 932 | #endif |
955 | retval = do_splice_direct(in_file, ppos, out_file, count, fl); | 933 | retval = do_splice_direct(in.file, ppos, out.file, count, fl); |
956 | 934 | ||
957 | if (retval > 0) { | 935 | if (retval > 0) { |
958 | add_rchar(current, retval); | 936 | add_rchar(current, retval); |
@@ -965,9 +943,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
965 | retval = -EOVERFLOW; | 943 | retval = -EOVERFLOW; |
966 | 944 | ||
967 | fput_out: | 945 | fput_out: |
968 | fput_light(out_file, fput_needed_out); | 946 | fdput(out); |
969 | fput_in: | 947 | fput_in: |
970 | fput_light(in_file, fput_needed_in); | 948 | fdput(in); |
971 | out: | 949 | out: |
972 | return retval; | 950 | return retval; |
973 | } | 951 | } |
diff --git a/fs/readdir.c b/fs/readdir.c index 39e3370d79cf..5e69ef533b77 100644 --- a/fs/readdir.c +++ b/fs/readdir.c | |||
@@ -106,22 +106,20 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd, | |||
106 | struct old_linux_dirent __user *, dirent, unsigned int, count) | 106 | struct old_linux_dirent __user *, dirent, unsigned int, count) |
107 | { | 107 | { |
108 | int error; | 108 | int error; |
109 | struct file * file; | 109 | struct fd f = fdget(fd); |
110 | struct readdir_callback buf; | 110 | struct readdir_callback buf; |
111 | int fput_needed; | ||
112 | 111 | ||
113 | file = fget_light(fd, &fput_needed); | 112 | if (!f.file) |
114 | if (!file) | ||
115 | return -EBADF; | 113 | return -EBADF; |
116 | 114 | ||
117 | buf.result = 0; | 115 | buf.result = 0; |
118 | buf.dirent = dirent; | 116 | buf.dirent = dirent; |
119 | 117 | ||
120 | error = vfs_readdir(file, fillonedir, &buf); | 118 | error = vfs_readdir(f.file, fillonedir, &buf); |
121 | if (buf.result) | 119 | if (buf.result) |
122 | error = buf.result; | 120 | error = buf.result; |
123 | 121 | ||
124 | fput_light(file, fput_needed); | 122 | fdput(f); |
125 | return error; | 123 | return error; |
126 | } | 124 | } |
127 | 125 | ||
@@ -191,17 +189,16 @@ efault: | |||
191 | SYSCALL_DEFINE3(getdents, unsigned int, fd, | 189 | SYSCALL_DEFINE3(getdents, unsigned int, fd, |
192 | struct linux_dirent __user *, dirent, unsigned int, count) | 190 | struct linux_dirent __user *, dirent, unsigned int, count) |
193 | { | 191 | { |
194 | struct file * file; | 192 | struct fd f; |
195 | struct linux_dirent __user * lastdirent; | 193 | struct linux_dirent __user * lastdirent; |
196 | struct getdents_callback buf; | 194 | struct getdents_callback buf; |
197 | int fput_needed; | ||
198 | int error; | 195 | int error; |
199 | 196 | ||
200 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 197 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
201 | return -EFAULT; | 198 | return -EFAULT; |
202 | 199 | ||
203 | file = fget_light(fd, &fput_needed); | 200 | f = fdget(fd); |
204 | if (!file) | 201 | if (!f.file) |
205 | return -EBADF; | 202 | return -EBADF; |
206 | 203 | ||
207 | buf.current_dir = dirent; | 204 | buf.current_dir = dirent; |
@@ -209,17 +206,17 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd, | |||
209 | buf.count = count; | 206 | buf.count = count; |
210 | buf.error = 0; | 207 | buf.error = 0; |
211 | 208 | ||
212 | error = vfs_readdir(file, filldir, &buf); | 209 | error = vfs_readdir(f.file, filldir, &buf); |
213 | if (error >= 0) | 210 | if (error >= 0) |
214 | error = buf.error; | 211 | error = buf.error; |
215 | lastdirent = buf.previous; | 212 | lastdirent = buf.previous; |
216 | if (lastdirent) { | 213 | if (lastdirent) { |
217 | if (put_user(file->f_pos, &lastdirent->d_off)) | 214 | if (put_user(f.file->f_pos, &lastdirent->d_off)) |
218 | error = -EFAULT; | 215 | error = -EFAULT; |
219 | else | 216 | else |
220 | error = count - buf.count; | 217 | error = count - buf.count; |
221 | } | 218 | } |
222 | fput_light(file, fput_needed); | 219 | fdput(f); |
223 | return error; | 220 | return error; |
224 | } | 221 | } |
225 | 222 | ||
@@ -272,17 +269,16 @@ efault: | |||
272 | SYSCALL_DEFINE3(getdents64, unsigned int, fd, | 269 | SYSCALL_DEFINE3(getdents64, unsigned int, fd, |
273 | struct linux_dirent64 __user *, dirent, unsigned int, count) | 270 | struct linux_dirent64 __user *, dirent, unsigned int, count) |
274 | { | 271 | { |
275 | struct file * file; | 272 | struct fd f; |
276 | struct linux_dirent64 __user * lastdirent; | 273 | struct linux_dirent64 __user * lastdirent; |
277 | struct getdents_callback64 buf; | 274 | struct getdents_callback64 buf; |
278 | int fput_needed; | ||
279 | int error; | 275 | int error; |
280 | 276 | ||
281 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 277 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
282 | return -EFAULT; | 278 | return -EFAULT; |
283 | 279 | ||
284 | file = fget_light(fd, &fput_needed); | 280 | f = fdget(fd); |
285 | if (!file) | 281 | if (!f.file) |
286 | return -EBADF; | 282 | return -EBADF; |
287 | 283 | ||
288 | buf.current_dir = dirent; | 284 | buf.current_dir = dirent; |
@@ -290,17 +286,17 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd, | |||
290 | buf.count = count; | 286 | buf.count = count; |
291 | buf.error = 0; | 287 | buf.error = 0; |
292 | 288 | ||
293 | error = vfs_readdir(file, filldir64, &buf); | 289 | error = vfs_readdir(f.file, filldir64, &buf); |
294 | if (error >= 0) | 290 | if (error >= 0) |
295 | error = buf.error; | 291 | error = buf.error; |
296 | lastdirent = buf.previous; | 292 | lastdirent = buf.previous; |
297 | if (lastdirent) { | 293 | if (lastdirent) { |
298 | typeof(lastdirent->d_off) d_off = file->f_pos; | 294 | typeof(lastdirent->d_off) d_off = f.file->f_pos; |
299 | if (__put_user(d_off, &lastdirent->d_off)) | 295 | if (__put_user(d_off, &lastdirent->d_off)) |
300 | error = -EFAULT; | 296 | error = -EFAULT; |
301 | else | 297 | else |
302 | error = count - buf.count; | 298 | error = count - buf.count; |
303 | } | 299 | } |
304 | fput_light(file, fput_needed); | 300 | fdput(f); |
305 | return error; | 301 | return error; |
306 | } | 302 | } |
diff --git a/fs/select.c b/fs/select.c index ffdd16d6e691..2ef72d965036 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -428,8 +428,6 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
428 | for (i = 0; i < n; ++rinp, ++routp, ++rexp) { | 428 | for (i = 0; i < n; ++rinp, ++routp, ++rexp) { |
429 | unsigned long in, out, ex, all_bits, bit = 1, mask, j; | 429 | unsigned long in, out, ex, all_bits, bit = 1, mask, j; |
430 | unsigned long res_in = 0, res_out = 0, res_ex = 0; | 430 | unsigned long res_in = 0, res_out = 0, res_ex = 0; |
431 | const struct file_operations *f_op = NULL; | ||
432 | struct file *file = NULL; | ||
433 | 431 | ||
434 | in = *inp++; out = *outp++; ex = *exp++; | 432 | in = *inp++; out = *outp++; ex = *exp++; |
435 | all_bits = in | out | ex; | 433 | all_bits = in | out | ex; |
@@ -439,20 +437,21 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
439 | } | 437 | } |
440 | 438 | ||
441 | for (j = 0; j < BITS_PER_LONG; ++j, ++i, bit <<= 1) { | 439 | for (j = 0; j < BITS_PER_LONG; ++j, ++i, bit <<= 1) { |
442 | int fput_needed; | 440 | struct fd f; |
443 | if (i >= n) | 441 | if (i >= n) |
444 | break; | 442 | break; |
445 | if (!(bit & all_bits)) | 443 | if (!(bit & all_bits)) |
446 | continue; | 444 | continue; |
447 | file = fget_light(i, &fput_needed); | 445 | f = fdget(i); |
448 | if (file) { | 446 | if (f.file) { |
449 | f_op = file->f_op; | 447 | const struct file_operations *f_op; |
448 | f_op = f.file->f_op; | ||
450 | mask = DEFAULT_POLLMASK; | 449 | mask = DEFAULT_POLLMASK; |
451 | if (f_op && f_op->poll) { | 450 | if (f_op && f_op->poll) { |
452 | wait_key_set(wait, in, out, bit); | 451 | wait_key_set(wait, in, out, bit); |
453 | mask = (*f_op->poll)(file, wait); | 452 | mask = (*f_op->poll)(f.file, wait); |
454 | } | 453 | } |
455 | fput_light(file, fput_needed); | 454 | fdput(f); |
456 | if ((mask & POLLIN_SET) && (in & bit)) { | 455 | if ((mask & POLLIN_SET) && (in & bit)) { |
457 | res_in |= bit; | 456 | res_in |= bit; |
458 | retval++; | 457 | retval++; |
@@ -725,20 +724,17 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait) | |||
725 | mask = 0; | 724 | mask = 0; |
726 | fd = pollfd->fd; | 725 | fd = pollfd->fd; |
727 | if (fd >= 0) { | 726 | if (fd >= 0) { |
728 | int fput_needed; | 727 | struct fd f = fdget(fd); |
729 | struct file * file; | ||
730 | |||
731 | file = fget_light(fd, &fput_needed); | ||
732 | mask = POLLNVAL; | 728 | mask = POLLNVAL; |
733 | if (file != NULL) { | 729 | if (f.file) { |
734 | mask = DEFAULT_POLLMASK; | 730 | mask = DEFAULT_POLLMASK; |
735 | if (file->f_op && file->f_op->poll) { | 731 | if (f.file->f_op && f.file->f_op->poll) { |
736 | pwait->_key = pollfd->events|POLLERR|POLLHUP; | 732 | pwait->_key = pollfd->events|POLLERR|POLLHUP; |
737 | mask = file->f_op->poll(file, pwait); | 733 | mask = f.file->f_op->poll(f.file, pwait); |
738 | } | 734 | } |
739 | /* Mask out unneeded events. */ | 735 | /* Mask out unneeded events. */ |
740 | mask &= pollfd->events | POLLERR | POLLHUP; | 736 | mask &= pollfd->events | POLLERR | POLLHUP; |
741 | fput_light(file, fput_needed); | 737 | fdput(f); |
742 | } | 738 | } |
743 | } | 739 | } |
744 | pollfd->revents = mask; | 740 | pollfd->revents = mask; |
diff --git a/fs/signalfd.c b/fs/signalfd.c index 9f35a37173de..8bee4e570911 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -269,13 +269,12 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask, | |||
269 | if (ufd < 0) | 269 | if (ufd < 0) |
270 | kfree(ctx); | 270 | kfree(ctx); |
271 | } else { | 271 | } else { |
272 | int fput_needed; | 272 | struct fd f = fdget(ufd); |
273 | struct file *file = fget_light(ufd, &fput_needed); | 273 | if (!f.file) |
274 | if (!file) | ||
275 | return -EBADF; | 274 | return -EBADF; |
276 | ctx = file->private_data; | 275 | ctx = f.file->private_data; |
277 | if (file->f_op != &signalfd_fops) { | 276 | if (f.file->f_op != &signalfd_fops) { |
278 | fput_light(file, fput_needed); | 277 | fdput(f); |
279 | return -EINVAL; | 278 | return -EINVAL; |
280 | } | 279 | } |
281 | spin_lock_irq(¤t->sighand->siglock); | 280 | spin_lock_irq(¤t->sighand->siglock); |
@@ -283,7 +282,7 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask, | |||
283 | spin_unlock_irq(¤t->sighand->siglock); | 282 | spin_unlock_irq(¤t->sighand->siglock); |
284 | 283 | ||
285 | wake_up(¤t->sighand->signalfd_wqh); | 284 | wake_up(¤t->sighand->signalfd_wqh); |
286 | fput_light(file, fput_needed); | 285 | fdput(f); |
287 | } | 286 | } |
288 | 287 | ||
289 | return ufd; | 288 | return ufd; |
diff --git a/fs/splice.c b/fs/splice.c index 41514dd89462..13e5b4776e7a 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -1666,9 +1666,8 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, | |||
1666 | SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov, | 1666 | SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov, |
1667 | unsigned long, nr_segs, unsigned int, flags) | 1667 | unsigned long, nr_segs, unsigned int, flags) |
1668 | { | 1668 | { |
1669 | struct file *file; | 1669 | struct fd f; |
1670 | long error; | 1670 | long error; |
1671 | int fput; | ||
1672 | 1671 | ||
1673 | if (unlikely(nr_segs > UIO_MAXIOV)) | 1672 | if (unlikely(nr_segs > UIO_MAXIOV)) |
1674 | return -EINVAL; | 1673 | return -EINVAL; |
@@ -1676,14 +1675,14 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov, | |||
1676 | return 0; | 1675 | return 0; |
1677 | 1676 | ||
1678 | error = -EBADF; | 1677 | error = -EBADF; |
1679 | file = fget_light(fd, &fput); | 1678 | f = fdget(fd); |
1680 | if (file) { | 1679 | if (f.file) { |
1681 | if (file->f_mode & FMODE_WRITE) | 1680 | if (f.file->f_mode & FMODE_WRITE) |
1682 | error = vmsplice_to_pipe(file, iov, nr_segs, flags); | 1681 | error = vmsplice_to_pipe(f.file, iov, nr_segs, flags); |
1683 | else if (file->f_mode & FMODE_READ) | 1682 | else if (f.file->f_mode & FMODE_READ) |
1684 | error = vmsplice_to_user(file, iov, nr_segs, flags); | 1683 | error = vmsplice_to_user(f.file, iov, nr_segs, flags); |
1685 | 1684 | ||
1686 | fput_light(file, fput); | 1685 | fdput(f); |
1687 | } | 1686 | } |
1688 | 1687 | ||
1689 | return error; | 1688 | return error; |
@@ -1693,30 +1692,27 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, | |||
1693 | int, fd_out, loff_t __user *, off_out, | 1692 | int, fd_out, loff_t __user *, off_out, |
1694 | size_t, len, unsigned int, flags) | 1693 | size_t, len, unsigned int, flags) |
1695 | { | 1694 | { |
1695 | struct fd in, out; | ||
1696 | long error; | 1696 | long error; |
1697 | struct file *in, *out; | ||
1698 | int fput_in, fput_out; | ||
1699 | 1697 | ||
1700 | if (unlikely(!len)) | 1698 | if (unlikely(!len)) |
1701 | return 0; | 1699 | return 0; |
1702 | 1700 | ||
1703 | error = -EBADF; | 1701 | error = -EBADF; |
1704 | in = fget_light(fd_in, &fput_in); | 1702 | in = fdget(fd_in); |
1705 | if (in) { | 1703 | if (in.file) { |
1706 | if (in->f_mode & FMODE_READ) { | 1704 | if (in.file->f_mode & FMODE_READ) { |
1707 | out = fget_light(fd_out, &fput_out); | 1705 | out = fdget(fd_out); |
1708 | if (out) { | 1706 | if (out.file) { |
1709 | if (out->f_mode & FMODE_WRITE) | 1707 | if (out.file->f_mode & FMODE_WRITE) |
1710 | error = do_splice(in, off_in, | 1708 | error = do_splice(in.file, off_in, |
1711 | out, off_out, | 1709 | out.file, off_out, |
1712 | len, flags); | 1710 | len, flags); |
1713 | fput_light(out, fput_out); | 1711 | fdput(out); |
1714 | } | 1712 | } |
1715 | } | 1713 | } |
1716 | 1714 | fdput(in); | |
1717 | fput_light(in, fput_in); | ||
1718 | } | 1715 | } |
1719 | |||
1720 | return error; | 1716 | return error; |
1721 | } | 1717 | } |
1722 | 1718 | ||
@@ -2027,26 +2023,25 @@ static long do_tee(struct file *in, struct file *out, size_t len, | |||
2027 | 2023 | ||
2028 | SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags) | 2024 | SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags) |
2029 | { | 2025 | { |
2030 | struct file *in; | 2026 | struct fd in; |
2031 | int error, fput_in; | 2027 | int error; |
2032 | 2028 | ||
2033 | if (unlikely(!len)) | 2029 | if (unlikely(!len)) |
2034 | return 0; | 2030 | return 0; |
2035 | 2031 | ||
2036 | error = -EBADF; | 2032 | error = -EBADF; |
2037 | in = fget_light(fdin, &fput_in); | 2033 | in = fdget(fdin); |
2038 | if (in) { | 2034 | if (in.file) { |
2039 | if (in->f_mode & FMODE_READ) { | 2035 | if (in.file->f_mode & FMODE_READ) { |
2040 | int fput_out; | 2036 | struct fd out = fdget(fdout); |
2041 | struct file *out = fget_light(fdout, &fput_out); | 2037 | if (out.file) { |
2042 | 2038 | if (out.file->f_mode & FMODE_WRITE) | |
2043 | if (out) { | 2039 | error = do_tee(in.file, out.file, |
2044 | if (out->f_mode & FMODE_WRITE) | 2040 | len, flags); |
2045 | error = do_tee(in, out, len, flags); | 2041 | fdput(out); |
2046 | fput_light(out, fput_out); | ||
2047 | } | 2042 | } |
2048 | } | 2043 | } |
2049 | fput_light(in, fput_in); | 2044 | fdput(in); |
2050 | } | 2045 | } |
2051 | 2046 | ||
2052 | return error; | 2047 | return error; |
@@ -57,13 +57,13 @@ EXPORT_SYMBOL(vfs_getattr); | |||
57 | 57 | ||
58 | int vfs_fstat(unsigned int fd, struct kstat *stat) | 58 | int vfs_fstat(unsigned int fd, struct kstat *stat) |
59 | { | 59 | { |
60 | int fput_needed; | 60 | struct fd f = fdget_raw(fd); |
61 | struct file *f = fget_raw_light(fd, &fput_needed); | ||
62 | int error = -EBADF; | 61 | int error = -EBADF; |
63 | 62 | ||
64 | if (f) { | 63 | if (f.file) { |
65 | error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat); | 64 | error = vfs_getattr(f.file->f_path.mnt, f.file->f_path.dentry, |
66 | fput_light(f, fput_needed); | 65 | stat); |
66 | fdput(f); | ||
67 | } | 67 | } |
68 | return error; | 68 | return error; |
69 | } | 69 | } |
diff --git a/fs/statfs.c b/fs/statfs.c index 95ad5c0e586c..f8e832e6f0a2 100644 --- a/fs/statfs.c +++ b/fs/statfs.c | |||
@@ -87,12 +87,11 @@ int user_statfs(const char __user *pathname, struct kstatfs *st) | |||
87 | 87 | ||
88 | int fd_statfs(int fd, struct kstatfs *st) | 88 | int fd_statfs(int fd, struct kstatfs *st) |
89 | { | 89 | { |
90 | int fput_needed; | 90 | struct fd f = fdget(fd); |
91 | struct file *file = fget_light(fd, &fput_needed); | ||
92 | int error = -EBADF; | 91 | int error = -EBADF; |
93 | if (file) { | 92 | if (f.file) { |
94 | error = vfs_statfs(&file->f_path, st); | 93 | error = vfs_statfs(&f.file->f_path, st); |
95 | fput_light(file, fput_needed); | 94 | fdput(f); |
96 | } | 95 | } |
97 | return error; | 96 | return error; |
98 | } | 97 | } |
@@ -148,21 +148,19 @@ void emergency_sync(void) | |||
148 | */ | 148 | */ |
149 | SYSCALL_DEFINE1(syncfs, int, fd) | 149 | SYSCALL_DEFINE1(syncfs, int, fd) |
150 | { | 150 | { |
151 | struct file *file; | 151 | struct fd f = fdget(fd); |
152 | struct super_block *sb; | 152 | struct super_block *sb; |
153 | int ret; | 153 | int ret; |
154 | int fput_needed; | ||
155 | 154 | ||
156 | file = fget_light(fd, &fput_needed); | 155 | if (!f.file) |
157 | if (!file) | ||
158 | return -EBADF; | 156 | return -EBADF; |
159 | sb = file->f_dentry->d_sb; | 157 | sb = f.file->f_dentry->d_sb; |
160 | 158 | ||
161 | down_read(&sb->s_umount); | 159 | down_read(&sb->s_umount); |
162 | ret = sync_filesystem(sb); | 160 | ret = sync_filesystem(sb); |
163 | up_read(&sb->s_umount); | 161 | up_read(&sb->s_umount); |
164 | 162 | ||
165 | fput_light(file, fput_needed); | 163 | fdput(f); |
166 | return ret; | 164 | return ret; |
167 | } | 165 | } |
168 | 166 | ||
@@ -201,14 +199,12 @@ EXPORT_SYMBOL(vfs_fsync); | |||
201 | 199 | ||
202 | static int do_fsync(unsigned int fd, int datasync) | 200 | static int do_fsync(unsigned int fd, int datasync) |
203 | { | 201 | { |
204 | struct file *file; | 202 | struct fd f = fdget(fd); |
205 | int ret = -EBADF; | 203 | int ret = -EBADF; |
206 | int fput_needed; | ||
207 | 204 | ||
208 | file = fget_light(fd, &fput_needed); | 205 | if (f.file) { |
209 | if (file) { | 206 | ret = vfs_fsync(f.file, datasync); |
210 | ret = vfs_fsync(file, datasync); | 207 | fdput(f); |
211 | fput_light(file, fput_needed); | ||
212 | } | 208 | } |
213 | return ret; | 209 | return ret; |
214 | } | 210 | } |
@@ -291,10 +287,9 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, | |||
291 | unsigned int flags) | 287 | unsigned int flags) |
292 | { | 288 | { |
293 | int ret; | 289 | int ret; |
294 | struct file *file; | 290 | struct fd f; |
295 | struct address_space *mapping; | 291 | struct address_space *mapping; |
296 | loff_t endbyte; /* inclusive */ | 292 | loff_t endbyte; /* inclusive */ |
297 | int fput_needed; | ||
298 | umode_t i_mode; | 293 | umode_t i_mode; |
299 | 294 | ||
300 | ret = -EINVAL; | 295 | ret = -EINVAL; |
@@ -333,17 +328,17 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, | |||
333 | endbyte--; /* inclusive */ | 328 | endbyte--; /* inclusive */ |
334 | 329 | ||
335 | ret = -EBADF; | 330 | ret = -EBADF; |
336 | file = fget_light(fd, &fput_needed); | 331 | f = fdget(fd); |
337 | if (!file) | 332 | if (!f.file) |
338 | goto out; | 333 | goto out; |
339 | 334 | ||
340 | i_mode = file->f_path.dentry->d_inode->i_mode; | 335 | i_mode = f.file->f_path.dentry->d_inode->i_mode; |
341 | ret = -ESPIPE; | 336 | ret = -ESPIPE; |
342 | if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) && | 337 | if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) && |
343 | !S_ISLNK(i_mode)) | 338 | !S_ISLNK(i_mode)) |
344 | goto out_put; | 339 | goto out_put; |
345 | 340 | ||
346 | mapping = file->f_mapping; | 341 | mapping = f.file->f_mapping; |
347 | if (!mapping) { | 342 | if (!mapping) { |
348 | ret = -EINVAL; | 343 | ret = -EINVAL; |
349 | goto out_put; | 344 | goto out_put; |
@@ -366,7 +361,7 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, | |||
366 | ret = filemap_fdatawait_range(mapping, offset, endbyte); | 361 | ret = filemap_fdatawait_range(mapping, offset, endbyte); |
367 | 362 | ||
368 | out_put: | 363 | out_put: |
369 | fput_light(file, fput_needed); | 364 | fdput(f); |
370 | out: | 365 | out: |
371 | return ret; | 366 | return ret; |
372 | } | 367 | } |
diff --git a/fs/timerfd.c b/fs/timerfd.c index dd91e9420c9e..d03822bbf190 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c | |||
@@ -234,19 +234,17 @@ static const struct file_operations timerfd_fops = { | |||
234 | .llseek = noop_llseek, | 234 | .llseek = noop_llseek, |
235 | }; | 235 | }; |
236 | 236 | ||
237 | static struct file *timerfd_fget(int fd, int *fput_needed) | 237 | static int timerfd_fget(int fd, struct fd *p) |
238 | { | 238 | { |
239 | struct file *file; | 239 | struct fd f = fdget(fd); |
240 | 240 | if (!f.file) | |
241 | file = fget_light(fd, fput_needed); | 241 | return -EBADF; |
242 | if (!file) | 242 | if (f.file->f_op != &timerfd_fops) { |
243 | return ERR_PTR(-EBADF); | 243 | fdput(f); |
244 | if (file->f_op != &timerfd_fops) { | 244 | return -EINVAL; |
245 | fput_light(file, *fput_needed); | ||
246 | return ERR_PTR(-EINVAL); | ||
247 | } | 245 | } |
248 | 246 | *p = f; | |
249 | return file; | 247 | return 0; |
250 | } | 248 | } |
251 | 249 | ||
252 | SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) | 250 | SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) |
@@ -284,10 +282,10 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
284 | const struct itimerspec __user *, utmr, | 282 | const struct itimerspec __user *, utmr, |
285 | struct itimerspec __user *, otmr) | 283 | struct itimerspec __user *, otmr) |
286 | { | 284 | { |
287 | struct file *file; | 285 | struct fd f; |
288 | struct timerfd_ctx *ctx; | 286 | struct timerfd_ctx *ctx; |
289 | struct itimerspec ktmr, kotmr; | 287 | struct itimerspec ktmr, kotmr; |
290 | int ret, fput_needed; | 288 | int ret; |
291 | 289 | ||
292 | if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) | 290 | if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) |
293 | return -EFAULT; | 291 | return -EFAULT; |
@@ -297,10 +295,10 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
297 | !timespec_valid(&ktmr.it_interval)) | 295 | !timespec_valid(&ktmr.it_interval)) |
298 | return -EINVAL; | 296 | return -EINVAL; |
299 | 297 | ||
300 | file = timerfd_fget(ufd, &fput_needed); | 298 | ret = timerfd_fget(ufd, &f); |
301 | if (IS_ERR(file)) | 299 | if (ret) |
302 | return PTR_ERR(file); | 300 | return ret; |
303 | ctx = file->private_data; | 301 | ctx = f.file->private_data; |
304 | 302 | ||
305 | timerfd_setup_cancel(ctx, flags); | 303 | timerfd_setup_cancel(ctx, flags); |
306 | 304 | ||
@@ -334,7 +332,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
334 | ret = timerfd_setup(ctx, flags, &ktmr); | 332 | ret = timerfd_setup(ctx, flags, &ktmr); |
335 | 333 | ||
336 | spin_unlock_irq(&ctx->wqh.lock); | 334 | spin_unlock_irq(&ctx->wqh.lock); |
337 | fput_light(file, fput_needed); | 335 | fdput(f); |
338 | if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr))) | 336 | if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr))) |
339 | return -EFAULT; | 337 | return -EFAULT; |
340 | 338 | ||
@@ -343,15 +341,13 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
343 | 341 | ||
344 | SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | 342 | SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) |
345 | { | 343 | { |
346 | struct file *file; | 344 | struct fd f; |
347 | struct timerfd_ctx *ctx; | 345 | struct timerfd_ctx *ctx; |
348 | struct itimerspec kotmr; | 346 | struct itimerspec kotmr; |
349 | int fput_needed; | 347 | int ret = timerfd_fget(ufd, &f); |
350 | 348 | if (ret) | |
351 | file = timerfd_fget(ufd, &fput_needed); | 349 | return ret; |
352 | if (IS_ERR(file)) | 350 | ctx = f.file->private_data; |
353 | return PTR_ERR(file); | ||
354 | ctx = file->private_data; | ||
355 | 351 | ||
356 | spin_lock_irq(&ctx->wqh.lock); | 352 | spin_lock_irq(&ctx->wqh.lock); |
357 | if (ctx->expired && ctx->tintv.tv64) { | 353 | if (ctx->expired && ctx->tintv.tv64) { |
@@ -363,7 +359,7 @@ SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | |||
363 | kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | 359 | kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); |
364 | kotmr.it_interval = ktime_to_timespec(ctx->tintv); | 360 | kotmr.it_interval = ktime_to_timespec(ctx->tintv); |
365 | spin_unlock_irq(&ctx->wqh.lock); | 361 | spin_unlock_irq(&ctx->wqh.lock); |
366 | fput_light(file, fput_needed); | 362 | fdput(f); |
367 | 363 | ||
368 | return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; | 364 | return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; |
369 | } | 365 | } |
diff --git a/fs/utimes.c b/fs/utimes.c index fa4dbe451e27..bb0696a41735 100644 --- a/fs/utimes.c +++ b/fs/utimes.c | |||
@@ -140,19 +140,18 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times, | |||
140 | goto out; | 140 | goto out; |
141 | 141 | ||
142 | if (filename == NULL && dfd != AT_FDCWD) { | 142 | if (filename == NULL && dfd != AT_FDCWD) { |
143 | int fput_needed; | 143 | struct fd f; |
144 | struct file *file; | ||
145 | 144 | ||
146 | if (flags & AT_SYMLINK_NOFOLLOW) | 145 | if (flags & AT_SYMLINK_NOFOLLOW) |
147 | goto out; | 146 | goto out; |
148 | 147 | ||
149 | file = fget_light(dfd, &fput_needed); | 148 | f = fdget(dfd); |
150 | error = -EBADF; | 149 | error = -EBADF; |
151 | if (!file) | 150 | if (!f.file) |
152 | goto out; | 151 | goto out; |
153 | 152 | ||
154 | error = utimes_common(&file->f_path, times); | 153 | error = utimes_common(&f.file->f_path, times); |
155 | fput_light(file, fput_needed); | 154 | fdput(f); |
156 | } else { | 155 | } else { |
157 | struct path path; | 156 | struct path path; |
158 | int lookup_flags = 0; | 157 | int lookup_flags = 0; |
diff --git a/fs/xattr.c b/fs/xattr.c index 4d45b7189e7e..14a7e2544fe3 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -399,22 +399,20 @@ SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, | |||
399 | SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, | 399 | SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, |
400 | const void __user *,value, size_t, size, int, flags) | 400 | const void __user *,value, size_t, size, int, flags) |
401 | { | 401 | { |
402 | int fput_needed; | 402 | struct fd f = fdget(fd); |
403 | struct file *f; | ||
404 | struct dentry *dentry; | 403 | struct dentry *dentry; |
405 | int error = -EBADF; | 404 | int error = -EBADF; |
406 | 405 | ||
407 | f = fget_light(fd, &fput_needed); | 406 | if (!f.file) |
408 | if (!f) | ||
409 | return error; | 407 | return error; |
410 | dentry = f->f_path.dentry; | 408 | dentry = f.file->f_path.dentry; |
411 | audit_inode(NULL, dentry); | 409 | audit_inode(NULL, dentry); |
412 | error = mnt_want_write_file(f); | 410 | error = mnt_want_write_file(f.file); |
413 | if (!error) { | 411 | if (!error) { |
414 | error = setxattr(dentry, name, value, size, flags); | 412 | error = setxattr(dentry, name, value, size, flags); |
415 | mnt_drop_write_file(f); | 413 | mnt_drop_write_file(f.file); |
416 | } | 414 | } |
417 | fput_light(f, fput_needed); | 415 | fdput(f); |
418 | return error; | 416 | return error; |
419 | } | 417 | } |
420 | 418 | ||
@@ -495,16 +493,14 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, | |||
495 | SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, | 493 | SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, |
496 | void __user *, value, size_t, size) | 494 | void __user *, value, size_t, size) |
497 | { | 495 | { |
498 | int fput_needed; | 496 | struct fd f = fdget(fd); |
499 | struct file *f; | ||
500 | ssize_t error = -EBADF; | 497 | ssize_t error = -EBADF; |
501 | 498 | ||
502 | f = fget_light(fd, &fput_needed); | 499 | if (!f.file) |
503 | if (!f) | ||
504 | return error; | 500 | return error; |
505 | audit_inode(NULL, f->f_path.dentry); | 501 | audit_inode(NULL, f.file->f_path.dentry); |
506 | error = getxattr(f->f_path.dentry, name, value, size); | 502 | error = getxattr(f.file->f_path.dentry, name, value, size); |
507 | fput_light(f, fput_needed); | 503 | fdput(f); |
508 | return error; | 504 | return error; |
509 | } | 505 | } |
510 | 506 | ||
@@ -576,16 +572,14 @@ SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, | |||
576 | 572 | ||
577 | SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) | 573 | SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) |
578 | { | 574 | { |
579 | int fput_needed; | 575 | struct fd f = fdget(fd); |
580 | struct file *f; | ||
581 | ssize_t error = -EBADF; | 576 | ssize_t error = -EBADF; |
582 | 577 | ||
583 | f = fget_light(fd, &fput_needed); | 578 | if (!f.file) |
584 | if (!f) | ||
585 | return error; | 579 | return error; |
586 | audit_inode(NULL, f->f_path.dentry); | 580 | audit_inode(NULL, f.file->f_path.dentry); |
587 | error = listxattr(f->f_path.dentry, list, size); | 581 | error = listxattr(f.file->f_path.dentry, list, size); |
588 | fput_light(f, fput_needed); | 582 | fdput(f); |
589 | return error; | 583 | return error; |
590 | } | 584 | } |
591 | 585 | ||
@@ -645,22 +639,20 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, | |||
645 | 639 | ||
646 | SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) | 640 | SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) |
647 | { | 641 | { |
648 | int fput_needed; | 642 | struct fd f = fdget(fd); |
649 | struct file *f; | ||
650 | struct dentry *dentry; | 643 | struct dentry *dentry; |
651 | int error = -EBADF; | 644 | int error = -EBADF; |
652 | 645 | ||
653 | f = fget_light(fd, &fput_needed); | 646 | if (!f.file) |
654 | if (!f) | ||
655 | return error; | 647 | return error; |
656 | dentry = f->f_path.dentry; | 648 | dentry = f.file->f_path.dentry; |
657 | audit_inode(NULL, dentry); | 649 | audit_inode(NULL, dentry); |
658 | error = mnt_want_write_file(f); | 650 | error = mnt_want_write_file(f.file); |
659 | if (!error) { | 651 | if (!error) { |
660 | error = removexattr(dentry, name); | 652 | error = removexattr(dentry, name); |
661 | mnt_drop_write_file(f); | 653 | mnt_drop_write_file(f.file); |
662 | } | 654 | } |
663 | fput_light(f, fput_needed); | 655 | fdput(f); |
664 | return error; | 656 | return error; |
665 | } | 657 | } |
666 | 658 | ||
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index e6cdf224d7ea..b9b8646e62db 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -48,44 +48,44 @@ xfs_swapext( | |||
48 | xfs_swapext_t *sxp) | 48 | xfs_swapext_t *sxp) |
49 | { | 49 | { |
50 | xfs_inode_t *ip, *tip; | 50 | xfs_inode_t *ip, *tip; |
51 | struct file *file, *tmp_file; | 51 | struct fd f, tmp; |
52 | int error = 0, fput_needed, fput_needed_tmp; | 52 | int error = 0; |
53 | 53 | ||
54 | /* Pull information for the target fd */ | 54 | /* Pull information for the target fd */ |
55 | file = fget_light((int)sxp->sx_fdtarget, &fput_needed); | 55 | f = fdget((int)sxp->sx_fdtarget); |
56 | if (!file) { | 56 | if (!f.file) { |
57 | error = XFS_ERROR(EINVAL); | 57 | error = XFS_ERROR(EINVAL); |
58 | goto out; | 58 | goto out; |
59 | } | 59 | } |
60 | 60 | ||
61 | if (!(file->f_mode & FMODE_WRITE) || | 61 | if (!(f.file->f_mode & FMODE_WRITE) || |
62 | !(file->f_mode & FMODE_READ) || | 62 | !(f.file->f_mode & FMODE_READ) || |
63 | (file->f_flags & O_APPEND)) { | 63 | (f.file->f_flags & O_APPEND)) { |
64 | error = XFS_ERROR(EBADF); | 64 | error = XFS_ERROR(EBADF); |
65 | goto out_put_file; | 65 | goto out_put_file; |
66 | } | 66 | } |
67 | 67 | ||
68 | tmp_file = fget_light((int)sxp->sx_fdtmp, &fput_needed_tmp); | 68 | tmp = fdget((int)sxp->sx_fdtmp); |
69 | if (!tmp_file) { | 69 | if (!tmp.file) { |
70 | error = XFS_ERROR(EINVAL); | 70 | error = XFS_ERROR(EINVAL); |
71 | goto out_put_file; | 71 | goto out_put_file; |
72 | } | 72 | } |
73 | 73 | ||
74 | if (!(tmp_file->f_mode & FMODE_WRITE) || | 74 | if (!(tmp.file->f_mode & FMODE_WRITE) || |
75 | !(tmp_file->f_mode & FMODE_READ) || | 75 | !(tmp.file->f_mode & FMODE_READ) || |
76 | (tmp_file->f_flags & O_APPEND)) { | 76 | (tmp.file->f_flags & O_APPEND)) { |
77 | error = XFS_ERROR(EBADF); | 77 | error = XFS_ERROR(EBADF); |
78 | goto out_put_tmp_file; | 78 | goto out_put_tmp_file; |
79 | } | 79 | } |
80 | 80 | ||
81 | if (IS_SWAPFILE(file->f_path.dentry->d_inode) || | 81 | if (IS_SWAPFILE(f.file->f_path.dentry->d_inode) || |
82 | IS_SWAPFILE(tmp_file->f_path.dentry->d_inode)) { | 82 | IS_SWAPFILE(tmp.file->f_path.dentry->d_inode)) { |
83 | error = XFS_ERROR(EINVAL); | 83 | error = XFS_ERROR(EINVAL); |
84 | goto out_put_tmp_file; | 84 | goto out_put_tmp_file; |
85 | } | 85 | } |
86 | 86 | ||
87 | ip = XFS_I(file->f_path.dentry->d_inode); | 87 | ip = XFS_I(f.file->f_path.dentry->d_inode); |
88 | tip = XFS_I(tmp_file->f_path.dentry->d_inode); | 88 | tip = XFS_I(tmp.file->f_path.dentry->d_inode); |
89 | 89 | ||
90 | if (ip->i_mount != tip->i_mount) { | 90 | if (ip->i_mount != tip->i_mount) { |
91 | error = XFS_ERROR(EINVAL); | 91 | error = XFS_ERROR(EINVAL); |
@@ -105,9 +105,9 @@ xfs_swapext( | |||
105 | error = xfs_swap_extents(ip, tip, sxp); | 105 | error = xfs_swap_extents(ip, tip, sxp); |
106 | 106 | ||
107 | out_put_tmp_file: | 107 | out_put_tmp_file: |
108 | fput_light(tmp_file, fput_needed_tmp); | 108 | fdput(tmp); |
109 | out_put_file: | 109 | out_put_file: |
110 | fput_light(file, fput_needed); | 110 | fdput(f); |
111 | out: | 111 | out: |
112 | return error; | 112 | return error; |
113 | } | 113 | } |
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 21483eac402d..8305f2ac6773 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
@@ -70,16 +70,16 @@ xfs_find_handle( | |||
70 | int hsize; | 70 | int hsize; |
71 | xfs_handle_t handle; | 71 | xfs_handle_t handle; |
72 | struct inode *inode; | 72 | struct inode *inode; |
73 | struct file *file = NULL; | 73 | struct fd f; |
74 | struct path path; | 74 | struct path path; |
75 | int error, fput_needed; | 75 | int error; |
76 | struct xfs_inode *ip; | 76 | struct xfs_inode *ip; |
77 | 77 | ||
78 | if (cmd == XFS_IOC_FD_TO_HANDLE) { | 78 | if (cmd == XFS_IOC_FD_TO_HANDLE) { |
79 | file = fget_light(hreq->fd, &fput_needed); | 79 | f = fdget(hreq->fd); |
80 | if (!file) | 80 | if (!f.file) |
81 | return -EBADF; | 81 | return -EBADF; |
82 | inode = file->f_path.dentry->d_inode; | 82 | inode = f.file->f_path.dentry->d_inode; |
83 | } else { | 83 | } else { |
84 | error = user_lpath((const char __user *)hreq->path, &path); | 84 | error = user_lpath((const char __user *)hreq->path, &path); |
85 | if (error) | 85 | if (error) |
@@ -134,7 +134,7 @@ xfs_find_handle( | |||
134 | 134 | ||
135 | out_put: | 135 | out_put: |
136 | if (cmd == XFS_IOC_FD_TO_HANDLE) | 136 | if (cmd == XFS_IOC_FD_TO_HANDLE) |
137 | fput_light(file, fput_needed); | 137 | fdput(f); |
138 | else | 138 | else |
139 | path_put(&path); | 139 | path_put(&path); |
140 | return error; | 140 | return error; |
diff --git a/include/linux/file.h b/include/linux/file.h index c38bfbff4647..cbacf4faf447 100644 --- a/include/linux/file.h +++ b/include/linux/file.h | |||
@@ -47,6 +47,9 @@ static inline struct fd fdget(unsigned int fd) | |||
47 | return (struct fd){f,b}; | 47 | return (struct fd){f,b}; |
48 | } | 48 | } |
49 | 49 | ||
50 | extern struct file *fget_raw(unsigned int fd); | ||
51 | extern struct file *fget_raw_light(unsigned int fd, int *fput_needed); | ||
52 | |||
50 | static inline struct fd fdget_raw(unsigned int fd) | 53 | static inline struct fd fdget_raw(unsigned int fd) |
51 | { | 54 | { |
52 | int b; | 55 | int b; |
@@ -54,8 +57,6 @@ static inline struct fd fdget_raw(unsigned int fd) | |||
54 | return (struct fd){f,b}; | 57 | return (struct fd){f,b}; |
55 | } | 58 | } |
56 | 59 | ||
57 | extern struct file *fget_raw(unsigned int fd); | ||
58 | extern struct file *fget_raw_light(unsigned int fd, int *fput_needed); | ||
59 | extern int f_dupfd(unsigned int from, struct file *file, unsigned flags); | 60 | extern int f_dupfd(unsigned int from, struct file *file, unsigned flags); |
60 | extern int replace_fd(unsigned fd, struct file *file, unsigned flags); | 61 | extern int replace_fd(unsigned fd, struct file *file, unsigned flags); |
61 | extern void set_close_on_exec(unsigned int fd, int flag); | 62 | extern void set_close_on_exec(unsigned int fd, int flag); |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 5db1b69500fd..6d255e535d03 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -944,7 +944,7 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, | |||
944 | size_t, msg_len, unsigned int, msg_prio, | 944 | size_t, msg_len, unsigned int, msg_prio, |
945 | const struct timespec __user *, u_abs_timeout) | 945 | const struct timespec __user *, u_abs_timeout) |
946 | { | 946 | { |
947 | struct file *filp; | 947 | struct fd f; |
948 | struct inode *inode; | 948 | struct inode *inode; |
949 | struct ext_wait_queue wait; | 949 | struct ext_wait_queue wait; |
950 | struct ext_wait_queue *receiver; | 950 | struct ext_wait_queue *receiver; |
@@ -953,7 +953,7 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, | |||
953 | ktime_t expires, *timeout = NULL; | 953 | ktime_t expires, *timeout = NULL; |
954 | struct timespec ts; | 954 | struct timespec ts; |
955 | struct posix_msg_tree_node *new_leaf = NULL; | 955 | struct posix_msg_tree_node *new_leaf = NULL; |
956 | int ret = 0, fput_needed; | 956 | int ret = 0; |
957 | 957 | ||
958 | if (u_abs_timeout) { | 958 | if (u_abs_timeout) { |
959 | int res = prepare_timeout(u_abs_timeout, &expires, &ts); | 959 | int res = prepare_timeout(u_abs_timeout, &expires, &ts); |
@@ -967,21 +967,21 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, | |||
967 | 967 | ||
968 | audit_mq_sendrecv(mqdes, msg_len, msg_prio, timeout ? &ts : NULL); | 968 | audit_mq_sendrecv(mqdes, msg_len, msg_prio, timeout ? &ts : NULL); |
969 | 969 | ||
970 | filp = fget_light(mqdes, &fput_needed); | 970 | f = fdget(mqdes); |
971 | if (unlikely(!filp)) { | 971 | if (unlikely(!f.file)) { |
972 | ret = -EBADF; | 972 | ret = -EBADF; |
973 | goto out; | 973 | goto out; |
974 | } | 974 | } |
975 | 975 | ||
976 | inode = filp->f_path.dentry->d_inode; | 976 | inode = f.file->f_path.dentry->d_inode; |
977 | if (unlikely(filp->f_op != &mqueue_file_operations)) { | 977 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { |
978 | ret = -EBADF; | 978 | ret = -EBADF; |
979 | goto out_fput; | 979 | goto out_fput; |
980 | } | 980 | } |
981 | info = MQUEUE_I(inode); | 981 | info = MQUEUE_I(inode); |
982 | audit_inode(NULL, filp->f_path.dentry); | 982 | audit_inode(NULL, f.file->f_path.dentry); |
983 | 983 | ||
984 | if (unlikely(!(filp->f_mode & FMODE_WRITE))) { | 984 | if (unlikely(!(f.file->f_mode & FMODE_WRITE))) { |
985 | ret = -EBADF; | 985 | ret = -EBADF; |
986 | goto out_fput; | 986 | goto out_fput; |
987 | } | 987 | } |
@@ -1023,7 +1023,7 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, | |||
1023 | } | 1023 | } |
1024 | 1024 | ||
1025 | if (info->attr.mq_curmsgs == info->attr.mq_maxmsg) { | 1025 | if (info->attr.mq_curmsgs == info->attr.mq_maxmsg) { |
1026 | if (filp->f_flags & O_NONBLOCK) { | 1026 | if (f.file->f_flags & O_NONBLOCK) { |
1027 | ret = -EAGAIN; | 1027 | ret = -EAGAIN; |
1028 | } else { | 1028 | } else { |
1029 | wait.task = current; | 1029 | wait.task = current; |
@@ -1056,7 +1056,7 @@ out_free: | |||
1056 | if (ret) | 1056 | if (ret) |
1057 | free_msg(msg_ptr); | 1057 | free_msg(msg_ptr); |
1058 | out_fput: | 1058 | out_fput: |
1059 | fput_light(filp, fput_needed); | 1059 | fdput(f); |
1060 | out: | 1060 | out: |
1061 | return ret; | 1061 | return ret; |
1062 | } | 1062 | } |
@@ -1067,14 +1067,13 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, | |||
1067 | { | 1067 | { |
1068 | ssize_t ret; | 1068 | ssize_t ret; |
1069 | struct msg_msg *msg_ptr; | 1069 | struct msg_msg *msg_ptr; |
1070 | struct file *filp; | 1070 | struct fd f; |
1071 | struct inode *inode; | 1071 | struct inode *inode; |
1072 | struct mqueue_inode_info *info; | 1072 | struct mqueue_inode_info *info; |
1073 | struct ext_wait_queue wait; | 1073 | struct ext_wait_queue wait; |
1074 | ktime_t expires, *timeout = NULL; | 1074 | ktime_t expires, *timeout = NULL; |
1075 | struct timespec ts; | 1075 | struct timespec ts; |
1076 | struct posix_msg_tree_node *new_leaf = NULL; | 1076 | struct posix_msg_tree_node *new_leaf = NULL; |
1077 | int fput_needed; | ||
1078 | 1077 | ||
1079 | if (u_abs_timeout) { | 1078 | if (u_abs_timeout) { |
1080 | int res = prepare_timeout(u_abs_timeout, &expires, &ts); | 1079 | int res = prepare_timeout(u_abs_timeout, &expires, &ts); |
@@ -1085,21 +1084,21 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, | |||
1085 | 1084 | ||
1086 | audit_mq_sendrecv(mqdes, msg_len, 0, timeout ? &ts : NULL); | 1085 | audit_mq_sendrecv(mqdes, msg_len, 0, timeout ? &ts : NULL); |
1087 | 1086 | ||
1088 | filp = fget_light(mqdes, &fput_needed); | 1087 | f = fdget(mqdes); |
1089 | if (unlikely(!filp)) { | 1088 | if (unlikely(!f.file)) { |
1090 | ret = -EBADF; | 1089 | ret = -EBADF; |
1091 | goto out; | 1090 | goto out; |
1092 | } | 1091 | } |
1093 | 1092 | ||
1094 | inode = filp->f_path.dentry->d_inode; | 1093 | inode = f.file->f_path.dentry->d_inode; |
1095 | if (unlikely(filp->f_op != &mqueue_file_operations)) { | 1094 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { |
1096 | ret = -EBADF; | 1095 | ret = -EBADF; |
1097 | goto out_fput; | 1096 | goto out_fput; |
1098 | } | 1097 | } |
1099 | info = MQUEUE_I(inode); | 1098 | info = MQUEUE_I(inode); |
1100 | audit_inode(NULL, filp->f_path.dentry); | 1099 | audit_inode(NULL, f.file->f_path.dentry); |
1101 | 1100 | ||
1102 | if (unlikely(!(filp->f_mode & FMODE_READ))) { | 1101 | if (unlikely(!(f.file->f_mode & FMODE_READ))) { |
1103 | ret = -EBADF; | 1102 | ret = -EBADF; |
1104 | goto out_fput; | 1103 | goto out_fput; |
1105 | } | 1104 | } |
@@ -1131,7 +1130,7 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, | |||
1131 | } | 1130 | } |
1132 | 1131 | ||
1133 | if (info->attr.mq_curmsgs == 0) { | 1132 | if (info->attr.mq_curmsgs == 0) { |
1134 | if (filp->f_flags & O_NONBLOCK) { | 1133 | if (f.file->f_flags & O_NONBLOCK) { |
1135 | spin_unlock(&info->lock); | 1134 | spin_unlock(&info->lock); |
1136 | ret = -EAGAIN; | 1135 | ret = -EAGAIN; |
1137 | } else { | 1136 | } else { |
@@ -1161,7 +1160,7 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, | |||
1161 | free_msg(msg_ptr); | 1160 | free_msg(msg_ptr); |
1162 | } | 1161 | } |
1163 | out_fput: | 1162 | out_fput: |
1164 | fput_light(filp, fput_needed); | 1163 | fdput(f); |
1165 | out: | 1164 | out: |
1166 | return ret; | 1165 | return ret; |
1167 | } | 1166 | } |
@@ -1174,8 +1173,8 @@ out: | |||
1174 | SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes, | 1173 | SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes, |
1175 | const struct sigevent __user *, u_notification) | 1174 | const struct sigevent __user *, u_notification) |
1176 | { | 1175 | { |
1177 | int ret, fput_needed; | 1176 | int ret; |
1178 | struct file *filp; | 1177 | struct fd f; |
1179 | struct sock *sock; | 1178 | struct sock *sock; |
1180 | struct inode *inode; | 1179 | struct inode *inode; |
1181 | struct sigevent notification; | 1180 | struct sigevent notification; |
@@ -1221,13 +1220,13 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes, | |||
1221 | skb_put(nc, NOTIFY_COOKIE_LEN); | 1220 | skb_put(nc, NOTIFY_COOKIE_LEN); |
1222 | /* and attach it to the socket */ | 1221 | /* and attach it to the socket */ |
1223 | retry: | 1222 | retry: |
1224 | filp = fget_light(notification.sigev_signo, &fput_needed); | 1223 | f = fdget(notification.sigev_signo); |
1225 | if (!filp) { | 1224 | if (!f.file) { |
1226 | ret = -EBADF; | 1225 | ret = -EBADF; |
1227 | goto out; | 1226 | goto out; |
1228 | } | 1227 | } |
1229 | sock = netlink_getsockbyfilp(filp); | 1228 | sock = netlink_getsockbyfilp(f.file); |
1230 | fput_light(filp, fput_needed); | 1229 | fdput(f); |
1231 | if (IS_ERR(sock)) { | 1230 | if (IS_ERR(sock)) { |
1232 | ret = PTR_ERR(sock); | 1231 | ret = PTR_ERR(sock); |
1233 | sock = NULL; | 1232 | sock = NULL; |
@@ -1246,14 +1245,14 @@ retry: | |||
1246 | } | 1245 | } |
1247 | } | 1246 | } |
1248 | 1247 | ||
1249 | filp = fget_light(mqdes, &fput_needed); | 1248 | f = fdget(mqdes); |
1250 | if (!filp) { | 1249 | if (!f.file) { |
1251 | ret = -EBADF; | 1250 | ret = -EBADF; |
1252 | goto out; | 1251 | goto out; |
1253 | } | 1252 | } |
1254 | 1253 | ||
1255 | inode = filp->f_path.dentry->d_inode; | 1254 | inode = f.file->f_path.dentry->d_inode; |
1256 | if (unlikely(filp->f_op != &mqueue_file_operations)) { | 1255 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { |
1257 | ret = -EBADF; | 1256 | ret = -EBADF; |
1258 | goto out_fput; | 1257 | goto out_fput; |
1259 | } | 1258 | } |
@@ -1293,7 +1292,7 @@ retry: | |||
1293 | } | 1292 | } |
1294 | spin_unlock(&info->lock); | 1293 | spin_unlock(&info->lock); |
1295 | out_fput: | 1294 | out_fput: |
1296 | fput_light(filp, fput_needed); | 1295 | fdput(f); |
1297 | out: | 1296 | out: |
1298 | if (sock) { | 1297 | if (sock) { |
1299 | netlink_detachskb(sock, nc); | 1298 | netlink_detachskb(sock, nc); |
@@ -1309,8 +1308,7 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes, | |||
1309 | { | 1308 | { |
1310 | int ret; | 1309 | int ret; |
1311 | struct mq_attr mqstat, omqstat; | 1310 | struct mq_attr mqstat, omqstat; |
1312 | int fput_needed; | 1311 | struct fd f; |
1313 | struct file *filp; | ||
1314 | struct inode *inode; | 1312 | struct inode *inode; |
1315 | struct mqueue_inode_info *info; | 1313 | struct mqueue_inode_info *info; |
1316 | 1314 | ||
@@ -1321,14 +1319,14 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes, | |||
1321 | return -EINVAL; | 1319 | return -EINVAL; |
1322 | } | 1320 | } |
1323 | 1321 | ||
1324 | filp = fget_light(mqdes, &fput_needed); | 1322 | f = fdget(mqdes); |
1325 | if (!filp) { | 1323 | if (!f.file) { |
1326 | ret = -EBADF; | 1324 | ret = -EBADF; |
1327 | goto out; | 1325 | goto out; |
1328 | } | 1326 | } |
1329 | 1327 | ||
1330 | inode = filp->f_path.dentry->d_inode; | 1328 | inode = f.file->f_path.dentry->d_inode; |
1331 | if (unlikely(filp->f_op != &mqueue_file_operations)) { | 1329 | if (unlikely(f.file->f_op != &mqueue_file_operations)) { |
1332 | ret = -EBADF; | 1330 | ret = -EBADF; |
1333 | goto out_fput; | 1331 | goto out_fput; |
1334 | } | 1332 | } |
@@ -1337,15 +1335,15 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes, | |||
1337 | spin_lock(&info->lock); | 1335 | spin_lock(&info->lock); |
1338 | 1336 | ||
1339 | omqstat = info->attr; | 1337 | omqstat = info->attr; |
1340 | omqstat.mq_flags = filp->f_flags & O_NONBLOCK; | 1338 | omqstat.mq_flags = f.file->f_flags & O_NONBLOCK; |
1341 | if (u_mqstat) { | 1339 | if (u_mqstat) { |
1342 | audit_mq_getsetattr(mqdes, &mqstat); | 1340 | audit_mq_getsetattr(mqdes, &mqstat); |
1343 | spin_lock(&filp->f_lock); | 1341 | spin_lock(&f.file->f_lock); |
1344 | if (mqstat.mq_flags & O_NONBLOCK) | 1342 | if (mqstat.mq_flags & O_NONBLOCK) |
1345 | filp->f_flags |= O_NONBLOCK; | 1343 | f.file->f_flags |= O_NONBLOCK; |
1346 | else | 1344 | else |
1347 | filp->f_flags &= ~O_NONBLOCK; | 1345 | f.file->f_flags &= ~O_NONBLOCK; |
1348 | spin_unlock(&filp->f_lock); | 1346 | spin_unlock(&f.file->f_lock); |
1349 | 1347 | ||
1350 | inode->i_atime = inode->i_ctime = CURRENT_TIME; | 1348 | inode->i_atime = inode->i_ctime = CURRENT_TIME; |
1351 | } | 1349 | } |
@@ -1358,7 +1356,7 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes, | |||
1358 | ret = -EFAULT; | 1356 | ret = -EFAULT; |
1359 | 1357 | ||
1360 | out_fput: | 1358 | out_fput: |
1361 | fput_light(filp, fput_needed); | 1359 | fdput(f); |
1362 | out: | 1360 | out: |
1363 | return ret; | 1361 | return ret; |
1364 | } | 1362 | } |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 2bd199bfaef8..bd9c5bca42ae 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -467,14 +467,13 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, | |||
467 | { | 467 | { |
468 | struct perf_cgroup *cgrp; | 468 | struct perf_cgroup *cgrp; |
469 | struct cgroup_subsys_state *css; | 469 | struct cgroup_subsys_state *css; |
470 | struct file *file; | 470 | struct fd f = fdget(fd); |
471 | int ret = 0, fput_needed; | 471 | int ret = 0; |
472 | 472 | ||
473 | file = fget_light(fd, &fput_needed); | 473 | if (!f.file) |
474 | if (!file) | ||
475 | return -EBADF; | 474 | return -EBADF; |
476 | 475 | ||
477 | css = cgroup_css_from_dir(file, perf_subsys_id); | 476 | css = cgroup_css_from_dir(f.file, perf_subsys_id); |
478 | if (IS_ERR(css)) { | 477 | if (IS_ERR(css)) { |
479 | ret = PTR_ERR(css); | 478 | ret = PTR_ERR(css); |
480 | goto out; | 479 | goto out; |
@@ -500,7 +499,7 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, | |||
500 | ret = -EINVAL; | 499 | ret = -EINVAL; |
501 | } | 500 | } |
502 | out: | 501 | out: |
503 | fput_light(file, fput_needed); | 502 | fdput(f); |
504 | return ret; | 503 | return ret; |
505 | } | 504 | } |
506 | 505 | ||
@@ -3233,21 +3232,18 @@ unlock: | |||
3233 | 3232 | ||
3234 | static const struct file_operations perf_fops; | 3233 | static const struct file_operations perf_fops; |
3235 | 3234 | ||
3236 | static struct file *perf_fget_light(int fd, int *fput_needed) | 3235 | static inline int perf_fget_light(int fd, struct fd *p) |
3237 | { | 3236 | { |
3238 | struct file *file; | 3237 | struct fd f = fdget(fd); |
3239 | 3238 | if (!f.file) | |
3240 | file = fget_light(fd, fput_needed); | 3239 | return -EBADF; |
3241 | if (!file) | ||
3242 | return ERR_PTR(-EBADF); | ||
3243 | 3240 | ||
3244 | if (file->f_op != &perf_fops) { | 3241 | if (f.file->f_op != &perf_fops) { |
3245 | fput_light(file, *fput_needed); | 3242 | fdput(f); |
3246 | *fput_needed = 0; | 3243 | return -EBADF; |
3247 | return ERR_PTR(-EBADF); | ||
3248 | } | 3244 | } |
3249 | 3245 | *p = f; | |
3250 | return file; | 3246 | return 0; |
3251 | } | 3247 | } |
3252 | 3248 | ||
3253 | static int perf_event_set_output(struct perf_event *event, | 3249 | static int perf_event_set_output(struct perf_event *event, |
@@ -3279,22 +3275,19 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3279 | 3275 | ||
3280 | case PERF_EVENT_IOC_SET_OUTPUT: | 3276 | case PERF_EVENT_IOC_SET_OUTPUT: |
3281 | { | 3277 | { |
3282 | struct file *output_file = NULL; | ||
3283 | struct perf_event *output_event = NULL; | ||
3284 | int fput_needed = 0; | ||
3285 | int ret; | 3278 | int ret; |
3286 | |||
3287 | if (arg != -1) { | 3279 | if (arg != -1) { |
3288 | output_file = perf_fget_light(arg, &fput_needed); | 3280 | struct perf_event *output_event; |
3289 | if (IS_ERR(output_file)) | 3281 | struct fd output; |
3290 | return PTR_ERR(output_file); | 3282 | ret = perf_fget_light(arg, &output); |
3291 | output_event = output_file->private_data; | 3283 | if (ret) |
3284 | return ret; | ||
3285 | output_event = output.file->private_data; | ||
3286 | ret = perf_event_set_output(event, output_event); | ||
3287 | fdput(output); | ||
3288 | } else { | ||
3289 | ret = perf_event_set_output(event, NULL); | ||
3292 | } | 3290 | } |
3293 | |||
3294 | ret = perf_event_set_output(event, output_event); | ||
3295 | if (output_event) | ||
3296 | fput_light(output_file, fput_needed); | ||
3297 | |||
3298 | return ret; | 3291 | return ret; |
3299 | } | 3292 | } |
3300 | 3293 | ||
@@ -6229,12 +6222,11 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6229 | struct perf_event_attr attr; | 6222 | struct perf_event_attr attr; |
6230 | struct perf_event_context *ctx; | 6223 | struct perf_event_context *ctx; |
6231 | struct file *event_file = NULL; | 6224 | struct file *event_file = NULL; |
6232 | struct file *group_file = NULL; | 6225 | struct fd group = {NULL, 0}; |
6233 | struct task_struct *task = NULL; | 6226 | struct task_struct *task = NULL; |
6234 | struct pmu *pmu; | 6227 | struct pmu *pmu; |
6235 | int event_fd; | 6228 | int event_fd; |
6236 | int move_group = 0; | 6229 | int move_group = 0; |
6237 | int fput_needed = 0; | ||
6238 | int err; | 6230 | int err; |
6239 | 6231 | ||
6240 | /* for future expandability... */ | 6232 | /* for future expandability... */ |
@@ -6269,12 +6261,10 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6269 | return event_fd; | 6261 | return event_fd; |
6270 | 6262 | ||
6271 | if (group_fd != -1) { | 6263 | if (group_fd != -1) { |
6272 | group_file = perf_fget_light(group_fd, &fput_needed); | 6264 | err = perf_fget_light(group_fd, &group); |
6273 | if (IS_ERR(group_file)) { | 6265 | if (err) |
6274 | err = PTR_ERR(group_file); | ||
6275 | goto err_fd; | 6266 | goto err_fd; |
6276 | } | 6267 | group_leader = group.file->private_data; |
6277 | group_leader = group_file->private_data; | ||
6278 | if (flags & PERF_FLAG_FD_OUTPUT) | 6268 | if (flags & PERF_FLAG_FD_OUTPUT) |
6279 | output_event = group_leader; | 6269 | output_event = group_leader; |
6280 | if (flags & PERF_FLAG_FD_NO_GROUP) | 6270 | if (flags & PERF_FLAG_FD_NO_GROUP) |
@@ -6450,7 +6440,7 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6450 | * of the group leader will find the pointer to itself in | 6440 | * of the group leader will find the pointer to itself in |
6451 | * perf_group_detach(). | 6441 | * perf_group_detach(). |
6452 | */ | 6442 | */ |
6453 | fput_light(group_file, fput_needed); | 6443 | fdput(group); |
6454 | fd_install(event_fd, event_file); | 6444 | fd_install(event_fd, event_file); |
6455 | return event_fd; | 6445 | return event_fd; |
6456 | 6446 | ||
@@ -6464,7 +6454,7 @@ err_task: | |||
6464 | if (task) | 6454 | if (task) |
6465 | put_task_struct(task); | 6455 | put_task_struct(task); |
6466 | err_group_fd: | 6456 | err_group_fd: |
6467 | fput_light(group_file, fput_needed); | 6457 | fdput(group); |
6468 | err_fd: | 6458 | err_fd: |
6469 | put_unused_fd(event_fd); | 6459 | put_unused_fd(event_fd); |
6470 | return err; | 6460 | return err; |
diff --git a/kernel/sys.c b/kernel/sys.c index 0cb4283df884..f9492284e5d2 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1788,15 +1788,15 @@ SYSCALL_DEFINE1(umask, int, mask) | |||
1788 | #ifdef CONFIG_CHECKPOINT_RESTORE | 1788 | #ifdef CONFIG_CHECKPOINT_RESTORE |
1789 | static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) | 1789 | static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) |
1790 | { | 1790 | { |
1791 | struct file *exe_file; | 1791 | struct fd exe; |
1792 | struct dentry *dentry; | 1792 | struct dentry *dentry; |
1793 | int err, fput_needed; | 1793 | int err; |
1794 | 1794 | ||
1795 | exe_file = fget_light(fd, &fput_needed); | 1795 | exe = fdget(fd); |
1796 | if (!exe_file) | 1796 | if (!exe.file) |
1797 | return -EBADF; | 1797 | return -EBADF; |
1798 | 1798 | ||
1799 | dentry = exe_file->f_path.dentry; | 1799 | dentry = exe.file->f_path.dentry; |
1800 | 1800 | ||
1801 | /* | 1801 | /* |
1802 | * Because the original mm->exe_file points to executable file, make | 1802 | * Because the original mm->exe_file points to executable file, make |
@@ -1805,7 +1805,7 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) | |||
1805 | */ | 1805 | */ |
1806 | err = -EACCES; | 1806 | err = -EACCES; |
1807 | if (!S_ISREG(dentry->d_inode->i_mode) || | 1807 | if (!S_ISREG(dentry->d_inode->i_mode) || |
1808 | exe_file->f_path.mnt->mnt_flags & MNT_NOEXEC) | 1808 | exe.file->f_path.mnt->mnt_flags & MNT_NOEXEC) |
1809 | goto exit; | 1809 | goto exit; |
1810 | 1810 | ||
1811 | err = inode_permission(dentry->d_inode, MAY_EXEC); | 1811 | err = inode_permission(dentry->d_inode, MAY_EXEC); |
@@ -1839,12 +1839,12 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) | |||
1839 | goto exit_unlock; | 1839 | goto exit_unlock; |
1840 | 1840 | ||
1841 | err = 0; | 1841 | err = 0; |
1842 | set_mm_exe_file(mm, exe_file); /* this grabs a reference to exe_file */ | 1842 | set_mm_exe_file(mm, exe.file); /* this grabs a reference to exe.file */ |
1843 | exit_unlock: | 1843 | exit_unlock: |
1844 | up_write(&mm->mmap_sem); | 1844 | up_write(&mm->mmap_sem); |
1845 | 1845 | ||
1846 | exit: | 1846 | exit: |
1847 | fput_light(exe_file, fput_needed); | 1847 | fdput(exe); |
1848 | return err; | 1848 | return err; |
1849 | } | 1849 | } |
1850 | 1850 | ||
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index d0a32796550f..5116b7e5962e 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
@@ -415,16 +415,15 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | |||
415 | struct nlattr *na; | 415 | struct nlattr *na; |
416 | size_t size; | 416 | size_t size; |
417 | u32 fd; | 417 | u32 fd; |
418 | struct file *file; | 418 | struct fd f; |
419 | int fput_needed; | ||
420 | 419 | ||
421 | na = info->attrs[CGROUPSTATS_CMD_ATTR_FD]; | 420 | na = info->attrs[CGROUPSTATS_CMD_ATTR_FD]; |
422 | if (!na) | 421 | if (!na) |
423 | return -EINVAL; | 422 | return -EINVAL; |
424 | 423 | ||
425 | fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]); | 424 | fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]); |
426 | file = fget_light(fd, &fput_needed); | 425 | f = fdget(fd); |
427 | if (!file) | 426 | if (!f.file) |
428 | return 0; | 427 | return 0; |
429 | 428 | ||
430 | size = nla_total_size(sizeof(struct cgroupstats)); | 429 | size = nla_total_size(sizeof(struct cgroupstats)); |
@@ -444,7 +443,7 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | |||
444 | stats = nla_data(na); | 443 | stats = nla_data(na); |
445 | memset(stats, 0, sizeof(*stats)); | 444 | memset(stats, 0, sizeof(*stats)); |
446 | 445 | ||
447 | rc = cgroupstats_build(stats, file->f_dentry); | 446 | rc = cgroupstats_build(stats, f.file->f_dentry); |
448 | if (rc < 0) { | 447 | if (rc < 0) { |
449 | nlmsg_free(rep_skb); | 448 | nlmsg_free(rep_skb); |
450 | goto err; | 449 | goto err; |
@@ -453,7 +452,7 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | |||
453 | rc = send_reply(rep_skb, info); | 452 | rc = send_reply(rep_skb, info); |
454 | 453 | ||
455 | err: | 454 | err: |
456 | fput_light(file, fput_needed); | 455 | fdput(f); |
457 | return rc; | 456 | return rc; |
458 | } | 457 | } |
459 | 458 | ||
diff --git a/mm/fadvise.c b/mm/fadvise.c index a83245763cf8..a47f0f50c89f 100644 --- a/mm/fadvise.c +++ b/mm/fadvise.c | |||
@@ -26,8 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) | 27 | SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) |
28 | { | 28 | { |
29 | int fput_needed; | 29 | struct fd f = fdget(fd); |
30 | struct file *file = fget_light(fd, &fput_needed); | ||
31 | struct address_space *mapping; | 30 | struct address_space *mapping; |
32 | struct backing_dev_info *bdi; | 31 | struct backing_dev_info *bdi; |
33 | loff_t endbyte; /* inclusive */ | 32 | loff_t endbyte; /* inclusive */ |
@@ -36,15 +35,15 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) | |||
36 | unsigned long nrpages; | 35 | unsigned long nrpages; |
37 | int ret = 0; | 36 | int ret = 0; |
38 | 37 | ||
39 | if (!file) | 38 | if (!f.file) |
40 | return -EBADF; | 39 | return -EBADF; |
41 | 40 | ||
42 | if (S_ISFIFO(file->f_path.dentry->d_inode->i_mode)) { | 41 | if (S_ISFIFO(f.file->f_path.dentry->d_inode->i_mode)) { |
43 | ret = -ESPIPE; | 42 | ret = -ESPIPE; |
44 | goto out; | 43 | goto out; |
45 | } | 44 | } |
46 | 45 | ||
47 | mapping = file->f_mapping; | 46 | mapping = f.file->f_mapping; |
48 | if (!mapping || len < 0) { | 47 | if (!mapping || len < 0) { |
49 | ret = -EINVAL; | 48 | ret = -EINVAL; |
50 | goto out; | 49 | goto out; |
@@ -77,21 +76,21 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) | |||
77 | 76 | ||
78 | switch (advice) { | 77 | switch (advice) { |
79 | case POSIX_FADV_NORMAL: | 78 | case POSIX_FADV_NORMAL: |
80 | file->f_ra.ra_pages = bdi->ra_pages; | 79 | f.file->f_ra.ra_pages = bdi->ra_pages; |
81 | spin_lock(&file->f_lock); | 80 | spin_lock(&f.file->f_lock); |
82 | file->f_mode &= ~FMODE_RANDOM; | 81 | f.file->f_mode &= ~FMODE_RANDOM; |
83 | spin_unlock(&file->f_lock); | 82 | spin_unlock(&f.file->f_lock); |
84 | break; | 83 | break; |
85 | case POSIX_FADV_RANDOM: | 84 | case POSIX_FADV_RANDOM: |
86 | spin_lock(&file->f_lock); | 85 | spin_lock(&f.file->f_lock); |
87 | file->f_mode |= FMODE_RANDOM; | 86 | f.file->f_mode |= FMODE_RANDOM; |
88 | spin_unlock(&file->f_lock); | 87 | spin_unlock(&f.file->f_lock); |
89 | break; | 88 | break; |
90 | case POSIX_FADV_SEQUENTIAL: | 89 | case POSIX_FADV_SEQUENTIAL: |
91 | file->f_ra.ra_pages = bdi->ra_pages * 2; | 90 | f.file->f_ra.ra_pages = bdi->ra_pages * 2; |
92 | spin_lock(&file->f_lock); | 91 | spin_lock(&f.file->f_lock); |
93 | file->f_mode &= ~FMODE_RANDOM; | 92 | f.file->f_mode &= ~FMODE_RANDOM; |
94 | spin_unlock(&file->f_lock); | 93 | spin_unlock(&f.file->f_lock); |
95 | break; | 94 | break; |
96 | case POSIX_FADV_WILLNEED: | 95 | case POSIX_FADV_WILLNEED: |
97 | /* First and last PARTIAL page! */ | 96 | /* First and last PARTIAL page! */ |
@@ -107,7 +106,7 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) | |||
107 | * Ignore return value because fadvise() shall return | 106 | * Ignore return value because fadvise() shall return |
108 | * success even if filesystem can't retrieve a hint, | 107 | * success even if filesystem can't retrieve a hint, |
109 | */ | 108 | */ |
110 | force_page_cache_readahead(mapping, file, start_index, | 109 | force_page_cache_readahead(mapping, f.file, start_index, |
111 | nrpages); | 110 | nrpages); |
112 | break; | 111 | break; |
113 | case POSIX_FADV_NOREUSE: | 112 | case POSIX_FADV_NOREUSE: |
@@ -129,7 +128,7 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) | |||
129 | ret = -EINVAL; | 128 | ret = -EINVAL; |
130 | } | 129 | } |
131 | out: | 130 | out: |
132 | fput_light(file, fput_needed); | 131 | fdput(f); |
133 | return ret; | 132 | return ret; |
134 | } | 133 | } |
135 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | 134 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS |
diff --git a/mm/readahead.c b/mm/readahead.c index 1011111e2bf4..7963f2391236 100644 --- a/mm/readahead.c +++ b/mm/readahead.c | |||
@@ -579,20 +579,19 @@ do_readahead(struct address_space *mapping, struct file *filp, | |||
579 | SYSCALL_DEFINE(readahead)(int fd, loff_t offset, size_t count) | 579 | SYSCALL_DEFINE(readahead)(int fd, loff_t offset, size_t count) |
580 | { | 580 | { |
581 | ssize_t ret; | 581 | ssize_t ret; |
582 | struct file *file; | 582 | struct fd f; |
583 | int fput_needed; | ||
584 | 583 | ||
585 | ret = -EBADF; | 584 | ret = -EBADF; |
586 | file = fget_light(fd, &fput_needed); | 585 | f = fdget(fd); |
587 | if (file) { | 586 | if (f.file) { |
588 | if (file->f_mode & FMODE_READ) { | 587 | if (f.file->f_mode & FMODE_READ) { |
589 | struct address_space *mapping = file->f_mapping; | 588 | struct address_space *mapping = f.file->f_mapping; |
590 | pgoff_t start = offset >> PAGE_CACHE_SHIFT; | 589 | pgoff_t start = offset >> PAGE_CACHE_SHIFT; |
591 | pgoff_t end = (offset + count - 1) >> PAGE_CACHE_SHIFT; | 590 | pgoff_t end = (offset + count - 1) >> PAGE_CACHE_SHIFT; |
592 | unsigned long len = end - start + 1; | 591 | unsigned long len = end - start + 1; |
593 | ret = do_readahead(mapping, file, start, len); | 592 | ret = do_readahead(mapping, f.file, start, len); |
594 | } | 593 | } |
595 | fput_light(file, fput_needed); | 594 | fdput(f); |
596 | } | 595 | } |
597 | return ret; | 596 | return ret; |
598 | } | 597 | } |