switch simple cases of fget_light to fdget

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro
2012-08-28 12:52:22 -04:00
parent a5b470ba06
commit 2903ff019b
44 changed files with 631 additions and 761 deletions

View File

@@ -144,28 +144,25 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
struct osf_dirent __user *, dirent, unsigned int, count, struct osf_dirent __user *, dirent, unsigned int, count,
long __user *, basep) long __user *, basep)
{ {
int error, fput_needed; int error;
struct file *file; struct fd arg = fdget(fd);
struct osf_dirent_callback buf; struct osf_dirent_callback buf;
error = -EBADF; if (!arg.file)
file = fget_light(fd, &fput_needed); return -EBADF;
if (!file)
goto out;
buf.dirent = dirent; buf.dirent = dirent;
buf.basep = basep; buf.basep = basep;
buf.count = count; buf.count = count;
buf.error = 0; buf.error = 0;
error = vfs_readdir(file, osf_filldir, &buf); error = vfs_readdir(arg.file, osf_filldir, &buf);
if (error >= 0) if (error >= 0)
error = buf.error; error = buf.error;
if (count != buf.count) if (count != buf.count)
error = count - buf.count; error = count - buf.count;
fput_light(file, fput_needed); fdput(arg);
out:
return error; return error;
} }

View File

