diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2011-04-07 10:18:11 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-05-19 10:10:52 -0400 |
commit | 6feb9891da4f8b04ffca69c00eb56bb7c1b64dc4 (patch) | |
tree | 647e083e7e9c78b7f1b63482c7c6aaa5185963ff /fs | |
parent | 0b81c1c405c063f3ecea66c2f5e9c3aefc5359c8 (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.c | 33 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 4 | ||||
-rw-r--r-- | fs/cifs/file.c | 16 | ||||
-rw-r--r-- | fs/cifs/inode.c | 117 |
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); | |||
59 | extern int cifs_rmdir(struct inode *, struct dentry *); | 59 | extern int cifs_rmdir(struct inode *, struct dentry *); |
60 | extern int cifs_rename(struct inode *, struct dentry *, struct inode *, | 60 | extern int cifs_rename(struct inode *, struct dentry *, struct inode *, |
61 | struct dentry *); | 61 | struct dentry *); |
62 | extern int cifs_revalidate_file_attr(struct file *filp); | ||
63 | extern int cifs_revalidate_dentry_attr(struct dentry *); | ||
62 | extern int cifs_revalidate_file(struct file *filp); | 64 | extern int cifs_revalidate_file(struct file *filp); |
63 | extern int cifs_revalidate_dentry(struct dentry *); | 65 | extern int cifs_revalidate_dentry(struct dentry *); |
64 | extern void cifs_invalidate_mapping(struct inode *inode); | 66 | extern int cifs_invalidate_mapping(struct inode *inode); |
65 | extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 67 | extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
66 | extern int cifs_setattr(struct dentry *, struct iattr *); | 68 | extern 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 | */ |
1686 | void | 1686 | int |
1687 | cifs_invalidate_mapping(struct inode *inode) | 1687 | cifs_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 | ||
1709 | int cifs_revalidate_file(struct file *filp) | 1707 | int 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 | ||
1723 | check_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 */ | 1724 | int cifs_revalidate_dentry_attr(struct dentry *dentry) |
1731 | int 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 | ||
1765 | check_inval: | 1758 | out: |
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 | ||
1764 | int 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 */ | ||
1779 | int 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 | |||
1774 | int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, | 1793 | int 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 | ||
1802 | static int cifs_truncate_page(struct address_space *mapping, loff_t from) | 1835 | static int cifs_truncate_page(struct address_space *mapping, loff_t from) |