aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-09 22:08:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-09 22:08:43 -0400
commitb1cce8032f6abe900b078d24f3c3938726528f97 (patch)
treea387bf49544b0620af61781e3438a908c951a6a3 /fs/cifs/inode.c
parent1c54fc1efe6922b4e7ffd591739d72050976ccd6 (diff)
parent663a962151593c69374776e8651238d0da072459 (diff)
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
Pull CIFS fixes from Steve French. * 'for-next' of git://git.samba.org/sfrench/cifs-2.6: CIFS: Fix memory leaks in SMB2_open cifs: ensure that vol->username is not NULL before running strlen on it Clarify SMB2/SMB3 create context and add missing ones Do not send ClientGUID on SMB2.02 dialect cifs: Set client guid on per connection basis fs/cifs/netmisc.c: convert printk to pr_foo() fs/cifs/cifs.c: replace seq_printf by seq_puts Update cifs version number to 2.03 fs: cifs: new helper: file_inode(file) cifs: fix potential races in cifs_revalidate_mapping cifs: new helper function: cifs_revalidate_mapping cifs: convert booleans in cifsInodeInfo to a flags field cifs: fix cifs_uniqueid_to_ino_t not to ever return 0
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c71
1 files changed, 55 insertions, 16 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index a22d667f1069..a174605f6afa 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -22,6 +22,7 @@
22#include <linux/stat.h> 22#include <linux/stat.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/pagemap.h> 24#include <linux/pagemap.h>
25#include <linux/freezer.h>
25#include <asm/div64.h> 26#include <asm/div64.h>
26#include "cifsfs.h" 27#include "cifsfs.h"
27#include "cifspdu.h" 28#include "cifspdu.h"
@@ -117,7 +118,7 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
117 118
118 cifs_dbg(FYI, "%s: invalidating inode %llu mapping\n", 119 cifs_dbg(FYI, "%s: invalidating inode %llu mapping\n",
119 __func__, cifs_i->uniqueid); 120 __func__, cifs_i->uniqueid);
120 cifs_i->invalid_mapping = true; 121 set_bit(CIFS_INO_INVALID_MAPPING, &cifs_i->flags);
121} 122}
122 123
123/* 124/*
@@ -177,7 +178,10 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
177 else 178 else
178 cifs_i->time = jiffies; 179 cifs_i->time = jiffies;
179 180
180 cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING; 181 if (fattr->cf_flags & CIFS_FATTR_DELETE_PENDING)
182 set_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags);
183 else
184 clear_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags);
181 185
182 cifs_i->server_eof = fattr->cf_eof; 186 cifs_i->server_eof = fattr->cf_eof;
183 /* 187 /*
@@ -1121,7 +1125,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
1121 } 1125 }
1122 1126
1123 /* try to set DELETE_ON_CLOSE */ 1127 /* try to set DELETE_ON_CLOSE */
1124 if (!cifsInode->delete_pending) { 1128 if (!test_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags)) {
1125 rc = CIFSSMBSetFileDisposition(xid, tcon, true, fid.netfid, 1129 rc = CIFSSMBSetFileDisposition(xid, tcon, true, fid.netfid,
1126 current->tgid); 1130 current->tgid);
1127 /* 1131 /*
@@ -1138,7 +1142,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
1138 rc = -EBUSY; 1142 rc = -EBUSY;
1139 goto undo_rename; 1143 goto undo_rename;
1140 } 1144 }
1141 cifsInode->delete_pending = true; 1145 set_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags);
1142 } 1146 }
1143 1147
1144out_close: 1148out_close:
@@ -1759,23 +1763,62 @@ int
1759cifs_invalidate_mapping(struct inode *inode) 1763cifs_invalidate_mapping(struct inode *inode)
1760{ 1764{
1761 int rc = 0; 1765 int rc = 0;
1762 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1763
1764 cifs_i->invalid_mapping = false;
1765 1766
1766 if (inode->i_mapping && inode->i_mapping->nrpages != 0) { 1767 if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
1767 rc = invalidate_inode_pages2(inode->i_mapping); 1768 rc = invalidate_inode_pages2(inode->i_mapping);
1768 if (rc) { 1769 if (rc)
1769 cifs_dbg(VFS, "%s: could not invalidate inode %p\n", 1770 cifs_dbg(VFS, "%s: could not invalidate inode %p\n",
1770 __func__, inode); 1771 __func__, inode);
1771 cifs_i->invalid_mapping = true;
1772 }
1773 } 1772 }
1774 1773
1775 cifs_fscache_reset_inode_cookie(inode); 1774 cifs_fscache_reset_inode_cookie(inode);
1776 return rc; 1775 return rc;
1777} 1776}
1778 1777
1778/**
1779 * cifs_wait_bit_killable - helper for functions that are sleeping on bit locks
1780 * @word: long word containing the bit lock
1781 */
1782static int
1783cifs_wait_bit_killable(void *word)
1784{
1785 if (fatal_signal_pending(current))
1786 return -ERESTARTSYS;
1787 freezable_schedule_unsafe();
1788 return 0;
1789}
1790
1791int
1792cifs_revalidate_mapping(struct inode *inode)
1793{
1794 int rc;
1795 unsigned long *flags = &CIFS_I(inode)->flags;
1796
1797 rc = wait_on_bit_lock(flags, CIFS_INO_LOCK, cifs_wait_bit_killable,
1798 TASK_KILLABLE);
1799 if (rc)
1800 return rc;
1801
1802 if (test_and_clear_bit(CIFS_INO_INVALID_MAPPING, flags)) {
1803 rc = cifs_invalidate_mapping(inode);
1804 if (rc)
1805 set_bit(CIFS_INO_INVALID_MAPPING, flags);
1806 }
1807
1808 clear_bit_unlock(CIFS_INO_LOCK, flags);
1809 smp_mb__after_atomic();
1810 wake_up_bit(flags, CIFS_INO_LOCK);
1811
1812 return rc;
1813}
1814
1815int
1816cifs_zap_mapping(struct inode *inode)
1817{
1818 set_bit(CIFS_INO_INVALID_MAPPING, &CIFS_I(inode)->flags);
1819 return cifs_revalidate_mapping(inode);
1820}
1821
1779int cifs_revalidate_file_attr(struct file *filp) 1822int cifs_revalidate_file_attr(struct file *filp)
1780{ 1823{
1781 int rc = 0; 1824 int rc = 0;
@@ -1842,9 +1885,7 @@ int cifs_revalidate_file(struct file *filp)
1842 if (rc) 1885 if (rc)
1843 return rc; 1886 return rc;
1844 1887
1845 if (CIFS_I(inode)->invalid_mapping) 1888 return cifs_revalidate_mapping(inode);
1846 rc = cifs_invalidate_mapping(inode);
1847 return rc;
1848} 1889}
1849 1890
1850/* revalidate a dentry's inode attributes */ 1891/* revalidate a dentry's inode attributes */
@@ -1857,9 +1898,7 @@ int cifs_revalidate_dentry(struct dentry *dentry)
1857 if (rc) 1898 if (rc)
1858 return rc; 1899 return rc;
1859 1900
1860 if (CIFS_I(inode)->invalid_mapping) 1901 return cifs_revalidate_mapping(inode);
1861 rc = cifs_invalidate_mapping(inode);
1862 return rc;
1863} 1902}
1864 1903
1865int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, 1904int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,