|
@@ -548,12 +548,12 @@ static int shmem_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
|
|
struct inode *inode = dentry->d_inode;
|
|
|
struct shmem_inode_info *info = SHMEM_I(inode);
|
|
|
|
|
|
- spin_lock(&info->lock);
|
|
|
- shmem_recalc_inode(inode);
|
|
|
- spin_unlock(&info->lock);
|
|
|
-
|
|
|
+ if (info->alloced - info->swapped != inode->i_mapping->nrpages) {
|
|
|
+ spin_lock(&info->lock);
|
|
|
+ shmem_recalc_inode(inode);
|
|
|
+ spin_unlock(&info->lock);
|
|
|
+ }
|
|
|
generic_fillattr(inode, stat);
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -586,10 +586,16 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr)
|
|
|
}
|
|
|
if (newsize <= oldsize) {
|
|
|
loff_t holebegin = round_up(newsize, PAGE_SIZE);
|
|
|
- unmap_mapping_range(inode->i_mapping, holebegin, 0, 1);
|
|
|
- shmem_truncate_range(inode, newsize, (loff_t)-1);
|
|
|
+ if (oldsize > holebegin)
|
|
|
+ unmap_mapping_range(inode->i_mapping,
|
|
|
+ holebegin, 0, 1);
|
|
|
+ if (info->alloced)
|
|
|
+ shmem_truncate_range(inode,
|
|
|
+ newsize, (loff_t)-1);
|
|
|
/* unmap again to remove racily COWed private pages */
|
|
|
- unmap_mapping_range(inode->i_mapping, holebegin, 0, 1);
|
|
|
+ if (oldsize > holebegin)
|
|
|
+ unmap_mapping_range(inode->i_mapping,
|
|
|
+ holebegin, 0, 1);
|
|
|
}
|
|
|
}
|
|
|
|