aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-08-11 23:51:22 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2008-08-25 01:18:06 -0400
commit645e68ed4d14272f0b47e2474f90577191bef781 (patch)
tree8d147a043237074bee9745cf4da521d37709c444
parent2690421743b03c9be05d8e44c3b827986d1329a7 (diff)
[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 6e943135f0e0..8509dad31204 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,
121 if (reclen > buf->count) 121 if (reclen > buf->count)
122 return -EINVAL; 122 return -EINVAL;
123 d_ino = ino; 123 d_ino = ino;
124 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) 124 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
125 buf->error = -EOVERFLOW;
125 return -EOVERFLOW; 126 return -EOVERFLOW;
127 }
126 if (buf->basep) { 128 if (buf->basep) {
127 if (put_user(offset, buf->basep)) 129 if (put_user(offset, buf->basep))
128 return -EFAULT; 130 goto Efault;
129 buf->basep = NULL; 131 buf->basep = NULL;
130 } 132 }
131 dirent = buf->dirent; 133 dirent = buf->dirent;
132 put_user(d_ino, &dirent->d_ino); 134 if (put_user(d_ino, &dirent->d_ino) ||
133 put_user(namlen, &dirent->d_namlen); 135 put_user(namlen, &dirent->d_namlen) ||
134 put_user(reclen, &dirent->d_reclen); 136 put_user(reclen, &dirent->d_reclen) ||
135 if (copy_to_user(dirent->d_name, name, namlen) || 137 copy_to_user(dirent->d_name, name, namlen) ||
136 put_user(0, dirent->d_name + namlen)) 138 put_user(0, dirent->d_name + namlen))
137 return -EFAULT; 139 goto Efault;
138 dirent = (void __user *)dirent + reclen; 140 dirent = (void __user *)dirent + reclen;
139 buf->dirent = dirent; 141 buf->dirent = dirent;
140 buf->count -= reclen; 142 buf->count -= reclen;
141 return 0; 143 return 0;
144Efault:
145 buf->error = -EFAULT;
146 return -EFAULT;
142} 147}
143 148
144asmlinkage int 149asmlinkage int