aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsfs.c15
-rw-r--r--fs/cifs/inode.c86
2 files changed, 52 insertions, 49 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index a5ed10c9afef..b7431afdd76d 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -329,8 +329,10 @@ cifs_destroy_inode(struct inode *inode)
329} 329}
330 330
331static void 331static void
332cifs_clear_inode(struct inode *inode) 332cifs_evict_inode(struct inode *inode)
333{ 333{
334 truncate_inode_pages(&inode->i_data, 0);
335 end_writeback(inode);
334 cifs_fscache_release_inode_cookie(inode); 336 cifs_fscache_release_inode_cookie(inode);
335} 337}
336 338
@@ -479,14 +481,13 @@ static int cifs_remount(struct super_block *sb, int *flags, char *data)
479 return 0; 481 return 0;
480} 482}
481 483
482void cifs_drop_inode(struct inode *inode) 484static int cifs_drop_inode(struct inode *inode)
483{ 485{
484 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 486 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
485 487
486 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) 488 /* no serverino => unconditional eviction */
487 return generic_drop_inode(inode); 489 return !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) ||
488 490 generic_drop_inode(inode);
489 return generic_delete_inode(inode);
490} 491}
491 492
492static const struct super_operations cifs_super_ops = { 493static const struct super_operations cifs_super_ops = {
@@ -495,7 +496,7 @@ static const struct super_operations cifs_super_ops = {
495 .alloc_inode = cifs_alloc_inode, 496 .alloc_inode = cifs_alloc_inode,
496 .destroy_inode = cifs_destroy_inode, 497 .destroy_inode = cifs_destroy_inode,
497 .drop_inode = cifs_drop_inode, 498 .drop_inode = cifs_drop_inode,
498 .clear_inode = cifs_clear_inode, 499 .evict_inode = cifs_evict_inode,
499/* .delete_inode = cifs_delete_inode, */ /* Do not need above 500/* .delete_inode = cifs_delete_inode, */ /* Do not need above
500 function unless later we add lazy close of inodes or unless the 501 function unless later we add lazy close of inodes or unless the
501 kernel forgets to call us with the same number of releases (closes) 502 kernel forgets to call us with the same number of releases (closes)
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);