diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 8a1758200b57..2a03bfeec10a 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1403,12 +1403,22 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat | |||
1403 | if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) | 1403 | if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) |
1404 | return 0; | 1404 | return 0; |
1405 | 1405 | ||
1406 | if (!(fattr->valid & NFS_ATTR_FATTR_FILEID)) { | ||
1407 | /* Only a mounted-on-fileid? Just exit */ | ||
1408 | if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) | ||
1409 | return 0; | ||
1406 | /* Has the inode gone and changed behind our back? */ | 1410 | /* Has the inode gone and changed behind our back? */ |
1407 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) | 1411 | } else if (nfsi->fileid != fattr->fileid) { |
1412 | /* Is this perhaps the mounted-on fileid? */ | ||
1413 | if ((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) && | ||
1414 | nfsi->fileid == fattr->mounted_on_fileid) | ||
1415 | return 0; | ||
1408 | return -ESTALE; | 1416 | return -ESTALE; |
1417 | } | ||
1409 | if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) | 1418 | if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) |
1410 | return -ESTALE; | 1419 | return -ESTALE; |
1411 | 1420 | ||
1421 | |||
1412 | if (!nfs_file_has_buffered_writers(nfsi)) { | 1422 | if (!nfs_file_has_buffered_writers(nfsi)) { |
1413 | /* Verify a few of the more important attributes */ | 1423 | /* Verify a few of the more important attributes */ |
1414 | if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && !inode_eq_iversion_raw(inode, fattr->change_attr)) | 1424 | if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && !inode_eq_iversion_raw(inode, fattr->change_attr)) |
@@ -1768,18 +1778,6 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa | |||
1768 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc); | 1778 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc); |
1769 | 1779 | ||
1770 | 1780 | ||
1771 | static inline bool nfs_fileid_valid(struct nfs_inode *nfsi, | ||
1772 | struct nfs_fattr *fattr) | ||
1773 | { | ||
1774 | bool ret1 = true, ret2 = true; | ||
1775 | |||
1776 | if (fattr->valid & NFS_ATTR_FATTR_FILEID) | ||
1777 | ret1 = (nfsi->fileid == fattr->fileid); | ||
1778 | if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) | ||
1779 | ret2 = (nfsi->fileid == fattr->mounted_on_fileid); | ||
1780 | return ret1 || ret2; | ||
1781 | } | ||
1782 | |||
1783 | /* | 1781 | /* |
1784 | * Many nfs protocol calls return the new file attributes after | 1782 | * Many nfs protocol calls return the new file attributes after |
1785 | * an operation. Here we update the inode to reflect the state | 1783 | * an operation. Here we update the inode to reflect the state |
@@ -1810,7 +1808,16 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1810 | nfs_display_fhandle_hash(NFS_FH(inode)), | 1808 | nfs_display_fhandle_hash(NFS_FH(inode)), |
1811 | atomic_read(&inode->i_count), fattr->valid); | 1809 | atomic_read(&inode->i_count), fattr->valid); |
1812 | 1810 | ||
1813 | if (!nfs_fileid_valid(nfsi, fattr)) { | 1811 | if (!(fattr->valid & NFS_ATTR_FATTR_FILEID)) { |
1812 | /* Only a mounted-on-fileid? Just exit */ | ||
1813 | if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) | ||
1814 | return 0; | ||
1815 | /* Has the inode gone and changed behind our back? */ | ||
1816 | } else if (nfsi->fileid != fattr->fileid) { | ||
1817 | /* Is this perhaps the mounted-on fileid? */ | ||
1818 | if ((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) && | ||
1819 | nfsi->fileid == fattr->mounted_on_fileid) | ||
1820 | return 0; | ||
1814 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" | 1821 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" |
1815 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", | 1822 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", |
1816 | NFS_SERVER(inode)->nfs_client->cl_hostname, | 1823 | NFS_SERVER(inode)->nfs_client->cl_hostname, |