summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-08-12 03:51:22 (GMT)
committerAl Viro <viro@zeniv.linux.org.uk>2008-08-25 05:18:06 (GMT)
commit645e68ed4d14272f0b47e2474f90577191bef781 (patch)
tree8d147a043237074bee9745cf4da521d37709c444
parent2690421743b03c9be05d8e44c3b827986d1329a7 (diff)
downloadlinux-645e68ed4d14272f0b47e2474f90577191bef781.tar.xz
[PATCH] fix osf_getdirents()
Return value of filldir callback is just "should we stop here"; it's not a usable channel for passing error values (i.e. ->readdir() will forget anything except "is it non-zero"). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--arch/alpha/kernel/osf_sys.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 6e94313..8509dad 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -121,24 +121,29 @@ osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
if (reclen > buf->count)
return -EINVAL;
d_ino = ino;
- if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
+ buf->error = -EOVERFLOW;
return -EOVERFLOW;
+ }
if (buf->basep) {
if (put_user(offset, buf->basep))
- return -EFAULT;
+ goto Efault;
buf->basep = NULL;
}
dirent = buf->dirent;
- put_user(d_ino, &dirent->d_ino);
- put_user(namlen, &dirent->d_namlen);
- put_user(reclen, &dirent->d_reclen);
- if (copy_to_user(dirent->d_name, name, namlen) ||
+ if (put_user(d_ino, &dirent->d_ino) ||
+ put_user(namlen, &dirent->d_namlen) ||
+ put_user(reclen, &dirent->d_reclen) ||
+ copy_to_user(dirent->d_name, name, namlen) ||
put_user(0, dirent->d_name + namlen))
- return -EFAULT;
+ goto Efault;
dirent = (void __user *)dirent + reclen;
buf->dirent = dirent;
buf->count -= reclen;
return 0;
+Efault:
+ buf->error = -EFAULT;
+ return -EFAULT;
}
asmlinkage int