From 645e68ed4d14272f0b47e2474f90577191bef781 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Mon, 11 Aug 2008 23:51:22 -0400
Subject: [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>
---
 arch/alpha/kernel/osf_sys.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

(limited to 'arch/alpha/kernel/osf_sys.c')

diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 6e943135f0e..8509dad3120 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
-- 
cgit v1.2.3