@@ -4780,7 +4780,7 @@ recheck:
asmlinkage long asmlinkage long
sys_perfmonctl (int fd, int cmd, void __user *arg, int count) sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
{ {
struct file *file = NULL; struct fd f = {NULL, 0};
pfm_context_t *ctx = NULL; pfm_context_t *ctx = NULL;
unsigned long flags = 0UL; unsigned long flags = 0UL;
void *args_k = NULL; void *args_k = NULL;
@@ -4789,7 +4789,6 @@ sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
int narg, completed_args = 0, call_made = 0, cmd_flags; int narg, completed_args = 0, call_made = 0, cmd_flags;
int (*func)(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); int (*func)(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
int (*getsize)(void *arg, size_t *sz); int (*getsize)(void *arg, size_t *sz);
int fput_needed;
#define PFM_MAX_ARGSIZE 4096 #define PFM_MAX_ARGSIZE 4096
/* /*
@@ -4878,17 +4877,17 @@ restart_args:
ret = -EBADF; ret = -EBADF;
file = fget_light(fd, &fput_needed); f = fdget(fd);
if (unlikely(file == NULL)) { if (unlikely(f.file == NULL)) {
DPRINT(("invalid fd %d\n", fd)); DPRINT(("invalid fd %d\n", fd));
goto error_args; goto error_args;
} }
if (unlikely(PFM_IS_FILE(file) == 0)) { if (unlikely(PFM_IS_FILE(f.file) == 0)) {
DPRINT(("fd %d not related to perfmon\n", fd)); DPRINT(("fd %d not related to perfmon\n", fd));
goto error_args; goto error_args;
} }
ctx = file->private_data; ctx = f.file->private_data;
if (unlikely(ctx == NULL)) { if (unlikely(ctx == NULL)) {
DPRINT(("no context for fd %d\n", fd)); DPRINT(("no context for fd %d\n", fd));
goto error_args; goto error_args;
@@ -4918,8 +4917,8 @@ abort_locked:
if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT; if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
error_args: error_args:
if (file) if (f.file)
fput_light(file, fput_needed); fdput(f);
kfree(args_k); kfree(args_k);

View File

@@ -109,33 +109,32 @@ Efault:
int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count) int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count)
{ {
struct file * file; struct fd arg;
struct hpux_dirent __user * lastdirent; struct hpux_dirent __user * lastdirent;
struct getdents_callback buf; struct getdents_callback buf;
int error = -EBADF, fput_needed; int error;
file = fget_light(fd, &fput_needed); arg = fdget(fd);
if (!file) if (!arg.file)
goto out; return -EBADF;
buf.current_dir = dirent; buf.current_dir = dirent;
buf.previous = NULL; buf.previous = NULL;
buf.count = count; buf.count = count;
buf.error = 0; buf.error = 0;
error = vfs_readdir(file, filldir, &buf); error = vfs_readdir(arg.file, filldir, &buf);
if (error >= 0) if (error >= 0)
error = buf.error; error = buf.error;
lastdirent = buf.previous; lastdirent = buf.previous;
if (lastdirent) { if (lastdirent) {
if (put_user(file->f_pos, &lastdirent->d_off)) if (put_user(arg.file->f_pos, &lastdirent->d_off))
error = -EFAULT; error = -EFAULT;
else else
error = count - buf.count; error = count - buf.count;
} }
fput_light(file, fput_needed); fdput(arg);
out:
return error; return error;
} }

View File

@@ -69,8 +69,6 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
umode_t, mode, int, neighbor_fd) umode_t, mode, int, neighbor_fd)
{ {
long ret; long ret;
struct file *neighbor;
int fput_needed;
struct spufs_calls *calls; struct spufs_calls *calls;
calls = spufs_calls_get(); calls = spufs_calls_get();
@@ -78,11 +76,11 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
return -ENOSYS; return -ENOSYS;
if (flags & SPU_CREATE_AFFINITY_SPU) { if (flags & SPU_CREATE_AFFINITY_SPU) {
struct fd neighbor = fdget(neighbor_fd);
ret = -EBADF; ret = -EBADF;
neighbor = fget_light(neighbor_fd, &fput_needed); if (neighbor.file) {
if (neighbor) { ret = calls->create_thread(name, flags, mode, neighbor.file);
ret = calls->create_thread(name, flags, mode, neighbor); fdput(neighbor);
fput_light(neighbor, fput_needed);
} }
} else } else
ret = calls->create_thread(name, flags, mode, NULL); ret = calls->create_thread(name, flags, mode, NULL);
@@ -94,8 +92,7 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus) asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
{ {
long ret; long ret;
struct file *filp; struct fd arg;
int fput_needed;
struct spufs_calls *calls; struct spufs_calls *calls;
calls = spufs_calls_get(); calls = spufs_calls_get();
@@ -103,10 +100,10 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
return -ENOSYS; return -ENOSYS;
ret = -EBADF; ret = -EBADF;
filp = fget_light(fd, &fput_needed); arg = fdget(fd);
if (filp) { if (arg.file) {
ret = calls->spu_run(filp, unpc, ustatus); ret = calls->spu_run(arg.file, unpc, ustatus);
fput_light(filp, fput_needed); fdput(arg);
} }
spufs_calls_put(calls); spufs_calls_put(calls);

View File

@@ -1184,20 +1184,20 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
struct rdma_ucm_migrate_id cmd; struct rdma_ucm_migrate_id cmd;
struct rdma_ucm_migrate_resp resp; struct rdma_ucm_migrate_resp resp;
struct ucma_context *ctx; struct ucma_context *ctx;
struct file *filp; struct fd f;
struct ucma_file *cur_file; struct ucma_file *cur_file;
int ret = 0, fput_needed; int ret = 0;
if (copy_from_user(&cmd, inbuf, sizeof(cmd))) if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
return -EFAULT; return -EFAULT;
/* Get current fd to protect against it being closed */ /* Get current fd to protect against it being closed */
filp = fget_light(cmd.fd, &fput_needed); f = fdget(cmd.fd);
if (!filp) if (!f.file)
return -ENOENT; return -ENOENT;
/* Validate current fd and prevent destruction of id. */ /* Validate current fd and prevent destruction of id. */
ctx = ucma_get_ctx(filp->private_data, cmd.id); ctx = ucma_get_ctx(f.file->private_data, cmd.id);
if (IS_ERR(ctx)) { if (IS_ERR(ctx)) {
ret = PTR_ERR(ctx); ret = PTR_ERR(ctx);
goto file_put; goto file_put;
@@ -1231,7 +1231,7 @@ response:
ucma_put_ctx(ctx); ucma_put_ctx(ctx);
file_put: file_put:
fput_light(filp, fput_needed); fdput(f);
return ret; return ret;
} }

View File

@@ -705,9 +705,9 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
struct ib_udata udata; struct ib_udata udata;
struct ib_uxrcd_object *obj; struct ib_uxrcd_object *obj;
struct ib_xrcd *xrcd = NULL; struct ib_xrcd *xrcd = NULL;
struct file *f = NULL; struct fd f = {NULL, 0};
struct inode *inode = NULL; struct inode *inode = NULL;
int ret = 0, fput_needed; int ret = 0;
int new_xrcd = 0; int new_xrcd = 0;
if (out_len < sizeof resp) if (out_len < sizeof resp)
@@ -724,13 +724,13 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
if (cmd.fd != -1) { if (cmd.fd != -1) {
/* search for file descriptor */ /* search for file descriptor */
f = fget_light(cmd.fd, &fput_needed); f = fdget(cmd.fd);
if (!f) { if (!f.file) {
ret = -EBADF; ret = -EBADF;
goto err_tree_mutex_unlock; goto err_tree_mutex_unlock;
} }
inode = f->f_dentry->d_inode; inode = f.file->f_path.dentry->d_inode;
xrcd = find_xrcd(file->device, inode); xrcd = find_xrcd(file->device, inode);
if (!xrcd && !(cmd.oflags & O_CREAT)) { if (!xrcd && !(cmd.oflags & O_CREAT)) {
/* no file descriptor. Need CREATE flag */ /* no file descriptor. Need CREATE flag */
@@ -795,8 +795,8 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
goto err_copy; goto err_copy;
} }
if (f) if (f.file)
fput_light(f, fput_needed); fdput(f);
mutex_lock(&file->mutex); mutex_lock(&file->mutex);
list_add_tail(&obj->uobject.list, &file->ucontext->xrcd_list); list_add_tail(&obj->uobject.list, &file->ucontext->xrcd_list);
@@ -825,8 +825,8 @@ err:
put_uobj_write(&obj->uobject); put_uobj_write(&obj->uobject);
err_tree_mutex_unlock: err_tree_mutex_unlock:
if (f) if (f.file)
fput_light(f, fput_needed); fdput(f);
mutex_unlock(&file->device->xrcd_tree_mutex); mutex_unlock(&file->device->xrcd_tree_mutex);

View File

@@ -541,17 +541,15 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd) struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd)
{ {
struct ib_uverbs_event_file *ev_file = NULL; struct ib_uverbs_event_file *ev_file = NULL;
struct file *filp; struct fd f = fdget(fd);
int fput_needed;
filp = fget_light(fd, &fput_needed); if (!f.file)
if (!filp)
return NULL; return NULL;
if (filp->f_op != &uverbs_event_fops) if (f.file->f_op != &uverbs_event_fops)
goto out; goto out;
ev_file = filp->private_data; ev_file = f.file->private_data;
if (ev_file->is_async) { if (ev_file->is_async) {
ev_file = NULL; ev_file = NULL;
goto out; goto out;
@@ -560,7 +558,7 @@ struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd)
kref_get(&ev_file->ref); kref_get(&ev_file->ref);
out: out:
fput_light(filp, fput_needed); fdput(f);
return ev_file; return ev_file;
} }

View File

@@ -1014,25 +1014,25 @@ static void vfio_group_try_dissolve_container(struct vfio_group *group)
static int vfio_group_set_container(struct vfio_group *group, int container_fd) static int vfio_group_set_container(struct vfio_group *group, int container_fd)
{ {
struct file *filep; struct fd f;
struct vfio_container *container; struct vfio_container *container;
struct vfio_iommu_driver *driver; struct vfio_iommu_driver *driver;
int ret = 0, fput_needed; int ret = 0;
if (atomic_read(&group->container_users)) if (atomic_read(&group->container_users))
return -EINVAL; return -EINVAL;
filep = fget_light(container_fd, &fput_needed); f = fdget(container_fd);
if (!filep) if (!f.file)
return -EBADF; return -EBADF;
/* Sanity check, is this really our fd? */ /* Sanity check, is this really our fd? */
if (filep->f_op != &vfio_fops) { if (f.file->f_op != &vfio_fops) {
fput_light(filep, fput_needed); fdput(f);
return -EINVAL; return -EINVAL;
} }
container = filep->private_data; container = f.file->private_data;
WARN_ON(!container); /* fget ensures we don't race vfio_release */ WARN_ON(!container); /* fget ensures we don't race vfio_release */
mutex_lock(&container->group_lock); mutex_lock(&container->group_lock);
@@ -1054,8 +1054,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
unlock_out: unlock_out:
mutex_unlock(&container->group_lock); mutex_unlock(&container->group_lock);
fput_light(filep, fput_needed); fdput(f);
return ret; return ret;
} }

View File

@@ -257,19 +257,17 @@ int get_img(struct mdp_img *img, struct fb_info *info,
unsigned long *start, unsigned long *len, unsigned long *start, unsigned long *len,
struct file **filep) struct file **filep)
{ {
int put_needed, ret = 0; int ret = 0;
struct file *file; struct fd f = fdget(img->memory_id);
if (f.file == NULL)
file = fget_light(img->memory_id, &put_needed);
if (file == NULL)
return -1; return -1;
if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) { if (MAJOR(f.file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
*start = info->fix.smem_start; *start = info->fix.smem_start;
*len = info->fix.smem_len; *len = info->fix.smem_len;
} else } else
ret = -1; ret = -1;
fput_light(file, put_needed); fdput(f);
return ret; return ret;
} }

View File

@@ -1397,7 +1397,6 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
u64 *transid, bool readonly, u64 *transid, bool readonly,
struct btrfs_qgroup_inherit **inherit) struct btrfs_qgroup_inherit **inherit)
{ {
struct file *src_file;
int namelen; int namelen;
int ret = 0; int ret = 0;
@@ -1421,15 +1420,14 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
ret = btrfs_mksubvol(&file->f_path, name, namelen, ret = btrfs_mksubvol(&file->f_path, name, namelen,
NULL, transid, readonly, inherit); NULL, transid, readonly, inherit);
} else { } else {
struct fd src = fdget(fd);
struct inode *src_inode; struct inode *src_inode;
int fput_needed; if (!src.file) {
src_file = fget_light(fd, &fput_needed);
if (!src_file) {
ret = -EINVAL; ret = -EINVAL;
goto out_drop_write; goto out_drop_write;
} }
src_inode = src_file->f_path.dentry->d_inode; src_inode = src.file->f_path.dentry->d_inode;
if (src_inode->i_sb != file->f_path.dentry->d_inode->i_sb) { if (src_inode->i_sb != file->f_path.dentry->d_inode->i_sb) {
printk(KERN_INFO "btrfs: Snapshot src from " printk(KERN_INFO "btrfs: Snapshot src from "
"another FS\n"); "another FS\n");
@@ -1439,7 +1437,7 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
BTRFS_I(src_inode)->root, BTRFS_I(src_inode)->root,
transid, readonly, inherit); transid, readonly, inherit);
} }
fput_light(src_file, fput_needed); fdput(src);
} }
out_drop_write: out_drop_write:
mnt_drop_write_file(file); mnt_drop_write_file(file);
@@ -2341,7 +2339,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
{ {
struct inode *inode = fdentry(file)->d_inode; struct inode *inode = fdentry(file)->d_inode;
struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *root = BTRFS_I(inode)->root;
struct file *src_file; struct fd src_file;
struct inode *src; struct inode *src;
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
struct btrfs_path *path; struct btrfs_path *path;
@@ -2350,7 +2348,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
struct btrfs_key key; struct btrfs_key key;
u32 nritems; u32 nritems;
int slot; int slot;
int ret, fput_needed; int ret;
u64 len = olen; u64 len = olen;
u64 bs = root->fs_info->sb->s_blocksize; u64 bs = root->fs_info->sb->s_blocksize;
u64 hint_byte; u64 hint_byte;
@@ -2376,24 +2374,24 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
if (ret) if (ret)
return ret; return ret;
src_file = fget_light(srcfd, &fput_needed); src_file = fdget(srcfd);
if (!src_file) { if (!src_file.file) {
ret = -EBADF; ret = -EBADF;
goto out_drop_write; goto out_drop_write;
} }
ret = -EXDEV; ret = -EXDEV;
if (src_file->f_path.mnt != file->f_path.mnt) if (src_file.file->f_path.mnt != file->f_path.mnt)
goto out_fput; goto out_fput;
src = src_file->f_dentry->d_inode; src = src_file.file->f_dentry->d_inode;
ret = -EINVAL; ret = -EINVAL;
if (src == inode) if (src == inode)
goto out_fput; goto out_fput;
/* the src must be open for reading */ /* the src must be open for reading */
if (!(src_file->f_mode & FMODE_READ)) if (!(src_file.file->f_mode & FMODE_READ))
goto out_fput; goto out_fput;
/* don't make the dst file partly checksummed */ /* don't make the dst file partly checksummed */
@@ -2724,7 +2722,7 @@ out_unlock:
vfree(buf); vfree(buf);
btrfs_free_path(path); btrfs_free_path(path);
out_fput: out_fput:
fput_light(src_file, fput_needed); fdput(src_file);
out_drop_write: out_drop_write:
mnt_drop_write_file(file); mnt_drop_write_file(file);
return ret; return ret;

View File

@@ -107,9 +107,9 @@ static const struct super_operations coda_super_operations =
static int get_device_index(struct coda_mount_data *data) static int get_device_index(struct coda_mount_data *data)
{ {
struct file *file; struct fd f;
struct inode *inode; struct inode *inode;
int idx, fput_needed; int idx;
if (data == NULL) { if (data == NULL) {
printk("coda_read_super: Bad mount data\n"); printk("coda_read_super: Bad mount data\n");
@@ -121,17 +121,17 @@ static int get_device_index(struct coda_mount_data *data)
return -1; return -1;
} }
file = fget_light(data->fd, &fput_needed); f = fdget(data->fd);
if (!file) if (!f.file)
goto Ebadf; goto Ebadf;
inode = file->f_path.dentry->d_inode; inode = f.file->f_path.dentry->d_inode;
if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) { if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) {
fput_light(file, fput_needed); fdput(f);
goto Ebadf; goto Ebadf;
} }
idx = iminor(inode); idx = iminor(inode);
fput_light(file, fput_needed); fdput(f);
if (idx < 0 || idx >= MAX_CODADEVS) { if (idx < 0 || idx >= MAX_CODADEVS) {
printk("coda_read_super: Bad minor number\n"); printk("coda_read_super: Bad minor number\n");

View File

@@ -870,22 +870,20 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,
struct compat_old_linux_dirent __user *dirent, unsigned int count) struct compat_old_linux_dirent __user *dirent, unsigned int count)
{ {
int error; int error;
struct file *file; struct fd f = fdget(fd);
int fput_needed;
struct compat_readdir_callback buf; struct compat_readdir_callback buf;
file = fget_light(fd, &fput_needed); if (!f.file)
if (!file)
return -EBADF; return -EBADF;
buf.result = 0; buf.result = 0;
buf.dirent = dirent; buf.dirent = dirent;
error = vfs_readdir(file, compat_fillonedir, &buf); error = vfs_readdir(f.file, compat_fillonedir, &buf);
if (buf.result) if (buf.result)
error = buf.result; error = buf.result;
fput_light(file, fput_needed); fdput(f);
return error; return error;
} }
@@ -949,17 +947,16 @@ efault:
asmlinkage long compat_sys_getdents(unsigned int fd, asmlinkage long compat_sys_getdents(unsigned int fd,
struct compat_linux_dirent __user *dirent, unsigned int count) struct compat_linux_dirent __user *dirent, unsigned int count)
{ {
struct file * file; struct fd f;
struct compat_linux_dirent __user * lastdirent; struct compat_linux_dirent __user * lastdirent;
struct compat_getdents_callback buf; struct compat_getdents_callback buf;
int fput_needed;
int error; int error;
if (!access_ok(VERIFY_WRITE, dirent, count)) if (!access_ok(VERIFY_WRITE, dirent, count))
return -EFAULT; return -EFAULT;
file = fget_light(fd, &fput_needed); f = fdget(fd);
if (!file) if (!f.file)
return -EBADF; return -EBADF;
buf.current_dir = dirent; buf.current_dir = dirent;
@@ -967,17 +964,17 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
buf.count = count; buf.count = count;
buf.error = 0; buf.error = 0;
error = vfs_readdir(file, compat_filldir, &buf); error = vfs_readdir(f.file, compat_filldir, &buf);
if (error >= 0) if (error >= 0)
error = buf.error; error = buf.error;
lastdirent = buf.previous; lastdirent = buf.previous;
if (lastdirent) { if (lastdirent) {
if (put_user(file->f_pos, &lastdirent->d_off)) if (put_user(f.file->f_pos, &lastdirent->d_off))
error = -EFAULT; error = -EFAULT;
else else
error = count - buf.count; error = count - buf.count;
} }
fput_light(file, fput_needed); fdput(f);
return error; return error;
} }
@@ -1035,17 +1032,16 @@ efault:
asmlinkage long compat_sys_getdents64(unsigned int fd, asmlinkage long compat_sys_getdents64(unsigned int fd,
struct linux_dirent64 __user * dirent, unsigned int count) struct linux_dirent64 __user * dirent, unsigned int count)
{ {
struct file * file; struct fd f;
struct linux_dirent64 __user * lastdirent; struct linux_dirent64 __user * lastdirent;
struct compat_getdents_callback64 buf; struct compat_getdents_callback64 buf;
int fput_needed;
int error; int error;
if (!access_ok(VERIFY_WRITE, dirent, count)) if (!access_ok(VERIFY_WRITE, dirent, count))
return -EFAULT; return -EFAULT;
file = fget_light(fd, &fput_needed); f = fdget(fd);
if (!file) if (!f.file)
return -EBADF; return -EBADF;
buf.current_dir = dirent; buf.current_dir = dirent;
@@ -1053,18 +1049,18 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
buf.count = count; buf.count = count;
buf.error = 0; buf.error = 0;
error = vfs_readdir(file, compat_filldir64, &buf); error = vfs_readdir(f.file, compat_filldir64, &buf);
if (error >= 0) if (error >= 0)
error = buf.error; error = buf.error;
lastdirent = buf.previous; lastdirent = buf.previous;
if (lastdirent) { if (lastdirent) {
typeof(lastdirent->d_off) d_off = file->f_pos; typeof(lastdirent->d_off) d_off = f.file->f_pos;
if (__put_user_unaligned(d_off, &lastdirent->d_off)) if (__put_user_unaligned(d_off, &lastdirent->d_off))
error = -EFAULT; error = -EFAULT;
else else
error = count - buf.count; error = count - buf.count;
} }
fput_light(file, fput_needed); fdput(f);
return error; return error;
} }
#endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */ #endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */
@@ -1152,18 +1148,16 @@ asmlinkage ssize_t
compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen) unsigned long vlen)
{ {
struct file *file; struct fd f = fdget(fd);
int fput_needed;
ssize_t ret; ssize_t ret;
loff_t pos; loff_t pos;
file = fget_light(fd, &fput_needed); if (!f.file)
if (!file)
return -EBADF; return -EBADF;
pos = file->f_pos; pos = f.file->f_pos;
ret = compat_readv(file, vec, vlen, &pos); ret = compat_readv(f.file, vec, vlen, &pos);
file->f_pos = pos; f.file->f_pos = pos;
fput_light(file, fput_needed); fdput(f);
return ret; return ret;
} }
@@ -1171,19 +1165,18 @@ asmlinkage ssize_t
compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec, compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen, loff_t pos) unsigned long vlen, loff_t pos)
{ {
struct file *file; struct fd f;
int fput_needed;
ssize_t ret; ssize_t ret;
if (pos < 0) if (pos < 0)
return -EINVAL; return -EINVAL;
file = fget_light(fd, &fput_needed); f = fdget(fd);
if (!file) if (!f.file)
return -EBADF; return -EBADF;
ret = -ESPIPE; ret = -ESPIPE;
if (file->f_mode & FMODE_PREAD) if (f.file->f_mode & FMODE_PREAD)
ret = compat_readv(file, vec, vlen, &pos); ret = compat_readv(f.file, vec, vlen, &pos);
fput_light(file, fput_needed); fdput(f);
return ret; return ret;
} }
@@ -1221,18 +1214,16 @@ asmlinkage ssize_t
compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen) unsigned long vlen)
{ {
struct file *file; struct fd f = fdget(fd);
int fput_needed;
ssize_t ret; ssize_t ret;
loff_t pos; loff_t pos;
file = fget_light(fd, &fput_needed); if (!f.file)
if (!file)
return -EBADF; return -EBADF;
pos = file->f_pos; pos = f.file->f_pos;
ret = compat_writev(file, vec, vlen, &pos); ret = compat_writev(f.file, vec, vlen, &pos);
file->f_pos = pos; f.file->f_pos = pos;
fput_light(file, fput_needed); fdput(f);
return ret; return ret;
} }
@@ -1240,19 +1231,18 @@ asmlinkage ssize_t
compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec, compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen, loff_t pos) unsigned long vlen, loff_t pos)
{ {
struct file *file; struct fd f;
int fput_needed;
ssize_t ret; ssize_t ret;
if (pos < 0) if (pos < 0)
return -EINVAL; return -EINVAL;
file = fget_light(fd, &fput_needed); f = fdget(fd);
if (!file) if (!f.file)
return -EBADF; return -EBADF;
ret = -ESPIPE; ret = -ESPIPE;
if (file->f_mode & FMODE_PWRITE) if (f.file->f_mode & FMODE_PWRITE)
ret = compat_writev(file, vec, vlen, &pos); ret = compat_writev(f.file, vec, vlen, &pos);
fput_light(file, fput_needed); fdput(f);
return ret; return ret;
} }

