@@ -727,10 +727,11 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
727
727
if (inode -> i_mapping -> nrpages && (info -> flags & SHMEM_PAGEIN )) {
728
728
/*
729
729
* Call truncate_inode_pages again: racing shmem_unuse_inode
730
- * may have swizzled a page in from swap since vmtruncate or
731
- * generic_delete_inode did it, before we lowered next_index.
732
- * Also, though shmem_getpage checks i_size before adding to
733
- * cache, no recheck after: so fix the narrow window there too.
730
+ * may have swizzled a page in from swap since
731
+ * truncate_pagecache or generic_delete_inode did it, before we
732
+ * lowered next_index. Also, though shmem_getpage checks
733
+ * i_size before adding to cache, no recheck after: so fix the
734
+ * narrow window there too.
734
735
*
735
736
* Recalling truncate_inode_pages_range and unmap_mapping_range
736
737
* every time for punch_hole (which never got a chance to clear
@@ -760,29 +761,26 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
760
761
}
761
762
}
762
763
763
- static void shmem_truncate (struct inode * inode )
764
- {
765
- shmem_truncate_range (inode , inode -> i_size , (loff_t )- 1 );
766
- }
767
-
768
764
static int shmem_notify_change (struct dentry * dentry , struct iattr * attr )
769
765
{
770
766
struct inode * inode = dentry -> d_inode ;
771
- struct page * page = NULL ;
772
767
int error ;
773
768
774
769
if (S_ISREG (inode -> i_mode ) && (attr -> ia_valid & ATTR_SIZE )) {
775
- if (attr -> ia_size < inode -> i_size ) {
770
+ loff_t newsize = attr -> ia_size ;
771
+ struct page * page = NULL ;
772
+
773
+ if (newsize < inode -> i_size ) {
776
774
/*
777
775
* If truncating down to a partial page, then
778
776
* if that page is already allocated, hold it
779
777
* in memory until the truncation is over, so
780
778
* truncate_partial_page cannnot miss it were
781
779
* it assigned to swap.
782
780
*/
783
- if (attr -> ia_size & (PAGE_CACHE_SIZE - 1 )) {
781
+ if (newsize & (PAGE_CACHE_SIZE - 1 )) {
784
782
(void ) shmem_getpage (inode ,
785
- attr -> ia_size >> PAGE_CACHE_SHIFT ,
783
+ newsize >> PAGE_CACHE_SHIFT ,
786
784
& page , SGP_READ , NULL );
787
785
if (page )
788
786
unlock_page (page );
@@ -794,36 +792,41 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
794
792
* if it's being fully truncated to zero-length: the
795
793
* nrpages check is efficient enough in that case.
796
794
*/
797
- if (attr -> ia_size ) {
795
+ if (newsize ) {
798
796
struct shmem_inode_info * info = SHMEM_I (inode );
799
797
spin_lock (& info -> lock );
800
798
info -> flags &= ~SHMEM_PAGEIN ;
801
799
spin_unlock (& info -> lock );
802
800
}
803
801
}
802
+
803
+ error = simple_setsize (inode , newsize );
804
+ if (page )
805
+ page_cache_release (page );
806
+ if (error )
807
+ return error ;
808
+ shmem_truncate_range (inode , newsize , (loff_t )- 1 );
804
809
}
805
810
806
811
error = inode_change_ok (inode , attr );
807
812
if (!error )
808
- error = inode_setattr (inode , attr );
813
+ generic_setattr (inode , attr );
809
814
#ifdef CONFIG_TMPFS_POSIX_ACL
810
815
if (!error && (attr -> ia_valid & ATTR_MODE ))
811
816
error = generic_acl_chmod (inode );
812
817
#endif
813
- if (page )
814
- page_cache_release (page );
815
818
return error ;
816
819
}
817
820
818
821
static void shmem_delete_inode (struct inode * inode )
819
822
{
820
823
struct shmem_inode_info * info = SHMEM_I (inode );
821
824
822
- if (inode -> i_op -> truncate == shmem_truncate ) {
825
+ if (inode -> i_mapping -> a_ops == & shmem_aops ) {
823
826
truncate_inode_pages (inode -> i_mapping , 0 );
824
827
shmem_unacct_size (info -> flags , inode -> i_size );
825
828
inode -> i_size = 0 ;
826
- shmem_truncate (inode );
829
+ shmem_truncate_range (inode , 0 , ( loff_t ) - 1 );
827
830
if (!list_empty (& info -> swaplist )) {
828
831
mutex_lock (& shmem_swaplist_mutex );
829
832
list_del_init (& info -> swaplist );
@@ -2022,7 +2025,6 @@ static const struct inode_operations shmem_symlink_inline_operations = {
2022
2025
};
2023
2026
2024
2027
static const struct inode_operations shmem_symlink_inode_operations = {
2025
- .truncate = shmem_truncate ,
2026
2028
.readlink = generic_readlink ,
2027
2029
.follow_link = shmem_follow_link ,
2028
2030
.put_link = shmem_put_link ,
@@ -2440,7 +2442,6 @@ static const struct file_operations shmem_file_operations = {
2440
2442
};
2441
2443
2442
2444
static const struct inode_operations shmem_inode_operations = {
2443
- .truncate = shmem_truncate ,
2444
2445
.setattr = shmem_notify_change ,
2445
2446
.truncate_range = shmem_truncate_range ,
2446
2447
#ifdef CONFIG_TMPFS_POSIX_ACL
0 commit comments