aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-03 17:33:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-03 17:33:09 -0400
commit54161df1fb1469d66bce3a3b14d8281adbb69263 (patch)
treeb5f0f8741db382daf09dd236e9e678d60422dc48 /fs/cifs/file.c
parentbe82ae0238b0453afcf4a76f0512b7dde34ba500 (diff)
parentcb76d5e25008b76fb8e348c861d32659430ac3fa (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (29 commits) cifs: fsc should not default to "on" [CIFS] remove redundant path walking in dfs_do_refmount cifs: ignore the "mand", "nomand" and "_netdev" mount options cifs: map NT_STATUS_ERROR_WRITE_PROTECTED to -EROFS cifs: don't allow cifs_iget to match inodes of the wrong type [CIFS] relinquish fscache cookie before freeing CIFSTconInfo cifs: add separate cred_uid field to sesInfo fs: cifs: check kmalloc() result [CIFS] Missing ifdef [CIFS] Missing line from previous commit [CIFS] Fix build break when CONFIG_CIFS_FSCACHE disabled cifs: add mount option to enable local caching cifs: read pages from FS-Cache cifs: store pages into local cache cifs: FS-Cache page management cifs: define inode-level cache object and register them cifs: define superblock-level cache index objects and register them cifs: remove unused cifsUidInfo struct cifs: clean up cifs_find_smb_ses (try #2) cifs: match secType when searching for existing tcp session ...
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c74
1 files changed, 60 insertions, 14 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 409e4f523e61..fa04a00d126d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -40,6 +40,7 @@
40#include "cifs_unicode.h" 40#include "cifs_unicode.h"
41#include "cifs_debug.h" 41#include "cifs_debug.h"
42#include "cifs_fs_sb.h" 42#include "cifs_fs_sb.h"
43#include "fscache.h"
43 44
44static inline int cifs_convert_flags(unsigned int flags) 45static inline int cifs_convert_flags(unsigned int flags)
45{ 46{
@@ -282,6 +283,9 @@ int cifs_open(struct inode *inode, struct file *file)
282 CIFSSMBClose(xid, tcon, netfid); 283 CIFSSMBClose(xid, tcon, netfid);
283 rc = -ENOMEM; 284 rc = -ENOMEM;
284 } 285 }
286
287 cifs_fscache_set_inode_cookie(inode, file);
288
285 goto out; 289 goto out;
286 } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 290 } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
287 if (tcon->ses->serverNOS) 291 if (tcon->ses->serverNOS)
@@ -373,6 +377,8 @@ int cifs_open(struct inode *inode, struct file *file)
373 goto out; 377 goto out;
374 } 378 }
375 379
380 cifs_fscache_set_inode_cookie(inode, file);
381
376 if (oplock & CIFS_CREATE_ACTION) { 382 if (oplock & CIFS_CREATE_ACTION) {
377 /* time to set mode which we can not set earlier due to 383 /* time to set mode which we can not set earlier due to
378 problems creating new read-only files */ 384 problems creating new read-only files */
@@ -427,7 +433,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
427 __u16 netfid; 433 __u16 netfid;
428 434
429 if (file->private_data) 435 if (file->private_data)
430 pCifsFile = (struct cifsFileInfo *)file->private_data; 436 pCifsFile = file->private_data;
431 else 437 else
432 return -EBADF; 438 return -EBADF;
433 439
@@ -565,8 +571,7 @@ int cifs_close(struct inode *inode, struct file *file)
565 int xid, timeout; 571 int xid, timeout;
566 struct cifs_sb_info *cifs_sb; 572 struct cifs_sb_info *cifs_sb;
567 struct cifsTconInfo *pTcon; 573 struct cifsTconInfo *pTcon;
568 struct cifsFileInfo *pSMBFile = 574 struct cifsFileInfo *pSMBFile = file->private_data;
569 (struct cifsFileInfo *)file->private_data;
570 575
571 xid = GetXid(); 576 xid = GetXid();
572 577
@@ -641,8 +646,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
641{ 646{
642 int rc = 0; 647 int rc = 0;
643 int xid; 648 int xid;
644 struct cifsFileInfo *pCFileStruct = 649 struct cifsFileInfo *pCFileStruct = file->private_data;
645 (struct cifsFileInfo *)file->private_data;
646 char *ptmp; 650 char *ptmp;
647 651
648 cFYI(1, "Closedir inode = 0x%p", inode); 652 cFYI(1, "Closedir inode = 0x%p", inode);
@@ -863,8 +867,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
863 length, pfLock, 867 length, pfLock,
864 posix_lock_type, wait_flag); 868 posix_lock_type, wait_flag);
865 } else { 869 } else {
866 struct cifsFileInfo *fid = 870 struct cifsFileInfo *fid = file->private_data;
867 (struct cifsFileInfo *)file->private_data;
868 871
869 if (numLock) { 872 if (numLock) {
870 rc = CIFSSMBLock(xid, tcon, netfid, length, 873 rc = CIFSSMBLock(xid, tcon, netfid, length,
@@ -965,7 +968,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
965 968
966 if (file->private_data == NULL) 969 if (file->private_data == NULL)
967 return -EBADF; 970 return -EBADF;
968 open_file = (struct cifsFileInfo *) file->private_data; 971 open_file = file->private_data;
969 972
970 rc = generic_write_checks(file, poffset, &write_size, 0); 973 rc = generic_write_checks(file, poffset, &write_size, 0);
971 if (rc) 974 if (rc)
@@ -1067,7 +1070,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1067 1070
1068 if (file->private_data == NULL) 1071 if (file->private_data == NULL)
1069 return -EBADF; 1072 return -EBADF;
1070 open_file = (struct cifsFileInfo *)file->private_data; 1073 open_file = file->private_data;
1071 1074
1072 xid = GetXid(); 1075 xid = GetXid();
1073 1076
@@ -1651,8 +1654,7 @@ int cifs_fsync(struct file *file, int datasync)
1651 int xid; 1654 int xid;
1652 int rc = 0; 1655 int rc = 0;
1653 struct cifsTconInfo *tcon; 1656 struct cifsTconInfo *tcon;
1654 struct cifsFileInfo *smbfile = 1657 struct cifsFileInfo *smbfile = file->private_data;
1655 (struct cifsFileInfo *)file->private_data;
1656 struct inode *inode = file->f_path.dentry->d_inode; 1658 struct inode *inode = file->f_path.dentry->d_inode;
1657 1659
1658 xid = GetXid(); 1660 xid = GetXid();
@@ -1756,7 +1758,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1756 FreeXid(xid); 1758 FreeXid(xid);
1757 return rc; 1759 return rc;
1758 } 1760 }
1759 open_file = (struct cifsFileInfo *)file->private_data; 1761 open_file = file->private_data;
1760 1762
1761 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1763 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1762 cFYI(1, "attempting read on write only file instance"); 1764 cFYI(1, "attempting read on write only file instance");
@@ -1837,7 +1839,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1837 FreeXid(xid); 1839 FreeXid(xid);
1838 return rc; 1840 return rc;
1839 } 1841 }
1840 open_file = (struct cifsFileInfo *)file->private_data; 1842 open_file = file->private_data;
1841 1843
1842 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1844 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1843 cFYI(1, "attempting read on write only file instance"); 1845 cFYI(1, "attempting read on write only file instance");
@@ -1942,6 +1944,9 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
1942 SetPageUptodate(page); 1944 SetPageUptodate(page);
1943 unlock_page(page); 1945 unlock_page(page);
1944 data += PAGE_CACHE_SIZE; 1946 data += PAGE_CACHE_SIZE;
1947
1948 /* add page to FS-Cache */
1949 cifs_readpage_to_fscache(mapping->host, page);
1945 } 1950 }
1946 return; 1951 return;
1947} 1952}
@@ -1968,10 +1973,19 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1968 FreeXid(xid); 1973 FreeXid(xid);
1969 return rc; 1974 return rc;
1970 } 1975 }
1971 open_file = (struct cifsFileInfo *)file->private_data; 1976 open_file = file->private_data;
1972 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1977 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1973 pTcon = cifs_sb->tcon; 1978 pTcon = cifs_sb->tcon;
1974 1979
1980 /*
1981 * Reads as many pages as possible from fscache. Returns -ENOBUFS
1982 * immediately if the cookie is negative
1983 */
1984 rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list,
1985 &num_pages);
1986 if (rc == 0)
1987 goto read_complete;
1988
1975 cFYI(DBG2, "rpages: num pages %d", num_pages); 1989 cFYI(DBG2, "rpages: num pages %d", num_pages);
1976 for (i = 0; i < num_pages; ) { 1990 for (i = 0; i < num_pages; ) {
1977 unsigned contig_pages; 1991 unsigned contig_pages;
@@ -2082,6 +2096,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
2082 smb_read_data = NULL; 2096 smb_read_data = NULL;
2083 } 2097 }
2084 2098
2099read_complete:
2085 FreeXid(xid); 2100 FreeXid(xid);
2086 return rc; 2101 return rc;
2087} 2102}
@@ -2092,6 +2107,11 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
2092 char *read_data; 2107 char *read_data;
2093 int rc; 2108 int rc;
2094 2109
2110 /* Is the page cached? */
2111 rc = cifs_readpage_from_fscache(file->f_path.dentry->d_inode, page);
2112 if (rc == 0)
2113 goto read_complete;
2114
2095 page_cache_get(page); 2115 page_cache_get(page);
2096 read_data = kmap(page); 2116 read_data = kmap(page);
2097 /* for reads over a certain size could initiate async read ahead */ 2117 /* for reads over a certain size could initiate async read ahead */
@@ -2111,11 +2131,17 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
2111 2131
2112 flush_dcache_page(page); 2132 flush_dcache_page(page);
2113 SetPageUptodate(page); 2133 SetPageUptodate(page);
2134
2135 /* send this page to the cache */
2136 cifs_readpage_to_fscache(file->f_path.dentry->d_inode, page);
2137
2114 rc = 0; 2138 rc = 0;
2115 2139
2116io_error: 2140io_error:
2117 kunmap(page); 2141 kunmap(page);
2118 page_cache_release(page); 2142 page_cache_release(page);
2143
2144read_complete:
2119 return rc; 2145 return rc;
2120} 2146}
2121 2147
@@ -2265,6 +2291,22 @@ out:
2265 return rc; 2291 return rc;
2266} 2292}
2267 2293
2294static int cifs_release_page(struct page *page, gfp_t gfp)
2295{
2296 if (PagePrivate(page))
2297 return 0;
2298
2299 return cifs_fscache_release_page(page, gfp);
2300}
2301
2302static void cifs_invalidate_page(struct page *page, unsigned long offset)
2303{
2304 struct cifsInodeInfo *cifsi = CIFS_I(page->mapping->host);
2305
2306 if (offset == 0)
2307 cifs_fscache_invalidate_page(page, &cifsi->vfs_inode);
2308}
2309
2268static void 2310static void
2269cifs_oplock_break(struct slow_work *work) 2311cifs_oplock_break(struct slow_work *work)
2270{ 2312{
@@ -2338,6 +2380,8 @@ const struct address_space_operations cifs_addr_ops = {
2338 .write_begin = cifs_write_begin, 2380 .write_begin = cifs_write_begin,
2339 .write_end = cifs_write_end, 2381 .write_end = cifs_write_end,
2340 .set_page_dirty = __set_page_dirty_nobuffers, 2382 .set_page_dirty = __set_page_dirty_nobuffers,
2383 .releasepage = cifs_release_page,
2384 .invalidatepage = cifs_invalidate_page,
2341 /* .sync_page = cifs_sync_page, */ 2385 /* .sync_page = cifs_sync_page, */
2342 /* .direct_IO = */ 2386 /* .direct_IO = */
2343}; 2387};
@@ -2354,6 +2398,8 @@ const struct address_space_operations cifs_addr_ops_smallbuf = {
2354 .write_begin = cifs_write_begin, 2398 .write_begin = cifs_write_begin,
2355 .write_end = cifs_write_end, 2399 .write_end = cifs_write_end,
2356 .set_page_dirty = __set_page_dirty_nobuffers, 2400 .set_page_dirty = __set_page_dirty_nobuffers,
2401 .releasepage = cifs_release_page,
2402 .invalidatepage = cifs_invalidate_page,
2357 /* .sync_page = cifs_sync_page, */ 2403 /* .sync_page = cifs_sync_page, */
2358 /* .direct_IO = */ 2404 /* .direct_IO = */
2359}; 2405};