View File

@@ -1531,16 +1531,13 @@ static int compat_ioctl_check_table(unsigned int xcmd)
asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
struct file *filp; struct fd f = fdget(fd);
int error = -EBADF; int error = -EBADF;
int fput_needed; if (!f.file)
filp = fget_light(fd, &fput_needed);
if (!filp)
goto out; goto out;
/* RED-PEN how should LSM module know it's handling 32bit? */ /* RED-PEN how should LSM module know it's handling 32bit? */
error = security_file_ioctl(filp, cmd, arg); error = security_file_ioctl(f.file, cmd, arg);
if (error) if (error)
goto out_fput; goto out_fput;
@@ -1560,30 +1557,30 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) #if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
case FS_IOC_RESVSP_32: case FS_IOC_RESVSP_32:
case FS_IOC_RESVSP64_32: case FS_IOC_RESVSP64_32:
error = compat_ioctl_preallocate(filp, compat_ptr(arg)); error = compat_ioctl_preallocate(f.file, compat_ptr(arg));
goto out_fput; goto out_fput;
#else #else
case FS_IOC_RESVSP: case FS_IOC_RESVSP:
case FS_IOC_RESVSP64: case FS_IOC_RESVSP64:
error = ioctl_preallocate(filp, compat_ptr(arg)); error = ioctl_preallocate(f.file, compat_ptr(arg));
goto out_fput; goto out_fput;
#endif #endif
case FIBMAP: case FIBMAP:
case FIGETBSZ: case FIGETBSZ:
case FIONREAD: case FIONREAD:
if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) if (S_ISREG(f.file->f_path.dentry->d_inode->i_mode))
break; break;
/*FALL THROUGH*/ /*FALL THROUGH*/
default: default:
if (filp->f_op && filp->f_op->compat_ioctl) { if (f.file->f_op && f.file->f_op->compat_ioctl) {
error = filp->f_op->compat_ioctl(filp, cmd, arg); error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
if (error != -ENOIOCTLCMD) if (error != -ENOIOCTLCMD)
goto out_fput; goto out_fput;
} }
if (!filp->f_op || !filp->f_op->unlocked_ioctl) if (!f.file->f_op || !f.file->f_op->unlocked_ioctl)
goto do_ioctl; goto do_ioctl;
break; break;
} }
@@ -1591,7 +1588,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
if (compat_ioctl_check_table(XFORM(cmd))) if (compat_ioctl_check_table(XFORM(cmd)))
goto found_handler; goto found_handler;
error = do_ioctl_trans(fd, cmd, arg, filp); error = do_ioctl_trans(fd, cmd, arg, f.file);
if (error == -ENOIOCTLCMD) if (error == -ENOIOCTLCMD)
error = -ENOTTY; error = -ENOTTY;
@@ -1600,9 +1597,9 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
found_handler: found_handler:
arg = (unsigned long)compat_ptr(arg); arg = (unsigned long)compat_ptr(arg);
do_ioctl: do_ioctl:
error = do_vfs_ioctl(filp, fd, cmd, arg); error = do_vfs_ioctl(f.file, fd, cmd, arg);
out_fput: out_fput:
fput_light(filp, fput_needed); fdput(f);
out: out:
return error; return error;
} }

