[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: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
a9885444f7
Коммит
53c9c5c0e3
|
@ -165,14 +165,11 @@ osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent,
|
|||
buf.error = 0;
|
||||
|
||||
error = vfs_readdir(file, osf_filldir, &buf);
|
||||
if (error < 0)
|
||||
goto out_putf;
|
||||
|
||||
error = buf.error;
|
||||
if (error >= 0)
|
||||
error = buf.error;
|
||||
if (count != buf.count)
|
||||
error = count - buf.count;
|
||||
|
||||
out_putf:
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -127,9 +127,8 @@ int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned i
|
|||
buf.error = 0;
|
||||
|
||||
error = vfs_readdir(file, filldir, &buf);
|
||||
if (error < 0)
|
||||
goto out_putf;
|
||||
error = buf.error;
|
||||
if (error >= 0)
|
||||
error = buf.error;
|
||||
lastdirent = buf.previous;
|
||||
if (lastdirent) {
|
||||
if (put_user(file->f_pos, &lastdirent->d_off))
|
||||
|
|
22
fs/compat.c
22
fs/compat.c
|
@ -869,7 +869,7 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,
|
|||
buf.dirent = dirent;
|
||||
|
||||
error = vfs_readdir(file, compat_fillonedir, &buf);
|
||||
if (error >= 0)
|
||||
if (buf.result)
|
||||
error = buf.result;
|
||||
|
||||
fput(file);
|
||||
|
@ -956,9 +956,8 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
|
|||
buf.error = 0;
|
||||
|
||||
error = vfs_readdir(file, compat_filldir, &buf);
|
||||
if (error < 0)
|
||||
goto out_putf;
|
||||
error = buf.error;
|
||||
if (error >= 0)
|
||||
error = buf.error;
|
||||
lastdirent = buf.previous;
|
||||
if (lastdirent) {
|
||||
if (put_user(file->f_pos, &lastdirent->d_off))
|
||||
|
@ -966,8 +965,6 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
|
|||
else
|
||||
error = count - buf.count;
|
||||
}
|
||||
|
||||
out_putf:
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
|
@ -1047,19 +1044,16 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
|
|||
buf.error = 0;
|
||||
|
||||
error = vfs_readdir(file, compat_filldir64, &buf);
|
||||
if (error < 0)
|
||||
goto out_putf;
|
||||
error = buf.error;
|
||||
if (error >= 0)
|
||||
error = buf.error;
|
||||
lastdirent = buf.previous;
|
||||
if (lastdirent) {
|
||||
typeof(lastdirent->d_off) d_off = file->f_pos;
|
||||
error = -EFAULT;
|
||||
if (__put_user_unaligned(d_off, &lastdirent->d_off))
|
||||
goto out_putf;
|
||||
error = count - buf.count;
|
||||
error = -EFAULT;
|
||||
else
|
||||
error = count - buf.count;
|
||||
}
|
||||
|
||||
out_putf:
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -280,13 +280,14 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
|
|||
int old_seq = buffer.sequence;
|
||||
|
||||
error = vfs_readdir(file, filldir_one, &buffer);
|
||||
if (buffer.found) {
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (error < 0)
|
||||
break;
|
||||
|
||||
error = 0;
|
||||
if (buffer.found)
|
||||
break;
|
||||
error = -ENOENT;
|
||||
if (old_seq == buffer.sequence)
|
||||
break;
|
||||
|
|
|
@ -1831,6 +1831,7 @@ struct buffered_dirent {
|
|||
struct readdir_data {
|
||||
char *dirent;
|
||||
size_t used;
|
||||
int full;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
de->namlen = namlen;
|
||||
de->offset = offset;
|
||||
|
@ -1874,9 +1877,13 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func,
|
|||
unsigned int reclen;
|
||||
|
||||
buf.used = 0;
|
||||
buf.full = 0;
|
||||
|
||||
host_err = vfs_readdir(file, nfsd_buffered_filldir, &buf);
|
||||
if (host_err)
|
||||
if (buf.full)
|
||||
host_err = 0;
|
||||
|
||||
if (host_err < 0)
|
||||
break;
|
||||
|
||||
size = buf.used;
|
||||
|
|
22
fs/readdir.c
22
fs/readdir.c
|
@ -117,7 +117,7 @@ asmlinkage long old_readdir(unsigned int fd, struct old_linux_dirent __user * di
|
|||
buf.dirent = dirent;
|
||||
|
||||
error = vfs_readdir(file, fillonedir, &buf);
|
||||
if (error >= 0)
|
||||
if (buf.result)
|
||||
error = buf.result;
|
||||
|
||||
fput(file);
|
||||
|
@ -209,9 +209,8 @@ asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user * diren
|
|||
buf.error = 0;
|
||||
|
||||
error = vfs_readdir(file, filldir, &buf);
|
||||
if (error < 0)
|
||||
goto out_putf;
|
||||
error = buf.error;
|
||||
if (error >= 0)
|
||||
error = buf.error;
|
||||
lastdirent = buf.previous;
|
||||
if (lastdirent) {
|
||||
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
|
|||
else
|
||||
error = count - buf.count;
|
||||
}
|
||||
|
||||
out_putf:
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
|
@ -293,19 +290,16 @@ asmlinkage long sys_getdents64(unsigned int fd, struct linux_dirent64 __user * d
|
|||
buf.error = 0;
|
||||
|
||||
error = vfs_readdir(file, filldir64, &buf);
|
||||
if (error < 0)
|
||||
goto out_putf;
|
||||
error = buf.error;
|
||||
if (error >= 0)
|
||||
error = buf.error;
|
||||
lastdirent = buf.previous;
|
||||
if (lastdirent) {
|
||||
typeof(lastdirent->d_off) d_off = file->f_pos;
|
||||
error = -EFAULT;
|
||||
if (__put_user(d_off, &lastdirent->d_off))
|
||||
goto out_putf;
|
||||
error = count - buf.count;
|
||||
error = -EFAULT;
|
||||
else
|
||||
error = count - buf.count;
|
||||
}
|
||||
|
||||
out_putf:
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
|
|
Загрузка…
Ссылка в новой задаче