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 | } |
