Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…

…/git/viro/vfs

Pull vfs update from Al Viro:

 - big one - consolidation of descriptor-related logics; almost all of
   that is moved to fs/file.c

   (BTW, I'm seriously tempted to rename the result to fd.c.  As it is,
   we have a situation when file_table.c is about handling of struct
   file and file.c is about handling of descriptor tables; the reasons
   are historical - file_table.c used to be about a static array of
   struct file we used to have way back).

   A lot of stray ends got cleaned up and converted to saner primitives,
   disgusting mess in android/binder.c is still disgusting, but at least
   doesn't poke so much in descriptor table guts anymore.  A bunch of
   relatively minor races got fixed in process, plus an ext4 struct file
   leak.

 - related thing - fget_light() partially unuglified; see fdget() in
   there (and yes, it generates the code as good as we used to have).

 - also related - bits of Cyrill's procfs stuff that got entangled into
   that work; _not_ all of it, just the initial move to fs/proc/fd.c and
   switch of fdinfo to seq_file.

 - Alex's fs/coredump.c spiltoff - the same story, had been easier to
   take that commit than mess with conflicts.  The rest is a separate
   pile, this was just a mechanical code movement.

 - a few misc patches all over the place.  Not all for this cycle,
   there'll be more (and quite a few currently sit in akpm's tree)."

