aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 23:25:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 23:25:04 -0400
commitaab174f0df5d72d31caccf281af5f614fa254578 (patch)
tree2a172c5009c4ac8755e858593154c258ce7709a0 /arch
parentca41cc96b2813221b05af57d0355157924de5a07 (diff)
parent2bd2c1941f141ad780135ccc1cd08ca71a24f10a (diff)
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() ...
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/osf_sys.c13
-rw-r--r--arch/ia64/kernel/perfmon.c18
-rw-r--r--arch/parisc/hpux/fs.c17
-rw-r--r--arch/powerpc/include/asm/systbl.h4
-rw-r--r--arch/powerpc/include/asm/unistd.h1
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c45
-rw-r--r--arch/powerpc/platforms/cell/spu_syscalls.c21
-rw-r--r--arch/powerpc/platforms/cell/spufs/coredump.c40
-rw-r--r--arch/s390/hypfs/inode.c2
-rw-r--r--arch/sparc/include/asm/unistd.h1
-rw-r--r--arch/sparc/kernel/sys32.S2
-rw-r--r--arch/sparc/kernel/sys_sparc32.c46
-rw-r--r--arch/um/drivers/mconsole_kern.c99
13 files changed, 83 insertions, 226 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 9503a4be40f6..63e77e3944ce 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -145,27 +145,24 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
145 long __user *, basep) 145 long __user *, basep)
146{ 146{
147 int error; 147 int error;
148 struct file *file; 148 struct fd arg = fdget(fd);
149 struct osf_dirent_callback buf; 149 struct osf_dirent_callback buf;
150 150
151 error = -EBADF; 151 if (!arg.file)
152 file = fget(fd); 152 return -EBADF;
153 if (!file)
154 goto out;
155 153
156 buf.dirent = dirent; 154 buf.dirent = dirent;
157 buf.basep = basep; 155 buf.basep = basep;
158 buf.count = count; 156 buf.count = count;
159 buf.error = 0; 157 buf.error = 0;
160 158
161 error = vfs_readdir(file, osf_filldir, &buf); 159 error = vfs_readdir(arg.file, osf_filldir, &buf);
162 if (error >= 0) 160 if (error >= 0)
163 error = buf.error; 161 error = buf.error;
164 if (count != buf.count) 162 if (count != buf.count)
165 error = count - buf.count; 163 error = count - buf.count;
166 164
167 fput(file); 165 fdput(arg);
168 out:
169 return error; 166 return error;
170} 167}
171 168
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 5a5c22245dee..f388b4e18a37 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2306,7 +2306,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
2306 * partially initialize the vma for the sampling buffer 2306 * partially initialize the vma for the sampling buffer
2307 */ 2307 */
2308 vma->vm_mm = mm; 2308 vma->vm_mm = mm;
2309 vma->vm_file = filp; 2309 vma->vm_file = get_file(filp);
2310 vma->vm_flags = VM_READ| VM_MAYREAD |VM_RESERVED; 2310 vma->vm_flags = VM_READ| VM_MAYREAD |VM_RESERVED;
2311 vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */ 2311 vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */
2312 2312
@@ -2345,8 +2345,6 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
2345 goto error; 2345 goto error;
2346 } 2346 }
2347 2347
2348 get_file(filp);
2349
2350 /* 2348 /*
2351 * now insert the vma in the vm list for the process, must be 2349 * now insert the vma in the vm list for the process, must be
2352 * done with mmap lock held 2350 * done with mmap lock held
@@ -4782,7 +4780,7 @@ recheck:
4782asmlinkage long 4780asmlinkage long
4783sys_perfmonctl (int fd, int cmd, void __user *arg, int count) 4781sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
4784{ 4782{
4785 struct file *file = NULL; 4783 struct fd f = {NULL, 0};
4786 pfm_context_t *ctx = NULL; 4784 pfm_context_t *ctx = NULL;
4787 unsigned long flags = 0UL; 4785 unsigned long flags = 0UL;
4788 void *args_k = NULL; 4786 void *args_k = NULL;
@@ -4879,17 +4877,17 @@ restart_args:
4879 4877
4880 ret = -EBADF; 4878 ret = -EBADF;
4881 4879
4882 file = fget(fd); 4880 f = fdget(fd);
4883 if (unlikely(file == NULL)) { 4881 if (unlikely(f.file == NULL)) {
4884 DPRINT(("invalid fd %d\n", fd)); 4882 DPRINT(("invalid fd %d\n", fd));
4885 goto error_args; 4883 goto error_args;
4886 } 4884 }
4887 if (unlikely(PFM_IS_FILE(file) == 0)) { 4885 if (unlikely(PFM_IS_FILE(f.file) == 0)) {
4888 DPRINT(("fd %d not related to perfmon\n", fd)); 4886 DPRINT(("fd %d not related to perfmon\n", fd));
4889 goto error_args; 4887 goto error_args;
4890 } 4888 }
4891 4889
4892 ctx = file->private_data; 4890 ctx = f.file->private_data;
4893 if (unlikely(ctx == NULL)) { 4891 if (unlikely(ctx == NULL)) {
4894 DPRINT(("no context for fd %d\n", fd)); 4892 DPRINT(("no context for fd %d\n", fd));
4895 goto error_args; 4893 goto error_args;
@@ -4919,8 +4917,8 @@ abort_locked:
4919 if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT; 4917 if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
4920 4918
4921error_args: 4919error_args:
4922 if (file) 4920 if (f.file)
4923 fput(file); 4921 fdput(f);
4924 4922
4925 kfree(args_k); 4923 kfree(args_k);
4926 4924
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index c71eb6c79897..6785de7bd2a0 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -109,33 +109,32 @@ Efault:
109 109
110int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count) 110int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count)
111{ 111{
112 struct file * file; 112 struct fd arg;
113 struct hpux_dirent __user * lastdirent; 113 struct hpux_dirent __user * lastdirent;
114 struct getdents_callback buf; 114 struct getdents_callback buf;
115 int error = -EBADF; 115 int error;
116 116
117 file = fget(fd); 117 arg = fdget(fd);
118 if (!file) 118 if (!arg.file)
119 goto out; 119 return -EBADF;
120 120
121 buf.current_dir = dirent; 121 buf.current_dir = dirent;
122 buf.previous = NULL; 122 buf.previous = NULL;
123 buf.count = count; 123 buf.count = count;
124 buf.error = 0; 124 buf.error = 0;
125 125
126 error = vfs_readdir(file, filldir, &buf); 126 error = vfs_readdir(arg.file, filldir, &buf);
127 if (error >= 0) 127 if (error >= 0)
128 error = buf.error; 128 error = buf.error;
129 lastdirent = buf.previous; 129 lastdirent = buf.previous;
130 if (lastdirent) { 130 if (lastdirent) {
131 if (put_user(file->f_pos, &lastdirent->d_off)) 131 if (put_user(arg.file->f_pos, &lastdirent->d_off))
132 error = -EFAULT; 132 error = -EFAULT;
133 else 133 else
134 error = count - buf.count; 134 error = count - buf.count;
135 } 135 }
136 136
137 fput(file); 137 fdput(arg);
138out:
139 return error; 138 return error;
140} 139}
141 140
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 559ae1ee6706..840838769853 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -189,7 +189,7 @@ SYSCALL_SPU(getcwd)
189SYSCALL_SPU(capget) 189SYSCALL_SPU(capget)
190SYSCALL_SPU(capset) 190SYSCALL_SPU(capset)
191COMPAT_SYS(sigaltstack) 191COMPAT_SYS(sigaltstack)
192SYSX_SPU(sys_sendfile64,compat_sys_sendfile,sys_sendfile) 192SYSX_SPU(sys_sendfile,compat_sys_sendfile_wrapper,sys_sendfile)
193SYSCALL(ni_syscall) 193SYSCALL(ni_syscall)
194SYSCALL(ni_syscall) 194SYSCALL(ni_syscall)
195PPC_SYS(vfork) 195PPC_SYS(vfork)
@@ -229,7 +229,7 @@ COMPAT_SYS_SPU(sched_setaffinity)
229COMPAT_SYS_SPU(sched_getaffinity) 229COMPAT_SYS_SPU(sched_getaffinity)
230SYSCALL(ni_syscall) 230SYSCALL(ni_syscall)
231SYSCALL(ni_syscall) 231SYSCALL(ni_syscall)
232SYS32ONLY(sendfile64) 232SYSX(sys_ni_syscall,compat_sys_sendfile64_wrapper,sys_sendfile64)
233COMPAT_SYS_SPU(io_setup) 233COMPAT_SYS_SPU(io_setup)
234SYSCALL_SPU(io_destroy) 234SYSCALL_SPU(io_destroy)
235COMPAT_SYS_SPU(io_getevents) 235COMPAT_SYS_SPU(io_getevents)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index bd377a368611..c683fa350add 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -419,6 +419,7 @@
419#define __ARCH_WANT_COMPAT_SYS_TIME 419#define __ARCH_WANT_COMPAT_SYS_TIME
420#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 420#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
421#define __ARCH_WANT_SYS_NEWFSTATAT 421#define __ARCH_WANT_SYS_NEWFSTATAT
422#define __ARCH_WANT_COMPAT_SYS_SENDFILE
422#endif 423#endif
423 424
424/* 425/*
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index 81c570633ead..abd1112da54f 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/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
143 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 143 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
144 * and the register representation of a signed int (msr in 64-bit mode) is performed. 144 * and the register representation of a signed int (msr in 64-bit mode) is performed.
145 */ 145 */
146asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count) 146asmlinkage long compat_sys_sendfile_wrapper(u32 out_fd, u32 in_fd,
147 compat_off_t __user *offset, u32 count)
147{ 148{
148 mm_segment_t old_fs = get_fs(); 149 return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count);
149 int ret;
150 off_t of;
151 off_t __user *up;
152
153 if (offset && get_user(of, offset))
154 return -EFAULT;
155
156 /* The __user pointer cast is valid because of the set_fs() */
157 set_fs(KERNEL_DS);
158 up = offset ? (off_t __user *) &of : NULL;
159 ret = sys_sendfile((int)out_fd, (int)in_fd, up, count);
160 set_fs(old_fs);
161
162 if (offset && put_user(of, offset))
163 return -EFAULT;
164
165 return ret;
166} 150}
167 151
168asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) 152asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd,
153 compat_loff_t __user *offset, u32 count)
169{ 154{
170 mm_segment_t old_fs = get_fs(); 155 return sys_sendfile((int)out_fd, (int)in_fd,
171 int ret; 156 (off_t __user *)offset, count);
172 loff_t lof;
173 loff_t __user *up;
174
175 if (offset && get_user(lof, offset))
176 return -EFAULT;
177
178 /* The __user pointer cast is valid because of the set_fs() */
179 set_fs(KERNEL_DS);
180 up = offset ? (loff_t __user *) &lof : NULL;
181 ret = sys_sendfile64(out_fd, in_fd, up, count);
182 set_fs(old_fs);
183
184 if (offset && put_user(lof, offset))
185 return -EFAULT;
186
187 return ret;
188} 157}
189 158
190long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, 159long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c
index 714bbfc3162c..db4e638cf408 100644
--- a/arch/powerpc/platforms/cell/spu_syscalls.c
+++ b/arch/powerpc/platforms/cell/spu_syscalls.c
@@ -69,8 +69,6 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
69 umode_t, mode, int, neighbor_fd) 69 umode_t, mode, int, neighbor_fd)
70{ 70{
71 long ret; 71 long ret;
72 struct file *neighbor;
73 int fput_needed;
74 struct spufs_calls *calls; 72 struct spufs_calls *calls;
75 73
76 calls = spufs_calls_get(); 74 calls = spufs_calls_get();
@@ -78,11 +76,11 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
78 return -ENOSYS; 76 return -ENOSYS;
79 77
80 if (flags & SPU_CREATE_AFFINITY_SPU) { 78 if (flags & SPU_CREATE_AFFINITY_SPU) {
79 struct fd neighbor = fdget(neighbor_fd);
81 ret = -EBADF; 80 ret = -EBADF;
82 neighbor = fget_light(neighbor_fd, &fput_needed); 81 if (neighbor.file) {
83 if (neighbor) { 82 ret = calls->create_thread(name, flags, mode, neighbor.file);
84 ret = calls->create_thread(name, flags, mode, neighbor); 83 fdput(neighbor);
85 fput_light(neighbor, fput_needed);
86 } 84 }
87 } else 85 } else
88 ret = calls->create_thread(name, flags, mode, NULL); 86 ret = calls->create_thread(name, flags, mode, NULL);
@@ -94,8 +92,7 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
94asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus) 92asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
95{ 93{
96 long ret; 94 long ret;
97 struct file *filp; 95 struct fd arg;
98 int fput_needed;
99 struct spufs_calls *calls; 96 struct spufs_calls *calls;
100 97
101 calls = spufs_calls_get(); 98 calls = spufs_calls_get();
@@ -103,10 +100,10 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
103 return -ENOSYS; 100 return -ENOSYS;
104 101
105 ret = -EBADF; 102 ret = -EBADF;
106 filp = fget_light(fd, &fput_needed); 103 arg = fdget(fd);
107 if (filp) { 104 if (arg.file) {
108 ret = calls->spu_run(filp, unpc, ustatus); 105 ret = calls->spu_run(arg.file, unpc, ustatus);
109 fput_light(filp, fput_needed); 106 fdput(arg);
110 } 107 }
111 108
112 spufs_calls_put(calls); 109 spufs_calls_put(calls);
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index c2c5b078ba80..657e3f233a64 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -106,6 +106,17 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
106 return total; 106 return total;
107} 107}
108 108
109static int match_context(const void *v, struct file *file, unsigned fd)
110{
111 struct spu_context *ctx;
112 if (file->f_op != &spufs_context_fops)
113 return 0;
114 ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
115 if (ctx->flags & SPU_CREATE_NOSCHED)
116 return 0;
117 return fd + 1;
118}
119
109/* 120/*
110 * The additional architecture-specific notes for Cell are various 121 * The additional architecture-specific notes for Cell are various
111 * context files in the spu context. 122 * context files in the spu context.
@@ -115,29 +126,18 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
115 * internal functionality to dump them without needing to actually 126 * internal functionality to dump them without needing to actually
116 * open the files. 127 * open the files.
117 */ 128 */
129/*
130 * descriptor table is not shared, so files can't change or go away.
131 */
118static struct spu_context *coredump_next_context(int *fd) 132static struct spu_context *coredump_next_context(int *fd)
119{ 133{
120 struct fdtable *fdt = files_fdtable(current->files);
121 struct file *file; 134 struct file *file;
122 struct spu_context *ctx = NULL; 135 int n = iterate_fd(current->files, *fd, match_context, NULL);
123 136 if (!n)
124 for (; *fd < fdt->max_fds; (*fd)++) { 137 return NULL;
125 if (!fd_is_open(*fd, fdt)) 138 *fd = n - 1;
126 continue; 139 file = fcheck(*fd);
127 140 return SPUFS_I(file->f_dentry->d_inode)->i_ctx;
128 file = fcheck(*fd);
129
130 if (!file || file->f_op != &spufs_context_fops)
131 continue;
132
133 ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
134 if (ctx->flags & SPU_CREATE_NOSCHED)
135 continue;
136
137 break;
138 }
139
140 return ctx;
141} 141}
142 142
143int spufs_coredump_extra_notes_size(void) 143int spufs_coredump_extra_notes_size(void)
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 124ec1a55cc9..06ea69bd387a 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -72,8 +72,6 @@ static void hypfs_remove(struct dentry *dentry)
72 struct dentry *parent; 72 struct dentry *parent;
73 73
74 parent = dentry->d_parent; 74 parent = dentry->d_parent;
75 if (!parent || !parent->d_inode)
76 return;
77 mutex_lock(&parent->d_inode->i_mutex); 75 mutex_lock(&parent->d_inode->i_mutex);
78 if (hypfs_positive(dentry)) { 76 if (hypfs_positive(dentry)) {
79 if (S_ISDIR(dentry->d_inode->i_mode)) 77 if (S_ISDIR(dentry->d_inode->i_mode))
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index fb2693464807..d9a677c51926 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -447,6 +447,7 @@
447#else 447#else
448#define __ARCH_WANT_COMPAT_SYS_TIME 448#define __ARCH_WANT_COMPAT_SYS_TIME
449#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 449#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
450#define __ARCH_WANT_COMPAT_SYS_SENDFILE
450#endif 451#endif
451 452
452/* 453/*
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
index d97f3eb72e06..44025f4ba41f 100644
--- a/arch/sparc/kernel/sys32.S
+++ b/arch/sparc/kernel/sys32.S
@@ -90,7 +90,7 @@ SIGN1(sys32_mkdir, sys_mkdir, %o1)
90SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) 90SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
91SIGN1(sys32_sysfs, compat_sys_sysfs, %o0) 91SIGN1(sys32_sysfs, compat_sys_sysfs, %o0)
92SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1) 92SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1)
93SIGN2(sys32_sendfile64, compat_sys_sendfile64, %o0, %o1) 93SIGN2(sys32_sendfile64, sys_sendfile, %o0, %o1)
94SIGN1(sys32_prctl, sys_prctl, %o0) 94SIGN1(sys32_prctl, sys_prctl, %o0)
95SIGN1(sys32_sched_rr_get_interval, compat_sys_sched_rr_get_interval, %o0) 95SIGN1(sys32_sched_rr_get_interval, compat_sys_sched_rr_get_interval, %o0)
96SIGN2(sys32_waitpid, sys_waitpid, %o0, %o2) 96SIGN2(sys32_waitpid, sys_waitpid, %o0, %o2)
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c
index f7392336961f..d862499eb01c 100644
--- a/arch/sparc/kernel/sys_sparc32.c
+++ b/arch/sparc/kernel/sys_sparc32.c
@@ -506,52 +506,6 @@ long compat_sys_fadvise64_64(int fd,
506 advice); 506 advice);
507} 507}
508 508
509asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
510 compat_off_t __user *offset,
511 compat_size_t count)
512{
513 mm_segment_t old_fs = get_fs();
514 int ret;
515 off_t of;
516
517 if (offset && get_user(of, offset))
518 return -EFAULT;
519
520 set_fs(KERNEL_DS);
521 ret = sys_sendfile(out_fd, in_fd,
522 offset ? (off_t __user *) &of : NULL,
523 count);
524 set_fs(old_fs);
525
526 if (offset && put_user(of, offset))
527 return -EFAULT;
528
529 return ret;
530}
531
532asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,
533 compat_loff_t __user *offset,
534 compat_size_t count)
535{
536 mm_segment_t old_fs = get_fs();
537 int ret;
538 loff_t lof;
539
540 if (offset && get_user(lof, offset))
541 return -EFAULT;
542
543 set_fs(KERNEL_DS);
544 ret = sys_sendfile64(out_fd, in_fd,
545 offset ? (loff_t __user *) &lof : NULL,
546 count);
547 set_fs(old_fs);
548
549 if (offset && put_user(lof, offset))
550 return -EFAULT;
551
552 return ret;
553}
554
555/* This is just a version for 32-bit applications which does 509/* This is just a version for 32-bit applications which does
556 * not force O_LARGEFILE on. 510 * not force O_LARGEFILE on.
557 */ 511 */
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index c17de0db6736..9efeb6da48bc 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -21,6 +21,9 @@
21#include <linux/un.h> 21#include <linux/un.h>
22#include <linux/workqueue.h> 22#include <linux/workqueue.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/fs.h>
25#include <linux/mount.h>
26#include <linux/file.h>
24#include <asm/uaccess.h> 27#include <asm/uaccess.h>
25#include <asm/switch_to.h> 28#include <asm/switch_to.h>
26 29
@@ -118,90 +121,38 @@ void mconsole_log(struct mc_request *req)
118 mconsole_reply(req, "", 0, 0); 121 mconsole_reply(req, "", 0, 0);
119} 122}
120 123
121/* This is a more convoluted version of mconsole_proc, which has some stability
122 * problems; however, we need it fixed, because it is expected that UML users
123 * mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
124 * show the real procfs content, not the ones from hppfs.*/
125#if 0
126void mconsole_proc(struct mc_request *req) 124void mconsole_proc(struct mc_request *req)
127{ 125{
128 struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt; 126 struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
129 struct file *file;
130 int n;
131 char *ptr = req->request.data, *buf;
132 mm_segment_t old_fs = get_fs();
133
134 ptr += strlen("proc");
135 ptr = skip_spaces(ptr);
136
137 file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
138 if (IS_ERR(file)) {
139 mconsole_reply(req, "Failed to open file", 1, 0);
140 goto out;
141 }
142
143 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
144 if (buf == NULL) {
145 mconsole_reply(req, "Failed to allocate buffer", 1, 0);
146 goto out_fput;
147 }
148
149 if (file->f_op->read) {
150 do {
151 loff_t pos;
152 set_fs(KERNEL_DS);
153 n = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
154 file_pos_write(file, pos);
155 set_fs(old_fs);
156 if (n >= 0) {
157 buf[n] = '\0';
158 mconsole_reply(req, buf, 0, (n > 0));
159 }
160 else {
161 mconsole_reply(req, "Read of file failed",
162 1, 0);
163 goto out_free;
164 }
165 } while (n > 0);
166 }
167 else mconsole_reply(req, "", 0, 0);
168
169 out_free:
170 kfree(buf);
171 out_fput:
172 fput(file);
173 out: ;
174}
175#endif
176
177void mconsole_proc(struct mc_request *req)
178{
179 char path[64];
180 char *buf; 127 char *buf;
181 int len; 128 int len;
182 int fd; 129 struct file *file;
183 int first_chunk = 1; 130 int first_chunk = 1;
184 char *ptr = req->request.data; 131 char *ptr = req->request.data;
185 132
186 ptr += strlen("proc"); 133 ptr += strlen("proc");
187 ptr = skip_spaces(ptr); 134 ptr = skip_spaces(ptr);
188 snprintf(path, sizeof(path), "/proc/%s", ptr);
189 135
190 fd = sys_open(path, 0, 0); 136 file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
191 if (fd < 0) { 137 if (IS_ERR(file)) {
192 mconsole_reply(req, "Failed to open file", 1, 0); 138 mconsole_reply(req, "Failed to open file", 1, 0);
193 printk(KERN_ERR "open %s: %d\n",path,fd); 139 printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
194 goto out; 140 goto out;
195 } 141 }
196 142
197 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 143 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
198 if (buf == NULL) { 144 if (buf == NULL) {
199 mconsole_reply(req, "Failed to allocate buffer", 1, 0); 145 mconsole_reply(req, "Failed to allocate buffer", 1, 0);
200 goto out_close; 146 goto out_fput;
201 } 147 }
202 148
203 for (;;) { 149 do {
204 len = sys_read(fd, buf, PAGE_SIZE-1); 150 loff_t pos;
151 mm_segment_t old_fs = get_fs();
152 set_fs(KERNEL_DS);
153 len = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
154 set_fs(old_fs);
155 file->f_pos = pos;
205 if (len < 0) { 156 if (len < 0) {
206 mconsole_reply(req, "Read of file failed", 1, 0); 157 mconsole_reply(req, "Read of file failed", 1, 0);
207 goto out_free; 158 goto out_free;
@@ -211,22 +162,14 @@ void mconsole_proc(struct mc_request *req)
211 mconsole_reply(req, "\n", 0, 1); 162 mconsole_reply(req, "\n", 0, 1);
212 first_chunk = 0; 163 first_chunk = 0;
213 } 164 }
214 if (len == PAGE_SIZE-1) { 165 buf[len] = '\0';
215 buf[len] = '\0'; 166 mconsole_reply(req, buf, 0, (len > 0));
216 mconsole_reply(req, buf, 0, 1); 167 } while (len > 0);
217 } else {
218 buf[len] = '\0';
219 mconsole_reply(req, buf, 0, 0);
220 break;
221 }
222 }
223
224 out_free: 168 out_free:
225 kfree(buf); 169 kfree(buf);
226 out_close: 170 out_fput:
227 sys_close(fd); 171 fput(file);
228 out: 172 out: ;
229 /* nothing */;
230} 173}
231 174
232#define UML_MCONSOLE_HELPTEXT \ 175#define UML_MCONSOLE_HELPTEXT \