aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2011-04-07 10:18:11 -0400
committerSteve French <sfrench@us.ibm.com>2011-05-19 10:10:52 -0400
commit6feb9891da4f8b04ffca69c00eb56bb7c1b64dc4 (patch)
tree647e083e7e9c78b7f1b63482c7c6aaa5185963ff /fs
parent0b81c1c405c063f3ecea66c2f5e9c3aefc5359c8 (diff)
CIFS: Simplify invalidate part (try #5)
Simplify many places when we call cifs_revalidate/invalidate to make it do what it exactly needs. Reviewed-by: Jeff Layton <jlayton@samba.org> Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsfs.c33
-rw-r--r--fs/cifs/cifsfs.h4
-rw-r--r--fs/cifs/file.c16
-rw-r--r--fs/cifs/inode.c117
4 files changed, 113 insertions, 57 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index f736d8a2e771..0f6a54f14eff 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -618,16 +618,29 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
618{ 618{
619 /* origin == SEEK_END => we must revalidate the cached file length */ 619 /* origin == SEEK_END => we must revalidate the cached file length */
620 if (origin == SEEK_END) { 620 if (origin == SEEK_END) {
621 int retval; 621 int rc;
622 622 struct inode *inode = file->f_path.dentry->d_inode;
623 /* some applications poll for the file length in this strange 623
624 way so we must seek to end on non-oplocked files by 624 /*
625 setting the revalidate time to zero */ 625 * We need to be sure that all dirty pages are written and the
626 CIFS_I(file->f_path.dentry->d_inode)->time = 0; 626 * server has the newest file length.
627 627 */
628 retval = cifs_revalidate_file(file); 628 if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping &&
629 if (retval < 0) 629 inode->i_mapping->nrpages != 0) {
630 return (loff_t)retval; 630 rc = filemap_fdatawait(inode->i_mapping);
631 mapping_set_error(inode->i_mapping, rc);
632 return rc;
633 }
634 /*
635 * Some applications poll for the file length in this strange
636 * way so we must seek to end on non-oplocked files by
637 * setting the revalidate time to zero.
638 */
639 CIFS_I(inode)->time = 0;
640
641 rc = cifs_revalidate_file_attr(file);
642 if (rc < 0)
643 return (loff_t)rc;
631 } 644 }
632 return generic_file_llseek_unlocked(file, offset, origin); 645 return generic_file_llseek_unlocked(file, offset, origin);
633} 646}
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index bb64313fd750..d304584408d1 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -59,9 +59,11 @@ extern int cifs_mkdir(struct inode *, struct dentry *, int);
59extern int cifs_rmdir(struct inode *, struct dentry *); 59extern int cifs_rmdir(struct inode *, struct dentry *);
60extern int cifs_rename(struct inode *, struct dentry *, struct inode *, 60extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
61 struct dentry *); 61 struct dentry *);
62extern int cifs_revalidate_file_attr(struct file *filp);
63extern int cifs_revalidate_dentry_attr(struct dentry *);
62extern int cifs_revalidate_file(struct file *filp); 64extern int cifs_revalidate_file(struct file *filp);
63extern int cifs_revalidate_dentry(struct dentry *); 65extern int cifs_revalidate_dentry(struct dentry *);
64extern void cifs_invalidate_mapping(struct inode *inode); 66extern int cifs_invalidate_mapping(struct inode *inode);
65extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); 67extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
66extern int cifs_setattr(struct dentry *, struct iattr *); 68extern int cifs_setattr(struct dentry *, struct iattr *);
67 69
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 0aeaaf7bf153..c672afef0c09 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1445,8 +1445,13 @@ int cifs_strict_fsync(struct file *file, int datasync)
1445 cFYI(1, "Sync file - name: %s datasync: 0x%x", 1445 cFYI(1, "Sync file - name: %s datasync: 0x%x",
1446 file->f_path.dentry->d_name.name, datasync); 1446 file->f_path.dentry->d_name.name, datasync);
1447 1447
1448 if (!CIFS_I(inode)->clientCanCacheRead) 1448 if (!CIFS_I(inode)->clientCanCacheRead) {
1449 cifs_invalidate_mapping(inode); 1449 rc = cifs_invalidate_mapping(inode);
1450 if (rc) {
1451 cFYI(1, "rc: %d during invalidate phase", rc);
1452 rc = 0; /* don't care about it in fsync */
1453 }
1454 }
1450 1455
1451 tcon = tlink_tcon(smbfile->tlink); 1456 tcon = tlink_tcon(smbfile->tlink);
1452 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) 1457 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
@@ -1903,8 +1908,11 @@ int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
1903 1908
1904 xid = GetXid(); 1909 xid = GetXid();
1905 1910
1906 if (!CIFS_I(inode)->clientCanCacheRead) 1911 if (!CIFS_I(inode)->clientCanCacheRead) {
1907 cifs_invalidate_mapping(inode); 1912 rc = cifs_invalidate_mapping(inode);
1913 if (rc)
1914 return rc;
1915 }
1908 1916
1909 rc = generic_file_mmap(file, vma); 1917 rc = generic_file_mmap(file, vma);
1910 if (rc == 0) 1918 if (rc == 0)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index fbe7d5858563..0cc7eddb077f 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1683,18 +1683,15 @@ 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 if (inode->i_mapping && inode->i_mapping->nrpages != 0) { 1694 if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
1695 /* write back any cached data */
1696 rc = filemap_write_and_wait(inode->i_mapping);
1697 mapping_set_error(inode->i_mapping, rc);
1698 rc = invalidate_inode_pages2(inode->i_mapping); 1695 rc = invalidate_inode_pages2(inode->i_mapping);
1699 if (rc) { 1696 if (rc) {
1700 cERROR(1, "%s: could not invalidate inode %p", __func__, 1697 cERROR(1, "%s: could not invalidate inode %p", __func__,
@@ -1704,56 +1701,52 @@ cifs_invalidate_mapping(struct inode *inode)
1704 } 1701 }
1705 1702
1706 cifs_fscache_reset_inode_cookie(inode); 1703 cifs_fscache_reset_inode_cookie(inode);
1704 return rc;
1707} 1705}
1708 1706
1709int cifs_revalidate_file(struct file *filp) 1707int cifs_revalidate_file_attr(struct file *filp)
1710{ 1708{
1711 int rc = 0; 1709 int rc = 0;
1712 struct inode *inode = filp->f_path.dentry->d_inode; 1710 struct inode *inode = filp->f_path.dentry->d_inode;
1713 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; 1711 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
1714 1712
1715 if (!cifs_inode_needs_reval(inode)) 1713 if (!cifs_inode_needs_reval(inode))
1716 goto check_inval; 1714 return rc;
1717 1715
1718 if (tlink_tcon(cfile->tlink)->unix_ext) 1716 if (tlink_tcon(cfile->tlink)->unix_ext)
1719 rc = cifs_get_file_info_unix(filp); 1717 rc = cifs_get_file_info_unix(filp);
1720 else 1718 else
1721 rc = cifs_get_file_info(filp); 1719 rc = cifs_get_file_info(filp);
1722 1720
1723check_inval:
1724 if (CIFS_I(inode)->invalid_mapping)
1725 cifs_invalidate_mapping(inode);
1726
1727 return rc; 1721 return rc;
1728} 1722}
1729 1723
1730/* revalidate a dentry's inode attributes */ 1724int cifs_revalidate_dentry_attr(struct dentry *dentry)
1731int cifs_revalidate_dentry(struct dentry *dentry)
1732{ 1725{
1733 int xid; 1726 int xid;
1734 int rc = 0; 1727 int rc = 0;
1735 char *full_path = NULL;
1736 struct inode *inode = dentry->d_inode; 1728 struct inode *inode = dentry->d_inode;
1737 struct super_block *sb = dentry->d_sb; 1729 struct super_block *sb = dentry->d_sb;
1730 char *full_path = NULL;
1738 1731
1739 if (inode == NULL) 1732 if (inode == NULL)
1740 return -ENOENT; 1733 return -ENOENT;
1741 1734
1742 xid = GetXid();
1743
1744 if (!cifs_inode_needs_reval(inode)) 1735 if (!cifs_inode_needs_reval(inode))
1745 goto check_inval; 1736 return rc;
1737
1738 xid = GetXid();
1746 1739
1747 /* 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
1748 since that would deadlock */ 1741 since that would deadlock */
1749 full_path = build_path_from_dentry(dentry); 1742 full_path = build_path_from_dentry(dentry);
1750 if (full_path == NULL) { 1743 if (full_path == NULL) {
1751 rc = -ENOMEM; 1744 rc = -ENOMEM;
1752 goto check_inval; 1745 goto out;
1753 } 1746 }
1754 1747
1755 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 "
1756 "jiffies %ld", full_path, inode, inode->i_count.counter, 1749 "%ld jiffies %ld", full_path, inode, inode->i_count.counter,
1757 dentry, dentry->d_time, jiffies); 1750 dentry, dentry->d_time, jiffies);
1758 1751
1759 if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) 1752 if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
@@ -1762,41 +1755,81 @@ int cifs_revalidate_dentry(struct dentry *dentry)
1762 rc = cifs_get_inode_info(&inode, full_path, NULL, sb, 1755 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
1763 xid, NULL); 1756 xid, NULL);
1764 1757
1765check_inval: 1758out:
1766 if (CIFS_I(inode)->invalid_mapping)
1767 cifs_invalidate_mapping(inode);
1768
1769 kfree(full_path); 1759 kfree(full_path);
1770 FreeXid(xid); 1760 FreeXid(xid);
1771 return rc; 1761 return rc;
1772} 1762}
1773 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
1774int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, 1793int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1775 struct kstat *stat) 1794 struct kstat *stat)
1776{ 1795{
1777 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); 1796 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
1778 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); 1797 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
1779 int err = cifs_revalidate_dentry(dentry); 1798 struct inode *inode = dentry->d_inode;
1799 int rc;
1780 1800
1781 if (!err) { 1801 /*
1782 generic_fillattr(dentry->d_inode, stat); 1802 * We need to be sure that all dirty pages are written and the server
1783 stat->blksize = CIFS_MAX_MSGSIZE; 1803 * has actual ctime, mtime and file length.
1784 stat->ino = CIFS_I(dentry->d_inode)->uniqueid; 1804 */
1805 if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping &&
1806 inode->i_mapping->nrpages != 0) {
1807 rc = filemap_fdatawait(inode->i_mapping);
1808 mapping_set_error(inode->i_mapping, rc);
1809 return rc;
1810 }
1785 1811
1786 /* 1812 rc = cifs_revalidate_dentry_attr(dentry);
1787 * If on a multiuser mount without unix extensions, and the 1813 if (rc)
1788 * admin hasn't overridden them, set the ownership to the 1814 return rc;
1789 * fsuid/fsgid of the current process. 1815
1790 */ 1816 generic_fillattr(inode, stat);
1791 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) && 1817 stat->blksize = CIFS_MAX_MSGSIZE;
1792 !tcon->unix_ext) { 1818 stat->ino = CIFS_I(inode)->uniqueid;
1793 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) 1819
1794 stat->uid = current_fsuid(); 1820 /*
1795 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) 1821 * If on a multiuser mount without unix extensions, and the admin hasn't
1796 stat->gid = current_fsgid(); 1822 * overridden them, set the ownership to the fsuid/fsgid of the current
1797 } 1823 * process.
1824 */
1825 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
1826 !tcon->unix_ext) {
1827 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
1828 stat->uid = current_fsuid();
1829 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID))
1830 stat->gid = current_fsgid();
1798 } 1831 }
1799 return err; 1832 return rc;
1800} 1833}
1801 1834
1802static int cifs_truncate_page(struct address_space *mapping, loff_t from) 1835static int cifs_truncate_page(struct address_space *mapping, loff_t from)