diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 11:32:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 11:32:11 -0400 |
commit | 6c5daf012c9155aafd2c7973e4278766c30dfad0 (patch) | |
tree | 33959d7b36d03e1610615641a2940cb2de5e8603 /fs/cifs/inode.c | |
parent | 6d39b27f0ac7e805ae3bd9efa51d7da04bec0360 (diff) | |
parent | c08d3b0e33edce28e9cfa7b64f7fe5bdeeb29248 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
truncate: use new helpers
truncate: new helpers
fs: fix overflow in sys_mount() for in-kernel calls
fs: Make unload_nls() NULL pointer safe
freeze_bdev: grab active reference to frozen superblocks
freeze_bdev: kill bd_mount_sem
exofs: remove BKL from super operations
fs/romfs: correct error-handling code
vfs: seq_file: add helpers for data filling
vfs: remove redundant position check in do_sendfile
vfs: change sb->s_maxbytes to a loff_t
vfs: explicitly cast s_maxbytes in fiemap_check_ranges
libfs: return error code on failed attr set
seq_file: return a negative error code when seq_path_root() fails.
vfs: optimize touch_time() too
vfs: optimization for touch_atime()
vfs: split generic_forget_inode() so that hugetlbfs does not have to copy it
fs/inode.c: add dev-id and inode number for debugging in init_special_inode()
libfs: make simple_read_from_buffer conventional
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 53 |
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 | ||
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 |