diff options
Diffstat (limited to 'fs/readdir.c')
-rw-r--r-- | fs/readdir.c | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/fs/readdir.c b/fs/readdir.c index cc0a8227cddf..39e3370d79cf 100644 --- a/fs/readdir.c +++ b/fs/readdir.c | |||
@@ -108,11 +108,11 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd, | |||
108 | int error; | 108 | int error; |
109 | struct file * file; | 109 | struct file * file; |
110 | struct readdir_callback buf; | 110 | struct readdir_callback buf; |
111 | int fput_needed; | ||
111 | 112 | ||
112 | error = -EBADF; | 113 | file = fget_light(fd, &fput_needed); |
113 | file = fget(fd); | ||
114 | if (!file) | 114 | if (!file) |
115 | goto out; | 115 | return -EBADF; |
116 | 116 | ||
117 | buf.result = 0; | 117 | buf.result = 0; |
118 | buf.dirent = dirent; | 118 | buf.dirent = dirent; |
@@ -121,8 +121,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd, | |||
121 | if (buf.result) | 121 | if (buf.result) |
122 | error = buf.result; | 122 | error = buf.result; |
123 | 123 | ||
124 | fput(file); | 124 | fput_light(file, fput_needed); |
125 | out: | ||
126 | return error; | 125 | return error; |
127 | } | 126 | } |
128 | 127 | ||
@@ -195,16 +194,15 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd, | |||
195 | struct file * file; | 194 | struct file * file; |
196 | struct linux_dirent __user * lastdirent; | 195 | struct linux_dirent __user * lastdirent; |
197 | struct getdents_callback buf; | 196 | struct getdents_callback buf; |
197 | int fput_needed; | ||
198 | int error; | 198 | int error; |
199 | 199 | ||
200 | error = -EFAULT; | ||
201 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 200 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
202 | goto out; | 201 | return -EFAULT; |
203 | 202 | ||
204 | error = -EBADF; | 203 | file = fget_light(fd, &fput_needed); |
205 | file = fget(fd); | ||
206 | if (!file) | 204 | if (!file) |
207 | goto out; | 205 | return -EBADF; |
208 | 206 | ||
209 | buf.current_dir = dirent; | 207 | buf.current_dir = dirent; |
210 | buf.previous = NULL; | 208 | buf.previous = NULL; |
@@ -221,8 +219,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd, | |||
221 | else | 219 | else |
222 | error = count - buf.count; | 220 | error = count - buf.count; |
223 | } | 221 | } |
224 | fput(file); | 222 | fput_light(file, fput_needed); |
225 | out: | ||
226 | return error; | 223 | return error; |
227 | } | 224 | } |
228 | 225 | ||
@@ -278,16 +275,15 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd, | |||
278 | struct file * file; | 275 | struct file * file; |
279 | struct linux_dirent64 __user * lastdirent; | 276 | struct linux_dirent64 __user * lastdirent; |
280 | struct getdents_callback64 buf; | 277 | struct getdents_callback64 buf; |
278 | int fput_needed; | ||
281 | int error; | 279 | int error; |
282 | 280 | ||
283 | error = -EFAULT; | ||
284 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 281 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
285 | goto out; | 282 | return -EFAULT; |
286 | 283 | ||
287 | error = -EBADF; | 284 | file = fget_light(fd, &fput_needed); |
288 | file = fget(fd); | ||
289 | if (!file) | 285 | if (!file) |
290 | goto out; | 286 | return -EBADF; |
291 | 287 | ||
292 | buf.current_dir = dirent; | 288 | buf.current_dir = dirent; |
293 | buf.previous = NULL; | 289 | buf.previous = NULL; |
@@ -305,7 +301,6 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd, | |||
305 | else | 301 | else |
306 | error = count - buf.count; | 302 | error = count - buf.count; |
307 | } | 303 | } |
308 | fput(file); | 304 | fput_light(file, fput_needed); |
309 | out: | ||
310 | return error; | 305 | return error; |
311 | } | 306 | } |