diff options
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 9b0c55cb2a2e..c19e16f0b2d0 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -408,14 +408,22 @@ static int xdr_decode(nfs_readdir_descriptor_t *desc, | |||
408 | return 0; | 408 | return 0; |
409 | } | 409 | } |
410 | 410 | ||
411 | /* Match file and dirent using either filehandle or fileid | ||
412 | * Note: caller is responsible for checking the fsid | ||
413 | */ | ||
411 | static | 414 | static |
412 | int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry) | 415 | int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry) |
413 | { | 416 | { |
417 | struct nfs_inode *nfsi; | ||
418 | |||
414 | if (dentry->d_inode == NULL) | 419 | if (dentry->d_inode == NULL) |
415 | goto different; | 420 | goto different; |
416 | if (nfs_compare_fh(entry->fh, NFS_FH(dentry->d_inode)) != 0) | 421 | |
417 | goto different; | 422 | nfsi = NFS_I(dentry->d_inode); |
418 | return 1; | 423 | if (entry->fattr->fileid == nfsi->fileid) |
424 | return 1; | ||
425 | if (nfs_compare_fh(entry->fh, &nfsi->fh) == 0) | ||
426 | return 1; | ||
419 | different: | 427 | different: |
420 | return 0; | 428 | return 0; |
421 | } | 429 | } |
@@ -469,6 +477,10 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) | |||
469 | struct inode *inode; | 477 | struct inode *inode; |
470 | int status; | 478 | int status; |
471 | 479 | ||
480 | if (!(entry->fattr->valid & NFS_ATTR_FATTR_FILEID)) | ||
481 | return; | ||
482 | if (!(entry->fattr->valid & NFS_ATTR_FATTR_FSID)) | ||
483 | return; | ||
472 | if (filename.name[0] == '.') { | 484 | if (filename.name[0] == '.') { |
473 | if (filename.len == 1) | 485 | if (filename.len == 1) |
474 | return; | 486 | return; |
@@ -479,6 +491,10 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) | |||
479 | 491 | ||
480 | dentry = d_lookup(parent, &filename); | 492 | dentry = d_lookup(parent, &filename); |
481 | if (dentry != NULL) { | 493 | if (dentry != NULL) { |
494 | /* Is there a mountpoint here? If so, just exit */ | ||
495 | if (!nfs_fsid_equal(&NFS_SB(dentry->d_sb)->fsid, | ||
496 | &entry->fattr->fsid)) | ||
497 | goto out; | ||
482 | if (nfs_same_file(dentry, entry)) { | 498 | if (nfs_same_file(dentry, entry)) { |
483 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 499 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
484 | status = nfs_refresh_inode(dentry->d_inode, entry->fattr); | 500 | status = nfs_refresh_inode(dentry->d_inode, entry->fattr); |