diff options
author | Anna Schumaker <Anna.Schumaker@netapp.com> | 2015-04-03 14:35:59 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-04-23 14:43:54 -0400 |
commit | ea96d1ecbe4fcb1df487d99309d3157b4ff5fc02 (patch) | |
tree | fa64fa3c6b724b3423e13328a1be5b9bdec784fc /fs | |
parent | 3f9400981691f6845e5c22b962500742b80a5484 (diff) |
nfs: Fetch MOUNTED_ON_FILEID when updating an inode
2ef47eb1 (NFS: Fix use of nfs_attr_use_mounted_on_fileid()) was a good
start to fixing a circular directory structure warning for NFS v4
"junctioned" mountpoints. Unfortunately, further testing continued to
generate this error.
My server is configured like this:
anna@nfsd ~ % df
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 9.1G 2.0G 6.5G 24% /
/dev/vdc1 1014M 33M 982M 4% /exports
/dev/vdc2 1014M 33M 982M 4% /exports/vol1
/dev/vdc3 1014M 33M 982M 4% /exports/vol1/vol2
anna@nfsd ~ % cat /etc/exports
/exports/ *(rw,async,no_subtree_check,no_root_squash)
/exports/vol1/ *(rw,async,no_subtree_check,no_root_squash)
/exports/vol1/vol2 *(rw,async,no_subtree_check,no_root_squash)
I've been running chown across the entire mountpoint twice in a row to
hit this problem. The first run succeeds, but the second one fails with
the circular directory warning along with:
anna@client ~ % dmesg
[Apr 3 14:28] NFS: server 192.168.100.204 error: fileid changed
fsid 0:39: expected fileid 0x100080, got 0x80
WHere 0x80 is the mountpoint's fileid and 0x100080 is the mounted-on
fileid.
This patch fixes the issue by requesting an updated mounted-on fileid
from the server during nfs_update_inode(), and then checking that the
fileid stored in the nfs_inode matches either the fileid or mounted-on
fileid returned by the server.
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/inode.c | 15 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 3 |
2 files changed, 16 insertions, 2 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 83743a133204..2d8270801215 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1593,6 +1593,19 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa | |||
1593 | } | 1593 | } |
1594 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc); | 1594 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc); |
1595 | 1595 | ||
1596 | |||
1597 | static inline bool nfs_fileid_valid(struct nfs_inode *nfsi, | ||
1598 | struct nfs_fattr *fattr) | ||
1599 | { | ||
1600 | bool ret1 = true, ret2 = true; | ||
1601 | |||
1602 | if (fattr->valid & NFS_ATTR_FATTR_FILEID) | ||
1603 | ret1 = (nfsi->fileid == fattr->fileid); | ||
1604 | if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) | ||
1605 | ret2 = (nfsi->fileid == fattr->mounted_on_fileid); | ||
1606 | return ret1 || ret2; | ||
1607 | } | ||
1608 | |||
1596 | /* | 1609 | /* |
1597 | * Many nfs protocol calls return the new file attributes after | 1610 | * Many nfs protocol calls return the new file attributes after |
1598 | * an operation. Here we update the inode to reflect the state | 1611 | * an operation. Here we update the inode to reflect the state |
@@ -1619,7 +1632,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1619 | nfs_display_fhandle_hash(NFS_FH(inode)), | 1632 | nfs_display_fhandle_hash(NFS_FH(inode)), |
1620 | atomic_read(&inode->i_count), fattr->valid); | 1633 | atomic_read(&inode->i_count), fattr->valid); |
1621 | 1634 | ||
1622 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) { | 1635 | if (!nfs_fileid_valid(nfsi, fattr)) { |
1623 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" | 1636 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" |
1624 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", | 1637 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", |
1625 | NFS_SERVER(inode)->nfs_client->cl_hostname, | 1638 | NFS_SERVER(inode)->nfs_client->cl_hostname, |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 9ff8c63c9cac..6d48f37cfe8a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -185,7 +185,8 @@ const u32 nfs4_fattr_bitmap[3] = { | |||
185 | | FATTR4_WORD1_SPACE_USED | 185 | | FATTR4_WORD1_SPACE_USED |
186 | | FATTR4_WORD1_TIME_ACCESS | 186 | | FATTR4_WORD1_TIME_ACCESS |
187 | | FATTR4_WORD1_TIME_METADATA | 187 | | FATTR4_WORD1_TIME_METADATA |
188 | | FATTR4_WORD1_TIME_MODIFY, | 188 | | FATTR4_WORD1_TIME_MODIFY |
189 | | FATTR4_WORD1_MOUNTED_ON_FILEID, | ||
189 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL | 190 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL |
190 | FATTR4_WORD2_SECURITY_LABEL | 191 | FATTR4_WORD2_SECURITY_LABEL |
191 | #endif | 192 | #endif |