I'm looking into an issue with LTP's ustat01 & ustat02 tests in which
they report the following:
ustat01 1 FAIL : ustat(2) failed and setthe errno to 116 :
Stale NFS file handle
ustat02 2 FAIL : ustat(2) failed to produce expected error;
14, errno: EFAULT and got 116
It appears sometime between 2.6.21 and 2.6.22-rc1 some changes to NFS
got introduced that cause this.
was wondering about any ideas while I try to debug what's going on.
thanks
- k
On Tue, 2007-10-23 at 17:52 -0500, Kumar Gala wrote:
> I'm looking into an issue with LTP's ustat01 & ustat02 tests in which
> they report the following:
>
> ustat01 1 FAIL : ustat(2) failed and setthe errno to 116 :
> Stale NFS file handle
> ustat02 2 FAIL : ustat(2) failed to produce expected error;
> 14, errno: EFAULT and got 116
>
> It appears sometime between 2.6.21 and 2.6.22-rc1 some changes to NFS
> got introduced that cause this.
>
> was wondering about any ideas while I try to debug what's going on.
>
> thanks
>
> - k
I'm seeing zero problems with the latest checkouts from Linus' git tree.
Mind giving us some more details?
'strace' output would be useful, as would the standard NFS list of
client mount options, server export options, details on how your
exported partition is set up on the server, etc...
Trond
On Oct 23, 2007, at 8:21 PM, Trond Myklebust wrote:
>
> On Tue, 2007-10-23 at 17:52 -0500, Kumar Gala wrote:
>> I'm looking into an issue with LTP's ustat01 & ustat02 tests in which
>> they report the following:
>>
>> ustat01 1 FAIL : ustat(2) failed and setthe errno to 116 :
>> Stale NFS file handle
>> ustat02 2 FAIL : ustat(2) failed to produce expected error;
>> 14, errno: EFAULT and got 116
>>
>> It appears sometime between 2.6.21 and 2.6.22-rc1 some changes to NFS
>> got introduced that cause this.
>>
>> was wondering about any ideas while I try to debug what's going on.
>>
>> thanks
>>
>> - k
>
> I'm seeing zero problems with the latest checkouts from Linus' git
> tree.
> Mind giving us some more details?
I tried 2.6.24-rc1 w/the same result.
The system is a 32-bit PPC embedded board that we mounting the rootfs
over nfs on.
The defconfig is arch/powerpc/configs/mpc8641_hpcn_defconfig
> 'strace' output would be useful, as would the standard NFS list of
> client mount options, server export options, details on how your
> exported partition is set up on the server, etc...
strace:
stat64("/", {st_dev=makedev(0, 14), st_ino=58821800, st_mode=S_IFDIR|
0775, st_nlink=18, st_uid=500, st_gid=500, st_blksize=4096,
st_blocks=8, st_size=4096, st_atime=2007/10/23-22:43:30,
st_mtime=2007/10/18-19:51:19, st_ctime=2007/10/18-19:51:19}) = 0
ustat(0xe, 0x1001a008) = -1 ESTALE (Stale NFS file
handle)
fstat64(1, {st_dev=makedev(0, 14), st_ino=58821964, st_mode=S_IFCHR|
0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0,
st_rdev=makedev(4, 64), st_atime=2007/10/16-18:32:59,
st_mtime=2007/10/16-18:32:59, st_ctime=2007/10/24-05:03:34}) = 0
Info on the server:
[root@ducky ~]# exportfs -v
/ <world>(rw,async,wdelay,no_root_squash,no_subtree_check)
[root@ducky ~]# uname -a
Linux ducky.am.freescale.net 2.6.22.5-76.fc7 #1 SMP Thu Aug 30
13:04:34 EDT 2007 ppc64 ppc64 ppc64 GNU/Linux
On the host system:
(not sure how to get client mount options, mount reports:
%root% on / type unknown (rw)
-sh-2.05b# cat /proc/cmdline
root=/dev/nfs rw nfsroot=192.168.1.15:/home/galak/ltib-joust-8572/
rootfs
ip=192.168.1.147:192.168.1.15:192.168.1.1:255.255.254.0:rocky:eth0:off c
onsole=ttyS0,115200
If there is some other info that would be useful please let me know.
On Oct 24, 2007, at 12:05 AM, Kumar Gala wrote:
>
> On Oct 23, 2007, at 8:21 PM, Trond Myklebust wrote:
>
>>
>> On Tue, 2007-10-23 at 17:52 -0500, Kumar Gala wrote:
>>> I'm looking into an issue with LTP's ustat01 & ustat02 tests in
>>> which
>>> they report the following:
>>>
>>> ustat01 1 FAIL : ustat(2) failed and setthe errno to 116 :
>>> Stale NFS file handle
>>> ustat02 2 FAIL : ustat(2) failed to produce expected error;
>>> 14, errno: EFAULT and got 116
>>>
>>> It appears sometime between 2.6.21 and 2.6.22-rc1 some changes to
>>> NFS
>>> got introduced that cause this.
>>>
>>> was wondering about any ideas while I try to debug what's going on.
>>>
>>> thanks
>>>
>>> - k
>>
>> I'm seeing zero problems with the latest checkouts from Linus' git
>> tree.
>> Mind giving us some more details?
>
> I tried 2.6.24-rc1 w/the same result.
>
> The system is a 32-bit PPC embedded board that we mounting the
> rootfs over nfs on.
>
> The defconfig is arch/powerpc/configs/mpc8641_hpcn_defconfig
>
>> 'strace' output would be useful, as would the standard NFS list of
>> client mount options, server export options, details on how your
>> exported partition is set up on the server, etc...
>
> strace:
>
> stat64("/", {st_dev=makedev(0, 14), st_ino=58821800,
> st_mode=S_IFDIR|0775, st_nlink=18, st_uid=500, st_gid=500,
> st_blksize=4096, st_blocks=8, st_size=4096,
> st_atime=2007/10/23-22:43:30, st_mtime=2007/10/18-19:51:19,
> st_ctime=2007/10/18-19:51:19}) = 0
> ustat(0xe, 0x1001a008) = -1 ESTALE (Stale NFS file
> handle)
> fstat64(1, {st_dev=makedev(0, 14), st_ino=58821964, st_mode=S_IFCHR|
> 0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0,
> st_rdev=makedev(4, 64), st_atime=2007/10/16-18:32:59,
> st_mtime=2007/10/16-18:32:59, st_ctime=2007/10/24-05:03:34}) = 0
>
>
> Info on the server:
>
> [root@ducky ~]# exportfs -v
> / <world>
> (rw,async,wdelay,no_root_squash,no_subtree_check)
> [root@ducky ~]# uname -a
> Linux ducky.am.freescale.net 2.6.22.5-76.fc7 #1 SMP Thu Aug 30
> 13:04:34 EDT 2007 ppc64 ppc64 ppc64 GNU/Linux
>
> On the host system:
>
> (not sure how to get client mount options, mount reports:
>
> %root% on / type unknown (rw)
>
> -sh-2.05b# cat /proc/cmdline
> root=/dev/nfs rw nfsroot=192.168.1.15:/home/galak/ltib-joust-8572/
> rootfs
> ip=192.168.1.147:192.168.1.15:192.168.1.1:255.255.254.0:rocky:eth0:off
> console=ttyS0,115200
>
> If there is some other info that would be useful please let me know.
any ideas? any other debug info needed?
- k
Could you please try the following patch?
Cheers
Trond
--------------------------------- CUT HERE -----------------------------
From: Trond Myklebust <[email protected]>
Date: Thu, 25 Oct 2007 13:56:10 -0400
NFS: Fix the ustat() regression
Since 2.6.18, the superblock sb->s_root has been a dummy dentry with a
dummy inode. This breaks ustat(), which actually uses sb->s_root in a
vfstat() call.
Fix this by making the s_root a dummy alias to the directory inode that was
used when creating the superblock.
Signed-off-by: Trond Myklebust <[email protected]>
---
fs/nfs/getroot.c | 81 ++++++++++++++++++------------------------------------
1 files changed, 27 insertions(+), 54 deletions(-)
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 522e5ad..0ee4384 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -43,6 +43,25 @@
#define NFSDBG_FACILITY NFSDBG_CLIENT
/*
+ * Set the superblock root dentry.
+ * Note that this function frees the inode in case of error.
+ */
+static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *inode)
+{
+ /* The mntroot acts as the dummy root dentry for this superblock */
+ if (sb->s_root == NULL) {
+ sb->s_root = d_alloc_root(inode);
+ if (sb->s_root == NULL) {
+ iput(inode);
+ return -ENOMEM;
+ }
+ /* Circumvent igrab(): we know the inode is not being freed */
+ atomic_inc(&inode->i_count);
+ }
+ return 0;
+}
+
+/*
* get an NFS2/NFS3 root dentry from the root filehandle
*/
struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
@@ -54,33 +73,6 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
struct inode *inode;
int error;
- /* create a dummy root dentry with dummy inode for this superblock */
- if (!sb->s_root) {
- struct nfs_fh dummyfh;
- struct dentry *root;
- struct inode *iroot;
-
- memset(&dummyfh, 0, sizeof(dummyfh));
- memset(&fattr, 0, sizeof(fattr));
- nfs_fattr_init(&fattr);
- fattr.valid = NFS_ATTR_FATTR;
- fattr.type = NFDIR;
- fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
- fattr.nlink = 2;
-
- iroot = nfs_fhget(sb, &dummyfh, &fattr);
- if (IS_ERR(iroot))
- return ERR_PTR(PTR_ERR(iroot));
-
- root = d_alloc_root(iroot);
- if (!root) {
- iput(iroot);
- return ERR_PTR(-ENOMEM);
- }
-
- sb->s_root = root;
- }
-
/* get the actual root for this mount */
fsinfo.fattr = &fattr;
@@ -96,6 +88,10 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
return ERR_PTR(PTR_ERR(inode));
}
+ error = nfs_superblock_set_dummy_root(sb, inode);
+ if (error != 0)
+ return ERR_PTR(error);
+
/* root dentries normally start off anonymous and get spliced in later
* if the dentry tree reaches them; however if the dentry already
* exists, we'll pick it up at this point and use it as the root
@@ -241,33 +237,6 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
dprintk("--> nfs4_get_root()\n");
- /* create a dummy root dentry with dummy inode for this superblock */
- if (!sb->s_root) {
- struct nfs_fh dummyfh;
- struct dentry *root;
- struct inode *iroot;
-
- memset(&dummyfh, 0, sizeof(dummyfh));
- memset(&fattr, 0, sizeof(fattr));
- nfs_fattr_init(&fattr);
- fattr.valid = NFS_ATTR_FATTR;
- fattr.type = NFDIR;
- fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
- fattr.nlink = 2;
-
- iroot = nfs_fhget(sb, &dummyfh, &fattr);
- if (IS_ERR(iroot))
- return ERR_PTR(PTR_ERR(iroot));
-
- root = d_alloc_root(iroot);
- if (!root) {
- iput(iroot);
- return ERR_PTR(-ENOMEM);
- }
-
- sb->s_root = root;
- }
-
/* get the info about the server and filesystem */
error = nfs4_server_capabilities(server, mntfh);
if (error < 0) {
@@ -289,6 +258,10 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
return ERR_PTR(PTR_ERR(inode));
}
+ error = nfs_superblock_set_dummy_root(sb, inode);
+ if (error != 0)
+ return ERR_PTR(error);
+
/* root dentries normally start off anonymous and get spliced in later
* if the dentry tree reaches them; however if the dentry already
* exists, we'll pick it up at this point and use it as the root
On Oct 25, 2007, at 12:59 PM, Trond Myklebust wrote:
> Could you please try the following patch?
this fixes my issue. Any reason this hasn't been accepted?
- k
> --------------------------------- CUT HERE
> -----------------------------
> From: Trond Myklebust <[email protected]>
> Date: Thu, 25 Oct 2007 13:56:10 -0400
> NFS: Fix the ustat() regression
>
> Since 2.6.18, the superblock sb->s_root has been a dummy dentry with a
> dummy inode. This breaks ustat(), which actually uses sb->s_root in a
> vfstat() call.
>
> Fix this by making the s_root a dummy alias to the directory inode
> that was
> used when creating the superblock.
>
> Signed-off-by: Trond Myklebust <[email protected]>
> ---
>
> fs/nfs/getroot.c | 81 +++++++++++++++++
> +------------------------------------
> 1 files changed, 27 insertions(+), 54 deletions(-)
>
> diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
> index 522e5ad..0ee4384 100644
> --- a/fs/nfs/getroot.c
> +++ b/fs/nfs/getroot.c
> @@ -43,6 +43,25 @@
> #define NFSDBG_FACILITY NFSDBG_CLIENT
>
> /*
> + * Set the superblock root dentry.
> + * Note that this function frees the inode in case of error.
> + */
> +static int nfs_superblock_set_dummy_root(struct super_block *sb,
> struct inode *inode)
> +{
> + /* The mntroot acts as the dummy root dentry for this superblock */
> + if (sb->s_root == NULL) {
> + sb->s_root = d_alloc_root(inode);
> + if (sb->s_root == NULL) {
> + iput(inode);
> + return -ENOMEM;
> + }
> + /* Circumvent igrab(): we know the inode is not being freed */
> + atomic_inc(&inode->i_count);
> + }
> + return 0;
> +}
> +
> +/*
> * get an NFS2/NFS3 root dentry from the root filehandle
> */
> struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh
> *mntfh)
> @@ -54,33 +73,6 @@ struct dentry *nfs_get_root(struct super_block
> *sb, struct nfs_fh *mntfh)
> struct inode *inode;
> int error;
>
> - /* create a dummy root dentry with dummy inode for this
> superblock */
> - if (!sb->s_root) {
> - struct nfs_fh dummyfh;
> - struct dentry *root;
> - struct inode *iroot;
> -
> - memset(&dummyfh, 0, sizeof(dummyfh));
> - memset(&fattr, 0, sizeof(fattr));
> - nfs_fattr_init(&fattr);
> - fattr.valid = NFS_ATTR_FATTR;
> - fattr.type = NFDIR;
> - fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
> - fattr.nlink = 2;
> -
> - iroot = nfs_fhget(sb, &dummyfh, &fattr);
> - if (IS_ERR(iroot))
> - return ERR_PTR(PTR_ERR(iroot));
> -
> - root = d_alloc_root(iroot);
> - if (!root) {
> - iput(iroot);
> - return ERR_PTR(-ENOMEM);
> - }
> -
> - sb->s_root = root;
> - }
> -
> /* get the actual root for this mount */
> fsinfo.fattr = &fattr;
>
> @@ -96,6 +88,10 @@ struct dentry *nfs_get_root(struct super_block
> *sb, struct nfs_fh *mntfh)
> return ERR_PTR(PTR_ERR(inode));
> }
>
> + error = nfs_superblock_set_dummy_root(sb, inode);
> + if (error != 0)
> + return ERR_PTR(error);
> +
> /* root dentries normally start off anonymous and get spliced in
> later
> * if the dentry tree reaches them; however if the dentry already
> * exists, we'll pick it up at this point and use it as the root
> @@ -241,33 +237,6 @@ struct dentry *nfs4_get_root(struct
> super_block *sb, struct nfs_fh *mntfh)
>
> dprintk("--> nfs4_get_root()\n");
>
> - /* create a dummy root dentry with dummy inode for this
> superblock */
> - if (!sb->s_root) {
> - struct nfs_fh dummyfh;
> - struct dentry *root;
> - struct inode *iroot;
> -
> - memset(&dummyfh, 0, sizeof(dummyfh));
> - memset(&fattr, 0, sizeof(fattr));
> - nfs_fattr_init(&fattr);
> - fattr.valid = NFS_ATTR_FATTR;
> - fattr.type = NFDIR;
> - fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
> - fattr.nlink = 2;
> -
> - iroot = nfs_fhget(sb, &dummyfh, &fattr);
> - if (IS_ERR(iroot))
> - return ERR_PTR(PTR_ERR(iroot));
> -
> - root = d_alloc_root(iroot);
> - if (!root) {
> - iput(iroot);
> - return ERR_PTR(-ENOMEM);
> - }
> -
> - sb->s_root = root;
> - }
> -
> /* get the info about the server and filesystem */
> error = nfs4_server_capabilities(server, mntfh);
> if (error < 0) {
> @@ -289,6 +258,10 @@ struct dentry *nfs4_get_root(struct
> super_block *sb, struct nfs_fh *mntfh)
> return ERR_PTR(PTR_ERR(inode));
> }
>
> + error = nfs_superblock_set_dummy_root(sb, inode);
> + if (error != 0)
> + return ERR_PTR(error);
> +
> /* root dentries normally start off anonymous and get spliced in
> later
> * if the dentry tree reaches them; however if the dentry already
> * exists, we'll pick it up at this point and use it as the root
On Thu, 2007-10-25 at 13:36 -0500, Kumar Gala wrote:
> On Oct 25, 2007, at 12:59 PM, Trond Myklebust wrote:
>
> > Could you please try the following patch?
>
> this fixes my issue. Any reason this hasn't been accepted?
Do you mean apart from the fact that I wrote it a couple of hours
ago? :-)
Trond
On Oct 25, 2007, at 1:39 PM, Trond Myklebust wrote:
>
> On Thu, 2007-10-25 at 13:36 -0500, Kumar Gala wrote:
>> On Oct 25, 2007, at 12:59 PM, Trond Myklebust wrote:
>>
>>> Could you please try the following patch?
>>
>> this fixes my issue. Any reason this hasn't been accepted?
>
> Do you mean apart from the fact that I wrote it a couple of hours
> ago? :-)
Oh, sorry. I glanced at the commit message and the 2.6.18 made me
think its been around for a while.
- k
On Oct 25, 2007, at 12:59 PM, Trond Myklebust wrote:
> Could you please try the following patch?
>
> Cheers
> Trond
> --------------------------------- CUT HERE
> -----------------------------
> From: Trond Myklebust <[email protected]>
> Date: Thu, 25 Oct 2007 13:56:10 -0400
> NFS: Fix the ustat() regression
>
> Since 2.6.18, the superblock sb->s_root has been a dummy dentry with a
> dummy inode. This breaks ustat(), which actually uses sb->s_root in a
> vfstat() call.
>
> Fix this by making the s_root a dummy alias to the directory inode
> that was
> used when creating the superblock.
>
> Signed-off-by: Trond Myklebust <[email protected]>
> ---
>
> fs/nfs/getroot.c | 81 +++++++++++++++++
> +------------------------------------
> 1 files changed, 27 insertions(+), 54 deletions(-)
Any reason not to send this to Linus as a bug fix for 2.6.24 (and
possibly stable)?
- k
On Oct 26, 2007, at 4:42 AM, Kumar Gala wrote:
>
> On Oct 25, 2007, at 12:59 PM, Trond Myklebust wrote:
>
>> Could you please try the following patch?
>>
>> Cheers
>> Trond
>> --------------------------------- CUT HERE
>> -----------------------------
>> From: Trond Myklebust <[email protected]>
>> Date: Thu, 25 Oct 2007 13:56:10 -0400
>> NFS: Fix the ustat() regression
>>
>> Since 2.6.18, the superblock sb->s_root has been a dummy dentry
>> with a
>> dummy inode. This breaks ustat(), which actually uses sb->s_root in a
>> vfstat() call.
>>
>> Fix this by making the s_root a dummy alias to the directory inode
>> that was
>> used when creating the superblock.
>>
>> Signed-off-by: Trond Myklebust <[email protected]>
>> ---
>>
>> fs/nfs/getroot.c | 81 +++++++++++++++++
>> +------------------------------------
>> 1 files changed, 27 insertions(+), 54 deletions(-)
>
> Any reason not to send this to Linus as a bug fix for 2.6.24 (and
> possibly stable)?
ping. would love to see this is Linus's tree.
- k
On Thu, 25 Oct 2007, Trond Myklebust wrote:
> Could you please try the following patch?
>
> Cheers
> Trond
Its a new month so I'll ping again about sending this fix upstream to
linus for 2.6.24 :) ?
- k
> --------------------------------- CUT HERE -----------------------------
> From: Trond Myklebust <[email protected]>
> Date: Thu, 25 Oct 2007 13:56:10 -0400
> NFS: Fix the ustat() regression
>
> Since 2.6.18, the superblock sb->s_root has been a dummy dentry with a
> dummy inode. This breaks ustat(), which actually uses sb->s_root in a
> vfstat() call.
>
> Fix this by making the s_root a dummy alias to the directory inode that was
> used when creating the superblock.
>
> Signed-off-by: Trond Myklebust <[email protected]>
> ---
>
> fs/nfs/getroot.c | 81 ++++++++++++++++++------------------------------------
> 1 files changed, 27 insertions(+), 54 deletions(-)
>
> diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
> index 522e5ad..0ee4384 100644
> --- a/fs/nfs/getroot.c
> +++ b/fs/nfs/getroot.c
> @@ -43,6 +43,25 @@
> #define NFSDBG_FACILITY NFSDBG_CLIENT
>
> /*
> + * Set the superblock root dentry.
> + * Note that this function frees the inode in case of error.
> + */
> +static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *inode)
> +{
> + /* The mntroot acts as the dummy root dentry for this superblock */
> + if (sb->s_root == NULL) {
> + sb->s_root = d_alloc_root(inode);
> + if (sb->s_root == NULL) {
> + iput(inode);
> + return -ENOMEM;
> + }
> + /* Circumvent igrab(): we know the inode is not being freed */
> + atomic_inc(&inode->i_count);
> + }
> + return 0;
> +}
> +
> +/*
> * get an NFS2/NFS3 root dentry from the root filehandle
> */
> struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
> @@ -54,33 +73,6 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
> struct inode *inode;
> int error;
>
> - /* create a dummy root dentry with dummy inode for this superblock */
> - if (!sb->s_root) {
> - struct nfs_fh dummyfh;
> - struct dentry *root;
> - struct inode *iroot;
> -
> - memset(&dummyfh, 0, sizeof(dummyfh));
> - memset(&fattr, 0, sizeof(fattr));
> - nfs_fattr_init(&fattr);
> - fattr.valid = NFS_ATTR_FATTR;
> - fattr.type = NFDIR;
> - fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
> - fattr.nlink = 2;
> -
> - iroot = nfs_fhget(sb, &dummyfh, &fattr);
> - if (IS_ERR(iroot))
> - return ERR_PTR(PTR_ERR(iroot));
> -
> - root = d_alloc_root(iroot);
> - if (!root) {
> - iput(iroot);
> - return ERR_PTR(-ENOMEM);
> - }
> -
> - sb->s_root = root;
> - }
> -
> /* get the actual root for this mount */
> fsinfo.fattr = &fattr;
>
> @@ -96,6 +88,10 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
> return ERR_PTR(PTR_ERR(inode));
> }
>
> + error = nfs_superblock_set_dummy_root(sb, inode);
> + if (error != 0)
> + return ERR_PTR(error);
> +
> /* root dentries normally start off anonymous and get spliced in later
> * if the dentry tree reaches them; however if the dentry already
> * exists, we'll pick it up at this point and use it as the root
> @@ -241,33 +237,6 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
>
> dprintk("--> nfs4_get_root()\n");
>
> - /* create a dummy root dentry with dummy inode for this superblock */
> - if (!sb->s_root) {
> - struct nfs_fh dummyfh;
> - struct dentry *root;
> - struct inode *iroot;
> -
> - memset(&dummyfh, 0, sizeof(dummyfh));
> - memset(&fattr, 0, sizeof(fattr));
> - nfs_fattr_init(&fattr);
> - fattr.valid = NFS_ATTR_FATTR;
> - fattr.type = NFDIR;
> - fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
> - fattr.nlink = 2;
> -
> - iroot = nfs_fhget(sb, &dummyfh, &fattr);
> - if (IS_ERR(iroot))
> - return ERR_PTR(PTR_ERR(iroot));
> -
> - root = d_alloc_root(iroot);
> - if (!root) {
> - iput(iroot);
> - return ERR_PTR(-ENOMEM);
> - }
> -
> - sb->s_root = root;
> - }
> -
> /* get the info about the server and filesystem */
> error = nfs4_server_capabilities(server, mntfh);
> if (error < 0) {
> @@ -289,6 +258,10 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
> return ERR_PTR(PTR_ERR(inode));
> }
>
> + error = nfs_superblock_set_dummy_root(sb, inode);
> + if (error != 0)
> + return ERR_PTR(error);
> +
> /* root dentries normally start off anonymous and get spliced in later
> * if the dentry tree reaches them; however if the dentry already
> * exists, we'll pick it up at this point and use it as the root
>
On Nov 2, 2007, at 9:28 AM, Kumar Gala wrote:
> On Thu, 25 Oct 2007, Trond Myklebust wrote:
>
>> Could you please try the following patch?
>>
>> Cheers
>> Trond
>
> Its a new month so I'll ping again about sending this fix upstream to
> linus for 2.6.24 :) ?
>
> - k
Trond,
any update on sending this to Linus for 2.6.24?
- k
>> --------------------------------- CUT HERE
>> -----------------------------
>> From: Trond Myklebust <[email protected]>
>> Date: Thu, 25 Oct 2007 13:56:10 -0400
>> NFS: Fix the ustat() regression
>>
>> Since 2.6.18, the superblock sb->s_root has been a dummy dentry
>> with a
>> dummy inode. This breaks ustat(), which actually uses sb->s_root in a
>> vfstat() call.
>>
>> Fix this by making the s_root a dummy alias to the directory inode
>> that was
>> used when creating the superblock.
>>
>> Signed-off-by: Trond Myklebust <[email protected]>
>> ---
>>
>> fs/nfs/getroot.c | 81 +++++++++++++++++
>> +------------------------------------
>> 1 files changed, 27 insertions(+), 54 deletions(-)
>>
>> diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
>> index 522e5ad..0ee4384 100644
>> --- a/fs/nfs/getroot.c
>> +++ b/fs/nfs/getroot.c
>> @@ -43,6 +43,25 @@
>> #define NFSDBG_FACILITY NFSDBG_CLIENT
>>
>> /*
>> + * Set the superblock root dentry.
>> + * Note that this function frees the inode in case of error.
>> + */
>> +static int nfs_superblock_set_dummy_root(struct super_block *sb,
>> struct inode *inode)
>> +{
>> + /* The mntroot acts as the dummy root dentry for this superblock */
>> + if (sb->s_root == NULL) {
>> + sb->s_root = d_alloc_root(inode);
>> + if (sb->s_root == NULL) {
>> + iput(inode);
>> + return -ENOMEM;
>> + }
>> + /* Circumvent igrab(): we know the inode is not being freed */
>> + atomic_inc(&inode->i_count);
>> + }
>> + return 0;
>> +}
>> +
>> +/*
>> * get an NFS2/NFS3 root dentry from the root filehandle
>> */
>> struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh
>> *mntfh)
>> @@ -54,33 +73,6 @@ struct dentry *nfs_get_root(struct super_block
>> *sb, struct nfs_fh *mntfh)
>> struct inode *inode;
>> int error;
>>
>> - /* create a dummy root dentry with dummy inode for this
>> superblock */
>> - if (!sb->s_root) {
>> - struct nfs_fh dummyfh;
>> - struct dentry *root;
>> - struct inode *iroot;
>> -
>> - memset(&dummyfh, 0, sizeof(dummyfh));
>> - memset(&fattr, 0, sizeof(fattr));
>> - nfs_fattr_init(&fattr);
>> - fattr.valid = NFS_ATTR_FATTR;
>> - fattr.type = NFDIR;
>> - fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
>> - fattr.nlink = 2;
>> -
>> - iroot = nfs_fhget(sb, &dummyfh, &fattr);
>> - if (IS_ERR(iroot))
>> - return ERR_PTR(PTR_ERR(iroot));
>> -
>> - root = d_alloc_root(iroot);
>> - if (!root) {
>> - iput(iroot);
>> - return ERR_PTR(-ENOMEM);
>> - }
>> -
>> - sb->s_root = root;
>> - }
>> -
>> /* get the actual root for this mount */
>> fsinfo.fattr = &fattr;
>>
>> @@ -96,6 +88,10 @@ struct dentry *nfs_get_root(struct super_block
>> *sb, struct nfs_fh *mntfh)
>> return ERR_PTR(PTR_ERR(inode));
>> }
>>
>> + error = nfs_superblock_set_dummy_root(sb, inode);
>> + if (error != 0)
>> + return ERR_PTR(error);
>> +
>> /* root dentries normally start off anonymous and get spliced in
>> later
>> * if the dentry tree reaches them; however if the dentry already
>> * exists, we'll pick it up at this point and use it as the root
>> @@ -241,33 +237,6 @@ struct dentry *nfs4_get_root(struct
>> super_block *sb, struct nfs_fh *mntfh)
>>
>> dprintk("--> nfs4_get_root()\n");
>>
>> - /* create a dummy root dentry with dummy inode for this
>> superblock */
>> - if (!sb->s_root) {
>> - struct nfs_fh dummyfh;
>> - struct dentry *root;
>> - struct inode *iroot;
>> -
>> - memset(&dummyfh, 0, sizeof(dummyfh));
>> - memset(&fattr, 0, sizeof(fattr));
>> - nfs_fattr_init(&fattr);
>> - fattr.valid = NFS_ATTR_FATTR;
>> - fattr.type = NFDIR;
>> - fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
>> - fattr.nlink = 2;
>> -
>> - iroot = nfs_fhget(sb, &dummyfh, &fattr);
>> - if (IS_ERR(iroot))
>> - return ERR_PTR(PTR_ERR(iroot));
>> -
>> - root = d_alloc_root(iroot);
>> - if (!root) {
>> - iput(iroot);
>> - return ERR_PTR(-ENOMEM);
>> - }
>> -
>> - sb->s_root = root;
>> - }
>> -
>> /* get the info about the server and filesystem */
>> error = nfs4_server_capabilities(server, mntfh);
>> if (error < 0) {
>> @@ -289,6 +258,10 @@ struct dentry *nfs4_get_root(struct
>> super_block *sb, struct nfs_fh *mntfh)
>> return ERR_PTR(PTR_ERR(inode));
>> }
>>
>> + error = nfs_superblock_set_dummy_root(sb, inode);
>> + if (error != 0)
>> + return ERR_PTR(error);
>> +
>> /* root dentries normally start off anonymous and get spliced in
>> later
>> * if the dentry tree reaches them; however if the dentry already
>> * exists, we'll pick it up at this point and use it as the root
>>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-
> kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/