diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-08-11 23:51:22 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-08-25 01:18:06 -0400 |
commit | 645e68ed4d14272f0b47e2474f90577191bef781 (patch) | |
tree | 8d147a043237074bee9745cf4da521d37709c444 | |
parent | 2690421743b03c9be05d8e44c3b827986d1329a7 (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.c | 19 |
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; |
144 | Efault: | ||
145 | buf->error = -EFAULT; | ||
146 | return -EFAULT; | ||
142 | } | 147 | } |
143 | 148 | ||
144 | asmlinkage int | 149 | asmlinkage int |