diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/compat.c | 22 | ||||
-rw-r--r-- | fs/exportfs/expfs.c | 7 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 11 | ||||
-rw-r--r-- | fs/readdir.c | 22 |
4 files changed, 29 insertions, 33 deletions
diff --git a/fs/compat.c b/fs/compat.c index 5f9ec449c799..cb36245f9fe0 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -869,7 +869,7 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd, | |||
869 | buf.dirent = dirent; | 869 | buf.dirent = dirent; |
870 | 870 | ||
871 | error = vfs_readdir(file, compat_fillonedir, &buf); | 871 | error = vfs_readdir(file, compat_fillonedir, &buf); |
872 | if (error >= 0) | 872 | if (buf.result) |
873 | error = buf.result; | 873 | error = buf.result; |
874 | 874 | ||
875 | fput(file); | 875 | fput(file); |
@@ -956,9 +956,8 @@ asmlinkage long compat_sys_getdents(unsigned int fd, | |||
956 | buf.error = 0; | 956 | buf.error = 0; |
957 | 957 | ||
958 | error = vfs_readdir(file, compat_filldir, &buf); | 958 | error = vfs_readdir(file, compat_filldir, &buf); |
959 | if (error < 0) | 959 | if (error >= 0) |
960 | goto out_putf; | 960 | error = buf.error; |
961 | error = buf.error; | ||
962 | lastdirent = buf.previous; | 961 | lastdirent = buf.previous; |
963 | if (lastdirent) { | 962 | if (lastdirent) { |
964 | if (put_user(file->f_pos, &lastdirent->d_off)) | 963 | if (put_user(file->f_pos, &lastdirent->d_off)) |
@@ -966,8 +965,6 @@ asmlinkage long compat_sys_getdents(unsigned int fd, | |||
966 | else | 965 | else |
967 | error = count - buf.count; | 966 | error = count - buf.count; |
968 | } | 967 | } |
969 | |||
970 | out_putf: | ||
971 | fput(file); | 968 | fput(file); |
972 | out: | 969 | out: |
973 | return error; | 970 | return error; |
@@ -1047,19 +1044,16 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, | |||
1047 | buf.error = 0; | 1044 | buf.error = 0; |
1048 | 1045 | ||
1049 | error = vfs_readdir(file, compat_filldir64, &buf); | 1046 | error = vfs_readdir(file, compat_filldir64, &buf); |
1050 | if (error < 0) | 1047 | if (error >= 0) |
1051 | goto out_putf; | 1048 | error = buf.error; |
1052 | error = buf.error; | ||
1053 | lastdirent = buf.previous; | 1049 | lastdirent = buf.previous; |
1054 | if (lastdirent) { | 1050 | if (lastdirent) { |
1055 | typeof(lastdirent->d_off) d_off = file->f_pos; | 1051 | typeof(lastdirent->d_off) d_off = file->f_pos; |
1056 | error = -EFAULT; | ||
1057 | if (__put_user_unaligned(d_off, &lastdirent->d_off)) | 1052 | if (__put_user_unaligned(d_off, &lastdirent->d_off)) |
1058 | goto out_putf; | 1053 | error = -EFAULT; |
1059 | error = count - buf.count; | 1054 | else |
1055 | error = count - buf.count; | ||
1060 | } | 1056 | } |
1061 | |||
1062 | out_putf: | ||
1063 | fput(file); | 1057 | fput(file); |
1064 | out: | 1058 | out: |
1065 | return error; | 1059 | return error; |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 51bdc5cab069..80246bad1b7f 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -280,13 +280,14 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry, | |||
280 | int old_seq = buffer.sequence; | 280 | int old_seq = buffer.sequence; |
281 | 281 | ||
282 | error = vfs_readdir(file, filldir_one, &buffer); | 282 | error = vfs_readdir(file, filldir_one, &buffer); |
283 | if (buffer.found) { | ||
284 | error = 0; | ||
285 | break; | ||
286 | } | ||
283 | 287 | ||
284 | if (error < 0) | 288 | if (error < 0) |
285 | break; | 289 | break; |
286 | 290 | ||
287 | error = 0; | ||
288 | if (buffer.found) | ||
289 | break; | ||
290 | error = -ENOENT; | 291 | error = -ENOENT; |
291 | if (old_seq == buffer.sequence) | 292 | if (old_seq == buffer.sequence) |
292 | break; | 293 | break; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 93b22f661d9d..e3e37f7c8477 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1831,6 +1831,7 @@ struct buffered_dirent { | |||
1831 | struct readdir_data { | 1831 | struct readdir_data { |
1832 | char *dirent; | 1832 | char *dirent; |
1833 | size_t used; | 1833 | size_t used; |
1834 | int full; | ||
1834 | }; | 1835 | }; |
1835 | 1836 | ||
1836 | static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen, | 1837 | static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen, |
@@ -1841,8 +1842,10 @@ static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen, | |||
1841 | unsigned int reclen; | 1842 | unsigned int reclen; |
1842 | 1843 | ||
1843 | reclen = ALIGN(sizeof(struct buffered_dirent) + namlen, sizeof(u64)); | 1844 | reclen = ALIGN(sizeof(struct buffered_dirent) + namlen, sizeof(u64)); |
1844 | if (buf->used + reclen > PAGE_SIZE) | 1845 | if (buf->used + reclen > PAGE_SIZE) { |
1846 | buf->full = 1; | ||
1845 | return -EINVAL; | 1847 | return -EINVAL; |
1848 | } | ||
1846 | 1849 | ||
1847 | de->namlen = namlen; | 1850 | de->namlen = namlen; |
1848 | de->offset = offset; | 1851 | de->offset = offset; |
@@ -1874,9 +1877,13 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func, | |||
1874 | unsigned int reclen; | 1877 | unsigned int reclen; |
1875 | 1878 | ||
1876 | buf.used = 0; | 1879 | buf.used = 0; |
1880 | buf.full = 0; | ||
1877 | 1881 | ||
1878 | host_err = vfs_readdir(file, nfsd_buffered_filldir, &buf); | 1882 | host_err = vfs_readdir(file, nfsd_buffered_filldir, &buf); |
1879 | if (host_err) | 1883 | if (buf.full) |
1884 | host_err = 0; | ||
1885 | |||
1886 | if (host_err < 0) | ||
1880 | break; | 1887 | break; |
1881 | 1888 | ||
1882 | size = buf.used; | 1889 | size = buf.used; |
diff --git a/fs/readdir.c b/fs/readdir.c index 93a7559bbfd8..b318d9b5af2e 100644 --- a/fs/readdir.c +++ b/fs/readdir.c | |||
@@ -117,7 +117,7 @@ asmlinkage long old_readdir(unsigned int fd, struct old_linux_dirent __user * di | |||
117 | buf.dirent = dirent; | 117 | buf.dirent = dirent; |
118 | 118 | ||
119 | error = vfs_readdir(file, fillonedir, &buf); | 119 | error = vfs_readdir(file, fillonedir, &buf); |
120 | if (error >= 0) | 120 | if (buf.result) |
121 | error = buf.result; | 121 | error = buf.result; |
122 | 122 | ||
123 | fput(file); | 123 | fput(file); |
@@ -209,9 +209,8 @@ asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user * diren | |||
209 | buf.error = 0; | 209 | buf.error = 0; |
210 | 210 | ||
211 | error = vfs_readdir(file, filldir, &buf); | 211 | error = vfs_readdir(file, filldir, &buf); |
212 | if (error < 0) | 212 | if (error >= 0) |
213 | goto out_putf; | 213 | error = buf.error; |
214 | error = buf.error; | ||
215 | lastdirent = buf.previous; | 214 | lastdirent = buf.previous; |
216 | if (lastdirent) { | 215 | if (lastdirent) { |
217 | if (put_user(file->f_pos, &lastdirent->d_off)) | 216 | if (put_user(file->f_pos, &lastdirent->d_off)) |
@@ -219,8 +218,6 @@ asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user * diren | |||
219 | else | 218 | else |
220 | error = count - buf.count; | 219 | error = count - buf.count; |
221 | } | 220 | } |
222 | |||
223 | out_putf: | ||
224 | fput(file); | 221 | fput(file); |
225 | out: | 222 | out: |
226 | return error; | 223 | return error; |
@@ -293,19 +290,16 @@ asmlinkage long sys_getdents64(unsigned int fd, struct linux_dirent64 __user * d | |||
293 | buf.error = 0; | 290 | buf.error = 0; |
294 | 291 | ||
295 | error = vfs_readdir(file, filldir64, &buf); | 292 | error = vfs_readdir(file, filldir64, &buf); |
296 | if (error < 0) | 293 | if (error >= 0) |
297 | goto out_putf; | 294 | error = buf.error; |
298 | error = buf.error; | ||
299 | lastdirent = buf.previous; | 295 | lastdirent = buf.previous; |
300 | if (lastdirent) { | 296 | if (lastdirent) { |
301 | typeof(lastdirent->d_off) d_off = file->f_pos; | 297 | typeof(lastdirent->d_off) d_off = file->f_pos; |
302 | error = -EFAULT; | ||
303 | if (__put_user(d_off, &lastdirent->d_off)) | 298 | if (__put_user(d_off, &lastdirent->d_off)) |
304 | goto out_putf; | 299 | error = -EFAULT; |
305 | error = count - buf.count; | 300 | else |
301 | error = count - buf.count; | ||
306 | } | 302 | } |
307 | |||
308 | out_putf: | ||
309 | fput(file); | 303 | fput(file); |
310 | out: | 304 | out: |
311 | return error; | 305 | return error; |