Andrew, please apply.
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
differnet - it already returns -EFAULT in genuine fault cases, and can
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 <[email protected]>
Index: working-2.6/fs/compat.c
===================================================================
--- working-2.6.orig/fs/compat.c 2005-11-08 10:57:20.000000000 +1100
+++ working-2.6/fs/compat.c 2005-11-18 14:12:06.000000000 +1100
@@ -168,8 +168,8 @@
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 @@
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 @@
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 @@
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;
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson