aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c167
1 files changed, 56 insertions, 111 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index faf59529e847..c672afef0c09 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -857,95 +857,6 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
857 cifsi->server_eof = end_of_write; 857 cifsi->server_eof = end_of_write;
858} 858}
859 859
860ssize_t cifs_user_write(struct file *file, const char __user *write_data,
861 size_t write_size, loff_t *poffset)
862{
863 struct inode *inode = file->f_path.dentry->d_inode;
864 int rc = 0;
865 unsigned int bytes_written = 0;
866 unsigned int total_written;
867 struct cifs_sb_info *cifs_sb;
868 struct cifsTconInfo *pTcon;
869 int xid;
870 struct cifsFileInfo *open_file;
871 struct cifsInodeInfo *cifsi = CIFS_I(inode);
872
873 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
874
875 /* cFYI(1, " write %d bytes to offset %lld of %s", write_size,
876 *poffset, file->f_path.dentry->d_name.name); */
877
878 if (file->private_data == NULL)
879 return -EBADF;
880
881 open_file = file->private_data;
882 pTcon = tlink_tcon(open_file->tlink);
883
884 rc = generic_write_checks(file, poffset, &write_size, 0);
885 if (rc)
886 return rc;
887
888 xid = GetXid();
889
890 for (total_written = 0; write_size > total_written;
891 total_written += bytes_written) {
892 rc = -EAGAIN;
893 while (rc == -EAGAIN) {
894 if (file->private_data == NULL) {
895 /* file has been closed on us */
896 FreeXid(xid);
897 /* if we have gotten here we have written some data
898 and blocked, and the file has been freed on us while
899 we blocked so return what we managed to write */
900 return total_written;
901 }
902 if (open_file->invalidHandle) {
903 /* we could deadlock if we called
904 filemap_fdatawait from here so tell
905 reopen_file not to flush data to server
906 now */
907 rc = cifs_reopen_file(open_file, false);
908 if (rc != 0)
909 break;
910 }
911
912 rc = CIFSSMBWrite(xid, pTcon,
913 open_file->netfid,
914 min_t(const int, cifs_sb->wsize,
915 write_size - total_written),
916 *poffset, &bytes_written,
917 NULL, write_data + total_written, 0);
918 }
919 if (rc || (bytes_written == 0)) {
920 if (total_written)
921 break;
922 else {
923 FreeXid(xid);
924 return rc;
925 }
926 } else {
927 cifs_update_eof(cifsi, *poffset, bytes_written);
928 *poffset += bytes_written;
929 }
930 }
931
932 cifs_stats_bytes_written(pTcon, total_written);
933
934/* Do not update local mtime - server will set its actual value on write
935 * inode->i_ctime = inode->i_mtime =
936 * current_fs_time(inode->i_sb);*/
937 if (total_written > 0) {
938 spin_lock(&inode->i_lock);
939 if (*poffset > inode->i_size)
940 i_size_write(inode, *poffset);
941 spin_unlock(&inode->i_lock);
942 }
943 mark_inode_dirty_sync(inode);
944
945 FreeXid(xid);
946 return total_written;
947}
948
949static ssize_t cifs_write(struct cifsFileInfo *open_file, 860static ssize_t cifs_write(struct cifsFileInfo *open_file,
950 const char *write_data, size_t write_size, 861 const char *write_data, size_t write_size,
951 loff_t *poffset) 862 loff_t *poffset)
@@ -1420,9 +1331,10 @@ retry_write:
1420 return rc; 1331 return rc;
1421} 1332}
1422 1333
1423static int cifs_writepage(struct page *page, struct writeback_control *wbc) 1334static int
1335cifs_writepage_locked(struct page *page, struct writeback_control *wbc)
1424{ 1336{
1425 int rc = -EFAULT; 1337 int rc;
1426 int xid; 1338 int xid;
1427 1339
1428 xid = GetXid(); 1340 xid = GetXid();
@@ -1442,15 +1354,29 @@ static int cifs_writepage(struct page *page, struct writeback_control *wbc)
1442 * to fail to update with the state of the page correctly. 1354 * to fail to update with the state of the page correctly.
1443 */ 1355 */
1444 set_page_writeback(page); 1356 set_page_writeback(page);
1357retry_write:
1445 rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); 1358 rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE);
1446 SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ 1359 if (rc == -EAGAIN && wbc->sync_mode == WB_SYNC_ALL)
1447 unlock_page(page); 1360 goto retry_write;
1361 else if (rc == -EAGAIN)
1362 redirty_page_for_writepage(wbc, page);
1363 else if (rc != 0)
1364 SetPageError(page);
1365 else
1366 SetPageUptodate(page);
1448 end_page_writeback(page); 1367 end_page_writeback(page);
1449 page_cache_release(page); 1368 page_cache_release(page);
1450 FreeXid(xid); 1369 FreeXid(xid);
1451 return rc; 1370 return rc;
1452} 1371}
1453 1372
1373static int cifs_writepage(struct page *page, struct writeback_control *wbc)
1374{
1375 int rc = cifs_writepage_locked(page, wbc);
1376 unlock_page(page);
1377 return rc;
1378}
1379
1454static int cifs_write_end(struct file *file, struct address_space *mapping, 1380static int cifs_write_end(struct file *file, struct address_space *mapping,
1455 loff_t pos, unsigned len, unsigned copied, 1381 loff_t pos, unsigned len, unsigned copied,
1456 struct page *page, void *fsdata) 1382 struct page *page, void *fsdata)
@@ -1519,8 +1445,13 @@ int cifs_strict_fsync(struct file *file, int datasync)
1519 cFYI(1, "Sync file - name: %s datasync: 0x%x", 1445 cFYI(1, "Sync file - name: %s datasync: 0x%x",
1520 file->f_path.dentry->d_name.name, datasync); 1446 file->f_path.dentry->d_name.name, datasync);
1521 1447
1522 if (!CIFS_I(inode)->clientCanCacheRead) 1448 if (!CIFS_I(inode)->clientCanCacheRead) {
1523 cifs_invalidate_mapping(inode); 1449 rc = cifs_invalidate_mapping(inode);
1450 if (rc) {
1451 cFYI(1, "rc: %d during invalidate phase", rc);
1452 rc = 0; /* don't care about it in fsync */
1453 }
1454 }
1524 1455
1525 tcon = tlink_tcon(smbfile->tlink); 1456 tcon = tlink_tcon(smbfile->tlink);
1526 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) 1457 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
@@ -1726,7 +1657,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
1726 return total_written; 1657 return total_written;
1727} 1658}
1728 1659
1729static ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov, 1660ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov,
1730 unsigned long nr_segs, loff_t pos) 1661 unsigned long nr_segs, loff_t pos)
1731{ 1662{
1732 ssize_t written; 1663 ssize_t written;
@@ -1849,17 +1780,7 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
1849 return total_read; 1780 return total_read;
1850} 1781}
1851 1782
1852ssize_t cifs_user_read(struct file *file, char __user *read_data, 1783ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
1853 size_t read_size, loff_t *poffset)
1854{
1855 struct iovec iov;
1856 iov.iov_base = read_data;
1857 iov.iov_len = read_size;
1858
1859 return cifs_iovec_read(file, &iov, 1, poffset);
1860}
1861
1862static ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
1863 unsigned long nr_segs, loff_t pos) 1784 unsigned long nr_segs, loff_t pos)
1864{ 1785{
1865 ssize_t read; 1786 ssize_t read;
@@ -1987,8 +1908,11 @@ int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
1987 1908
1988 xid = GetXid(); 1909 xid = GetXid();
1989 1910
1990 if (!CIFS_I(inode)->clientCanCacheRead) 1911 if (!CIFS_I(inode)->clientCanCacheRead) {
1991 cifs_invalidate_mapping(inode); 1912 rc = cifs_invalidate_mapping(inode);
1913 if (rc)
1914 return rc;
1915 }
1992 1916
1993 rc = generic_file_mmap(file, vma); 1917 rc = generic_file_mmap(file, vma);
1994 if (rc == 0) 1918 if (rc == 0)
@@ -2415,6 +2339,27 @@ static void cifs_invalidate_page(struct page *page, unsigned long offset)
2415 cifs_fscache_invalidate_page(page, &cifsi->vfs_inode); 2339 cifs_fscache_invalidate_page(page, &cifsi->vfs_inode);
2416} 2340}
2417 2341
2342static int cifs_launder_page(struct page *page)
2343{
2344 int rc = 0;
2345 loff_t range_start = page_offset(page);
2346 loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1);
2347 struct writeback_control wbc = {
2348 .sync_mode = WB_SYNC_ALL,
2349 .nr_to_write = 0,
2350 .range_start = range_start,
2351 .range_end = range_end,
2352 };
2353
2354 cFYI(1, "Launder page: %p", page);
2355
2356 if (clear_page_dirty_for_io(page))
2357 rc = cifs_writepage_locked(page, &wbc);
2358
2359 cifs_fscache_invalidate_page(page, page->mapping->host);
2360 return rc;
2361}
2362
2418void cifs_oplock_break(struct work_struct *work) 2363void cifs_oplock_break(struct work_struct *work)
2419{ 2364{
2420 struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, 2365 struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
@@ -2486,7 +2431,7 @@ const struct address_space_operations cifs_addr_ops = {
2486 .set_page_dirty = __set_page_dirty_nobuffers, 2431 .set_page_dirty = __set_page_dirty_nobuffers,
2487 .releasepage = cifs_release_page, 2432 .releasepage = cifs_release_page,
2488 .invalidatepage = cifs_invalidate_page, 2433 .invalidatepage = cifs_invalidate_page,
2489 /* .direct_IO = */ 2434 .launder_page = cifs_launder_page,
2490}; 2435};
2491 2436
2492/* 2437/*
@@ -2503,5 +2448,5 @@ const struct address_space_operations cifs_addr_ops_smallbuf = {
2503 .set_page_dirty = __set_page_dirty_nobuffers, 2448 .set_page_dirty = __set_page_dirty_nobuffers,
2504 .releasepage = cifs_release_page, 2449 .releasepage = cifs_release_page,
2505 .invalidatepage = cifs_invalidate_page, 2450 .invalidatepage = cifs_invalidate_page,
2506 /* .direct_IO = */ 2451 .launder_page = cifs_launder_page,
2507}; 2452};