View File

@@ -1809,8 +1809,8 @@ error_return:
SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events, SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events,
int, maxevents, int, timeout) int, maxevents, int, timeout)
{ {
int error, fput_needed; int error;
struct file *file; struct fd f;
struct eventpoll *ep; struct eventpoll *ep;
/* The maximum number of event must be greater than zero */ /* 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,
return -EINVAL; return -EINVAL;
/* Verify that the area passed by the user is writeable */ /* Verify that the area passed by the user is writeable */
if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))) { if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event)))
error = -EFAULT; return -EFAULT;
goto error_return;
}
/* Get the "struct file *" for the eventpoll file */ /* Get the "struct file *" for the eventpoll file */
error = -EBADF; f = fdget(epfd);
file = fget_light(epfd, &fput_needed); if (!f.file)
if (!file) return -EBADF;
goto error_return;
/* /*
* We have to check that the file structure underneath the fd * We have to check that the file structure underneath the fd
* the user passed to us _is_ an eventpoll file. * the user passed to us _is_ an eventpoll file.
*/ */
error = -EINVAL; error = -EINVAL;
if (!is_file_epoll(file)) if (!is_file_epoll(f.file))
goto error_fput; goto error_fput;
/* /*
* At this point it is safe to assume that the "private_data" contains * At this point it is safe to assume that the "private_data" contains
* our own data structure. * our own data structure.
*/ */
ep = file->private_data; ep = f.file->private_data;
/* Time to fish for events ... */ /* Time to fish for events ... */
error = ep_poll(ep, events, maxevents, timeout); error = ep_poll(ep, events, maxevents, timeout);
error_fput: error_fput:
fput_light(file, fput_needed); fdput(f);
error_return:
return error; return error;
} }

