Commit 3d2dc1cb authored by Pu Long's avatar Pu Long Committed by Linus Torvalds

[PATCH] x86_64: Use compat readdir and aio functions

This patch replaced some sys32 syscall functions of X86_64 with the
corresponding compat version.
Signed-off-by: default avatarPu Long  <long.pu@intel.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f6826a07
......@@ -391,7 +391,7 @@ ia32_sys_call_table:
.quad sys_uselib
.quad sys_swapon
.quad sys_reboot
.quad sys32_oldreaddir
.quad compat_old_readdir
.quad sys32_mmap /* 90 */
.quad sys_munmap
.quad sys_truncate
......@@ -443,7 +443,7 @@ ia32_sys_call_table:
.quad sys_setfsuid16
.quad sys_setfsgid16
.quad sys_llseek /* 140 */
.quad sys32_getdents
.quad compat_sys_getdents
.quad compat_sys_select
.quad sys_flock
.quad sys_msync
......@@ -522,7 +522,7 @@ ia32_sys_call_table:
.quad sys_pivot_root
.quad sys_mincore
.quad sys_madvise
.quad sys_getdents64 /* 220 getdents64 */
.quad compat_sys_getdents64 /* 220 getdents64 */
.quad compat_sys_fcntl64
.quad quiet_ni_syscall /* tux */
.quad quiet_ni_syscall /* security */
......@@ -549,8 +549,8 @@ ia32_sys_call_table:
.quad sys32_get_thread_area
.quad compat_sys_io_setup /* 245 */
.quad sys_io_destroy
.quad sys32_io_getevents
.quad sys32_io_submit
.quad compat_sys_io_getevents
.quad compat_sys_io_submit
.quad sys_io_cancel
.quad sys_fadvise64 /* 250 */
.quad quiet_ni_syscall /* free_huge_pages */
......
......@@ -473,134 +473,6 @@ sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
}
struct linux32_dirent {
u32 d_ino;
u32 d_off;
u16 d_reclen;
char d_name[1];
};
struct old_linux32_dirent {
u32 d_ino;
u32 d_offset;
u16 d_namlen;
char d_name[1];
};
struct getdents32_callback {
struct linux32_dirent __user * current_dir;
struct linux32_dirent __user * previous;
int count;
int error;
};
struct readdir32_callback {
struct old_linux32_dirent __user * dirent;
int count;
};
static int
filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
unsigned int d_type)
{
struct linux32_dirent __user * dirent;
struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2, 4);
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
dirent = buf->previous;
if (dirent)
put_user(offset, &dirent->d_off);
dirent = buf->current_dir;
buf->previous = dirent;
put_user(ino, &dirent->d_ino);
put_user(reclen, &dirent->d_reclen);
copy_to_user(dirent->d_name, name, namlen);
put_user(0, dirent->d_name + namlen);
put_user(d_type, (char __user *)dirent + reclen - 1);
dirent = ((void __user *)dirent) + reclen;
buf->current_dir = dirent;
buf->count -= reclen;
return 0;
}
asmlinkage long
sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count)
{
struct file * file;
struct linux32_dirent __user * lastdirent;
struct getdents32_callback buf;
int error;
error = -EBADF;
file = fget(fd);
if (!file)
goto out;
buf.current_dir = (struct linux32_dirent __user *) dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
error = vfs_readdir(file, filldir32, &buf);
if (error < 0)
goto out_putf;
error = buf.error;
lastdirent = buf.previous;
if (lastdirent) {
put_user(file->f_pos, &lastdirent->d_off);
error = count - buf.count;
}
out_putf:
fput(file);
out:
return error;
}
static int
fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned d_type)
{
struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
struct old_linux32_dirent __user * dirent;
if (buf->count)
return -EINVAL;
buf->count++;
dirent = buf->dirent;
put_user(ino, &dirent->d_ino);
put_user(offset, &dirent->d_offset);
put_user(namlen, &dirent->d_namlen);
copy_to_user(dirent->d_name, name, namlen);
put_user(0, dirent->d_name + namlen);
return 0;
}
asmlinkage long
sys32_oldreaddir (unsigned int fd, void __user * dirent, unsigned int count)
{
int error;
struct file * file;
struct readdir32_callback buf;
error = -EBADF;
file = fget(fd);
if (!file)
goto out;
buf.count = 0;
buf.dirent = dirent;
error = vfs_readdir(file, fillonedir32, &buf);
if (error >= 0)
error = buf.count;
fput(file);
out:
return error;
}
struct sel_arg_struct {
unsigned int n;
unsigned int inp;
......@@ -1186,75 +1058,6 @@ long sys32_kill(int pid, int sig)
return sys_kill(pid, sig);
}
asmlinkage long sys32_io_submit(aio_context_t ctx_id, int nr,
compat_uptr_t __user *iocbpp)
{
struct kioctx *ctx;
long ret = 0;
int i;
if (unlikely(nr < 0))
return -EINVAL;
if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(*iocbpp)))))
return -EFAULT;
ctx = lookup_ioctx(ctx_id);
if (unlikely(!ctx)) {
pr_debug("EINVAL: io_submit: invalid context id\n");
return -EINVAL;
}
for (i=0; i<nr; i++) {
compat_uptr_t p32;
struct iocb __user *user_iocb;
struct iocb tmp;
if (unlikely(__get_user(p32, iocbpp + i))) {
ret = -EFAULT;
break;
}
user_iocb = compat_ptr(p32);
if (unlikely(copy_from_user(&tmp, user_iocb, sizeof(tmp)))) {
ret = -EFAULT;
break;
}
ret = io_submit_one(ctx, user_iocb, &tmp);
if (ret)
break;
}
put_ioctx(ctx);
return i ? i : ret;
}
asmlinkage long sys32_io_getevents(aio_context_t ctx_id,
unsigned long min_nr,
unsigned long nr,
struct io_event __user *events,
struct compat_timespec __user *timeout)
{
long ret;
mm_segment_t oldfs;
struct timespec t;
/* Harden against bogus ptrace */
if (nr >= 0xffffffff ||
!access_ok(VERIFY_WRITE, events, nr * sizeof(struct io_event)))
return -EFAULT;
if (timeout && get_compat_timespec(&t, timeout))
return -EFAULT;
oldfs = get_fs();
set_fs(KERNEL_DS);
ret = sys_io_getevents(ctx_id,min_nr,nr,events,timeout ? &t : NULL);
set_fs(oldfs);
if (!ret && timeout && put_compat_timespec(&t, timeout))
return -EFAULT;
return ret;
}
asmlinkage long sys32_open(const char __user * filename, int flags, int mode)
{
char * tmp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment