diff options
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 66 |
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); |
804 | out: | 801 | out: |
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 | ||
1558 | static int cifs_vmtruncate(struct inode *inode, loff_t offset) | 1555 | static 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 | |||
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); | 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); |
1601 | out_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; | 1573 | out: |
1605 | out_sig: | 1574 | return err; |
1606 | send_sig(SIGXFSZ, current, 0); | ||
1607 | out_big: | ||
1608 | return -EFBIG; | ||
1609 | out_busy: | ||
1610 | return -ETXTBSY; | ||
1611 | } | 1575 | } |
1612 | 1576 | ||
1613 | static int | 1577 | static 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, |