aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-10 14:26:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-10 14:26:52 -0400
commit5f248c9c251c60af3403902b26e08de43964ea0b (patch)
tree6d3328e72a7e4015a64017eb30be18095c6a3c64 /mm
parentf6cec0ae58c17522a7bc4e2f39dae19f199ab534 (diff)
parentdca332528bc69e05f67161e1ed59929633d5e63d (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: (96 commits) no need for list_for_each_entry_safe()/resetting with superblock list Fix sget() race with failing mount vfs: don't hold s_umount over close_bdev_exclusive() call sysv: do not mark superblock dirty on remount sysv: do not mark superblock dirty on mount btrfs: remove junk sb_dirt change BFS: clean up the superblock usage AFFS: wait for sb synchronization when needed AFFS: clean up dirty flag usage cifs: truncate fallout mbcache: fix shrinker function return value mbcache: Remove unused features add f_flags to struct statfs(64) pass a struct path to vfs_statfs update VFS documentation for method changes. All filesystems that need invalidate_inode_buffers() are doing that explicitly convert remaining ->clear_inode() to ->evict_inode() Make ->drop_inode() just return whether inode needs to be dropped fs/inode.c:clear_inode() is gone fs/inode.c:evict() doesn't care about delete vs. non-delete paths now ... Fix up trivial conflicts in fs/nilfs2/super.c
Diffstat (limited to 'mm')
-rw-r--r--mm/shmem.c23
-rw-r--r--mm/truncate.c38
2 files changed, 41 insertions, 20 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index 566f9a481e64..dfaa0f4e9789 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -766,6 +766,10 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
766 loff_t newsize = attr->ia_size; 766 loff_t newsize = attr->ia_size;
767 int error; 767 int error;
768 768
769 error = inode_change_ok(inode, attr);
770 if (error)
771 return error;
772
769 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE) 773 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)
770 && newsize != inode->i_size) { 774 && newsize != inode->i_size) {
771 struct page *page = NULL; 775 struct page *page = NULL;
@@ -800,25 +804,22 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
800 } 804 }
801 } 805 }
802 806
803 error = simple_setsize(inode, newsize); 807 /* XXX(truncate): truncate_setsize should be called last */
808 truncate_setsize(inode, newsize);
804 if (page) 809 if (page)
805 page_cache_release(page); 810 page_cache_release(page);
806 if (error)
807 return error;
808 shmem_truncate_range(inode, newsize, (loff_t)-1); 811 shmem_truncate_range(inode, newsize, (loff_t)-1);
809 } 812 }
810 813
811 error = inode_change_ok(inode, attr); 814 setattr_copy(inode, attr);
812 if (!error)
813 generic_setattr(inode, attr);
814#ifdef CONFIG_TMPFS_POSIX_ACL 815#ifdef CONFIG_TMPFS_POSIX_ACL
815 if (!error && (attr->ia_valid & ATTR_MODE)) 816 if (attr->ia_valid & ATTR_MODE)
816 error = generic_acl_chmod(inode); 817 error = generic_acl_chmod(inode);
817#endif 818#endif
818 return error; 819 return error;
819} 820}
820 821
821static void shmem_delete_inode(struct inode *inode) 822static void shmem_evict_inode(struct inode *inode)
822{ 823{
823 struct shmem_inode_info *info = SHMEM_I(inode); 824 struct shmem_inode_info *info = SHMEM_I(inode);
824 825
@@ -835,7 +836,7 @@ static void shmem_delete_inode(struct inode *inode)
835 } 836 }
836 BUG_ON(inode->i_blocks); 837 BUG_ON(inode->i_blocks);
837 shmem_free_inode(inode->i_sb); 838 shmem_free_inode(inode->i_sb);
838 clear_inode(inode); 839 end_writeback(inode);
839} 840}
840 841
841static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *dir, swp_entry_t *edir) 842static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *dir, swp_entry_t *edir)
@@ -932,7 +933,7 @@ found:
932 933
933 /* 934 /*
934 * Move _head_ to start search for next from here. 935 * Move _head_ to start search for next from here.
935 * But be careful: shmem_delete_inode checks list_empty without taking 936 * But be careful: shmem_evict_inode checks list_empty without taking
936 * mutex, and there's an instant in list_move_tail when info->swaplist 937 * mutex, and there's an instant in list_move_tail when info->swaplist
937 * would appear empty, if it were the only one on shmem_swaplist. We 938 * would appear empty, if it were the only one on shmem_swaplist. We
938 * could avoid doing it if inode NULL; or use this minor optimization. 939 * could avoid doing it if inode NULL; or use this minor optimization.
@@ -2518,7 +2519,7 @@ static const struct super_operations shmem_ops = {
2518 .remount_fs = shmem_remount_fs, 2519 .remount_fs = shmem_remount_fs,
2519 .show_options = shmem_show_options, 2520 .show_options = shmem_show_options,
2520#endif 2521#endif
2521 .delete_inode = shmem_delete_inode, 2522 .evict_inode = shmem_evict_inode,
2522 .drop_inode = generic_delete_inode, 2523 .drop_inode = generic_delete_inode,
2523 .put_super = shmem_put_super, 2524 .put_super = shmem_put_super,
2524}; 2525};
diff --git a/mm/truncate.c b/mm/truncate.c
index 937571b8b233..ba887bff48c5 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -541,28 +541,48 @@ void truncate_pagecache(struct inode *inode, loff_t old, loff_t new)
541EXPORT_SYMBOL(truncate_pagecache); 541EXPORT_SYMBOL(truncate_pagecache);
542 542
543/** 543/**
544 * truncate_setsize - update inode and pagecache for a new file size
545 * @inode: inode
546 * @newsize: new file size
547 *
548 * truncate_setsize updastes i_size update and performs pagecache
549 * truncation (if necessary) for a file size updates. It will be
550 * typically be called from the filesystem's setattr function when
551 * ATTR_SIZE is passed in.
552 *
553 * Must be called with inode_mutex held and after all filesystem
554 * specific block truncation has been performed.
555 */
556void truncate_setsize(struct inode *inode, loff_t newsize)
557{
558 loff_t oldsize;
559
560 oldsize = inode->i_size;
561 i_size_write(inode, newsize);
562
563 truncate_pagecache(inode, oldsize, newsize);
564}
565EXPORT_SYMBOL(truncate_setsize);
566
567/**
544 * vmtruncate - unmap mappings "freed" by truncate() syscall 568 * vmtruncate - unmap mappings "freed" by truncate() syscall
545 * @inode: inode of the file used 569 * @inode: inode of the file used
546 * @offset: file offset to start truncating 570 * @offset: file offset to start truncating
547 * 571 *
548 * NOTE! We have to be ready to update the memory sharing 572 * This function is deprecated and truncate_setsize or truncate_pagecache
549 * between the file and the memory map for a potential last 573 * should be used instead, together with filesystem specific block truncation.
550 * incomplete page. Ugly, but necessary.
551 *
552 * This function is deprecated and simple_setsize or truncate_pagecache
553 * should be used instead.
554 */ 574 */
555int vmtruncate(struct inode *inode, loff_t offset) 575int vmtruncate(struct inode *inode, loff_t offset)
556{ 576{
557 int error; 577 int error;
558 578
559 error = simple_setsize(inode, offset); 579 error = inode_newsize_ok(inode, offset);
560 if (error) 580 if (error)
561 return error; 581 return error;
562 582
583 truncate_setsize(inode, offset);
563 if (inode->i_op->truncate) 584 if (inode->i_op->truncate)
564 inode->i_op->truncate(inode); 585 inode->i_op->truncate(inode);
565 586 return 0;
566 return error;
567} 587}
568EXPORT_SYMBOL(vmtruncate); 588EXPORT_SYMBOL(vmtruncate);