diff options
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 86 |
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 | ||
1701 | static int cifs_vmtruncate(struct inode *inode, loff_t offset) | 1701 | static 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); | ||
1719 | out: | ||
1720 | return err; | ||
1721 | } | 1711 | } |
1722 | 1712 | ||
1723 | static int | 1713 | static 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; | ||
1923 | out: | 1917 | out: |
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 | |||
2064 | cifs_setattr_exit: | 2066 | cifs_setattr_exit: |
2065 | kfree(full_path); | 2067 | kfree(full_path); |
2066 | FreeXid(xid); | 2068 | FreeXid(xid); |