diff options
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 85 |
1 files changed, 29 insertions, 56 deletions
diff --git a/fs/compat.c b/fs/compat.c index 6490d2134ff3..52cfeb61da77 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -8,13 +8,14 @@ | |||
8 | * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) | 8 | * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) |
9 | * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) | 9 | * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) |
10 | * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs | 10 | * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs |
11 | * Copyright (C) 2003 Pavel Machek (pavel@suse.cz) | 11 | * Copyright (C) 2003 Pavel Machek (pavel@ucw.cz) |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License version 2 as | 14 | * it under the terms of the GNU General Public License version 2 as |
15 | * published by the Free Software Foundation. | 15 | * published by the Free Software Foundation. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/stddef.h> | ||
18 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
19 | #include <linux/linkage.h> | 20 | #include <linux/linkage.h> |
20 | #include <linux/compat.h> | 21 | #include <linux/compat.h> |
@@ -28,8 +29,6 @@ | |||
28 | #include <linux/vfs.h> | 29 | #include <linux/vfs.h> |
29 | #include <linux/ioctl.h> | 30 | #include <linux/ioctl.h> |
30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
31 | #include <linux/smb.h> | ||
32 | #include <linux/smb_mount.h> | ||
33 | #include <linux/ncp_mount.h> | 32 | #include <linux/ncp_mount.h> |
34 | #include <linux/nfs4_mount.h> | 33 | #include <linux/nfs4_mount.h> |
35 | #include <linux/syscalls.h> | 34 | #include <linux/syscalls.h> |
@@ -76,7 +75,8 @@ int compat_printk(const char *fmt, ...) | |||
76 | * Not all architectures have sys_utime, so implement this in terms | 75 | * Not all architectures have sys_utime, so implement this in terms |
77 | * of sys_utimes. | 76 | * of sys_utimes. |
78 | */ | 77 | */ |
79 | asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __user *t) | 78 | asmlinkage long compat_sys_utime(const char __user *filename, |
79 | struct compat_utimbuf __user *t) | ||
80 | { | 80 | { |
81 | struct timespec tv[2]; | 81 | struct timespec tv[2]; |
82 | 82 | ||
@@ -90,7 +90,7 @@ asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __ | |||
90 | return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0); | 90 | return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0); |
91 | } | 91 | } |
92 | 92 | ||
93 | asmlinkage long compat_sys_utimensat(unsigned int dfd, char __user *filename, struct compat_timespec __user *t, int flags) | 93 | asmlinkage long compat_sys_utimensat(unsigned int dfd, const char __user *filename, struct compat_timespec __user *t, int flags) |
94 | { | 94 | { |
95 | struct timespec tv[2]; | 95 | struct timespec tv[2]; |
96 | 96 | ||
@@ -105,7 +105,7 @@ asmlinkage long compat_sys_utimensat(unsigned int dfd, char __user *filename, st | |||
105 | return do_utimes(dfd, filename, t ? tv : NULL, flags); | 105 | return do_utimes(dfd, filename, t ? tv : NULL, flags); |
106 | } | 106 | } |
107 | 107 | ||
108 | asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, struct compat_timeval __user *t) | 108 | asmlinkage long compat_sys_futimesat(unsigned int dfd, const char __user *filename, struct compat_timeval __user *t) |
109 | { | 109 | { |
110 | struct timespec tv[2]; | 110 | struct timespec tv[2]; |
111 | 111 | ||
@@ -124,7 +124,7 @@ asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, st | |||
124 | return do_utimes(dfd, filename, t ? tv : NULL, 0); | 124 | return do_utimes(dfd, filename, t ? tv : NULL, 0); |
125 | } | 125 | } |
126 | 126 | ||
127 | asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t) | 127 | asmlinkage long compat_sys_utimes(const char __user *filename, struct compat_timeval __user *t) |
128 | { | 128 | { |
129 | return compat_sys_futimesat(AT_FDCWD, filename, t); | 129 | return compat_sys_futimesat(AT_FDCWD, filename, t); |
130 | } | 130 | } |
@@ -168,7 +168,7 @@ static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) | |||
168 | return err; | 168 | return err; |
169 | } | 169 | } |
170 | 170 | ||
171 | asmlinkage long compat_sys_newstat(char __user * filename, | 171 | asmlinkage long compat_sys_newstat(const char __user * filename, |
172 | struct compat_stat __user *statbuf) | 172 | struct compat_stat __user *statbuf) |
173 | { | 173 | { |
174 | struct kstat stat; | 174 | struct kstat stat; |
@@ -180,7 +180,7 @@ asmlinkage long compat_sys_newstat(char __user * filename, | |||
180 | return cp_compat_stat(&stat, statbuf); | 180 | return cp_compat_stat(&stat, statbuf); |
181 | } | 181 | } |
182 | 182 | ||
183 | asmlinkage long compat_sys_newlstat(char __user * filename, | 183 | asmlinkage long compat_sys_newlstat(const char __user * filename, |
184 | struct compat_stat __user *statbuf) | 184 | struct compat_stat __user *statbuf) |
185 | { | 185 | { |
186 | struct kstat stat; | 186 | struct kstat stat; |
@@ -193,7 +193,8 @@ asmlinkage long compat_sys_newlstat(char __user * filename, | |||
193 | } | 193 | } |
194 | 194 | ||
195 | #ifndef __ARCH_WANT_STAT64 | 195 | #ifndef __ARCH_WANT_STAT64 |
196 | asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename, | 196 | asmlinkage long compat_sys_newfstatat(unsigned int dfd, |
197 | const char __user *filename, | ||
197 | struct compat_stat __user *statbuf, int flag) | 198 | struct compat_stat __user *statbuf, int flag) |
198 | { | 199 | { |
199 | struct kstat stat; | 200 | struct kstat stat; |
@@ -266,7 +267,7 @@ asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_sta | |||
266 | error = user_path(pathname, &path); | 267 | error = user_path(pathname, &path); |
267 | if (!error) { | 268 | if (!error) { |
268 | struct kstatfs tmp; | 269 | struct kstatfs tmp; |
269 | error = vfs_statfs(path.dentry, &tmp); | 270 | error = vfs_statfs(&path, &tmp); |
270 | if (!error) | 271 | if (!error) |
271 | error = put_compat_statfs(buf, &tmp); | 272 | error = put_compat_statfs(buf, &tmp); |
272 | path_put(&path); | 273 | path_put(&path); |
@@ -284,7 +285,7 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user | |||
284 | file = fget(fd); | 285 | file = fget(fd); |
285 | if (!file) | 286 | if (!file) |
286 | goto out; | 287 | goto out; |
287 | error = vfs_statfs(file->f_path.dentry, &tmp); | 288 | error = vfs_statfs(&file->f_path, &tmp); |
288 | if (!error) | 289 | if (!error) |
289 | error = put_compat_statfs(buf, &tmp); | 290 | error = put_compat_statfs(buf, &tmp); |
290 | fput(file); | 291 | fput(file); |
@@ -334,7 +335,7 @@ asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t s | |||
334 | error = user_path(pathname, &path); | 335 | error = user_path(pathname, &path); |
335 | if (!error) { | 336 | if (!error) { |
336 | struct kstatfs tmp; | 337 | struct kstatfs tmp; |
337 | error = vfs_statfs(path.dentry, &tmp); | 338 | error = vfs_statfs(&path, &tmp); |
338 | if (!error) | 339 | if (!error) |
339 | error = put_compat_statfs64(buf, &tmp); | 340 | error = put_compat_statfs64(buf, &tmp); |
340 | path_put(&path); | 341 | path_put(&path); |
@@ -355,7 +356,7 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c | |||
355 | file = fget(fd); | 356 | file = fget(fd); |
356 | if (!file) | 357 | if (!file) |
357 | goto out; | 358 | goto out; |
358 | error = vfs_statfs(file->f_path.dentry, &tmp); | 359 | error = vfs_statfs(&file->f_path, &tmp); |
359 | if (!error) | 360 | if (!error) |
360 | error = put_compat_statfs64(buf, &tmp); | 361 | error = put_compat_statfs64(buf, &tmp); |
361 | fput(file); | 362 | fput(file); |
@@ -378,7 +379,7 @@ asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u) | |||
378 | sb = user_get_super(new_decode_dev(dev)); | 379 | sb = user_get_super(new_decode_dev(dev)); |
379 | if (!sb) | 380 | if (!sb) |
380 | return -EINVAL; | 381 | return -EINVAL; |
381 | err = vfs_statfs(sb->s_root, &sbuf); | 382 | err = statfs_by_dentry(sb->s_root, &sbuf); |
382 | drop_super(sb); | 383 | drop_super(sb); |
383 | if (err) | 384 | if (err) |
384 | return err; | 385 | return err; |
@@ -742,30 +743,6 @@ static void *do_ncp_super_data_conv(void *raw_data) | |||
742 | return raw_data; | 743 | return raw_data; |
743 | } | 744 | } |
744 | 745 | ||
745 | struct compat_smb_mount_data { | ||
746 | compat_int_t version; | ||
747 | __compat_uid_t mounted_uid; | ||
748 | __compat_uid_t uid; | ||
749 | __compat_gid_t gid; | ||
750 | compat_mode_t file_mode; | ||
751 | compat_mode_t dir_mode; | ||
752 | }; | ||
753 | |||
754 | static void *do_smb_super_data_conv(void *raw_data) | ||
755 | { | ||
756 | struct smb_mount_data *s = raw_data; | ||
757 | struct compat_smb_mount_data *c_s = raw_data; | ||
758 | |||
759 | if (c_s->version != SMB_MOUNT_OLDVERSION) | ||
760 | goto out; | ||
761 | s->dir_mode = c_s->dir_mode; | ||
762 | s->file_mode = c_s->file_mode; | ||
763 | s->gid = c_s->gid; | ||
764 | s->uid = c_s->uid; | ||
765 | s->mounted_uid = c_s->mounted_uid; | ||
766 | out: | ||
767 | return raw_data; | ||
768 | } | ||
769 | 746 | ||
770 | struct compat_nfs_string { | 747 | struct compat_nfs_string { |
771 | compat_uint_t len; | 748 | compat_uint_t len; |
@@ -832,13 +809,13 @@ static int do_nfs4_super_data_conv(void *raw_data) | |||
832 | return 0; | 809 | return 0; |
833 | } | 810 | } |
834 | 811 | ||
835 | #define SMBFS_NAME "smbfs" | ||
836 | #define NCPFS_NAME "ncpfs" | 812 | #define NCPFS_NAME "ncpfs" |
837 | #define NFS4_NAME "nfs4" | 813 | #define NFS4_NAME "nfs4" |
838 | 814 | ||
839 | asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, | 815 | asmlinkage long compat_sys_mount(const char __user * dev_name, |
840 | char __user * type, unsigned long flags, | 816 | const char __user * dir_name, |
841 | void __user * data) | 817 | const char __user * type, unsigned long flags, |
818 | const void __user * data) | ||
842 | { | 819 | { |
843 | char *kernel_type; | 820 | char *kernel_type; |
844 | unsigned long data_page; | 821 | unsigned long data_page; |
@@ -866,9 +843,7 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, | |||
866 | retval = -EINVAL; | 843 | retval = -EINVAL; |
867 | 844 | ||
868 | if (kernel_type && data_page) { | 845 | if (kernel_type && data_page) { |
869 | if (!strcmp(kernel_type, SMBFS_NAME)) { | 846 | if (!strcmp(kernel_type, NCPFS_NAME)) { |
870 | do_smb_super_data_conv((void *)data_page); | ||
871 | } else if (!strcmp(kernel_type, NCPFS_NAME)) { | ||
872 | do_ncp_super_data_conv((void *)data_page); | 847 | do_ncp_super_data_conv((void *)data_page); |
873 | } else if (!strcmp(kernel_type, NFS4_NAME)) { | 848 | } else if (!strcmp(kernel_type, NFS4_NAME)) { |
874 | if (do_nfs4_super_data_conv((void *) data_page)) | 849 | if (do_nfs4_super_data_conv((void *) data_page)) |
@@ -891,8 +866,6 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, | |||
891 | return retval; | 866 | return retval; |
892 | } | 867 | } |
893 | 868 | ||
894 | #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) | ||
895 | |||
896 | struct compat_old_linux_dirent { | 869 | struct compat_old_linux_dirent { |
897 | compat_ulong_t d_ino; | 870 | compat_ulong_t d_ino; |
898 | compat_ulong_t d_offset; | 871 | compat_ulong_t d_offset; |
@@ -981,7 +954,8 @@ static int compat_filldir(void *__buf, const char *name, int namlen, | |||
981 | struct compat_linux_dirent __user * dirent; | 954 | struct compat_linux_dirent __user * dirent; |
982 | struct compat_getdents_callback *buf = __buf; | 955 | struct compat_getdents_callback *buf = __buf; |
983 | compat_ulong_t d_ino; | 956 | compat_ulong_t d_ino; |
984 | int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 2, sizeof(compat_long_t)); | 957 | int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) + |
958 | namlen + 2, sizeof(compat_long_t)); | ||
985 | 959 | ||
986 | buf->error = -EINVAL; /* only used if we fail.. */ | 960 | buf->error = -EINVAL; /* only used if we fail.. */ |
987 | if (reclen > buf->count) | 961 | if (reclen > buf->count) |
@@ -1068,8 +1042,8 @@ static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t | |||
1068 | { | 1042 | { |
1069 | struct linux_dirent64 __user *dirent; | 1043 | struct linux_dirent64 __user *dirent; |
1070 | struct compat_getdents_callback64 *buf = __buf; | 1044 | struct compat_getdents_callback64 *buf = __buf; |
1071 | int jj = NAME_OFFSET(dirent); | 1045 | int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1, |
1072 | int reclen = ALIGN(jj + namlen + 1, sizeof(u64)); | 1046 | sizeof(u64)); |
1073 | u64 off; | 1047 | u64 off; |
1074 | 1048 | ||
1075 | buf->error = -EINVAL; /* only used if we fail.. */ | 1049 | buf->error = -EINVAL; /* only used if we fail.. */ |
@@ -1150,7 +1124,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, | |||
1150 | { | 1124 | { |
1151 | compat_ssize_t tot_len; | 1125 | compat_ssize_t tot_len; |
1152 | struct iovec iovstack[UIO_FASTIOV]; | 1126 | struct iovec iovstack[UIO_FASTIOV]; |
1153 | struct iovec *iov; | 1127 | struct iovec *iov = iovstack; |
1154 | ssize_t ret; | 1128 | ssize_t ret; |
1155 | io_fn_t fn; | 1129 | io_fn_t fn; |
1156 | iov_fn_t fnv; | 1130 | iov_fn_t fnv; |
@@ -1193,11 +1167,10 @@ out: | |||
1193 | if (iov != iovstack) | 1167 | if (iov != iovstack) |
1194 | kfree(iov); | 1168 | kfree(iov); |
1195 | if ((ret + (type == READ)) > 0) { | 1169 | if ((ret + (type == READ)) > 0) { |
1196 | struct dentry *dentry = file->f_path.dentry; | ||
1197 | if (type == READ) | 1170 | if (type == READ) |
1198 | fsnotify_access(dentry); | 1171 | fsnotify_access(file); |
1199 | else | 1172 | else |
1200 | fsnotify_modify(dentry); | 1173 | fsnotify_modify(file); |
1201 | } | 1174 | } |
1202 | return ret; | 1175 | return ret; |
1203 | } | 1176 | } |
@@ -1961,7 +1934,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, | |||
1961 | } | 1934 | } |
1962 | #endif /* HAVE_SET_RESTORE_SIGMASK */ | 1935 | #endif /* HAVE_SET_RESTORE_SIGMASK */ |
1963 | 1936 | ||
1964 | #if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE) | 1937 | #if (defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)) && !defined(CONFIG_NFSD_DEPRECATED) |
1965 | /* Stuff for NFS server syscalls... */ | 1938 | /* Stuff for NFS server syscalls... */ |
1966 | struct compat_nfsctl_svc { | 1939 | struct compat_nfsctl_svc { |
1967 | u16 svc32_port; | 1940 | u16 svc32_port; |