aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c53
1 files changed, 10 insertions, 43 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 1f09c7619319..5e2492535daa 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1557,57 +1557,24 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1557 1557
1558static int cifs_vmtruncate(struct inode *inode, loff_t offset) 1558static 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
1589do_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);
1601out_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; 1576out:
1605out_sig: 1577 return err;
1606 send_sig(SIGXFSZ, current, 0);
1607out_big:
1608 return -EFBIG;
1609out_busy:
1610 return -ETXTBSY;
1611} 1578}
1612 1579
1613static int 1580static int