View File

@@ -233,8 +233,8 @@ group_extend_out:
case EXT4_IOC_MOVE_EXT: { case EXT4_IOC_MOVE_EXT: {
struct move_extent me; struct move_extent me;
struct file *donor_filp; struct fd donor;
int err, fput_needed; int err;
if (!(filp->f_mode & FMODE_READ) || if (!(filp->f_mode & FMODE_READ) ||
!(filp->f_mode & FMODE_WRITE)) !(filp->f_mode & FMODE_WRITE))
@@ -245,11 +245,11 @@ group_extend_out:
return -EFAULT; return -EFAULT;
me.moved_len = 0; me.moved_len = 0;
donor_filp = fget_light(me.donor_fd, &fput_needed); donor = fdget(me.donor_fd);
if (!donor_filp) if (!donor.file)
return -EBADF; return -EBADF;
if (!(donor_filp->f_mode & FMODE_WRITE)) { if (!(donor.file->f_mode & FMODE_WRITE)) {
err = -EBADF; err = -EBADF;
goto mext_out; goto mext_out;
} }
@@ -266,7 +266,7 @@ group_extend_out:
if (err) if (err)
goto mext_out; goto mext_out;
err = ext4_move_extents(filp, donor_filp, me.orig_start, err = ext4_move_extents(filp, donor.file, me.orig_start,
me.donor_start, me.len, &me.moved_len); me.donor_start, me.len, &me.moved_len);
mnt_drop_write_file(filp); mnt_drop_write_file(filp);
@@ -274,7 +274,7 @@ group_extend_out:
&me, sizeof(me))) &me, sizeof(me)))
err = -EFAULT; err = -EFAULT;
mext_out: mext_out:
fput_light(donor_filp, fput_needed); fdput(donor);
return err; return err;
} }

