diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-09 22:08:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-09 22:08:43 -0400 |
commit | b1cce8032f6abe900b078d24f3c3938726528f97 (patch) | |
tree | a387bf49544b0620af61781e3438a908c951a6a3 /fs/cifs/inode.c | |
parent | 1c54fc1efe6922b4e7ffd591739d72050976ccd6 (diff) | |
parent | 663a962151593c69374776e8651238d0da072459 (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.c | 71 |
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 | ||
1144 | out_close: | 1148 | out_close: |
@@ -1759,23 +1763,62 @@ int | |||
1759 | cifs_invalidate_mapping(struct inode *inode) | 1763 | cifs_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 | */ | ||
1782 | static int | ||
1783 | cifs_wait_bit_killable(void *word) | ||
1784 | { | ||
1785 | if (fatal_signal_pending(current)) | ||
1786 | return -ERESTARTSYS; | ||
1787 | freezable_schedule_unsafe(); | ||
1788 | return 0; | ||
1789 | } | ||
1790 | |||
1791 | int | ||
1792 | cifs_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 | |||
1815 | int | ||
1816 | cifs_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 | |||
1779 | int cifs_revalidate_file_attr(struct file *filp) | 1822 | int 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 | ||
1865 | int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, | 1904 | int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, |