Commit 53c9c5c0 authored by Al Viro's avatar Al Viro

[PATCH] prepare vfs_readdir() callers to returning filldir result

It's not the final state, but it allows moving ->readdir() instances
to passing filldir return value to caller of vfs_readdir().
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a9885444
...@@ -165,14 +165,11 @@ osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent, ...@@ -165,14 +165,11 @@ osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent,
buf.error = 0; buf.error = 0;
error = vfs_readdir(file, osf_filldir, &buf); error = vfs_readdir(file, osf_filldir, &buf);
if (error < 0) if (error >= 0)
goto out_putf; error = buf.error;
error = buf.error;
if (count != buf.count) if (count != buf.count)
error = count - buf.count; error = count - buf.count;
out_putf:
fput(file); fput(file);
out: out:
return error; return error;
......
...@@ -127,9 +127,8 @@ int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned i ...@@ -127,9 +127,8 @@ int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned i
buf.error = 0; buf.error = 0;
error = vfs_readdir(file, filldir, &buf); error = vfs_readdir(file, filldir, &buf);
if (error < 0) if (error >= 0)
goto out_putf; error = buf.error;
error = buf.error;
lastdirent = buf.previous; lastdirent = buf.previous;
if (lastdirent) { if (lastdirent) {
if (put_user(file->f_pos, &lastdirent->d_off)) if (put_user(file->f_pos, &lastdirent->d_off))
......
...@@ -869,7 +869,7 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd, ...@@ -869,7 +869,7 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,
buf.dirent = dirent; buf.dirent = dirent;
error = vfs_readdir(file, compat_fillonedir, &buf); error = vfs_readdir(file, compat_fillonedir, &buf);
if (error >= 0) if (buf.result)
error = buf.result; error = buf.result;
fput(file); fput(file);
...@@ -956,9 +956,8 @@ asmlinkage long compat_sys_getdents(unsigned int fd, ...@@ -956,9 +956,8 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
buf.error = 0; buf.error = 0;
error = vfs_readdir(file, compat_filldir, &buf); error = vfs_readdir(file, compat_filldir, &buf);
if (error < 0) if (error >= 0)
goto out_putf; error = buf.error;
error = buf.error;
lastdirent = buf.previous; lastdirent = buf.previous;
if (lastdirent) { if (lastdirent) {
if (put_user(file->f_pos, &lastdirent->d_off)) if (put_user(file->f_pos, &lastdirent->d_off))
...@@ -966,8 +965,6 @@ asmlinkage long compat_sys_getdents(unsigned int fd, ...@@ -966,8 +965,6 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
else else
error = count - buf.count; error = count - buf.count;
} }
out_putf:
fput(file); fput(file);
out: out:
return error; return error;
...@@ -1047,19 +1044,16 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, ...@@ -1047,19 +1044,16 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
buf.error = 0; buf.error = 0;
error = vfs_readdir(file, compat_filldir64, &buf); error = vfs_readdir(file, compat_filldir64, &buf);
if (error < 0) if (error >= 0)
goto out_putf; error = buf.error;
error = buf.error;
lastdirent = buf.previous; lastdirent = buf.previous;
if (lastdirent) { if (lastdirent) {
typeof(lastdirent->d_off) d_off = file->f_pos; typeof(lastdirent->d_off) d_off = file->f_pos;
error = -EFAULT;
if (__put_user_unaligned(d_off, &lastdirent->d_off)) if (__put_user_unaligned(d_off, &lastdirent->d_off))
goto out_putf; error = -EFAULT;
error = count - buf.count; else
error = count - buf.count;
} }
out_putf:
fput(file); fput(file);
out: out:
return error; return error;
......
...@@ -280,13 +280,14 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry, ...@@ -280,13 +280,14 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
int old_seq = buffer.sequence; int old_seq = buffer.sequence;
error = vfs_readdir(file, filldir_one, &buffer); error = vfs_readdir(file, filldir_one, &buffer);
if (buffer.found) {
error = 0;
break;
}
if (error < 0) if (error < 0)
break; break;
error = 0;
if (buffer.found)
break;
error = -ENOENT; error = -ENOENT;
if (old_seq == buffer.sequence) if (old_seq == buffer.sequence)
break; break;
......
...@@ -1831,6 +1831,7 @@ struct buffered_dirent { ...@@ -1831,6 +1831,7 @@ struct buffered_dirent {
struct readdir_data { struct readdir_data {
char *dirent; char *dirent;
size_t used; size_t used;
int full;
}; };
static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen, 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,8 +1842,10 @@ static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen,
unsigned int reclen; unsigned int reclen;
reclen = ALIGN(sizeof(struct buffered_dirent) + namlen, sizeof(u64)); reclen = ALIGN(sizeof(struct buffered_dirent) + namlen, sizeof(u64));
if (buf->used + reclen > PAGE_SIZE) if (buf->used + reclen > PAGE_SIZE) {
buf->full = 1;
return -EINVAL; return -EINVAL;
}
de->namlen = namlen; de->namlen = namlen;
de->offset = offset; de->offset = offset;
...@@ -1874,9 +1877,13 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func, ...@@ -1874,9 +1877,13 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func,
unsigned int reclen; unsigned int reclen;
buf.used = 0; buf.used = 0;
buf.full = 0;
host_err = vfs_readdir(file, nfsd_buffered_filldir, &buf); host_err = vfs_readdir(file, nfsd_buffered_filldir, &buf);
if (host_err) if (buf.full)
host_err = 0;
if (host_err < 0)
break; break;
size = buf.used; size = buf.used;
......
...@@ -117,7 +117,7 @@ asmlinkage long old_readdir(unsigned int fd, struct old_linux_dirent __user * di ...@@ -117,7 +117,7 @@ asmlinkage long old_readdir(unsigned int fd, struct old_linux_dirent __user * di
buf.dirent = dirent; buf.dirent = dirent;
error = vfs_readdir(file, fillonedir, &buf); error = vfs_readdir(file, fillonedir, &buf);
if (error >= 0) if (buf.result)
error = buf.result; error = buf.result;
fput(file); fput(file);
...@@ -209,9 +209,8 @@ asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user * diren ...@@ -209,9 +209,8 @@ asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user * diren
buf.error = 0; buf.error = 0;
error = vfs_readdir(file, filldir, &buf); error = vfs_readdir(file, filldir, &buf);
if (error < 0) if (error >= 0)
goto out_putf; error = buf.error;
error = buf.error;
lastdirent = buf.previous; lastdirent = buf.previous;
if (lastdirent) { if (lastdirent) {
if (put_user(file->f_pos, &lastdirent->d_off)) 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,8 +218,6 @@ asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user * diren
else else
error = count - buf.count; error = count - buf.count;
} }
out_putf:
fput(file); fput(file);
out: out:
return error; return error;
...@@ -293,19 +290,16 @@ asmlinkage long sys_getdents64(unsigned int fd, struct linux_dirent64 __user * d ...@@ -293,19 +290,16 @@ asmlinkage long sys_getdents64(unsigned int fd, struct linux_dirent64 __user * d
buf.error = 0; buf.error = 0;
error = vfs_readdir(file, filldir64, &buf); error = vfs_readdir(file, filldir64, &buf);
if (error < 0) if (error >= 0)
goto out_putf; error = buf.error;
error = buf.error;
lastdirent = buf.previous; lastdirent = buf.previous;
if (lastdirent) { if (lastdirent) {
typeof(lastdirent->d_off) d_off = file->f_pos; typeof(lastdirent->d_off) d_off = file->f_pos;
error = -EFAULT;
if (__put_user(d_off, &lastdirent->d_off)) if (__put_user(d_off, &lastdirent->d_off))
goto out_putf; error = -EFAULT;
error = count - buf.count; else
error = count - buf.count;
} }
out_putf:
fput(file); fput(file);
out: out:
return error; return error;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment