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.c175
1 files changed, 130 insertions, 45 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index bd2a028af833..d7d65a70678e 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -287,6 +287,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
287 struct inode *inode = cifs_file->dentry->d_inode; 287 struct inode *inode = cifs_file->dentry->d_inode;
288 struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); 288 struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink);
289 struct cifsInodeInfo *cifsi = CIFS_I(inode); 289 struct cifsInodeInfo *cifsi = CIFS_I(inode);
290 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
290 struct cifsLockInfo *li, *tmp; 291 struct cifsLockInfo *li, *tmp;
291 292
292 spin_lock(&cifs_file_list_lock); 293 spin_lock(&cifs_file_list_lock);
@@ -302,6 +303,13 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
302 if (list_empty(&cifsi->openFileList)) { 303 if (list_empty(&cifsi->openFileList)) {
303 cFYI(1, "closing last open instance for inode %p", 304 cFYI(1, "closing last open instance for inode %p",
304 cifs_file->dentry->d_inode); 305 cifs_file->dentry->d_inode);
306
307 /* in strict cache mode we need invalidate mapping on the last
308 close because it may cause a error when we open this file
309 again and get at least level II oplock */
310 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
311 CIFS_I(inode)->invalid_mapping = true;
312
305 cifs_set_oplock_level(cifsi, 0); 313 cifs_set_oplock_level(cifsi, 0);
306 } 314 }
307 spin_unlock(&cifs_file_list_lock); 315 spin_unlock(&cifs_file_list_lock);
@@ -1520,27 +1528,47 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
1520 return rc; 1528 return rc;
1521} 1529}
1522 1530
1523int cifs_fsync(struct file *file, int datasync) 1531int cifs_strict_fsync(struct file *file, int datasync)
1524{ 1532{
1525 int xid; 1533 int xid;
1526 int rc = 0; 1534 int rc = 0;
1527 struct cifsTconInfo *tcon; 1535 struct cifsTconInfo *tcon;
1528 struct cifsFileInfo *smbfile = file->private_data; 1536 struct cifsFileInfo *smbfile = file->private_data;
1529 struct inode *inode = file->f_path.dentry->d_inode; 1537 struct inode *inode = file->f_path.dentry->d_inode;
1538 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1530 1539
1531 xid = GetXid(); 1540 xid = GetXid();
1532 1541
1533 cFYI(1, "Sync file - name: %s datasync: 0x%x", 1542 cFYI(1, "Sync file - name: %s datasync: 0x%x",
1534 file->f_path.dentry->d_name.name, datasync); 1543 file->f_path.dentry->d_name.name, datasync);
1535 1544
1536 rc = filemap_write_and_wait(inode->i_mapping); 1545 if (!CIFS_I(inode)->clientCanCacheRead)
1537 if (rc == 0) { 1546 cifs_invalidate_mapping(inode);
1538 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1539 1547
1540 tcon = tlink_tcon(smbfile->tlink); 1548 tcon = tlink_tcon(smbfile->tlink);
1541 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) 1549 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
1542 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); 1550 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
1543 } 1551
1552 FreeXid(xid);
1553 return rc;
1554}
1555
1556int cifs_fsync(struct file *file, int datasync)
1557{
1558 int xid;
1559 int rc = 0;
1560 struct cifsTconInfo *tcon;
1561 struct cifsFileInfo *smbfile = file->private_data;
1562 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1563
1564 xid = GetXid();
1565
1566 cFYI(1, "Sync file - name: %s datasync: 0x%x",
1567 file->f_path.dentry->d_name.name, datasync);
1568
1569 tcon = tlink_tcon(smbfile->tlink);
1570 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
1571 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
1544 1572
1545 FreeXid(xid); 1573 FreeXid(xid);
1546 return rc; 1574 return rc;
@@ -1591,42 +1619,42 @@ int cifs_flush(struct file *file, fl_owner_t id)
1591 return rc; 1619 return rc;
1592} 1620}
1593 1621
1594ssize_t cifs_user_read(struct file *file, char __user *read_data, 1622static ssize_t
1595 size_t read_size, loff_t *poffset) 1623cifs_iovec_read(struct file *file, const struct iovec *iov,
1624 unsigned long nr_segs, loff_t *poffset)
1596{ 1625{
1597 int rc = -EACCES; 1626 int rc;
1598 unsigned int bytes_read = 0; 1627 int xid;
1599 unsigned int total_read = 0; 1628 unsigned int total_read, bytes_read = 0;
1600 unsigned int current_read_size; 1629 size_t len, cur_len;
1630 int iov_offset = 0;
1601 struct cifs_sb_info *cifs_sb; 1631 struct cifs_sb_info *cifs_sb;
1602 struct cifsTconInfo *pTcon; 1632 struct cifsTconInfo *pTcon;
1603 int xid;
1604 struct cifsFileInfo *open_file; 1633 struct cifsFileInfo *open_file;
1605 char *smb_read_data;
1606 char __user *current_offset;
1607 struct smb_com_read_rsp *pSMBr; 1634 struct smb_com_read_rsp *pSMBr;
1635 char *read_data;
1636
1637 if (!nr_segs)
1638 return 0;
1639
1640 len = iov_length(iov, nr_segs);
1641 if (!len)
1642 return 0;
1608 1643
1609 xid = GetXid(); 1644 xid = GetXid();
1610 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1645 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1611 1646
1612 if (file->private_data == NULL) {
1613 rc = -EBADF;
1614 FreeXid(xid);
1615 return rc;
1616 }
1617 open_file = file->private_data; 1647 open_file = file->private_data;
1618 pTcon = tlink_tcon(open_file->tlink); 1648 pTcon = tlink_tcon(open_file->tlink);
1619 1649
1620 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1650 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1621 cFYI(1, "attempting read on write only file instance"); 1651 cFYI(1, "attempting read on write only file instance");
1622 1652
1623 for (total_read = 0, current_offset = read_data; 1653 for (total_read = 0; total_read < len; total_read += bytes_read) {
1624 read_size > total_read; 1654 cur_len = min_t(const size_t, len - total_read, cifs_sb->rsize);
1625 total_read += bytes_read, current_offset += bytes_read) {
1626 current_read_size = min_t(const int, read_size - total_read,
1627 cifs_sb->rsize);
1628 rc = -EAGAIN; 1655 rc = -EAGAIN;
1629 smb_read_data = NULL; 1656 read_data = NULL;
1657
1630 while (rc == -EAGAIN) { 1658 while (rc == -EAGAIN) {
1631 int buf_type = CIFS_NO_BUFFER; 1659 int buf_type = CIFS_NO_BUFFER;
1632 if (open_file->invalidHandle) { 1660 if (open_file->invalidHandle) {
@@ -1634,27 +1662,25 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1634 if (rc != 0) 1662 if (rc != 0)
1635 break; 1663 break;
1636 } 1664 }
1637 rc = CIFSSMBRead(xid, pTcon, 1665 rc = CIFSSMBRead(xid, pTcon, open_file->netfid,
1638 open_file->netfid, 1666 cur_len, *poffset, &bytes_read,
1639 current_read_size, *poffset, 1667 &read_data, &buf_type);
1640 &bytes_read, &smb_read_data, 1668 pSMBr = (struct smb_com_read_rsp *)read_data;
1641 &buf_type); 1669 if (read_data) {
1642 pSMBr = (struct smb_com_read_rsp *)smb_read_data; 1670 char *data_offset = read_data + 4 +
1643 if (smb_read_data) { 1671 le16_to_cpu(pSMBr->DataOffset);
1644 if (copy_to_user(current_offset, 1672 if (memcpy_toiovecend(iov, data_offset,
1645 smb_read_data + 1673 iov_offset, bytes_read))
1646 4 /* RFC1001 length field */ +
1647 le16_to_cpu(pSMBr->DataOffset),
1648 bytes_read))
1649 rc = -EFAULT; 1674 rc = -EFAULT;
1650
1651 if (buf_type == CIFS_SMALL_BUFFER) 1675 if (buf_type == CIFS_SMALL_BUFFER)
1652 cifs_small_buf_release(smb_read_data); 1676 cifs_small_buf_release(read_data);
1653 else if (buf_type == CIFS_LARGE_BUFFER) 1677 else if (buf_type == CIFS_LARGE_BUFFER)
1654 cifs_buf_release(smb_read_data); 1678 cifs_buf_release(read_data);
1655 smb_read_data = NULL; 1679 read_data = NULL;
1680 iov_offset += bytes_read;
1656 } 1681 }
1657 } 1682 }
1683
1658 if (rc || (bytes_read == 0)) { 1684 if (rc || (bytes_read == 0)) {
1659 if (total_read) { 1685 if (total_read) {
1660 break; 1686 break;
@@ -1667,13 +1693,57 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1667 *poffset += bytes_read; 1693 *poffset += bytes_read;
1668 } 1694 }
1669 } 1695 }
1696
1670 FreeXid(xid); 1697 FreeXid(xid);
1671 return total_read; 1698 return total_read;
1672} 1699}
1673 1700
1701ssize_t cifs_user_read(struct file *file, char __user *read_data,
1702 size_t read_size, loff_t *poffset)
1703{
1704 struct iovec iov;
1705 iov.iov_base = read_data;
1706 iov.iov_len = read_size;
1707
1708 return cifs_iovec_read(file, &iov, 1, poffset);
1709}
1710
1711static ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
1712 unsigned long nr_segs, loff_t pos)
1713{
1714 ssize_t read;
1715
1716 read = cifs_iovec_read(iocb->ki_filp, iov, nr_segs, &pos);
1717 if (read > 0)
1718 iocb->ki_pos = pos;
1719
1720 return read;
1721}
1722
1723ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,
1724 unsigned long nr_segs, loff_t pos)
1725{
1726 struct inode *inode;
1727
1728 inode = iocb->ki_filp->f_path.dentry->d_inode;
1729
1730 if (CIFS_I(inode)->clientCanCacheRead)
1731 return generic_file_aio_read(iocb, iov, nr_segs, pos);
1732
1733 /*
1734 * In strict cache mode we need to read from the server all the time
1735 * if we don't have level II oplock because the server can delay mtime
1736 * change - so we can't make a decision about inode invalidating.
1737 * And we can also fail with pagereading if there are mandatory locks
1738 * on pages affected by this read but not on the region from pos to
1739 * pos+len-1.
1740 */
1741
1742 return cifs_user_readv(iocb, iov, nr_segs, pos);
1743}
1674 1744
1675static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, 1745static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1676 loff_t *poffset) 1746 loff_t *poffset)
1677{ 1747{
1678 int rc = -EACCES; 1748 int rc = -EACCES;
1679 unsigned int bytes_read = 0; 1749 unsigned int bytes_read = 0;
@@ -1741,6 +1811,21 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1741 return total_read; 1811 return total_read;
1742} 1812}
1743 1813
1814int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
1815{
1816 int rc, xid;
1817 struct inode *inode = file->f_path.dentry->d_inode;
1818
1819 xid = GetXid();
1820
1821 if (!CIFS_I(inode)->clientCanCacheRead)
1822 cifs_invalidate_mapping(inode);
1823
1824 rc = generic_file_mmap(file, vma);
1825 FreeXid(xid);
1826 return rc;
1827}
1828
1744int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) 1829int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
1745{ 1830{
1746 int rc, xid; 1831 int rc, xid;