Fix up trivial conflicts in the android binder driver, and some fairly
simple conflicts due to two different changes to the sock_alloc_file()
interface ("take descriptor handling from sock_alloc_file() to callers"
vs "net: Providing protocol type via system.sockprotoname xattr of
/proc/PID/fd entries" adding a dentry name to the socket)

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (72 commits)
  MAX_LFS_FILESIZE should be a loff_t
  compat: fs: Generic compat_sys_sendfile implementation
  fs: push rcu_barrier() from deactivate_locked_super() to filesystems
  btrfs: reada_extent doesn't need kref for refcount
  coredump: move core dump functionality into its own file
  coredump: prevent double-free on an error path in core dumper
  usb/gadget: fix misannotations
  fcntl: fix misannotations
  ceph: don't abuse d_delete() on failure exits
  hypfs: ->d_parent is never NULL or negative
  vfs: delete surplus inode NULL check
  switch simple cases of fget_light to fdget
  new helpers: fdget()/fdput()
  switch o2hb_region_dev_write() to fget_light()
  proc_map_files_readdir(): don't bother with grabbing files
  make get_file() return its argument
  vhost_set_vring(): turn pollstart/pollstop into bool
  switch prctl_set_mm_exe_file() to fget_light()
  switch xfs_find_handle() to fget_light()
  switch xfs_swapext() to fget_light()
  ...
  • Loading branch information...
commit aab174f0df5d72d31caccf281af5f614fa254578 2 parents ca41cc9 + 2bd2c19
@torvalds authored
Showing with 2,915 additions and 2,877 deletions.
  1. +5 −8 arch/alpha/kernel/osf_sys.c
  2. +8 −10 arch/ia64/kernel/perfmon.c
  3. +8 −9 arch/parisc/hpux/fs.c
  4. +2 −2 arch/powerpc/include/asm/systbl.h
  5. +1 −0  arch/powerpc/include/asm/unistd.h
  6. +7 −38 arch/powerpc/kernel/sys_ppc32.c
  7. +9 −12 arch/powerpc/platforms/cell/spu_syscalls.c
  8. +20 −20 arch/powerpc/platforms/cell/spufs/coredump.c
  9. +0 −2  arch/s390/hypfs/inode.c
  10. +1 −0  arch/sparc/include/asm/unistd.h
  11. +1 −1  arch/sparc/kernel/sys32.S
  12. +0 −46 arch/sparc/kernel/sys_sparc32.c
  13. +21 −78 arch/um/drivers/mconsole_kern.c
  14. +1 −2  drivers/base/dma-buf.c
  15. +5 −5 drivers/infiniband/core/ucma.c
  16. +8 −13 drivers/infiniband/core/uverbs_cmd.c
  17. +5 −6 drivers/infiniband/core/uverbs_main.c
  18. +13 −98 drivers/staging/android/binder.c
  19. +1 −2  drivers/staging/omapdrm/omap_gem.c
  20. +16 −29 drivers/tty/tty_io.c
  21. +2 −2 drivers/usb/gadget/f_fs.c
  22. +7 −8 drivers/vfio/vfio.c
  23. +4 −4 drivers/vhost/vhost.c
  24. +5 −7 drivers/video/msm/mdp.c
  25. +5 −0 fs/9p/v9fs.c
  26. +1 −1  fs/Makefile
  27. +5 −0 fs/adfs/super.c
  28. +5 −0 fs/affs/super.c
  29. +5 −0 fs/afs/super.c
  30. +2 −16 fs/autofs4/dev-ioctl.c
  31. +1 −2  fs/autofs4/waitq.c
  32. +5 −0 fs/befs/linuxvfs.c
  33. +5 −0 fs/bfs/inode.c
  34. +4 −15 fs/binfmt_elf.c
  35. +6 −0 fs/btrfs/extent_io.c
  36. +5 −0 fs/btrfs/inode.c
  37. +15 −17 fs/btrfs/ioctl.c
  38. +7 −11 fs/btrfs/reada.c
  39. +2 −2 fs/ceph/inode.c
  40. +5 −0 fs/ceph/super.c
  41. +5 −0 fs/cifs/cifsfs.c
  42. +20 −17 fs/coda/inode.c
  43. +62 −50 fs/compat.c
  44. +12 −15 fs/compat_ioctl.c
  45. +686 −0 fs/coredump.c
  46. +1 −1  fs/dcache.c
  47. +6 −0 fs/ecryptfs/main.c
  48. +5 −0 fs/efs/super.c
  49. +9 −14 fs/eventpoll.c
  50. +7 −681 fs/exec.c
  51. +5 −0 fs/exofs/super.c
  52. +5 −0 fs/ext2/super.c
  53. +5 −0 fs/ext3/super.c
  54. +8 −7 fs/ext4/ioctl.c
  55. +5 −0 fs/ext4/super.c
  56. +5 −0 fs/fat/inode.c
  57. +20 −146 fs/fcntl.c
  58. +7 −10 fs/fhandle.c
  59. +549 −24 fs/file.c
  60. +0 −106 fs/file_table.c
  61. +5 −0 fs/freevxfs/vxfs_super.c
  62. +1 −2  fs/fuse/dev.c
  63. +6 −0 fs/fuse/inode.c
  64. +6 −0 fs/hfs/super.c
  65. +6 −0 fs/hfsplus/super.c
  66. +5 −0 fs/hpfs/super.c
  67. +5 −0 fs/hugetlbfs/inode.c
  68. +9 −16 fs/ioctl.c
  69. +5 −0 fs/isofs/inode.c
  70. +6 −0 fs/jffs2/super.c
  71. +6 −0 fs/jfs/super.c
  72. +9 −11 fs/locks.c
  73. +5 −0 fs/logfs/inode.c
  74. +5 −0 fs/minix/inode.c
  75. +18 −23 fs/namei.c
  76. +5 −0 fs/ncpfs/inode.c
  77. +5 −0 fs/nfs/inode.c
  78. +1 −2  fs/nfsd/nfs4state.c
  79. +6 −0 fs/nilfs2/super.c
  80. +33 −54 fs/notify/fanotify/fanotify_user.c
  81. +14 −14 fs/notify/inotify/inotify_user.c
  82. +6 −0 fs/ntfs/super.c
  83. +19 −19 fs/ocfs2/cluster/heartbeat.c
  84. +5 −0 fs/ocfs2/dlmfs/dlmfs.c
  85. +5 −0 fs/ocfs2/super.c
  86. +30 −100 fs/open.c
  87. +5 −0 fs/openpromfs/inode.c
  88. +22 −9 fs/pipe.c
  89. +1 −1  fs/proc/Makefile
  90. +11 −406 fs/proc/base.c
  91. +367 −0 fs/proc/fd.c
  92. +14 −0 fs/proc/fd.h
  93. +48 −0 fs/proc/internal.h
  94. +5 −0 fs/qnx4/inode.c
  95. +5 −0 fs/qnx6/inode.c
  96. +79 −101 fs/read_write.c
  97. +2 −0  fs/read_write.h
  98. +16 −20 fs/readdir.c
  99. +5 −0 fs/reiserfs/super.c
  100. +5 −0 fs/romfs/super.c
  101. +13 −18 fs/select.c
  102. +6 −7 fs/signalfd.c
  103. +32 −37 fs/splice.c
  104. +5 −0 fs/squashfs/super.c
  105. +5 −5 fs/stat.c
  106. +4 −5 fs/statfs.c
  107. +0 −6 fs/super.c
  108. +14 −19 fs/sync.c
  109. +5 −0 fs/sysv/inode.c
  110. +21 −24 fs/timerfd.c
  111. +6 −0 fs/ubifs/super.c
  112. +5 −0 fs/udf/super.c
  113. +5 −0 fs/ufs/super.c
  114. +5 −6 fs/utimes.c
  115. +22 −30 fs/xattr.c
  116. +17 −17 fs/xfs/xfs_dfrag.c
  117. +5 −5 fs/xfs/xfs_ioctl.c
  118. +5 −0 fs/xfs/xfs_super.c
  119. +3 −0  include/linux/compat.h
  120. +12 −27 include/linux/fdtable.h
  121. +32 −3 include/linux/file.h
  122. +7 −3 include/linux/fs.h
  123. +2 −1  include/linux/net.h
  124. +1 −0  include/linux/sched.h
  125. +39 −39 ipc/mqueue.c
  126. +31 −41 kernel/events/core.c
  127. +1 −96 kernel/exit.c
  128. +7 −7 kernel/sys.c
  129. +5 −6 kernel/taskstats.c
  130. +17 −17 mm/fadvise.c
  131. +1 −2  mm/fremap.c
  132. +1 −2  mm/mmap.c
  133. +2 −4 mm/nommu.c
  134. +7 −7 mm/readahead.c
  135. +7 −9 net/9p/trans_fd.c
  136. +1 −2  net/compat.c
  137. +12 −26 net/core/netprio_cgroup.c
  138. +1 −2  net/core/scm.c
  139. +20 −5 net/sctp/socket.c
  140. +42 −26 net/socket.c
  141. +21 −52 security/selinux/hooks.c
  142. +7 −6 sound/core/pcm_native.c
View
13 arch/alpha/kernel/osf_sys.c
@@ -145,27 +145,24 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
long __user *, basep)
{
int error;
- struct file *file;
+ struct fd arg = fdget(fd);
struct osf_dirent_callback buf;
- error = -EBADF;
- file = fget(fd);
- if (!file)
- goto out;
+ if (!arg.file)
+ return -EBADF;
buf.dirent = dirent;
buf.basep = basep;
buf.count = count;
buf.error = 0;
- error = vfs_readdir(file, osf_filldir, &buf);
+ error = vfs_readdir(arg.file, osf_filldir, &buf);
if (error >= 0)
error = buf.error;
if (count != buf.count)
error = count - buf.count;
- fput(file);
- out:
+ fdput(arg);
return error;
}
View
18 arch/ia64/kernel/perfmon.c
@@ -2306,7 +2306,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
* partially initialize the vma for the sampling buffer
*/
vma->vm_mm = mm;
- vma->vm_file = filp;
+ vma->vm_file = get_file(filp);
vma->vm_flags = VM_READ| VM_MAYREAD |VM_RESERVED;
vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */
@@ -2345,8 +2345,6 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
goto error;
}
- get_file(filp);
-
/*
* now insert the vma in the vm list for the process, must be
* done with mmap lock held
@@ -4782,7 +4780,7 @@ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags)
asmlinkage long
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;
unsigned long flags = 0UL;
void *args_k = NULL;
@@ -4879,17 +4877,17 @@ sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
ret = -EBADF;
- file = fget(fd);
- if (unlikely(file == NULL)) {
+ f = fdget(fd);
+ if (unlikely(f.file == NULL)) {
DPRINT(("invalid fd %d\n", fd));
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));
goto error_args;
}
- ctx = file->private_data;
+ ctx = f.file->private_data;
if (unlikely(ctx == NULL)) {
DPRINT(("no context for fd %d\n", fd));
goto error_args;
@@ -4919,8 +4917,8 @@ sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
error_args:
- if (file)
- fput(file);
+ if (f.file)
+ fdput(f);
kfree(args_k);
View
17 arch/parisc/hpux/fs.c
@@ -109,33 +109,32 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
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 getdents_callback buf;
- int error = -EBADF;
+ int error;
- file = fget(fd);
- if (!file)
- goto out;
+ arg = fdget(fd);
+ if (!arg.file)
+ return -EBADF;
buf.current_dir = dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
- error = vfs_readdir(file, filldir, &buf);
+ error = vfs_readdir(arg.file, filldir, &buf);
if (error >= 0)
error = buf.error;
lastdirent = buf.previous;
if (lastdirent) {
- if (put_user(file->f_pos, &lastdirent->d_off))
+ if (put_user(arg.file->f_pos, &lastdirent->d_off))
error = -EFAULT;
else
error = count - buf.count;
}
- fput(file);
-out:
+ fdput(arg);
return error;
}
View
4 arch/powerpc/include/asm/systbl.h
@@ -189,7 +189,7 @@ SYSCALL_SPU(getcwd)
SYSCALL_SPU(capget)
SYSCALL_SPU(capset)
COMPAT_SYS(sigaltstack)
-SYSX_SPU(sys_sendfile64,compat_sys_sendfile,sys_sendfile)
+SYSX_SPU(sys_sendfile,compat_sys_sendfile_wrapper,sys_sendfile)
SYSCALL(ni_syscall)
SYSCALL(ni_syscall)
PPC_SYS(vfork)
@@ -229,7 +229,7 @@ COMPAT_SYS_SPU(sched_setaffinity)
COMPAT_SYS_SPU(sched_getaffinity)
SYSCALL(ni_syscall)
SYSCALL(ni_syscall)
-SYS32ONLY(sendfile64)
+SYSX(sys_ni_syscall,compat_sys_sendfile64_wrapper,sys_sendfile64)
COMPAT_SYS_SPU(io_setup)
SYSCALL_SPU(io_destroy)
COMPAT_SYS_SPU(io_getevents)
View
1  arch/powerpc/include/asm/unistd.h
@@ -419,6 +419,7 @@
#define __ARCH_WANT_COMPAT_SYS_TIME
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_NEWFSTATAT
+#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#endif
/*
View
45 arch/powerpc/kernel/sys_ppc32.c
@@ -143,48 +143,17 @@ long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t pt
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count)
+asmlinkage long compat_sys_sendfile_wrapper(u32 out_fd, u32 in_fd,
+ compat_off_t __user *offset, u32 count)
{
- mm_segment_t old_fs = get_fs();
- int ret;
- off_t of;
- off_t __user *up;
-
- if (offset && get_user(of, offset))
- return -EFAULT;
-
- /* The __user pointer cast is valid because of the set_fs() */
- set_fs(KERNEL_DS);
- up = offset ? (off_t __user *) &of : NULL;
- ret = sys_sendfile((int)out_fd, (int)in_fd, up, count);
- set_fs(old_fs);
-
- if (offset && put_user(of, offset))
- return -EFAULT;
-
- return ret;
+ return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count);
}
-asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
+asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd,
+ compat_loff_t __user *offset, u32 count)
{
- mm_segment_t old_fs = get_fs();
- int ret;
- loff_t lof;
- loff_t __user *up;
-
- if (offset && get_user(lof, offset))
- return -EFAULT;
-
- /* The __user pointer cast is valid because of the set_fs() */
- set_fs(KERNEL_DS);
- up = offset ? (loff_t __user *) &lof : NULL;
- ret = sys_sendfile64(out_fd, in_fd, up, count);
- set_fs(old_fs);
-
- if (offset && put_user(lof, offset))
- return -EFAULT;
-
- return ret;
+ return sys_sendfile((int)out_fd, (int)in_fd,
+ (off_t __user *)offset, count);
}
long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
View
21 arch/powerpc/platforms/cell/spu_syscalls.c
@@ -69,8 +69,6 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
umode_t, mode, int, neighbor_fd)
{
long ret;
- struct file *neighbor;
- int fput_needed;
struct spufs_calls *calls;
calls = spufs_calls_get();
@@ -78,11 +76,11 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
return -ENOSYS;
if (flags & SPU_CREATE_AFFINITY_SPU) {
+ struct fd neighbor = fdget(neighbor_fd);
ret = -EBADF;
- neighbor = fget_light(neighbor_fd, &fput_needed);
- if (neighbor) {
- ret = calls->create_thread(name, flags, mode, neighbor);
- fput_light(neighbor, fput_needed);
+ if (neighbor.file) {
+ ret = calls->create_thread(name, flags, mode, neighbor.file);
+ fdput(neighbor);
}
} else
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)
{
long ret;
- struct file *filp;
- int fput_needed;
+ struct fd arg;
struct spufs_calls *calls;
calls = spufs_calls_get();
@@ -103,10 +100,10 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
return -ENOSYS;
ret = -EBADF;
- filp = fget_light(fd, &fput_needed);
- if (filp) {
- ret = calls->spu_run(filp, unpc, ustatus);
- fput_light(filp, fput_needed);
+ arg = fdget(fd);
+ if (arg.file) {
+ ret = calls->spu_run(arg.file, unpc, ustatus);
+ fdput(arg);
}
spufs_calls_put(calls);
View
40 arch/powerpc/platforms/cell/spufs/coredump.c
@@ -106,6 +106,17 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
return total;
}
+static int match_context(const void *v, struct file *file, unsigned fd)
+{
+ struct spu_context *ctx;
+ if (file->f_op != &spufs_context_fops)
+ return 0;
+ ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
+ if (ctx->flags & SPU_CREATE_NOSCHED)
+ return 0;
+ return fd + 1;
+}
+
/*
* The additional architecture-specific notes for Cell are various
* context files in the spu context.
@@ -115,29 +126,18 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
* internal functionality to dump them without needing to actually
* open the files.
*/
+/*
+ * descriptor table is not shared, so files can't change or go away.
+ */
static struct spu_context *coredump_next_context(int *fd)
{
- struct fdtable *fdt = files_fdtable(current->files);
struct file *file;
- struct spu_context *ctx = NULL;
-
- for (; *fd < fdt->max_fds; (*fd)++) {
- if (!fd_is_open(*fd, fdt))
- continue;
-
- file = fcheck(*fd);
-
- if (!file || file->f_op != &spufs_context_fops)
- continue;
-
- ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
- if (ctx->flags & SPU_CREATE_NOSCHED)
- continue;
-
- break;
- }
-
- return ctx;
+ int n = iterate_fd(current->files, *fd, match_context, NULL);
+ if (!n)
+ return NULL;
+ *fd = n - 1;
+ file = fcheck(*fd);
+ return SPUFS_I(file->f_dentry->d_inode)->i_ctx;
}
int spufs_coredump_extra_notes_size(void)
View
2  arch/s390/hypfs/inode.c
@@ -72,8 +72,6 @@ static void hypfs_remove(struct dentry *dentry)
struct dentry *parent;
parent = dentry->d_parent;
- if (!parent || !parent->d_inode)
- return;
mutex_lock(&parent->d_inode->i_mutex);
if (hypfs_positive(dentry)) {
if (S_ISDIR(dentry->d_inode->i_mode))
View
1  arch/sparc/include/asm/unistd.h
@@ -447,6 +447,7 @@
#else
#define __ARCH_WANT_COMPAT_SYS_TIME
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#endif
/*
View
2  arch/sparc/kernel/sys32.S
@@ -90,7 +90,7 @@ SIGN1(sys32_mkdir, sys_mkdir, %o1)
SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
SIGN1(sys32_sysfs, compat_sys_sysfs, %o0)
SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1)
-SIGN2(sys32_sendfile64, compat_sys_sendfile64, %o0, %o1)
+SIGN2(sys32_sendfile64, sys_sendfile, %o0, %o1)
SIGN1(sys32_prctl, sys_prctl, %o0)
SIGN1(sys32_sched_rr_get_interval, compat_sys_sched_rr_get_interval, %o0)
SIGN2(sys32_waitpid, sys_waitpid, %o0, %o2)
View
46 arch/sparc/kernel/sys_sparc32.c
@@ -506,52 +506,6 @@ long compat_sys_fadvise64_64(int fd,
advice);
}
-asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
- compat_off_t __user *offset,
- compat_size_t count)
-{
- mm_segment_t old_fs = get_fs();
- int ret;
- off_t of;
-
- if (offset && get_user(of, offset))
- return -EFAULT;
-
- set_fs(KERNEL_DS);
- ret = sys_sendfile(out_fd, in_fd,
- offset ? (off_t __user *) &of : NULL,
- count);
- set_fs(old_fs);
-
- if (offset && put_user(of, offset))
- return -EFAULT;
-
- return ret;
-}
-
-asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,
- compat_loff_t __user *offset,
- compat_size_t count)
-{
- mm_segment_t old_fs = get_fs();
- int ret;
- loff_t lof;
-
- if (offset && get_user(lof, offset))
- return -EFAULT;
-
- set_fs(KERNEL_DS);
- ret = sys_sendfile64(out_fd, in_fd,
- offset ? (loff_t __user *) &lof : NULL,
- count);
- set_fs(old_fs);
-
- if (offset && put_user(lof, offset))
- return -EFAULT;
-
- return ret;
-}
-
/* This is just a version for 32-bit applications which does
* not force O_LARGEFILE on.
*/
View
99 arch/um/drivers/mconsole_kern.c
@@ -21,6 +21,9 @@
#include <linux/un.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/file.h>
#include <asm/uaccess.h>
#include <asm/switch_to.h>
@@ -118,90 +121,38 @@ void mconsole_log(struct mc_request *req)
mconsole_reply(req, "", 0, 0);
}
-/* This is a more convoluted version of mconsole_proc, which has some stability
- * problems; however, we need it fixed, because it is expected that UML users
- * mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
- * show the real procfs content, not the ones from hppfs.*/
-#if 0
void mconsole_proc(struct mc_request *req)
{
struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
- struct file *file;
- int n;
- char *ptr = req->request.data, *buf;
- mm_segment_t old_fs = get_fs();
-
- ptr += strlen("proc");
- ptr = skip_spaces(ptr);
-
- file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
- if (IS_ERR(file)) {
- mconsole_reply(req, "Failed to open file", 1, 0);
- goto out;
- }
-
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (buf == NULL) {
- mconsole_reply(req, "Failed to allocate buffer", 1, 0);
- goto out_fput;
- }
-
- if (file->f_op->read) {
- do {
- loff_t pos;
- set_fs(KERNEL_DS);
- n = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
- file_pos_write(file, pos);
- set_fs(old_fs);
- if (n >= 0) {
- buf[n] = '\0';
- mconsole_reply(req, buf, 0, (n > 0));
- }
- else {
- mconsole_reply(req, "Read of file failed",
- 1, 0);
- goto out_free;
- }
- } while (n > 0);
- }
- else mconsole_reply(req, "", 0, 0);
-
- out_free:
- kfree(buf);
- out_fput:
- fput(file);
- out: ;
-}
-#endif
-
-void mconsole_proc(struct mc_request *req)
-{
- char path[64];
char *buf;
int len;
- int fd;
+ struct file *file;
int first_chunk = 1;
char *ptr = req->request.data;
ptr += strlen("proc");
ptr = skip_spaces(ptr);
- snprintf(path, sizeof(path), "/proc/%s", ptr);
- fd = sys_open(path, 0, 0);
- if (fd < 0) {
+ file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
+ if (IS_ERR(file)) {
mconsole_reply(req, "Failed to open file", 1, 0);
- printk(KERN_ERR "open %s: %d\n",path,fd);
+ printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
goto out;
}
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (buf == NULL) {
mconsole_reply(req, "Failed to allocate buffer", 1, 0);
- goto out_close;
+ goto out_fput;
}
- for (;;) {
- len = sys_read(fd, buf, PAGE_SIZE-1);
+ do {
+ loff_t pos;
+ mm_segment_t old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ len = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
+ set_fs(old_fs);
+ file->f_pos = pos;
if (len < 0) {
mconsole_reply(req, "Read of file failed", 1, 0);
goto out_free;
@@ -211,22 +162,14 @@ void mconsole_proc(struct mc_request *req)
mconsole_reply(req, "\n", 0, 1);
first_chunk = 0;
}
- if (len == PAGE_SIZE-1) {
- buf[len] = '\0';
- mconsole_reply(req, buf, 0, 1);
- } else {
- buf[len] = '\0';
- mconsole_reply(req, buf, 0, 0);
- break;
- }
- }
-
+ buf[len] = '\0';
+ mconsole_reply(req, buf, 0, (len > 0));
+ } while (len > 0);
out_free:
kfree(buf);
- out_close:
- sys_close(fd);
- out:
- /* nothing */;
+ out_fput:
+ fput(file);
+ out: ;
}
#define UML_MCONSOLE_HELPTEXT \
View
3  drivers/base/dma-buf.c
@@ -460,8 +460,7 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
if (vma->vm_file)
fput(vma->vm_file);
- vma->vm_file = dmabuf->file;
- get_file(vma->vm_file);
+ vma->vm_file = get_file(dmabuf->file);
vma->vm_pgoff = pgoff;
View
10 drivers/infiniband/core/ucma.c
@@ -1183,7 +1183,7 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
struct rdma_ucm_migrate_id cmd;
struct rdma_ucm_migrate_resp resp;
struct ucma_context *ctx;
- struct file *filp;
+ struct fd f;
struct ucma_file *cur_file;
int ret = 0;
@@ -1191,12 +1191,12 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
return -EFAULT;
/* Get current fd to protect against it being closed */
- filp = fget(cmd.fd);
- if (!filp)
+ f = fdget(cmd.fd);
+ if (!f.file)
return -ENOENT;
/* 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)) {
ret = PTR_ERR(ctx);
goto file_put;
@@ -1230,7 +1230,7 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
ucma_put_ctx(ctx);
file_put:
- fput(filp);
+ fdput(f);
return ret;
}
View
21 drivers/infiniband/core/uverbs_cmd.c
@@ -705,7 +705,7 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
struct ib_udata udata;
struct ib_uxrcd_object *obj;
struct ib_xrcd *xrcd = NULL;
- struct file *f = NULL;
+ struct fd f = {NULL, 0};
struct inode *inode = NULL;
int ret = 0;
int new_xrcd = 0;
@@ -724,18 +724,13 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
if (cmd.fd != -1) {
/* search for file descriptor */
- f = fget(cmd.fd);
- if (!f) {
- ret = -EBADF;
- goto err_tree_mutex_unlock;
- }
-
- inode = f->f_dentry->d_inode;
- if (!inode) {
+ f = fdget(cmd.fd);
+ if (!f.file) {
ret = -EBADF;
goto err_tree_mutex_unlock;
}
+ inode = f.file->f_path.dentry->d_inode;
xrcd = find_xrcd(file->device, inode);
if (!xrcd && !(cmd.oflags & O_CREAT)) {
/* no file descriptor. Need CREATE flag */
@@ -800,8 +795,8 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
goto err_copy;
}
- if (f)
- fput(f);
+ if (f.file)
+ fdput(f);
mutex_lock(&file->mutex);
list_add_tail(&obj->uobject.list, &file->ucontext->xrcd_list);
@@ -830,8 +825,8 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
put_uobj_write(&obj->uobject);
err_tree_mutex_unlock:
- if (f)
- fput(f);
+ if (f.file)
+ fdput(f);
mutex_unlock(&file->device->xrcd_tree_mutex);
View
11 drivers/infiniband/core/uverbs_main.c
@@ -541,16 +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 *ev_file = NULL;
- struct file *filp;
+ struct fd f = fdget(fd);
- filp = fget(fd);
- if (!filp)
+ if (!f.file)
return NULL;
- if (filp->f_op != &uverbs_event_fops)
+ if (f.file->f_op != &uverbs_event_fops)
goto out;
- ev_file = filp->private_data;
+ ev_file = f.file->private_data;
if (ev_file->is_async) {
ev_file = NULL;
goto out;
@@ -559,7 +558,7 @@ struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd)
kref_get(&ev_file->ref);
out:
- fput(filp);
+ fdput(f);
return ev_file;
}
View
111 drivers/staging/android/binder.c
@@ -362,71 +362,22 @@ struct binder_transaction {
static void
binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer);
-/*
- * copied from get_unused_fd_flags
- */
static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
{
struct files_struct *files = proc->files;
- int fd, error;
- struct fdtable *fdt;
unsigned long rlim_cur;
unsigned long irqs;
if (files == NULL)
return -ESRCH;
- error = -EMFILE;
- spin_lock(&files->file_lock);
-
-repeat:
- fdt = files_fdtable(files);
- fd = find_next_zero_bit(fdt->open_fds, fdt->max_fds, files->next_fd);
-
- /*
- * N.B. For clone tasks sharing a files structure, this test
- * will limit the total number of files that can be opened.
- */
- rlim_cur = 0;
- if (lock_task_sighand(proc->tsk, &irqs)) {
- rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur;
- unlock_task_sighand(proc->tsk, &irqs);
- }
- if (fd >= rlim_cur)
- goto out;
-
- /* Do we need to expand the fd array or fd set? */
- error = expand_files(files, fd);
- if (error < 0)
- goto out;
-
- if (error) {
- /*
- * If we needed to expand the fs array we
- * might have blocked - try again.
- */
- error = -EMFILE;
- goto repeat;
- }
-
- __set_open_fd(fd, fdt);
- if (flags & O_CLOEXEC)
- __set_close_on_exec(fd, fdt);
- else
- __clear_close_on_exec(fd, fdt);
- files->next_fd = fd + 1;
-
- /* Sanity check */
- if (fdt->fd[fd] != NULL) {
- pr_warn("get_unused_fd: slot %d not NULL!\n", fd);
- fdt->fd[fd] = NULL;
- }
+ if (!lock_task_sighand(proc->tsk, &irqs))
+ return -EMFILE;
- error = fd;
+ rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE);
+ unlock_task_sighand(proc->tsk, &irqs);
-out:
- spin_unlock(&files->file_lock);
- return error;
+ return __alloc_fd(files, 0, rlim_cur, flags);
}
/*
@@ -435,28 +386,8 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
static void task_fd_install(
struct binder_proc *proc, unsigned int fd, struct file *file)
{
- struct files_struct *files = proc->files;
- struct fdtable *fdt;
-
- if (files == NULL)
- return;
-
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- BUG_ON(fdt->fd[fd] != NULL);
- rcu_assign_pointer(fdt->fd[fd], file);
- spin_unlock(&files->file_lock);
-}
-
-/*
- * copied from __put_unused_fd in open.c
- */
-static void __put_unused_fd(struct files_struct *files, unsigned int fd)
-{
- struct fdtable *fdt = files_fdtable(files);
- __clear_open_fd(fd, fdt);
- if (fd < files->next_fd)
- files->next_fd = fd;
+ if (proc->files)
+ __fd_install(proc->files, fd, file);
}
/*
@@ -464,27 +395,12 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd)
*/
static long task_close_fd(struct binder_proc *proc, unsigned int fd)
{
- struct file *filp;
- struct files_struct *files = proc->files;
- struct fdtable *fdt;
int retval;
- if (files == NULL)
+ if (proc->files == NULL)
return -ESRCH;
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- if (fd >= fdt->max_fds)
- goto out_unlock;
- filp = fdt->fd[fd];
- if (!filp)
- goto out_unlock;
- rcu_assign_pointer(fdt->fd[fd], NULL);
- __clear_close_on_exec(fd, fdt);
- __put_unused_fd(files, fd);
- spin_unlock(&files->file_lock);
- retval = filp_close(filp, files);
-
+ retval = __close_fd(proc->files, fd);
/* can't restart close syscall because file table entry was cleared */
if (unlikely(retval == -ERESTARTSYS ||
retval == -ERESTARTNOINTR ||
@@ -493,10 +409,6 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd)
retval = -EINTR;
return retval;
-
-out_unlock:
- spin_unlock(&files->file_lock);
- return -EBADF;
}
static void binder_set_nice(long nice)
@@ -2793,6 +2705,9 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
const char *failure_string;
struct binder_buffer *buffer;
+ if (proc->tsk != current)
+ return -EINVAL;
+
if ((vma->vm_end - vma->vm_start) > SZ_4M)
vma->vm_end = vma->vm_start + SZ_4M;
@@ -2857,7 +2772,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
binder_insert_free_buffer(proc, buffer);
proc->free_async_space = proc->buffer_size / 2;
barrier();
- proc->files = get_files_struct(proc->tsk);
+ proc->files = get_files_struct(current);
proc->vma = vma;
proc->vma_vm_mm = vma->vm_mm;
View
3  drivers/staging/omapdrm/omap_gem.c
@@ -592,9 +592,8 @@ int omap_gem_mmap_obj(struct drm_gem_object *obj,
* in particular in the case of mmap'd dmabufs)
*/
fput(vma->vm_file);
- get_file(obj->filp);
vma->vm_pgoff = 0;
- vma->vm_file = obj->filp;
+ vma->vm_file = get_file(obj->filp);
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
}
View
45 drivers/tty/tty_io.c
@@ -1166,10 +1166,8 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
struct file *p = NULL;
spin_lock(&redirect_lock);
- if (redirect) {
- get_file(redirect);
- p = redirect;
- }
+ if (redirect)
+ p = get_file(redirect);
spin_unlock(&redirect_lock);
if (p) {
@@ -2264,8 +2262,7 @@ static int tioccons(struct file *file)
spin_unlock(&redirect_lock);
return -EBUSY;
}
- get_file(file);
- redirect = file;
+ redirect = get_file(file);
spin_unlock(&redirect_lock);
return 0;
}
@@ -2809,6 +2806,13 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
}
#endif
+static int this_tty(const void *t, struct file *file, unsigned fd)
+{
+ if (likely(file->f_op->read != tty_read))
+ return 0;
+ return file_tty(file) != t ? 0 : fd + 1;
+}
+
/*
* This implements the "Secure Attention Key" --- the idea is to
* prevent trojan horses by killing all processes associated with this
@@ -2836,8 +2840,6 @@ void __do_SAK(struct tty_struct *tty)
struct task_struct *g, *p;
struct pid *session;
int i;
- struct file *filp;
- struct fdtable *fdt;
if (!tty)
return;
@@ -2867,27 +2869,12 @@ void __do_SAK(struct tty_struct *tty)
continue;
}
task_lock(p);
- if (p->files) {
- /*
- * We don't take a ref to the file, so we must
- * hold ->file_lock instead.
- */
- spin_lock(&p->files->file_lock);
- fdt = files_fdtable(p->files);
- for (i = 0; i < fdt->max_fds; i++) {
- filp = fcheck_files(p->files, i);
- if (!filp)
- continue;
- if (filp->f_op->read == tty_read &&
- file_tty(filp) == tty) {
- printk(KERN_NOTICE "SAK: killed process %d"
- " (%s): fd#%d opened to the tty\n",
- task_pid_nr(p), p->comm, i);
- force_sig(SIGKILL, p);
- break;
- }
- }
- spin_unlock(&p->files->file_lock);
+ i = iterate_fd(p->files, 0, this_tty, tty);
+ if (i != 0) {
+ printk(KERN_NOTICE "SAK: killed process %d"
+ " (%s): fd#%d opened to the tty\n",
+ task_pid_nr(p), p->comm, i - 1);
+ force_sig(SIGKILL, p);
}
task_unlock(p);
} while_each_thread(g, p);
View
4 drivers/usb/gadget/f_fs.c
@@ -340,7 +340,7 @@ ffs_sb_create_file(struct super_block *sb, const char *name, void *data,
static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock)
__attribute__((warn_unused_result, nonnull));
-static char *ffs_prepare_buffer(const char * __user buf, size_t len)
+static char *ffs_prepare_buffer(const char __user *buf, size_t len)
__attribute__((warn_unused_result, nonnull));
@@ -2445,7 +2445,7 @@ static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock)
: mutex_lock_interruptible(mutex);
}
-static char *ffs_prepare_buffer(const char * __user buf, size_t len)
+static char *ffs_prepare_buffer(const char __user *buf, size_t len)
{
char *data;
View
15 drivers/vfio/vfio.c
@@ -1014,7 +1014,7 @@ static void vfio_group_try_dissolve_container(struct vfio_group *group)
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_iommu_driver *driver;
int ret = 0;
@@ -1022,17 +1022,17 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
if (atomic_read(&group->container_users))
return -EINVAL;
- filep = fget(container_fd);
- if (!filep)
+ f = fdget(container_fd);
+ if (!f.file)
return -EBADF;
/* Sanity check, is this really our fd? */
- if (filep->f_op != &vfio_fops) {
- fput(filep);
+ if (f.file->f_op != &vfio_fops) {
+ fdput(f);
return -EINVAL;
}
- container = filep->private_data;
+ container = f.file->private_data;
WARN_ON(!container); /* fget ensures we don't race vfio_release */
mutex_lock(&container->group_lock);
@@ -1054,8 +1054,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
unlock_out:
mutex_unlock(&container->group_lock);
- fput(filep);
-
+ fdput(f);
return ret;
}
View
8 drivers/vhost/vhost.c
@@ -636,8 +636,8 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
{
- struct file *eventfp, *filep = NULL,
- *pollstart = NULL, *pollstop = NULL;
+ struct file *eventfp, *filep = NULL;
+ bool pollstart = false, pollstop = false;
struct eventfd_ctx *ctx = NULL;
u32 __user *idxp = argp;
struct vhost_virtqueue *vq;
@@ -763,8 +763,8 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
break;
}
if (eventfp != vq->kick) {
- pollstop = filep = vq->kick;
- pollstart = vq->kick = eventfp;
+ pollstop = (filep = vq->kick) != NULL;
+ pollstart = (vq->kick = eventfp) != NULL;
} else
filep = eventfp;
break;
View
12 drivers/video/msm/mdp.c
@@ -257,19 +257,17 @@ int get_img(struct mdp_img *img, struct fb_info *info,
unsigned long *start, unsigned long *len,
struct file **filep)
{
- int put_needed, ret = 0;
- struct file *file;
-
- file = fget_light(img->memory_id, &put_needed);
- if (file == NULL)
+ int ret = 0;
+ struct fd f = fdget(img->memory_id);
+ if (f.file == NULL)
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;
*len = info->fix.smem_len;
} else
ret = -1;
- fput_light(file, put_needed);
+ fdput(f);
return ret;
}
View
5 fs/9p/v9fs.c
@@ -560,6 +560,11 @@ static int v9fs_init_inode_cache(void)
*/
static void v9fs_destroy_inode_cache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(v9fs_inode_cache);
}
View
2  fs/Makefile
@@ -11,7 +11,7 @@ obj-y := open.o read_write.o file_table.o super.o \
attr.o bad_inode.o file.o filesystems.o namespace.o \
seq_file.o xattr.o libfs.o fs-writeback.o \
pnode.o drop_caches.o splice.o sync.o utimes.o \
- stack.o fs_struct.o statfs.o
+ stack.o fs_struct.o statfs.o coredump.o
ifeq ($(CONFIG_BLOCK),y)
obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o
View
5 fs/adfs/super.c
@@ -280,6 +280,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(adfs_inode_cachep);
}
View
5 fs/affs/super.c
@@ -147,6 +147,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(affs_inode_cachep);
}
View
5 fs/afs/super.c
@@ -123,6 +123,11 @@ void __exit afs_fs_exit(void)
BUG();
}
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(afs_inode_cachep);
_leave("");
}
View
18 fs/autofs4/dev-ioctl.c
@@ -221,20 +221,6 @@ static int test_by_type(struct path *path, void *p)
return ino && ino->sbi->type & *(unsigned *)p;
}
-static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file)
-{
- struct files_struct *files = current->files;
- struct fdtable *fdt;
-
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- BUG_ON(fdt->fd[fd] != NULL);
- rcu_assign_pointer(fdt->fd[fd], file);
- __set_close_on_exec(fd, fdt);
- spin_unlock(&files->file_lock);
-}
-
-
/*
* Open a file descriptor on the autofs mount point corresponding
* to the given path and device number (aka. new_encode_dev(sb->s_dev)).
@@ -243,7 +229,7 @@ static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid)
{
int err, fd;
- fd = get_unused_fd();
+ fd = get_unused_fd_flags(O_CLOEXEC);
if (likely(fd >= 0)) {
struct file *filp;
struct path path;
@@ -264,7 +250,7 @@ static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid)
goto out;
}
- autofs_dev_ioctl_fd_install(fd, filp);
+ fd_install(fd, filp);
}
return fd;
View
3  fs/autofs4/waitq.c
@@ -175,8 +175,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
return;
}
- pipe = sbi->pipe;
- get_file(pipe);
+ pipe = get_file(sbi->pipe);
mutex_unlock(&sbi->wq_mutex);
View
5 fs/befs/linuxvfs.c
@@ -457,6 +457,11 @@ befs_init_inodecache(void)
static void
befs_destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(befs_inode_cachep);
}
View
5 fs/bfs/inode.c
@@ -280,6 +280,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(bfs_inode_cachep);
}
View
19 fs/binfmt_elf.c
@@ -1696,30 +1696,19 @@ static int elf_note_info_init(struct elf_note_info *info)
return 0;
info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL);
if (!info->psinfo)
- goto notes_free;
+ return 0;
info->prstatus = kmalloc(sizeof(*info->prstatus), GFP_KERNEL);
if (!info->prstatus)
- goto psinfo_free;
+ return 0;
info->fpu = kmalloc(sizeof(*info->fpu), GFP_KERNEL);
if (!info->fpu)
- goto prstatus_free;
+ return 0;
#ifdef ELF_CORE_COPY_XFPREGS
info->xfpu = kmalloc(sizeof(*info->xfpu), GFP_KERNEL);
if (!info->xfpu)
- goto fpu_free;
+ return 0;
#endif
return 1;
-#ifdef ELF_CORE_COPY_XFPREGS
- fpu_free:
- kfree(info->fpu);
-#endif
- prstatus_free:
- kfree(info->prstatus);
- psinfo_free:
- kfree(info->psinfo);
- notes_free:
- kfree(info->notes);
- return 0;
}
static int fill_note_info(struct elfhdr *elf, int phdrs,
View
6 fs/btrfs/extent_io.c
@@ -107,6 +107,12 @@ void extent_io_exit(void)
list_del(&eb->leak_list);
kmem_cache_free(extent_buffer_cache, eb);
}
+
+ /*
+ * Make sure all delayed rcu free are flushed before we
+ * destroy caches.
+ */
+ rcu_barrier();
if (extent_state_cache)
kmem_cache_destroy(extent_state_cache);
if (extent_buffer_cache)
View
5 fs/btrfs/inode.c
@@ -7076,6 +7076,11 @@ static void init_once(void *foo)
void btrfs_destroy_cachep(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
if (btrfs_inode_cachep)
kmem_cache_destroy(btrfs_inode_cachep);
if (btrfs_trans_handle_cachep)
View
32 fs/btrfs/ioctl.c
@@ -1397,7 +1397,6 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
u64 *transid, bool readonly,
struct btrfs_qgroup_inherit **inherit)
{
- struct file *src_file;
int namelen;
int ret = 0;
@@ -1421,25 +1420,24 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
ret = btrfs_mksubvol(&file->f_path, name, namelen,
NULL, transid, readonly, inherit);
} else {
+ struct fd src = fdget(fd);
struct inode *src_inode;
- src_file = fget(fd);
- if (!src_file) {
+ if (!src.file) {
ret = -EINVAL;
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) {
printk(KERN_INFO "btrfs: Snapshot src from "
"another FS\n");
ret = -EINVAL;
- fput(src_file);
- goto out_drop_write;
+ } else {
+ ret = btrfs_mksubvol(&file->f_path, name, namelen,
+ BTRFS_I(src_inode)->root,
+ transid, readonly, inherit);
}
- ret = btrfs_mksubvol(&file->f_path, name, namelen,
- BTRFS_I(src_inode)->root,
- transid, readonly, inherit);
- fput(src_file);
+ fdput(src);
}
out_drop_write:
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 btrfs_root *root = BTRFS_I(inode)->root;
- struct file *src_file;
+ struct fd src_file;
struct inode *src;
struct btrfs_trans_handle *trans;
struct btrfs_path *path;
@@ -2376,24 +2374,24 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
if (ret)
return ret;
- src_file = fget(srcfd);
- if (!src_file) {
+ src_file = fdget(srcfd);
+ if (!src_file.file) {
ret = -EBADF;
goto out_drop_write;
}
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;
- src = src_file->f_dentry->d_inode;
+ src = src_file.file->f_dentry->d_inode;
ret = -EINVAL;
if (src == inode)
goto out_fput;
/* 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;
/* don't make the dst file partly checksummed */
@@ -2724,7 +2722,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
vfree(buf);
btrfs_free_path(path);
out_fput:
- fput(src_file);
+ fdput(src_file);
out_drop_write:
mnt_drop_write_file(file);
return ret;
View
18 fs/btrfs/reada.c
@@ -68,7 +68,7 @@ struct reada_extent {
u32 blocksize;
int err;
struct list_head extctl;
- struct kref refcnt;
+ int refcnt;
spinlock_t lock;
struct reada_zone *zones[BTRFS_MAX_MIRRORS];
int nzones;
@@ -126,7 +126,7 @@ static int __readahead_hook(struct btrfs_root *root, struct extent_buffer *eb,
spin_lock(&fs_info->reada_lock);
re = radix_tree_lookup(&fs_info->reada_tree, index);
if (re)
- kref_get(&re->refcnt);
+ re->refcnt++;
spin_unlock(&fs_info->reada_lock);
if (!re)
@@ -336,7 +336,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
spin_lock(&fs_info->reada_lock);
re = radix_tree_lookup(&fs_info->reada_tree, index);
if (re)
- kref_get(&re->refcnt);
+ re->refcnt++;
spin_unlock(&fs_info->reada_lock);
if (re)
@@ -352,7 +352,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
re->top = *top;
INIT_LIST_HEAD(&re->extctl);
spin_lock_init(&re->lock);
- kref_init(&re->refcnt);
+ re->refcnt = 1;
/*
* map block
@@ -398,7 +398,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
if (ret == -EEXIST) {
re_exist = radix_tree_lookup(&fs_info->reada_tree, index);
BUG_ON(!re_exist);
- kref_get(&re_exist->refcnt);
+ re_exist->refcnt++;
spin_unlock(&fs_info->reada_lock);
goto error;
}
@@ -465,10 +465,6 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
return re_exist;
}
-static void reada_kref_dummy(struct kref *kr)
-{
-}
-
static void reada_extent_put(struct btrfs_fs_info *fs_info,
struct reada_extent *re)
{
@@ -476,7 +472,7 @@ static void reada_extent_put(struct btrfs_fs_info *fs_info,
unsigned long index = re->logical >> PAGE_CACHE_SHIFT;
spin_lock(&fs_info->reada_lock);
- if (!kref_put(&re->refcnt, reada_kref_dummy)) {
+ if (--re->refcnt) {
spin_unlock(&fs_info->reada_lock);
return;
}
@@ -671,7 +667,7 @@ static int reada_start_machine_dev(struct btrfs_fs_info *fs_info,
return 0;
}
dev->reada_next = re->logical + re->blocksize;
- kref_get(&re->refcnt);
+ re->refcnt++;
spin_unlock(&fs_info->reada_lock);
View
4 fs/ceph/inode.c
@@ -1104,7 +1104,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
pr_err("fill_trace bad get_inode "
"%llx.%llx\n", vino.ino, vino.snap);
err = PTR_ERR(in);
- d_delete(dn);
+ d_drop(dn);
goto done;
}
dn = splice_dentry(dn, in, &have_lease, true);
@@ -1277,7 +1277,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
in = ceph_get_inode(parent->d_sb, vino);
if (IS_ERR(in)) {
dout("new_inode badness\n");
- d_delete(dn);
+ d_drop(dn);
dput(dn);
err = PTR_ERR(in);
goto out;
View
5 fs/ceph/super.c
@@ -603,6 +603,11 @@ static int __init init_caches(void)
static void destroy_caches(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(ceph_inode_cachep);
kmem_cache_destroy(ceph_cap_cachep);
kmem_cache_destroy(ceph_dentry_cachep);
View
5 fs/cifs/cifsfs.c
@@ -968,6 +968,11 @@ cifs_init_inodecache(void)
static void
cifs_destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(cifs_inode_cachep);
}
View
37 fs/coda/inode.c
@@ -85,6 +85,11 @@ int coda_init_inodecache(void)
void coda_destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(coda_inode_cachep);
}
@@ -107,43 +112,41 @@ static const struct super_operations coda_super_operations =
static int get_device_index(struct coda_mount_data *data)
{
- struct file *file;
+ struct fd f;
struct inode *inode;
int idx;
- if(data == NULL) {
+ if (data == NULL) {
printk("coda_read_super: Bad mount data\n");
return -1;
}
- if(data->version != CODA_MOUNT_VERSION) {
+ if (data->version != CODA_MOUNT_VERSION) {
printk("coda_read_super: Bad mount version\n");
return -1;
}
- file = fget(data->fd);
- inode = NULL;
- if(file)
- inode = file->f_path.dentry->d_inode;
-
- if(!inode || !S_ISCHR(inode->i_mode) ||
- imajor(inode) != CODA_PSDEV_MAJOR) {
- if(file)
- fput(file);
-
- printk("coda_read_super: Bad file\n");
- return -1;
+ f = fdget(data->fd);
+ if (!f.file)
+ goto Ebadf;
+ inode = f.file->f_path.dentry->d_inode;
+ if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) {
+ fdput(f);
+ goto Ebadf;
}
idx = iminor(inode);
- fput(file);
+ fdput(f);
- if(idx < 0 || idx >= MAX_CODADEVS) {
+ if (idx < 0 || idx >= MAX_CODADEVS) {
printk("coda_read_super: Bad minor number\n");
return -1;
}
return idx;
+Ebadf:
+ printk("coda_read_super: Bad file\n");
+ return -1;
}
static int coda_fill_super(struct super_block *sb, void *data, int silent)
View
112 fs/compat.c
@@ -870,22 +870,20 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,
struct compat_old_linux_dirent __user *dirent, unsigned int count)
{
int error;
- struct file *file;
- int fput_needed;
+ struct fd f = fdget(fd);
struct compat_readdir_callback buf;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ if (!f.file)
return -EBADF;
buf.result = 0;
buf.dirent = dirent;
- error = vfs_readdir(file, compat_fillonedir, &buf);
+ error = vfs_readdir(f.file, compat_fillonedir, &buf);
if (buf.result)
error = buf.result;
- fput_light(file, fput_needed);
+ fdput(f);
return error;
}
@@ -949,17 +947,16 @@ static int compat_filldir(void *__buf, const char *name, int namlen,
asmlinkage long compat_sys_getdents(unsigned int fd,
struct compat_linux_dirent __user *dirent, unsigned int count)
{
- struct file * file;
+ struct fd f;
struct compat_linux_dirent __user * lastdirent;
struct compat_getdents_callback buf;
- int fput_needed;
int error;
if (!access_ok(VERIFY_WRITE, dirent, count))
return -EFAULT;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
buf.current_dir = dirent;
@@ -967,17 +964,17 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
buf.count = count;
buf.error = 0;
- error = vfs_readdir(file, compat_filldir, &buf);
+ error = vfs_readdir(f.file, compat_filldir, &buf);
if (error >= 0)
error = buf.error;
lastdirent = buf.previous;
if (lastdirent) {
- if (put_user(file->f_pos, &lastdirent->d_off))
+ if (put_user(f.file->f_pos, &lastdirent->d_off))
error = -EFAULT;
else
error = count - buf.count;
}
- fput_light(file, fput_needed);
+ fdput(f);
return error;
}
@@ -1035,17 +1032,16 @@ static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t
asmlinkage long compat_sys_getdents64(unsigned int fd,
struct linux_dirent64 __user * dirent, unsigned int count)
{
- struct file * file;
+ struct fd f;
struct linux_dirent64 __user * lastdirent;
struct compat_getdents_callback64 buf;
- int fput_needed;
int error;
if (!access_ok(VERIFY_WRITE, dirent, count))
return -EFAULT;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
buf.current_dir = dirent;
@@ -1053,18 +1049,18 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
buf.count = count;
buf.error = 0;
- error = vfs_readdir(file, compat_filldir64, &buf);
+ error = vfs_readdir(f.file, compat_filldir64, &buf);
if (error >= 0)
error = buf.error;
lastdirent = buf.previous;
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))
error = -EFAULT;
else
error = count - buf.count;
}
- fput_light(file, fput_needed);
+ fdput(f);
return error;
}
#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,
unsigned long vlen)
{
- struct file *file;
- int fput_needed;
+ struct fd f = fdget(fd);
ssize_t ret;
loff_t pos;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ if (!f.file)
return -EBADF;
- pos = file->f_pos;
- ret = compat_readv(file, vec, vlen, &pos);
- file->f_pos = pos;
- fput_light(file, fput_needed);
+ pos = f.file->f_pos;
+ ret = compat_readv(f.file, vec, vlen, &pos);
+ f.file->f_pos = pos;
+ fdput(f);
return ret;
}
@@ -1171,19 +1165,18 @@ asmlinkage ssize_t
compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen, loff_t pos)
{
- struct file *file;
- int fput_needed;
+ struct fd f;
ssize_t ret;
if (pos < 0)
return -EINVAL;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
ret = -ESPIPE;
- if (file->f_mode & FMODE_PREAD)
- ret = compat_readv(file, vec, vlen, &pos);
- fput_light(file, fput_needed);
+ if (f.file->f_mode & FMODE_PREAD)
+ ret = compat_readv(f.file, vec, vlen, &pos);
+ fdput(f);
return ret;
}
@@ -1221,18 +1214,16 @@ asmlinkage ssize_t
compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen)
{
- struct file *file;
- int fput_needed;
+ struct fd f = fdget(fd);
ssize_t ret;
loff_t pos;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ if (!f.file)
return -EBADF;
- pos = file->f_pos;
- ret = compat_writev(file, vec, vlen, &pos);
- file->f_pos = pos;
- fput_light(file, fput_needed);
+ pos = f.file->f_pos;
+ ret = compat_writev(f.file, vec, vlen, &pos);
+ f.file->f_pos = pos;
+ fdput(f);
return ret;
}
@@ -1240,19 +1231,18 @@ asmlinkage ssize_t
compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen, loff_t pos)
{
- struct file *file;
- int fput_needed;
+ struct fd f;
ssize_t ret;
if (pos < 0)
return -EINVAL;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
ret = -ESPIPE;
- if (file->f_mode & FMODE_PWRITE)
- ret = compat_writev(file, vec, vlen, &pos);
- fput_light(file, fput_needed);
+ if (f.file->f_mode & FMODE_PWRITE)
+ ret = compat_writev(f.file, vec, vlen, &pos);
+ fdput(f);
return ret;
}
@@ -1802,3 +1792,25 @@ compat_sys_open_by_handle_at(int mountdirfd,
return do_handle_open(mountdirfd, handle, flags);
}
#endif
+
+#ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE
+asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
+ compat_off_t __user *offset, compat_size_t count)
+{
+ loff_t pos;
+ off_t off;
+ ssize_t ret;
+
+ if (offset) {
+ if (unlikely(get_user(off, offset)))
+ return -EFAULT;
+ pos = off;
+ ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
+ if (unlikely(put_user(pos, offset)))
+ return -EFAULT;
+ return ret;
+ }
+
+ return do_sendfile(out_fd, in_fd, NULL, count, 0);
+}
+#endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */
View
27 fs/compat_ioctl.c
@@ -1539,16 +1539,13 @@ static int compat_ioctl_check_table(unsigned int xcmd)
asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg)
{
- struct file *filp;
+ struct fd f = fdget(fd);
int error = -EBADF;
- int fput_needed;
-
- filp = fget_light(fd, &fput_needed);
- if (!filp)
+ if (!f.file)
goto out;
/* 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)
goto out_fput;
@@ -1568,30 +1565,30 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
case FS_IOC_RESVSP_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;
#else
case FS_IOC_RESVSP:
case FS_IOC_RESVSP64:
- error = ioctl_preallocate(filp, compat_ptr(arg));
+ error = ioctl_preallocate(f.file, compat_ptr(arg));
goto out_fput;
#endif
case FIBMAP:
case FIGETBSZ:
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;
/*FALL THROUGH*/
default:
- if (filp->f_op && filp->f_op->compat_ioctl) {
- error = filp->f_op->compat_ioctl(filp, cmd, arg);
+ if (f.file->f_op && f.file->f_op->compat_ioctl) {
+ error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
if (error != -ENOIOCTLCMD)
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;
break;