diff options
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 62b324f26a56..a15b3a9bbff4 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "cifsproto.h" | 29 | #include "cifsproto.h" |
30 | #include "cifs_debug.h" | 30 | #include "cifs_debug.h" |
31 | #include "cifs_fs_sb.h" | 31 | #include "cifs_fs_sb.h" |
32 | #include "fscache.h" | ||
32 | 33 | ||
33 | 34 | ||
34 | static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral) | 35 | static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral) |
@@ -288,7 +289,7 @@ int cifs_get_file_info_unix(struct file *filp) | |||
288 | struct inode *inode = filp->f_path.dentry->d_inode; | 289 | struct inode *inode = filp->f_path.dentry->d_inode; |
289 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 290 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
290 | struct cifsTconInfo *tcon = cifs_sb->tcon; | 291 | struct cifsTconInfo *tcon = cifs_sb->tcon; |
291 | struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; | 292 | struct cifsFileInfo *cfile = filp->private_data; |
292 | 293 | ||
293 | xid = GetXid(); | 294 | xid = GetXid(); |
294 | rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); | 295 | rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); |
@@ -515,7 +516,7 @@ int cifs_get_file_info(struct file *filp) | |||
515 | struct inode *inode = filp->f_path.dentry->d_inode; | 516 | struct inode *inode = filp->f_path.dentry->d_inode; |
516 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 517 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
517 | struct cifsTconInfo *tcon = cifs_sb->tcon; | 518 | struct cifsTconInfo *tcon = cifs_sb->tcon; |
518 | struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; | 519 | struct cifsFileInfo *cfile = filp->private_data; |
519 | 520 | ||
520 | xid = GetXid(); | 521 | xid = GetXid(); |
521 | rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); | 522 | rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); |
@@ -723,9 +724,14 @@ cifs_find_inode(struct inode *inode, void *opaque) | |||
723 | { | 724 | { |
724 | struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; | 725 | struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; |
725 | 726 | ||
727 | /* don't match inode with different uniqueid */ | ||
726 | if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) | 728 | if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) |
727 | return 0; | 729 | return 0; |
728 | 730 | ||
731 | /* don't match inode of different type */ | ||
732 | if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT)) | ||
733 | return 0; | ||
734 | |||
729 | /* | 735 | /* |
730 | * uh oh -- it's a directory. We can't use it since hardlinked dirs are | 736 | * uh oh -- it's a directory. We can't use it since hardlinked dirs are |
731 | * verboten. Disable serverino and return it as if it were found, the | 737 | * verboten. Disable serverino and return it as if it were found, the |
@@ -776,6 +782,10 @@ retry_iget5_locked: | |||
776 | inode->i_flags |= S_NOATIME | S_NOCMTIME; | 782 | inode->i_flags |= S_NOATIME | S_NOCMTIME; |
777 | if (inode->i_state & I_NEW) { | 783 | if (inode->i_state & I_NEW) { |
778 | inode->i_ino = hash; | 784 | inode->i_ino = hash; |
785 | #ifdef CONFIG_CIFS_FSCACHE | ||
786 | /* initialize per-inode cache cookie pointer */ | ||
787 | CIFS_I(inode)->fscache = NULL; | ||
788 | #endif | ||
779 | unlock_new_inode(inode); | 789 | unlock_new_inode(inode); |
780 | } | 790 | } |
781 | } | 791 | } |
@@ -807,6 +817,11 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) | |||
807 | if (!inode) | 817 | if (!inode) |
808 | return ERR_PTR(-ENOMEM); | 818 | return ERR_PTR(-ENOMEM); |
809 | 819 | ||
820 | #ifdef CONFIG_CIFS_FSCACHE | ||
821 | /* populate tcon->resource_id */ | ||
822 | cifs_sb->tcon->resource_id = CIFS_I(inode)->uniqueid; | ||
823 | #endif | ||
824 | |||
810 | if (rc && cifs_sb->tcon->ipc) { | 825 | if (rc && cifs_sb->tcon->ipc) { |
811 | cFYI(1, "ipc connection - fake read inode"); | 826 | cFYI(1, "ipc connection - fake read inode"); |
812 | inode->i_mode |= S_IFDIR; | 827 | inode->i_mode |= S_IFDIR; |
@@ -1401,6 +1416,10 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath, | |||
1401 | if (rc == 0 || rc != -ETXTBSY) | 1416 | if (rc == 0 || rc != -ETXTBSY) |
1402 | return rc; | 1417 | return rc; |
1403 | 1418 | ||
1419 | /* open-file renames don't work across directories */ | ||
1420 | if (to_dentry->d_parent != from_dentry->d_parent) | ||
1421 | return rc; | ||
1422 | |||
1404 | /* open the file to be renamed -- we need DELETE perms */ | 1423 | /* open the file to be renamed -- we need DELETE perms */ |
1405 | rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, | 1424 | rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, |
1406 | CREATE_NOT_DIR, &srcfid, &oplock, NULL, | 1425 | CREATE_NOT_DIR, &srcfid, &oplock, NULL, |
@@ -1564,6 +1583,7 @@ cifs_invalidate_mapping(struct inode *inode) | |||
1564 | cifs_i->write_behind_rc = rc; | 1583 | cifs_i->write_behind_rc = rc; |
1565 | } | 1584 | } |
1566 | invalidate_remote_inode(inode); | 1585 | invalidate_remote_inode(inode); |
1586 | cifs_fscache_reset_inode_cookie(inode); | ||
1567 | } | 1587 | } |
1568 | 1588 | ||
1569 | int cifs_revalidate_file(struct file *filp) | 1589 | int cifs_revalidate_file(struct file *filp) |