View File

@@ -348,25 +348,23 @@ static int check_fcntl_cmd(unsigned cmd)
SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
{ {
struct file *filp; struct fd f = fdget_raw(fd);
int fput_needed;
long err = -EBADF; long err = -EBADF;
filp = fget_raw_light(fd, &fput_needed); if (!f.file)
if (!filp)
goto out; goto out;
if (unlikely(filp->f_mode & FMODE_PATH)) { if (unlikely(f.file->f_mode & FMODE_PATH)) {
if (!check_fcntl_cmd(cmd)) if (!check_fcntl_cmd(cmd))
goto out1; goto out1;
} }
err = security_file_fcntl(filp, cmd, arg); err = security_file_fcntl(f.file, cmd, arg);
if (!err) if (!err)
err = do_fcntl(fd, cmd, arg, filp); err = do_fcntl(fd, cmd, arg, f.file);
out1: out1:
fput_light(filp, fput_needed); fdput(f);
out: out:
return err; return err;
} }
@@ -375,38 +373,36 @@ out:
SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
unsigned long, arg) unsigned long, arg)
{ {
struct file * filp; struct fd f = fdget_raw(fd);
long err = -EBADF; long err = -EBADF;
int fput_needed;
filp = fget_raw_light(fd, &fput_needed); if (!f.file)
if (!filp)
goto out; goto out;
if (unlikely(filp->f_mode & FMODE_PATH)) { if (unlikely(f.file->f_mode & FMODE_PATH)) {
if (!check_fcntl_cmd(cmd)) if (!check_fcntl_cmd(cmd))
goto out1; goto out1;
} }
err = security_file_fcntl(filp, cmd, arg); err = security_file_fcntl(f.file, cmd, arg);
if (err) if (err)
goto out1; goto out1;
switch (cmd) { switch (cmd) {
case F_GETLK64: case F_GETLK64:
err = fcntl_getlk64(filp, (struct flock64 __user *) arg); err = fcntl_getlk64(f.file, (struct flock64 __user *) arg);
break; break;
case F_SETLK64: case F_SETLK64:
case F_SETLKW64: case F_SETLKW64:
err = fcntl_setlk64(fd, filp, cmd, err = fcntl_setlk64(fd, f.file, cmd,
(struct flock64 __user *) arg); (struct flock64 __user *) arg);
break; break;
default: default:
err = do_fcntl(fd, cmd, arg, filp); err = do_fcntl(fd, cmd, arg, f.file);
break; break;
} }
out1: out1:
fput_light(filp, fput_needed); fdput(f);
out: out:
return err; return err;
} }

