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.c66
1 files changed, 15 insertions, 51 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 82d83839655e..cababd8a52df 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -512,13 +512,10 @@ int cifs_get_inode_info(struct inode **pinode,
512 cifs_sb->local_nls, 512 cifs_sb->local_nls,
513 cifs_sb->mnt_cifs_flags & 513 cifs_sb->mnt_cifs_flags &
514 CIFS_MOUNT_MAP_SPECIAL_CHR); 514 CIFS_MOUNT_MAP_SPECIAL_CHR);
515 if (rc1) { 515 if (rc1 || !fattr.cf_uniqueid) {
516 cFYI(1, ("GetSrvInodeNum rc %d", rc1)); 516 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
517 fattr.cf_uniqueid = iunique(sb, ROOT_I); 517 fattr.cf_uniqueid = iunique(sb, ROOT_I);
518 /* disable serverino if call not supported */ 518 cifs_autodisable_serverino(cifs_sb);
519 if (rc1 == -EINVAL)
520 cifs_sb->mnt_cifs_flags &=
521 ~CIFS_MOUNT_SERVER_INUM;
522 } 519 }
523 } else { 520 } else {
524 fattr.cf_uniqueid = iunique(sb, ROOT_I); 521 fattr.cf_uniqueid = iunique(sb, ROOT_I);
@@ -800,7 +797,7 @@ set_via_filehandle:
800 if (open_file == NULL) 797 if (open_file == NULL)
801 CIFSSMBClose(xid, pTcon, netfid); 798 CIFSSMBClose(xid, pTcon, netfid);
802 else 799 else
803 atomic_dec(&open_file->wrtPending); 800 cifsFileInfo_put(open_file);
804out: 801out:
805 return rc; 802 return rc;
806} 803}
@@ -1557,57 +1554,24 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1557 1554
1558static int cifs_vmtruncate(struct inode *inode, loff_t offset) 1555static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1559{ 1556{
1560 struct address_space *mapping = inode->i_mapping; 1557 loff_t oldsize;
1561 unsigned long limit; 1558 int err;
1562 1559
1563 spin_lock(&inode->i_lock); 1560 spin_lock(&inode->i_lock);
1564 if (inode->i_size < offset) 1561 err = inode_newsize_ok(inode, offset);
1565 goto do_expand; 1562 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); 1563 spin_unlock(&inode->i_lock);
1593 goto out_sig; 1564 goto out;
1594 }
1595 if (offset > inode->i_sb->s_maxbytes) {
1596 spin_unlock(&inode->i_lock);
1597 goto out_big;
1598 } 1565 }
1566
1567 oldsize = inode->i_size;
1599 i_size_write(inode, offset); 1568 i_size_write(inode, offset);
1600 spin_unlock(&inode->i_lock); 1569 spin_unlock(&inode->i_lock);
1601out_truncate: 1570 truncate_pagecache(inode, oldsize, offset);
1602 if (inode->i_op->truncate) 1571 if (inode->i_op->truncate)
1603 inode->i_op->truncate(inode); 1572 inode->i_op->truncate(inode);
1604 return 0; 1573out:
1605out_sig: 1574 return err;
1606 send_sig(SIGXFSZ, current, 0);
1607out_big:
1608 return -EFBIG;
1609out_busy:
1610 return -ETXTBSY;
1611} 1575}
1612 1576
1613static int 1577static int
@@ -1635,7 +1599,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1635 __u32 npid = open_file->pid; 1599 __u32 npid = open_file->pid;
1636 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, 1600 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1637 npid, false); 1601 npid, false);
1638 atomic_dec(&open_file->wrtPending); 1602 cifsFileInfo_put(open_file);
1639 cFYI(1, ("SetFSize for attrs rc = %d", rc)); 1603 cFYI(1, ("SetFSize for attrs rc = %d", rc));
1640 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 1604 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1641 unsigned int bytes_written; 1605 unsigned int bytes_written;
@@ -1790,7 +1754,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1790 u16 nfid = open_file->netfid; 1754 u16 nfid = open_file->netfid;
1791 u32 npid = open_file->pid; 1755 u32 npid = open_file->pid;
1792 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); 1756 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
1793 atomic_dec(&open_file->wrtPending); 1757 cifsFileInfo_put(open_file);
1794 } else { 1758 } else {
1795 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, 1759 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
1796 cifs_sb->local_nls, 1760 cifs_sb->local_nls,