mirror of https://gitee.com/openkylin/linux.git
Remove compat_sys_getdents64()
Unlike normal compat syscall variants, it is needed only for biarch architectures that have different alignement requirements for u64 in 32bit and 64bit ABI *and* have __put_user() that won't handle a store of 64bit value at 32bit-aligned address. We used to have one such (ia64), but its biarch support has been gone since 2010 (after being broken in 2008, which went unnoticed since nobody had been using it). It had escaped removal at the same time only because back in 2004 a patch that switched several syscalls on amd64 from private wrappers to generic compat ones had switched to use of compat_sys_getdents64(), which hadn't needed (or used) a compat wrapper on amd64. Let's bury it - it's at least 7 years overdue. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
a71c9a1c77
commit
2611dc1939
|
@ -14,7 +14,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define __ARCH_WANT_COMPAT_SYS_GETDENTS64
|
||||
#define __ARCH_WANT_COMPAT_STAT64
|
||||
#define __ARCH_WANT_SYS_GETHOSTNAME
|
||||
#define __ARCH_WANT_SYS_PAUSE
|
||||
|
|
|
@ -456,7 +456,7 @@ __SYSCALL(__NR_setfsuid32, sys_setfsuid)
|
|||
#define __NR_setfsgid32 216
|
||||
__SYSCALL(__NR_setfsgid32, sys_setfsgid)
|
||||
#define __NR_getdents64 217
|
||||
__SYSCALL(__NR_getdents64, compat_sys_getdents64)
|
||||
__SYSCALL(__NR_getdents64, sys_getdents64)
|
||||
#define __NR_pivot_root 218
|
||||
__SYSCALL(__NR_pivot_root, sys_pivot_root)
|
||||
#define __NR_mincore 219
|
||||
|
|
|
@ -226,7 +226,7 @@
|
|||
217 i386 pivot_root sys_pivot_root
|
||||
218 i386 mincore sys_mincore
|
||||
219 i386 madvise sys_madvise
|
||||
220 i386 getdents64 sys_getdents64 compat_sys_getdents64
|
||||
220 i386 getdents64 sys_getdents64
|
||||
221 i386 fcntl64 sys_fcntl64 compat_sys_fcntl64
|
||||
# 222 is unused
|
||||
# 223 is unused
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
# include <asm/unistd_64.h>
|
||||
# include <asm/unistd_64_x32.h>
|
||||
# define __ARCH_WANT_COMPAT_SYS_TIME
|
||||
# define __ARCH_WANT_COMPAT_SYS_GETDENTS64
|
||||
# define __ARCH_WANT_COMPAT_SYS_PREADV64
|
||||
# define __ARCH_WANT_COMPAT_SYS_PWRITEV64
|
||||
# define __ARCH_WANT_COMPAT_SYS_PREADV64V2
|
||||
|
|
91
fs/compat.c
91
fs/compat.c
|
@ -907,97 +907,6 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
|
|||
return error;
|
||||
}
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_GETDENTS64
|
||||
|
||||
struct compat_getdents_callback64 {
|
||||
struct dir_context ctx;
|
||||
struct linux_dirent64 __user *current_dir;
|
||||
struct linux_dirent64 __user *previous;
|
||||
int count;
|
||||
int error;
|
||||
};
|
||||
|
||||
static int compat_filldir64(struct dir_context *ctx, const char *name,
|
||||
int namlen, loff_t offset, u64 ino,
|
||||
unsigned int d_type)
|
||||
{
|
||||
struct linux_dirent64 __user *dirent;
|
||||
struct compat_getdents_callback64 *buf =
|
||||
container_of(ctx, struct compat_getdents_callback64, ctx);
|
||||
int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1,
|
||||
sizeof(u64));
|
||||
u64 off;
|
||||
|
||||
buf->error = -EINVAL; /* only used if we fail.. */
|
||||
if (reclen > buf->count)
|
||||
return -EINVAL;
|
||||
dirent = buf->previous;
|
||||
|
||||
if (dirent) {
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
if (__put_user_unaligned(offset, &dirent->d_off))
|
||||
goto efault;
|
||||
}
|
||||
dirent = buf->current_dir;
|
||||
if (__put_user_unaligned(ino, &dirent->d_ino))
|
||||
goto efault;
|
||||
off = 0;
|
||||
if (__put_user_unaligned(off, &dirent->d_off))
|
||||
goto efault;
|
||||
if (__put_user(reclen, &dirent->d_reclen))
|
||||
goto efault;
|
||||
if (__put_user(d_type, &dirent->d_type))
|
||||
goto efault;
|
||||
if (copy_to_user(dirent->d_name, name, namlen))
|
||||
goto efault;
|
||||
if (__put_user(0, dirent->d_name + namlen))
|
||||
goto efault;
|
||||
buf->previous = dirent;
|
||||
dirent = (void __user *)dirent + reclen;
|
||||
buf->current_dir = dirent;
|
||||
buf->count -= reclen;
|
||||
return 0;
|
||||
efault:
|
||||
buf->error = -EFAULT;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE3(getdents64, unsigned int, fd,
|
||||
struct linux_dirent64 __user *, dirent, unsigned int, count)
|
||||
{
|
||||
struct fd f;
|
||||
struct linux_dirent64 __user * lastdirent;
|
||||
struct compat_getdents_callback64 buf = {
|
||||
.ctx.actor = compat_filldir64,
|
||||
.current_dir = dirent,
|
||||
.count = count
|
||||
};
|
||||
int error;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, dirent, count))
|
||||
return -EFAULT;
|
||||
|
||||
f = fdget_pos(fd);
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
|
||||
error = iterate_dir(f.file, &buf.ctx);
|
||||
if (error >= 0)
|
||||
error = buf.error;
|
||||
lastdirent = buf.previous;
|
||||
if (lastdirent) {
|
||||
typeof(lastdirent->d_off) d_off = buf.ctx.pos;
|
||||
if (__put_user_unaligned(d_off, &lastdirent->d_off))
|
||||
error = -EFAULT;
|
||||
else
|
||||
error = count - buf.count;
|
||||
}
|
||||
fdput_pos(f);
|
||||
return error;
|
||||
}
|
||||
#endif /* __ARCH_WANT_COMPAT_SYS_GETDENTS64 */
|
||||
|
||||
/*
|
||||
* Exactly like fs/open.c:sys_open(), except that it doesn't set the
|
||||
* O_LARGEFILE flag.
|
||||
|
|
|
@ -528,11 +528,6 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,
|
|||
asmlinkage long compat_sys_getdents(unsigned int fd,
|
||||
struct compat_linux_dirent __user *dirent,
|
||||
unsigned int count);
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_GETDENTS64
|
||||
asmlinkage long compat_sys_getdents64(unsigned int fd,
|
||||
struct linux_dirent64 __user *dirent,
|
||||
unsigned int count);
|
||||
#endif
|
||||
asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *,
|
||||
unsigned int nr_segs, unsigned int flags);
|
||||
asmlinkage long compat_sys_open(const char __user *filename, int flags,
|
||||
|
|
|
@ -194,8 +194,7 @@ __SYSCALL(__NR_quotactl, sys_quotactl)
|
|||
|
||||
/* fs/readdir.c */
|
||||
#define __NR_getdents64 61
|
||||
#define __ARCH_WANT_COMPAT_SYS_GETDENTS64
|
||||
__SC_COMP(__NR_getdents64, sys_getdents64, compat_sys_getdents64)
|
||||
__SYSCALL(__NR_getdents64, sys_getdents64)
|
||||
|
||||
/* fs/read_write.c */
|
||||
#define __NR3264_lseek 62
|
||||
|
|
Loading…
Reference in New Issue