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>
This commit is contained in:
parent
3f94009816
commit
ea96d1ecbe
|
@ -1593,6 +1593,19 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);
|
EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool nfs_fileid_valid(struct nfs_inode *nfsi,
|
||||||
|
struct nfs_fattr *fattr)
|
||||||
|
{
|
||||||
|
bool ret1 = true, ret2 = true;
|
||||||
|
|
||||||
|
if (fattr->valid & NFS_ATTR_FATTR_FILEID)
|
||||||
|
ret1 = (nfsi->fileid == fattr->fileid);
|
||||||
|
if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
|
||||||
|
ret2 = (nfsi->fileid == fattr->mounted_on_fileid);
|
||||||
|
return ret1 || ret2;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Many nfs protocol calls return the new file attributes after
|
* Many nfs protocol calls return the new file attributes after
|
||||||
* an operation. Here we update the inode to reflect the state
|
* 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)
|
||||||
nfs_display_fhandle_hash(NFS_FH(inode)),
|
nfs_display_fhandle_hash(NFS_FH(inode)),
|
||||||
atomic_read(&inode->i_count), fattr->valid);
|
atomic_read(&inode->i_count), fattr->valid);
|
||||||
|
|
||||||
if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) {
|
if (!nfs_fileid_valid(nfsi, fattr)) {
|
||||||
printk(KERN_ERR "NFS: server %s error: fileid changed\n"
|
printk(KERN_ERR "NFS: server %s error: fileid changed\n"
|
||||||
"fsid %s: expected fileid 0x%Lx, got 0x%Lx\n",
|
"fsid %s: expected fileid 0x%Lx, got 0x%Lx\n",
|
||||||
NFS_SERVER(inode)->nfs_client->cl_hostname,
|
NFS_SERVER(inode)->nfs_client->cl_hostname,
|
||||||
|
|
|
@ -185,7 +185,8 @@ const u32 nfs4_fattr_bitmap[3] = {
|
||||||
| FATTR4_WORD1_SPACE_USED
|
| FATTR4_WORD1_SPACE_USED
|
||||||
| FATTR4_WORD1_TIME_ACCESS
|
| FATTR4_WORD1_TIME_ACCESS
|
||||||
| FATTR4_WORD1_TIME_METADATA
|
| FATTR4_WORD1_TIME_METADATA
|
||||||
| FATTR4_WORD1_TIME_MODIFY,
|
| FATTR4_WORD1_TIME_MODIFY
|
||||||
|
| FATTR4_WORD1_MOUNTED_ON_FILEID,
|
||||||
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
|
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
|
||||||
FATTR4_WORD2_SECURITY_LABEL
|
FATTR4_WORD2_SECURITY_LABEL
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue