[PATCH] Fix error handling with put_compat_statfs()
In fs/compat.c, whenever put_compat_statfs() returns an error, the containing syscall returns -EFAULT. This is presumably by analogy with the non-compat case, where any non-zero code from copy_to_user() should be translated into an EFAULT. However, put_compat_statfs() is also return -EOVERFLOW. The same applies for put_compat_statfs64(). This bug can be observed with a statfs() on a hugetlbfs directory. hugetlbfs, when mounted without limits reports available, free and total blocks as -1 (itself a bug, another patch coming). statfs() will mysteriously return EFAULT although it's parameters are perfectly valid addresses. This patch causes the compat versions of statfs() and statfs64() to correctly propogate the return values from put_compat_statfs() and put_compat_statfs64(). Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Родитель
f3d48f0373
Коммит
86e07ce71a
16
fs/compat.c
16
fs/compat.c
|
@ -168,8 +168,8 @@ asmlinkage long compat_sys_statfs(const char __user *path, struct compat_statfs
|
|||
if (!error) {
|
||||
struct kstatfs tmp;
|
||||
error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
|
||||
if (!error && put_compat_statfs(buf, &tmp))
|
||||
error = -EFAULT;
|
||||
if (!error)
|
||||
error = put_compat_statfs(buf, &tmp);
|
||||
path_release(&nd);
|
||||
}
|
||||
return error;
|
||||
|
@ -186,8 +186,8 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user
|
|||
if (!file)
|
||||
goto out;
|
||||
error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
|
||||
if (!error && put_compat_statfs(buf, &tmp))
|
||||
error = -EFAULT;
|
||||
if (!error)
|
||||
error = put_compat_statfs(buf, &tmp);
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
|
@ -236,8 +236,8 @@ asmlinkage long compat_sys_statfs64(const char __user *path, compat_size_t sz, s
|
|||
if (!error) {
|
||||
struct kstatfs tmp;
|
||||
error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
|
||||
if (!error && put_compat_statfs64(buf, &tmp))
|
||||
error = -EFAULT;
|
||||
if (!error)
|
||||
error = put_compat_statfs64(buf, &tmp);
|
||||
path_release(&nd);
|
||||
}
|
||||
return error;
|
||||
|
@ -257,8 +257,8 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c
|
|||
if (!file)
|
||||
goto out;
|
||||
error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
|
||||
if (!error && put_compat_statfs64(buf, &tmp))
|
||||
error = -EFAULT;
|
||||
if (!error)
|
||||
error = put_compat_statfs64(buf, &tmp);
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
|
|
Загрузка…
Ссылка в новой задаче