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.c86
1 files changed, 44 insertions, 42 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index dc4c47ab9588..4bc47e5b5f29 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1698,26 +1698,16 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1698 return rc; 1698 return rc;
1699} 1699}
1700 1700
1701static int cifs_vmtruncate(struct inode *inode, loff_t offset) 1701static void cifs_setsize(struct inode *inode, loff_t offset)
1702{ 1702{
1703 loff_t oldsize; 1703 loff_t oldsize;
1704 int err;
1705 1704
1706 spin_lock(&inode->i_lock); 1705 spin_lock(&inode->i_lock);
1707 err = inode_newsize_ok(inode, offset);
1708 if (err) {
1709 spin_unlock(&inode->i_lock);
1710 goto out;
1711 }
1712
1713 oldsize = inode->i_size; 1706 oldsize = inode->i_size;
1714 i_size_write(inode, offset); 1707 i_size_write(inode, offset);
1715 spin_unlock(&inode->i_lock); 1708 spin_unlock(&inode->i_lock);
1709
1716 truncate_pagecache(inode, oldsize, offset); 1710 truncate_pagecache(inode, oldsize, offset);
1717 if (inode->i_op->truncate)
1718 inode->i_op->truncate(inode);
1719out:
1720 return err;
1721} 1711}
1722 1712
1723static int 1713static int
@@ -1790,7 +1780,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1790 1780
1791 if (rc == 0) { 1781 if (rc == 0) {
1792 cifsInode->server_eof = attrs->ia_size; 1782 cifsInode->server_eof = attrs->ia_size;
1793 rc = cifs_vmtruncate(inode, attrs->ia_size); 1783 cifs_setsize(inode, attrs->ia_size);
1794 cifs_truncate_page(inode->i_mapping, inode->i_size); 1784 cifs_truncate_page(inode->i_mapping, inode->i_size);
1795 } 1785 }
1796 1786
@@ -1815,14 +1805,12 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1815 1805
1816 xid = GetXid(); 1806 xid = GetXid();
1817 1807
1818 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) { 1808 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
1819 /* check if we have permission to change attrs */ 1809 attrs->ia_valid |= ATTR_FORCE;
1820 rc = inode_change_ok(inode, attrs); 1810
1821 if (rc < 0) 1811 rc = inode_change_ok(inode, attrs);
1822 goto out; 1812 if (rc < 0)
1823 else 1813 goto out;
1824 rc = 0;
1825 }
1826 1814
1827 full_path = build_path_from_dentry(direntry); 1815 full_path = build_path_from_dentry(direntry);
1828 if (full_path == NULL) { 1816 if (full_path == NULL) {
@@ -1908,18 +1896,24 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1908 CIFS_MOUNT_MAP_SPECIAL_CHR); 1896 CIFS_MOUNT_MAP_SPECIAL_CHR);
1909 } 1897 }
1910 1898
1911 if (!rc) { 1899 if (rc)
1912 rc = inode_setattr(inode, attrs); 1900 goto out;
1913 1901
1914 /* force revalidate when any of these times are set since some 1902 if ((attrs->ia_valid & ATTR_SIZE) &&
1915 of the fs types (eg ext3, fat) do not have fine enough 1903 attrs->ia_size != i_size_read(inode))
1916 time granularity to match protocol, and we do not have a 1904 truncate_setsize(inode, attrs->ia_size);
1917 a way (yet) to query the server fs's time granularity (and 1905
1918 whether it rounds times down). 1906 setattr_copy(inode, attrs);
1919 */ 1907 mark_inode_dirty(inode);
1920 if (!rc && (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))) 1908
1921 cifsInode->time = 0; 1909 /* force revalidate when any of these times are set since some
1922 } 1910 of the fs types (eg ext3, fat) do not have fine enough
1911 time granularity to match protocol, and we do not have a
1912 a way (yet) to query the server fs's time granularity (and
1913 whether it rounds times down).
1914 */
1915 if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))
1916 cifsInode->time = 0;
1923out: 1917out:
1924 kfree(args); 1918 kfree(args);
1925 kfree(full_path); 1919 kfree(full_path);
@@ -1944,14 +1938,13 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
1944 cFYI(1, "setattr on file %s attrs->iavalid 0x%x", 1938 cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
1945 direntry->d_name.name, attrs->ia_valid); 1939 direntry->d_name.name, attrs->ia_valid);
1946 1940
1947 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) { 1941 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
1948 /* check if we have permission to change attrs */ 1942 attrs->ia_valid |= ATTR_FORCE;
1949 rc = inode_change_ok(inode, attrs); 1943
1950 if (rc < 0) { 1944 rc = inode_change_ok(inode, attrs);
1951 FreeXid(xid); 1945 if (rc < 0) {
1952 return rc; 1946 FreeXid(xid);
1953 } else 1947 return rc;
1954 rc = 0;
1955 } 1948 }
1956 1949
1957 full_path = build_path_from_dentry(direntry); 1950 full_path = build_path_from_dentry(direntry);
@@ -2059,8 +2052,17 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
2059 2052
2060 /* do not need local check to inode_check_ok since the server does 2053 /* do not need local check to inode_check_ok since the server does
2061 that */ 2054 that */
2062 if (!rc) 2055 if (rc)
2063 rc = inode_setattr(inode, attrs); 2056 goto cifs_setattr_exit;
2057
2058 if ((attrs->ia_valid & ATTR_SIZE) &&
2059 attrs->ia_size != i_size_read(inode))
2060 truncate_setsize(inode, attrs->ia_size);
2061
2062 setattr_copy(inode, attrs);
2063 mark_inode_dirty(inode);
2064 return 0;
2065
2064cifs_setattr_exit: 2066cifs_setattr_exit:
2065 kfree(full_path); 2067 kfree(full_path);
2066 FreeXid(xid); 2068 FreeXid(xid);