Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 254099
b: refs/heads/master
c: 94c1e62
h: refs/heads/master
i:
  254097: 50b2e63
  254095: 9b5c704
v: v3
  • Loading branch information
Hugh Dickins authored and Linus Torvalds committed Jun 28, 2011
1 parent ef800e9 commit 00fe042
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 072441e21ddcd1140606b7d4ef6eab579a86b0b3
refs/heads/master: 94c1e62df4494b79782cb9c7279f827212d1de70
1 change: 1 addition & 0 deletions trunk/include/linux/shmem_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ extern struct file *shmem_file_setup(const char *name,
loff_t size, unsigned long flags);
extern int shmem_zero_setup(struct vm_area_struct *);
extern int shmem_lock(struct file *file, int lock, struct user_struct *user);
extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end);
extern int shmem_unuse(swp_entry_t entry, struct page *page);
extern void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
struct page **pagep, swp_entry_t *ent);
Expand Down
51 changes: 29 additions & 22 deletions trunk/mm/shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ static void shmem_free_pages(struct list_head *next)
} while (next);
}

static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
{
struct shmem_inode_info *info = SHMEM_I(inode);
unsigned long idx;
Expand All @@ -562,6 +562,8 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
spinlock_t *punch_lock;
unsigned long upper_limit;

truncate_inode_pages_range(inode->i_mapping, start, end);

inode->i_ctime = inode->i_mtime = CURRENT_TIME;
idx = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
if (idx >= info->next_index)
Expand Down Expand Up @@ -738,16 +740,8 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
* lowered next_index. Also, though shmem_getpage checks
* i_size before adding to cache, no recheck after: so fix the
* narrow window there too.
*
* Recalling truncate_inode_pages_range and unmap_mapping_range
* every time for punch_hole (which never got a chance to clear
* SHMEM_PAGEIN at the start of vmtruncate_range) is expensive,
* yet hardly ever necessary: try to optimize them out later.
*/
truncate_inode_pages_range(inode->i_mapping, start, end);
if (punch_hole)
unmap_mapping_range(inode->i_mapping, start,
end - start, 1);
}

spin_lock(&info->lock);
Expand All @@ -766,22 +760,23 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
shmem_free_pages(pages_to_free.next);
}
}
EXPORT_SYMBOL_GPL(shmem_truncate_range);

static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
static int shmem_setattr(struct dentry *dentry, struct iattr *attr)
{
struct inode *inode = dentry->d_inode;
loff_t newsize = attr->ia_size;
int error;

error = inode_change_ok(inode, attr);
if (error)
return error;

if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)
&& newsize != inode->i_size) {
if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
loff_t oldsize = inode->i_size;
loff_t newsize = attr->ia_size;
struct page *page = NULL;

if (newsize < inode->i_size) {
if (newsize < oldsize) {
/*
* If truncating down to a partial page, then
* if that page is already allocated, hold it
Expand Down Expand Up @@ -810,12 +805,19 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
spin_unlock(&info->lock);
}
}

/* XXX(truncate): truncate_setsize should be called last */
truncate_setsize(inode, newsize);
if (newsize != oldsize) {
i_size_write(inode, newsize);
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
}
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);
/* unmap again to remove racily COWed private pages */
unmap_mapping_range(inode->i_mapping, holebegin, 0, 1);
}
if (page)
page_cache_release(page);
shmem_truncate_range(inode, newsize, (loff_t)-1);
}

setattr_copy(inode, attr);
Expand All @@ -832,7 +834,6 @@ static void shmem_evict_inode(struct inode *inode)
struct shmem_xattr *xattr, *nxattr;

if (inode->i_mapping->a_ops == &shmem_aops) {
truncate_inode_pages(inode->i_mapping, 0);
shmem_unacct_size(info->flags, inode->i_size);
inode->i_size = 0;
shmem_truncate_range(inode, 0, (loff_t)-1);
Expand Down Expand Up @@ -2706,7 +2707,7 @@ static const struct file_operations shmem_file_operations = {
};

static const struct inode_operations shmem_inode_operations = {
.setattr = shmem_notify_change,
.setattr = shmem_setattr,
.truncate_range = shmem_truncate_range,
#ifdef CONFIG_TMPFS_XATTR
.setxattr = shmem_setxattr,
Expand Down Expand Up @@ -2739,7 +2740,7 @@ static const struct inode_operations shmem_dir_inode_operations = {
.removexattr = shmem_removexattr,
#endif
#ifdef CONFIG_TMPFS_POSIX_ACL
.setattr = shmem_notify_change,
.setattr = shmem_setattr,
.check_acl = generic_check_acl,
#endif
};
Expand All @@ -2752,7 +2753,7 @@ static const struct inode_operations shmem_special_inode_operations = {
.removexattr = shmem_removexattr,
#endif
#ifdef CONFIG_TMPFS_POSIX_ACL
.setattr = shmem_notify_change,
.setattr = shmem_setattr,
.check_acl = generic_check_acl,
#endif
};
Expand Down Expand Up @@ -2908,6 +2909,12 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
return 0;
}

void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
{
truncate_inode_pages_range(inode->i_mapping, start, end);
}
EXPORT_SYMBOL_GPL(shmem_truncate_range);

#ifdef CONFIG_CGROUP_MEM_RES_CTLR
/**
* mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file
Expand Down
4 changes: 2 additions & 2 deletions trunk/mm/truncate.c
Original file line number Diff line number Diff line change
Expand Up @@ -619,9 +619,9 @@ int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end)
mutex_lock(&inode->i_mutex);
down_write(&inode->i_alloc_sem);
unmap_mapping_range(mapping, offset, (end - offset), 1);
truncate_inode_pages_range(mapping, offset, end);
unmap_mapping_range(mapping, offset, (end - offset), 1);
inode->i_op->truncate_range(inode, offset, end);
/* unmap again to remove racily COWed private pages */
unmap_mapping_range(mapping, offset, (end - offset), 1);
up_write(&inode->i_alloc_sem);
mutex_unlock(&inode->i_mutex);

Expand Down

0 comments on commit 00fe042

Please sign in to comment.