View File

@@ -113,24 +113,21 @@ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name,
static struct vfsmount *get_vfsmount_from_fd(int fd) static struct vfsmount *get_vfsmount_from_fd(int fd)
{ {
struct path path; struct vfsmount *mnt;
if (fd == AT_FDCWD) { if (fd == AT_FDCWD) {
struct fs_struct *fs = current->fs; struct fs_struct *fs = current->fs;
spin_lock(&fs->lock); spin_lock(&fs->lock);
path = fs->pwd; mnt = mntget(fs->pwd.mnt);
mntget(path.mnt);
spin_unlock(&fs->lock); spin_unlock(&fs->lock);
} else { } else {
int fput_needed; struct fd f = fdget(fd);
struct file *file = fget_light(fd, &fput_needed); if (!f.file)
if (!file)
return ERR_PTR(-EBADF); return ERR_PTR(-EBADF);
path = file->f_path; mnt = mntget(f.file->f_path.mnt);
mntget(path.mnt); fdput(f);
fput_light(file, fput_needed);
} }
return path.mnt; return mnt;
} }
static int vfs_dentry_acceptable(void *context, struct dentry *dentry) static int vfs_dentry_acceptable(void *context, struct dentry *dentry)

View File

@@ -603,21 +603,14 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
{ {
struct file *filp; int error;
int error = -EBADF; struct fd f = fdget(fd);
int fput_needed;
filp = fget_light(fd, &fput_needed); if (!f.file)
if (!filp) return -EBADF;
goto out; error = security_file_ioctl(f.file, cmd, arg);
if (!error)
error = security_file_ioctl(filp, cmd, arg); error = do_vfs_ioctl(f.file, fd, cmd, arg);
if (error) fdput(f);
goto out_fput;
error = do_vfs_ioctl(filp, fd, cmd, arg);
out_fput:
fput_light(filp, fput_needed);
out:
return error; return error;
} }

