aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c43
1 files changed, 22 insertions, 21 deletions
diff --git a/fs/compat.c b/fs/compat.c
index fc3b55dce184..6af20de2c1a3 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -832,6 +832,7 @@ struct compat_old_linux_dirent {
832}; 832};
833 833
834struct compat_readdir_callback { 834struct compat_readdir_callback {
835 struct dir_context ctx;
835 struct compat_old_linux_dirent __user *dirent; 836 struct compat_old_linux_dirent __user *dirent;
836 int result; 837 int result;
837}; 838};
@@ -873,15 +874,15 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,
873{ 874{
874 int error; 875 int error;
875 struct fd f = fdget(fd); 876 struct fd f = fdget(fd);
876 struct compat_readdir_callback buf; 877 struct compat_readdir_callback buf = {
878 .ctx.actor = compat_fillonedir,
879 .dirent = dirent
880 };
877 881
878 if (!f.file) 882 if (!f.file)
879 return -EBADF; 883 return -EBADF;
880 884
881 buf.result = 0; 885 error = iterate_dir(f.file, &buf.ctx);
882 buf.dirent = dirent;
883
884 error = vfs_readdir(f.file, compat_fillonedir, &buf);
885 if (buf.result) 886 if (buf.result)
886 error = buf.result; 887 error = buf.result;
887 888
@@ -897,6 +898,7 @@ struct compat_linux_dirent {
897}; 898};
898 899
899struct compat_getdents_callback { 900struct compat_getdents_callback {
901 struct dir_context ctx;
900 struct compat_linux_dirent __user *current_dir; 902 struct compat_linux_dirent __user *current_dir;
901 struct compat_linux_dirent __user *previous; 903 struct compat_linux_dirent __user *previous;
902 int count; 904 int count;
@@ -951,7 +953,11 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
951{ 953{
952 struct fd f; 954 struct fd f;
953 struct compat_linux_dirent __user * lastdirent; 955 struct compat_linux_dirent __user * lastdirent;
954 struct compat_getdents_callback buf; 956 struct compat_getdents_callback buf = {
957 .ctx.actor = compat_filldir,
958 .current_dir = dirent,
959 .count = count
960 };
955 int error; 961 int error;
956 962
957 if (!access_ok(VERIFY_WRITE, dirent, count)) 963 if (!access_ok(VERIFY_WRITE, dirent, count))
@@ -961,17 +967,12 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
961 if (!f.file) 967 if (!f.file)
962 return -EBADF; 968 return -EBADF;
963 969
964 buf.current_dir = dirent; 970 error = iterate_dir(f.file, &buf.ctx);
965 buf.previous = NULL;
966 buf.count = count;
967 buf.error = 0;
968
969 error = vfs_readdir(f.file, compat_filldir, &buf);
970 if (error >= 0) 971 if (error >= 0)
971 error = buf.error; 972 error = buf.error;
972 lastdirent = buf.previous; 973 lastdirent = buf.previous;
973 if (lastdirent) { 974 if (lastdirent) {
974 if (put_user(f.file->f_pos, &lastdirent->d_off)) 975 if (put_user(buf.ctx.pos, &lastdirent->d_off))
975 error = -EFAULT; 976 error = -EFAULT;
976 else 977 else
977 error = count - buf.count; 978 error = count - buf.count;
@@ -983,6 +984,7 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
983#ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64 984#ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64
984 985
985struct compat_getdents_callback64 { 986struct compat_getdents_callback64 {
987 struct dir_context ctx;
986 struct linux_dirent64 __user *current_dir; 988 struct linux_dirent64 __user *current_dir;
987 struct linux_dirent64 __user *previous; 989 struct linux_dirent64 __user *previous;
988 int count; 990 int count;
@@ -1036,7 +1038,11 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
1036{ 1038{
1037 struct fd f; 1039 struct fd f;
1038 struct linux_dirent64 __user * lastdirent; 1040 struct linux_dirent64 __user * lastdirent;
1039 struct compat_getdents_callback64 buf; 1041 struct compat_getdents_callback64 buf = {
1042 .ctx.actor = compat_filldir64,
1043 .current_dir = dirent,
1044 .count = count
1045 };
1040 int error; 1046 int error;
1041 1047
1042 if (!access_ok(VERIFY_WRITE, dirent, count)) 1048 if (!access_ok(VERIFY_WRITE, dirent, count))
@@ -1046,17 +1052,12 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
1046 if (!f.file) 1052 if (!f.file)
1047 return -EBADF; 1053 return -EBADF;
1048 1054
1049 buf.current_dir = dirent; 1055 error = iterate_dir(f.file, &buf.ctx);
1050 buf.previous = NULL;
1051 buf.count = count;
1052 buf.error = 0;
1053
1054 error = vfs_readdir(f.file, compat_filldir64, &buf);
1055 if (error >= 0) 1056 if (error >= 0)
1056 error = buf.error; 1057 error = buf.error;
1057 lastdirent = buf.previous; 1058 lastdirent = buf.previous;
1058 if (lastdirent) { 1059 if (lastdirent) {
1059 typeof(lastdirent->d_off) d_off = f.file->f_pos; 1060 typeof(lastdirent->d_off) d_off = buf.ctx.pos;
1060 if (__put_user_unaligned(d_off, &lastdirent->d_off)) 1061 if (__put_user_unaligned(d_off, &lastdirent->d_off))
1061 error = -EFAULT; 1062 error = -EFAULT;
1062 else 1063 else