aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c129
1 files changed, 85 insertions, 44 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 8852470b4fbb..de02ed5e25c2 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -878,7 +878,7 @@ retry_iget5_locked:
878} 878}
879 879
880/* gets root inode */ 880/* gets root inode */
881struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) 881struct inode *cifs_root_iget(struct super_block *sb)
882{ 882{
883 int xid; 883 int xid;
884 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 884 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
@@ -1683,71 +1683,70 @@ cifs_inode_needs_reval(struct inode *inode)
1683/* 1683/*
1684 * Zap the cache. Called when invalid_mapping flag is set. 1684 * Zap the cache. Called when invalid_mapping flag is set.
1685 */ 1685 */
1686void 1686int
1687cifs_invalidate_mapping(struct inode *inode) 1687cifs_invalidate_mapping(struct inode *inode)
1688{ 1688{
1689 int rc; 1689 int rc = 0;
1690 struct cifsInodeInfo *cifs_i = CIFS_I(inode); 1690 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1691 1691
1692 cifs_i->invalid_mapping = false; 1692 cifs_i->invalid_mapping = false;
1693 1693
1694 /* write back any cached data */
1695 if (inode->i_mapping && inode->i_mapping->nrpages != 0) { 1694 if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
1696 rc = filemap_write_and_wait(inode->i_mapping); 1695 rc = invalidate_inode_pages2(inode->i_mapping);
1697 mapping_set_error(inode->i_mapping, rc); 1696 if (rc) {
1697 cERROR(1, "%s: could not invalidate inode %p", __func__,
1698 inode);
1699 cifs_i->invalid_mapping = true;
1700 }
1698 } 1701 }
1699 invalidate_remote_inode(inode); 1702
1700 cifs_fscache_reset_inode_cookie(inode); 1703 cifs_fscache_reset_inode_cookie(inode);
1704 return rc;
1701} 1705}
1702 1706
1703int cifs_revalidate_file(struct file *filp) 1707int cifs_revalidate_file_attr(struct file *filp)
1704{ 1708{
1705 int rc = 0; 1709 int rc = 0;
1706 struct inode *inode = filp->f_path.dentry->d_inode; 1710 struct inode *inode = filp->f_path.dentry->d_inode;
1707 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; 1711 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
1708 1712
1709 if (!cifs_inode_needs_reval(inode)) 1713 if (!cifs_inode_needs_reval(inode))
1710 goto check_inval; 1714 return rc;
1711 1715
1712 if (tlink_tcon(cfile->tlink)->unix_ext) 1716 if (tlink_tcon(cfile->tlink)->unix_ext)
1713 rc = cifs_get_file_info_unix(filp); 1717 rc = cifs_get_file_info_unix(filp);
1714 else 1718 else
1715 rc = cifs_get_file_info(filp); 1719 rc = cifs_get_file_info(filp);
1716 1720
1717check_inval:
1718 if (CIFS_I(inode)->invalid_mapping)
1719 cifs_invalidate_mapping(inode);
1720
1721 return rc; 1721 return rc;
1722} 1722}
1723 1723
1724/* revalidate a dentry's inode attributes */ 1724int cifs_revalidate_dentry_attr(struct dentry *dentry)
1725int cifs_revalidate_dentry(struct dentry *dentry)
1726{ 1725{
1727 int xid; 1726 int xid;
1728 int rc = 0; 1727 int rc = 0;
1729 char *full_path = NULL;
1730 struct inode *inode = dentry->d_inode; 1728 struct inode *inode = dentry->d_inode;
1731 struct super_block *sb = dentry->d_sb; 1729 struct super_block *sb = dentry->d_sb;
1730 char *full_path = NULL;
1732 1731
1733 if (inode == NULL) 1732 if (inode == NULL)
1734 return -ENOENT; 1733 return -ENOENT;
1735 1734
1736 xid = GetXid();
1737
1738 if (!cifs_inode_needs_reval(inode)) 1735 if (!cifs_inode_needs_reval(inode))
1739 goto check_inval; 1736 return rc;
1737
1738 xid = GetXid();
1740 1739
1741 /* can not safely grab the rename sem here if rename calls revalidate 1740 /* can not safely grab the rename sem here if rename calls revalidate
1742 since that would deadlock */ 1741 since that would deadlock */
1743 full_path = build_path_from_dentry(dentry); 1742 full_path = build_path_from_dentry(dentry);
1744 if (full_path == NULL) { 1743 if (full_path == NULL) {
1745 rc = -ENOMEM; 1744 rc = -ENOMEM;
1746 goto check_inval; 1745 goto out;
1747 } 1746 }
1748 1747
1749 cFYI(1, "Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld " 1748 cFYI(1, "Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time "
1750 "jiffies %ld", full_path, inode, inode->i_count.counter, 1749 "%ld jiffies %ld", full_path, inode, inode->i_count.counter,
1751 dentry, dentry->d_time, jiffies); 1750 dentry, dentry->d_time, jiffies);
1752 1751
1753 if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) 1752 if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
@@ -1756,41 +1755,83 @@ int cifs_revalidate_dentry(struct dentry *dentry)
1756 rc = cifs_get_inode_info(&inode, full_path, NULL, sb, 1755 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
1757 xid, NULL); 1756 xid, NULL);
1758 1757
1759check_inval: 1758out:
1760 if (CIFS_I(inode)->invalid_mapping)
1761 cifs_invalidate_mapping(inode);
1762
1763 kfree(full_path); 1759 kfree(full_path);
1764 FreeXid(xid); 1760 FreeXid(xid);
1765 return rc; 1761 return rc;
1766} 1762}
1767 1763
1764int cifs_revalidate_file(struct file *filp)
1765{
1766 int rc;
1767 struct inode *inode = filp->f_path.dentry->d_inode;
1768
1769 rc = cifs_revalidate_file_attr(filp);
1770 if (rc)
1771 return rc;
1772
1773 if (CIFS_I(inode)->invalid_mapping)
1774 rc = cifs_invalidate_mapping(inode);
1775 return rc;
1776}
1777
1778/* revalidate a dentry's inode attributes */
1779int cifs_revalidate_dentry(struct dentry *dentry)
1780{
1781 int rc;
1782 struct inode *inode = dentry->d_inode;
1783
1784 rc = cifs_revalidate_dentry_attr(dentry);
1785 if (rc)
1786 return rc;
1787
1788 if (CIFS_I(inode)->invalid_mapping)
1789 rc = cifs_invalidate_mapping(inode);
1790 return rc;
1791}
1792
1768int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, 1793int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1769 struct kstat *stat) 1794 struct kstat *stat)
1770{ 1795{
1771 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); 1796 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
1772 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); 1797 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
1773 int err = cifs_revalidate_dentry(dentry); 1798 struct inode *inode = dentry->d_inode;
1774 1799 int rc;
1775 if (!err) {
1776 generic_fillattr(dentry->d_inode, stat);
1777 stat->blksize = CIFS_MAX_MSGSIZE;
1778 stat->ino = CIFS_I(dentry->d_inode)->uniqueid;
1779 1800
1780 /* 1801 /*
1781 * If on a multiuser mount without unix extensions, and the 1802 * We need to be sure that all dirty pages are written and the server
1782 * admin hasn't overridden them, set the ownership to the 1803 * has actual ctime, mtime and file length.
1783 * fsuid/fsgid of the current process. 1804 */
1784 */ 1805 if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping &&
1785 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) && 1806 inode->i_mapping->nrpages != 0) {
1786 !tcon->unix_ext) { 1807 rc = filemap_fdatawait(inode->i_mapping);
1787 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) 1808 if (rc) {
1788 stat->uid = current_fsuid(); 1809 mapping_set_error(inode->i_mapping, rc);
1789 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) 1810 return rc;
1790 stat->gid = current_fsgid();
1791 } 1811 }
1792 } 1812 }
1793 return err; 1813
1814 rc = cifs_revalidate_dentry_attr(dentry);
1815 if (rc)
1816 return rc;
1817
1818 generic_fillattr(inode, stat);
1819 stat->blksize = CIFS_MAX_MSGSIZE;
1820 stat->ino = CIFS_I(inode)->uniqueid;
1821
1822 /*
1823 * If on a multiuser mount without unix extensions, and the admin hasn't
1824 * overridden them, set the ownership to the fsuid/fsgid of the current
1825 * process.
1826 */
1827 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
1828 !tcon->unix_ext) {
1829 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
1830 stat->uid = current_fsuid();
1831 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID))
1832 stat->gid = current_fsgid();
1833 }
1834 return rc;
1794} 1835}
1795 1836
1796static int cifs_truncate_page(struct address_space *mapping, loff_t from) 1837static int cifs_truncate_page(struct address_space *mapping, loff_t from)