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.c81
1 files changed, 50 insertions, 31 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index da4f5e10b3cc..77c990f0cb98 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -127,8 +127,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
127 if (file->f_dentry->d_inode->i_mapping) { 127 if (file->f_dentry->d_inode->i_mapping) {
128 /* BB no need to lock inode until after invalidate 128 /* BB no need to lock inode until after invalidate
129 since namei code should already have it locked? */ 129 since namei code should already have it locked? */
130 filemap_fdatawrite(file->f_dentry->d_inode->i_mapping); 130 filemap_write_and_wait(file->f_dentry->d_inode->i_mapping);
131 filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
132 } 131 }
133 cFYI(1, ("invalidating remote inode since open detected it " 132 cFYI(1, ("invalidating remote inode since open detected it "
134 "changed")); 133 "changed"));
@@ -419,8 +418,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
419 pCifsInode = CIFS_I(inode); 418 pCifsInode = CIFS_I(inode);
420 if (pCifsInode) { 419 if (pCifsInode) {
421 if (can_flush) { 420 if (can_flush) {
422 filemap_fdatawrite(inode->i_mapping); 421 filemap_write_and_wait(inode->i_mapping);
423 filemap_fdatawait(inode->i_mapping);
424 /* temporarily disable caching while we 422 /* temporarily disable caching while we
425 go to server to get inode info */ 423 go to server to get inode info */
426 pCifsInode->clientCanCacheAll = FALSE; 424 pCifsInode->clientCanCacheAll = FALSE;
@@ -489,8 +487,10 @@ int cifs_close(struct inode *inode, struct file *file)
489 the struct would be in each open file, 487 the struct would be in each open file,
490 but this should give enough time to 488 but this should give enough time to
491 clear the socket */ 489 clear the socket */
490 write_unlock(&file->f_owner.lock);
492 cERROR(1,("close with pending writes")); 491 cERROR(1,("close with pending writes"));
493 msleep(timeout); 492 msleep(timeout);
493 write_lock(&file->f_owner.lock);
494 timeout *= 4; 494 timeout *= 4;
495 } 495 }
496 write_unlock(&file->f_owner.lock); 496 write_unlock(&file->f_owner.lock);
@@ -553,13 +553,13 @@ int cifs_closedir(struct inode *inode, struct file *file)
553 } 553 }
554 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start; 554 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
555 if (ptmp) { 555 if (ptmp) {
556 /* BB removeme BB */ cFYI(1, ("freeing smb buf in srch struct in closedir")); 556 cFYI(1, ("closedir free smb buf in srch struct"));
557 pCFileStruct->srch_inf.ntwrk_buf_start = NULL; 557 pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
558 cifs_buf_release(ptmp); 558 cifs_buf_release(ptmp);
559 } 559 }
560 ptmp = pCFileStruct->search_resume_name; 560 ptmp = pCFileStruct->search_resume_name;
561 if (ptmp) { 561 if (ptmp) {
562 /* BB removeme BB */ cFYI(1, ("freeing resume name in closedir")); 562 cFYI(1, ("closedir free resume name"));
563 pCFileStruct->search_resume_name = NULL; 563 pCFileStruct->search_resume_name = NULL;
564 kfree(ptmp); 564 kfree(ptmp);
565 } 565 }
@@ -868,10 +868,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
868 if (rc != 0) 868 if (rc != 0)
869 break; 869 break;
870 } 870 }
871#ifdef CONFIG_CIFS_EXPERIMENTAL
872 /* BB FIXME We can not sign across two buffers yet */ 871 /* BB FIXME We can not sign across two buffers yet */
873 if((experimEnabled) && ((pTcon->ses->server->secMode & 872 if((pTcon->ses->server->secMode &
874 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) { 873 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
875 struct kvec iov[2]; 874 struct kvec iov[2];
876 unsigned int len; 875 unsigned int len;
877 876
@@ -887,7 +886,6 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
887 iov, 1, long_op); 886 iov, 1, long_op);
888 } else 887 } else
889 /* BB FIXME fixup indentation of line below */ 888 /* BB FIXME fixup indentation of line below */
890#endif
891 rc = CIFSSMBWrite(xid, pTcon, 889 rc = CIFSSMBWrite(xid, pTcon,
892 open_file->netfid, 890 open_file->netfid,
893 min_t(const int, cifs_sb->wsize, 891 min_t(const int, cifs_sb->wsize,
@@ -1024,7 +1022,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1024 return rc; 1022 return rc;
1025} 1023}
1026 1024
1027#ifdef CONFIG_CIFS_EXPERIMENTAL
1028static int cifs_writepages(struct address_space *mapping, 1025static int cifs_writepages(struct address_space *mapping,
1029 struct writeback_control *wbc) 1026 struct writeback_control *wbc)
1030{ 1027{
@@ -1227,7 +1224,6 @@ retry:
1227 1224
1228 return rc; 1225 return rc;
1229} 1226}
1230#endif
1231 1227
1232static int cifs_writepage(struct page* page, struct writeback_control *wbc) 1228static int cifs_writepage(struct page* page, struct writeback_control *wbc)
1233{ 1229{
@@ -1426,6 +1422,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1426 rc = -EAGAIN; 1422 rc = -EAGAIN;
1427 smb_read_data = NULL; 1423 smb_read_data = NULL;
1428 while (rc == -EAGAIN) { 1424 while (rc == -EAGAIN) {
1425 int buf_type = CIFS_NO_BUFFER;
1429 if ((open_file->invalidHandle) && 1426 if ((open_file->invalidHandle) &&
1430 (!open_file->closePend)) { 1427 (!open_file->closePend)) {
1431 rc = cifs_reopen_file(file->f_dentry->d_inode, 1428 rc = cifs_reopen_file(file->f_dentry->d_inode,
@@ -1434,20 +1431,22 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1434 break; 1431 break;
1435 } 1432 }
1436 rc = CIFSSMBRead(xid, pTcon, 1433 rc = CIFSSMBRead(xid, pTcon,
1437 open_file->netfid, 1434 open_file->netfid,
1438 current_read_size, *poffset, 1435 current_read_size, *poffset,
1439 &bytes_read, &smb_read_data); 1436 &bytes_read, &smb_read_data,
1437 &buf_type);
1440 pSMBr = (struct smb_com_read_rsp *)smb_read_data; 1438 pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1441 if (copy_to_user(current_offset, 1439 if (copy_to_user(current_offset,
1442 smb_read_data + 4 /* RFC1001 hdr */ 1440 smb_read_data + 4 /* RFC1001 hdr */
1443 + le16_to_cpu(pSMBr->DataOffset), 1441 + le16_to_cpu(pSMBr->DataOffset),
1444 bytes_read)) { 1442 bytes_read)) {
1445 rc = -EFAULT; 1443 rc = -EFAULT;
1446 FreeXid(xid); 1444 }
1447 return rc;
1448 }
1449 if (smb_read_data) { 1445 if (smb_read_data) {
1450 cifs_buf_release(smb_read_data); 1446 if(buf_type == CIFS_SMALL_BUFFER)
1447 cifs_small_buf_release(smb_read_data);
1448 else if(buf_type == CIFS_LARGE_BUFFER)
1449 cifs_buf_release(smb_read_data);
1451 smb_read_data = NULL; 1450 smb_read_data = NULL;
1452 } 1451 }
1453 } 1452 }
@@ -1480,6 +1479,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1480 int xid; 1479 int xid;
1481 char *current_offset; 1480 char *current_offset;
1482 struct cifsFileInfo *open_file; 1481 struct cifsFileInfo *open_file;
1482 int buf_type = CIFS_NO_BUFFER;
1483 1483
1484 xid = GetXid(); 1484 xid = GetXid();
1485 cifs_sb = CIFS_SB(file->f_dentry->d_sb); 1485 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
@@ -1516,9 +1516,10 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1516 break; 1516 break;
1517 } 1517 }
1518 rc = CIFSSMBRead(xid, pTcon, 1518 rc = CIFSSMBRead(xid, pTcon,
1519 open_file->netfid, 1519 open_file->netfid,
1520 current_read_size, *poffset, 1520 current_read_size, *poffset,
1521 &bytes_read, &current_offset); 1521 &bytes_read, &current_offset,
1522 &buf_type);
1522 } 1523 }
1523 if (rc || (bytes_read == 0)) { 1524 if (rc || (bytes_read == 0)) {
1524 if (total_read) { 1525 if (total_read) {
@@ -1616,6 +1617,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1616 struct smb_com_read_rsp *pSMBr; 1617 struct smb_com_read_rsp *pSMBr;
1617 struct pagevec lru_pvec; 1618 struct pagevec lru_pvec;
1618 struct cifsFileInfo *open_file; 1619 struct cifsFileInfo *open_file;
1620 int buf_type = CIFS_NO_BUFFER;
1619 1621
1620 xid = GetXid(); 1622 xid = GetXid();
1621 if (file->private_data == NULL) { 1623 if (file->private_data == NULL) {
@@ -1672,14 +1674,17 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1672 } 1674 }
1673 1675
1674 rc = CIFSSMBRead(xid, pTcon, 1676 rc = CIFSSMBRead(xid, pTcon,
1675 open_file->netfid, 1677 open_file->netfid,
1676 read_size, offset, 1678 read_size, offset,
1677 &bytes_read, &smb_read_data); 1679 &bytes_read, &smb_read_data,
1678 1680 &buf_type);
1679 /* BB more RC checks ? */ 1681 /* BB more RC checks ? */
1680 if (rc== -EAGAIN) { 1682 if (rc== -EAGAIN) {
1681 if (smb_read_data) { 1683 if (smb_read_data) {
1682 cifs_buf_release(smb_read_data); 1684 if(buf_type == CIFS_SMALL_BUFFER)
1685 cifs_small_buf_release(smb_read_data);
1686 else if(buf_type == CIFS_LARGE_BUFFER)
1687 cifs_buf_release(smb_read_data);
1683 smb_read_data = NULL; 1688 smb_read_data = NULL;
1684 } 1689 }
1685 } 1690 }
@@ -1736,7 +1741,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1736 break; 1741 break;
1737 } 1742 }
1738 if (smb_read_data) { 1743 if (smb_read_data) {
1739 cifs_buf_release(smb_read_data); 1744 if(buf_type == CIFS_SMALL_BUFFER)
1745 cifs_small_buf_release(smb_read_data);
1746 else if(buf_type == CIFS_LARGE_BUFFER)
1747 cifs_buf_release(smb_read_data);
1740 smb_read_data = NULL; 1748 smb_read_data = NULL;
1741 } 1749 }
1742 bytes_read = 0; 1750 bytes_read = 0;
@@ -1746,7 +1754,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1746 1754
1747/* need to free smb_read_data buf before exit */ 1755/* need to free smb_read_data buf before exit */
1748 if (smb_read_data) { 1756 if (smb_read_data) {
1749 cifs_buf_release(smb_read_data); 1757 if(buf_type == CIFS_SMALL_BUFFER)
1758 cifs_small_buf_release(smb_read_data);
1759 else if(buf_type == CIFS_LARGE_BUFFER)
1760 cifs_buf_release(smb_read_data);
1750 smb_read_data = NULL; 1761 smb_read_data = NULL;
1751 } 1762 }
1752 1763
@@ -1825,10 +1836,20 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode)
1825 open_file = find_writable_file(cifsInode); 1836 open_file = find_writable_file(cifsInode);
1826 1837
1827 if(open_file) { 1838 if(open_file) {
1839 struct cifs_sb_info *cifs_sb;
1840
1828 /* there is not actually a write pending so let 1841 /* there is not actually a write pending so let
1829 this handle go free and allow it to 1842 this handle go free and allow it to
1830 be closable if needed */ 1843 be closable if needed */
1831 atomic_dec(&open_file->wrtPending); 1844 atomic_dec(&open_file->wrtPending);
1845
1846 cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
1847 if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
1848 /* since no page cache to corrupt on directio
1849 we can change size safely */
1850 return 1;
1851 }
1852
1832 return 0; 1853 return 0;
1833 } else 1854 } else
1834 return 1; 1855 return 1;
@@ -1873,9 +1894,7 @@ struct address_space_operations cifs_addr_ops = {
1873 .readpage = cifs_readpage, 1894 .readpage = cifs_readpage,
1874 .readpages = cifs_readpages, 1895 .readpages = cifs_readpages,
1875 .writepage = cifs_writepage, 1896 .writepage = cifs_writepage,
1876#ifdef CONFIG_CIFS_EXPERIMENTAL
1877 .writepages = cifs_writepages, 1897 .writepages = cifs_writepages,
1878#endif
1879 .prepare_write = cifs_prepare_write, 1898 .prepare_write = cifs_prepare_write,
1880 .commit_write = cifs_commit_write, 1899 .commit_write = cifs_commit_write,
1881 .set_page_dirty = __set_page_dirty_nobuffers, 1900 .set_page_dirty = __set_page_dirty_nobuffers,