diff options
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 59 |
1 files changed, 13 insertions, 46 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 82d83839655e..5e2492535daa 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -800,7 +800,7 @@ set_via_filehandle: | |||
800 | if (open_file == NULL) | 800 | if (open_file == NULL) |
801 | CIFSSMBClose(xid, pTcon, netfid); | 801 | CIFSSMBClose(xid, pTcon, netfid); |
802 | else | 802 | else |
803 | atomic_dec(&open_file->wrtPending); | 803 | cifsFileInfo_put(open_file); |
804 | out: | 804 | out: |
805 | return rc; | 805 | return rc; |
806 | } | 806 | } |
@@ -1557,57 +1557,24 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from) | |||
1557 | 1557 | ||
1558 | static int cifs_vmtruncate(struct inode *inode, loff_t offset) | 1558 | static int cifs_vmtruncate(struct inode *inode, loff_t offset) |
1559 | { | 1559 | { |
1560 | struct address_space *mapping = inode->i_mapping; | 1560 | loff_t oldsize; |
1561 | unsigned long limit; | 1561 | int err; |
1562 | 1562 | ||
1563 | spin_lock(&inode->i_lock); | 1563 | spin_lock(&inode->i_lock); |
1564 | if (inode->i_size < offset) | 1564 | err = inode_newsize_ok(inode, offset); |
1565 | goto do_expand; | 1565 | if (err) { |
1566 | /* | ||
1567 | * truncation of in-use swapfiles is disallowed - it would cause | ||
1568 | * subsequent swapout to scribble on the now-freed blocks. | ||
1569 | */ | ||
1570 | if (IS_SWAPFILE(inode)) { | ||
1571 | spin_unlock(&inode->i_lock); | ||
1572 | goto out_busy; | ||
1573 | } | ||
1574 | i_size_write(inode, offset); | ||
1575 | spin_unlock(&inode->i_lock); | ||
1576 | /* | ||
1577 | * unmap_mapping_range is called twice, first simply for efficiency | ||
1578 | * so that truncate_inode_pages does fewer single-page unmaps. However | ||
1579 | * after this first call, and before truncate_inode_pages finishes, | ||
1580 | * it is possible for private pages to be COWed, which remain after | ||
1581 | * truncate_inode_pages finishes, hence the second unmap_mapping_range | ||
1582 | * call must be made for correctness. | ||
1583 | */ | ||
1584 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
1585 | truncate_inode_pages(mapping, offset); | ||
1586 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
1587 | goto out_truncate; | ||
1588 | |||
1589 | do_expand: | ||
1590 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | ||
1591 | if (limit != RLIM_INFINITY && offset > limit) { | ||
1592 | spin_unlock(&inode->i_lock); | 1566 | spin_unlock(&inode->i_lock); |
1593 | goto out_sig; | 1567 | goto out; |
1594 | } | ||
1595 | if (offset > inode->i_sb->s_maxbytes) { | ||
1596 | spin_unlock(&inode->i_lock); | ||
1597 | goto out_big; | ||
1598 | } | 1568 | } |
1569 | |||
1570 | oldsize = inode->i_size; | ||
1599 | i_size_write(inode, offset); | 1571 | i_size_write(inode, offset); |
1600 | spin_unlock(&inode->i_lock); | 1572 | spin_unlock(&inode->i_lock); |
1601 | out_truncate: | 1573 | truncate_pagecache(inode, oldsize, offset); |
1602 | if (inode->i_op->truncate) | 1574 | if (inode->i_op->truncate) |
1603 | inode->i_op->truncate(inode); | 1575 | inode->i_op->truncate(inode); |
1604 | return 0; | 1576 | out: |
1605 | out_sig: | 1577 | return err; |
1606 | send_sig(SIGXFSZ, current, 0); | ||
1607 | out_big: | ||
1608 | return -EFBIG; | ||
1609 | out_busy: | ||
1610 | return -ETXTBSY; | ||
1611 | } | 1578 | } |
1612 | 1579 | ||
1613 | static int | 1580 | static int |
@@ -1635,7 +1602,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, | |||
1635 | __u32 npid = open_file->pid; | 1602 | __u32 npid = open_file->pid; |
1636 | rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, | 1603 | rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, |
1637 | npid, false); | 1604 | npid, false); |
1638 | atomic_dec(&open_file->wrtPending); | 1605 | cifsFileInfo_put(open_file); |
1639 | cFYI(1, ("SetFSize for attrs rc = %d", rc)); | 1606 | cFYI(1, ("SetFSize for attrs rc = %d", rc)); |
1640 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { | 1607 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { |
1641 | unsigned int bytes_written; | 1608 | unsigned int bytes_written; |
@@ -1790,7 +1757,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) | |||
1790 | u16 nfid = open_file->netfid; | 1757 | u16 nfid = open_file->netfid; |
1791 | u32 npid = open_file->pid; | 1758 | u32 npid = open_file->pid; |
1792 | rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); | 1759 | rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); |
1793 | atomic_dec(&open_file->wrtPending); | 1760 | cifsFileInfo_put(open_file); |
1794 | } else { | 1761 | } else { |
1795 | rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, | 1762 | rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, |
1796 | cifs_sb->local_nls, | 1763 | cifs_sb->local_nls, |