aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/compat.c22
-rw-r--r--fs/exportfs/expfs.c7
-rw-r--r--fs/nfsd/vfs.c11
-rw-r--r--fs/readdir.c22
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
970out_putf:
971 fput(file); 968 fput(file);
972out: 969out:
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
1062out_putf:
1063 fput(file); 1057 fput(file);
1064out: 1058out:
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 {
1831struct readdir_data { 1831struct readdir_data {
1832 char *dirent; 1832 char *dirent;
1833 size_t used; 1833 size_t used;
1834 int full;
1834}; 1835};
1835 1836
1836static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen, 1837static 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
223out_putf:
224 fput(file); 221 fput(file);
225out: 222out:
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
308out_putf:
309 fput(file); 303 fput(file);
310out: 304out:
311 return error; 305 return error;