diff options
Diffstat (limited to 'fs/compat.c')
| -rw-r--r-- | fs/compat.c | 43 | 
1 files changed, 22 insertions, 21 deletions
diff --git a/fs/compat.c b/fs/compat.c index fc3b55dce184..6af20de2c1a3 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -832,6 +832,7 @@ struct compat_old_linux_dirent {  };  struct compat_readdir_callback { +	struct dir_context ctx;  	struct compat_old_linux_dirent __user *dirent;  	int result;  }; @@ -873,15 +874,15 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,  {  	int error;  	struct fd f = fdget(fd); -	struct compat_readdir_callback buf; +	struct compat_readdir_callback buf = { +		.ctx.actor = compat_fillonedir, +		.dirent = dirent +	};  	if (!f.file)  		return -EBADF; -	buf.result = 0; -	buf.dirent = dirent; - -	error = vfs_readdir(f.file, compat_fillonedir, &buf); +	error = iterate_dir(f.file, &buf.ctx);  	if (buf.result)  		error = buf.result; @@ -897,6 +898,7 @@ struct compat_linux_dirent {  };  struct compat_getdents_callback { +	struct dir_context ctx;  	struct compat_linux_dirent __user *current_dir;  	struct compat_linux_dirent __user *previous;  	int count; @@ -951,7 +953,11 @@ asmlinkage long compat_sys_getdents(unsigned int fd,  {  	struct fd f;  	struct compat_linux_dirent __user * lastdirent; -	struct compat_getdents_callback buf; +	struct compat_getdents_callback buf = { +		.ctx.actor = compat_filldir, +		.current_dir = dirent, +		.count = count +	};  	int error;  	if (!access_ok(VERIFY_WRITE, dirent, count)) @@ -961,17 +967,12 @@ asmlinkage long compat_sys_getdents(unsigned int fd,  	if (!f.file)  		return -EBADF; -	buf.current_dir = dirent; -	buf.previous = NULL; -	buf.count = count; -	buf.error = 0; - -	error = vfs_readdir(f.file, compat_filldir, &buf); +	error = iterate_dir(f.file, &buf.ctx);  	if (error >= 0)  		error = buf.error;  	lastdirent = buf.previous;  	if (lastdirent) { -		if (put_user(f.file->f_pos, &lastdirent->d_off)) +		if (put_user(buf.ctx.pos, &lastdirent->d_off))  			error = -EFAULT;  		else  			error = count - buf.count; @@ -983,6 +984,7 @@ asmlinkage long compat_sys_getdents(unsigned int fd,  #ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64  struct compat_getdents_callback64 { +	struct dir_context ctx;  	struct linux_dirent64 __user *current_dir;  	struct linux_dirent64 __user *previous;  	int count; @@ -1036,7 +1038,11 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,  {  	struct fd f;  	struct linux_dirent64 __user * lastdirent; -	struct compat_getdents_callback64 buf; +	struct compat_getdents_callback64 buf = { +		.ctx.actor = compat_filldir64, +		.current_dir = dirent, +		.count = count +	};  	int error;  	if (!access_ok(VERIFY_WRITE, dirent, count)) @@ -1046,17 +1052,12 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,  	if (!f.file)  		return -EBADF; -	buf.current_dir = dirent; -	buf.previous = NULL; -	buf.count = count; -	buf.error = 0; - -	error = vfs_readdir(f.file, compat_filldir64, &buf); +	error = iterate_dir(f.file, &buf.ctx);  	if (error >= 0)  		error = buf.error;  	lastdirent = buf.previous;  	if (lastdirent) { -		typeof(lastdirent->d_off) d_off = f.file->f_pos; +		typeof(lastdirent->d_off) d_off = buf.ctx.pos;  		if (__put_user_unaligned(d_off, &lastdirent->d_off))  			error = -EFAULT;  		else  |