Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Anna Schumaker and committed by
Trond Myklebust
ea96d1ec 3f940098

+16 -2
+14 -1
fs/nfs/inode.c
··· 1593 1593 } 1594 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 1610 * Many nfs protocol calls return the new file attributes after 1598 1611 * an operation. Here we update the inode to reflect the state ··· 1632 1619 nfs_display_fhandle_hash(NFS_FH(inode)), 1633 1620 atomic_read(&inode->i_count), fattr->valid); 1634 1621 1635 - if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) { 1622 + if (!nfs_fileid_valid(nfsi, fattr)) { 1636 1623 printk(KERN_ERR "NFS: server %s error: fileid changed\n" 1637 1624 "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", 1638 1625 NFS_SERVER(inode)->nfs_client->cl_hostname,
+2 -1
fs/nfs/nfs4proc.c
··· 185 185 | FATTR4_WORD1_SPACE_USED 186 186 | FATTR4_WORD1_TIME_ACCESS 187 187 | FATTR4_WORD1_TIME_METADATA 188 - | FATTR4_WORD1_TIME_MODIFY, 188 + | FATTR4_WORD1_TIME_MODIFY 189 + | FATTR4_WORD1_MOUNTED_ON_FILEID, 189 190 #ifdef CONFIG_NFS_V4_SECURITY_LABEL 190 191 FATTR4_WORD2_SECURITY_LABEL 191 192 #endif