View File

@@ -1625,15 +1625,13 @@ EXPORT_SYMBOL(flock_lock_file_wait);
*/ */
SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
{ {
struct file *filp; struct fd f = fdget(fd);
int fput_needed;
struct file_lock *lock; struct file_lock *lock;
int can_sleep, unlock; int can_sleep, unlock;
int error; int error;
error = -EBADF; error = -EBADF;
filp = fget_light(fd, &fput_needed); if (!f.file)
if (!filp)
goto out; goto out;
can_sleep = !(cmd & LOCK_NB); can_sleep = !(cmd & LOCK_NB);
@@ -1641,31 +1639,31 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
unlock = (cmd == LOCK_UN); unlock = (cmd == LOCK_UN);
if (!unlock && !(cmd & LOCK_MAND) && if (!unlock && !(cmd & LOCK_MAND) &&
!(filp->f_mode & (FMODE_READ|FMODE_WRITE))) !(f.file->f_mode & (FMODE_READ|FMODE_WRITE)))
goto out_putf; goto out_putf;
error = flock_make_lock(filp, &lock, cmd); error = flock_make_lock(f.file, &lock, cmd);
if (error) if (error)
goto out_putf; goto out_putf;
if (can_sleep) if (can_sleep)
lock->fl_flags |= FL_SLEEP; lock->fl_flags |= FL_SLEEP;
error = security_file_lock(filp, lock->fl_type); error = security_file_lock(f.file, lock->fl_type);
if (error) if (error)
goto out_free; goto out_free;
if (filp->f_op && filp->f_op->flock) if (f.file->f_op && f.file->f_op->flock)
error = filp->f_op->flock(filp, error = f.file->f_op->flock(f.file,
(can_sleep) ? F_SETLKW : F_SETLK, (can_sleep) ? F_SETLKW : F_SETLK,
lock); lock);
else else
error = flock_lock_file_wait(filp, lock); error = flock_lock_file_wait(f.file, lock);
out_free: out_free:
locks_free_lock(lock); locks_free_lock(lock);
out_putf: out_putf:
fput_light(filp, fput_needed); fdput(f);
out: out:
return error; return error;
} }

View File

@@ -1797,8 +1797,6 @@ static int path_init(int dfd, const char *name, unsigned int flags,
struct nameidata *nd, struct file **fp) struct nameidata *nd, struct file **fp)
{ {
int retval = 0; int retval = 0;
int fput_needed;
struct file *file;
nd->last_type = LAST_ROOT; /* if there are only slashes... */ nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags | LOOKUP_JUMPED; nd->flags = flags | LOOKUP_JUMPED;
@@ -1850,44 +1848,41 @@ static int path_init(int dfd, const char *name, unsigned int flags,
get_fs_pwd(current->fs, &nd->path); get_fs_pwd(current->fs, &nd->path);
} }
} else { } else {
struct fd f = fdget_raw(dfd);
struct dentry *dentry; struct dentry *dentry;
file = fget_raw_light(dfd, &fput_needed); if (!f.file)
retval = -EBADF; return -EBADF;
if (!file)
goto out_fail;
dentry = file->f_path.dentry; dentry = f.file->f_path.dentry;
if (*name) { if (*name) {
retval = -ENOTDIR; if (!S_ISDIR(dentry->d_inode->i_mode)) {
if (!S_ISDIR(dentry->d_inode->i_mode)) fdput(f);
goto fput_fail; return -ENOTDIR;
}
retval = inode_permission(dentry->d_inode, MAY_EXEC); retval = inode_permission(dentry->d_inode, MAY_EXEC);
if (retval) if (retval) {
goto fput_fail; fdput(f);
return retval;
}
} }
nd->path = file->f_path; nd->path = f.file->f_path;
if (flags & LOOKUP_RCU) { if (flags & LOOKUP_RCU) {
if (fput_needed) if (f.need_put)
*fp = file; *fp = f.file;
nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
lock_rcu_walk(); lock_rcu_walk();
} else { } else {
path_get(&file->f_path); path_get(&nd->path);
fput_light(file, fput_needed); fdput(f);
} }
} }
nd->inode = nd->path.dentry->d_inode; nd->inode = nd->path.dentry->d_inode;
return 0; return 0;
fput_fail:
fput_light(file, fput_needed);
out_fail:
return retval;
} }
static inline int lookup_last(struct nameidata *nd, struct path *path) static inline int lookup_last(struct nameidata *nd, struct path *path)

Some files were not shown because too many files have changed in this diff Show More