mirror of
https://github.com/torvalds/linux.git
synced 2024-10-23 21:50:43 +00:00
tmpfs: convert to use the new truncate convention
Cc: Christoph Hellwig <hch@lst.de> Acked-by: Hugh Dickins <hugh.dickins@tiscali.co.uk> Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
3322e79a38
commit
3889e6e76f
43
mm/shmem.c
43
mm/shmem.c
|
@ -727,10 +727,11 @@ done2:
|
||||||
if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) {
|
if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) {
|
||||||
/*
|
/*
|
||||||
* Call truncate_inode_pages again: racing shmem_unuse_inode
|
* Call truncate_inode_pages again: racing shmem_unuse_inode
|
||||||
* may have swizzled a page in from swap since vmtruncate or
|
* may have swizzled a page in from swap since
|
||||||
* generic_delete_inode did it, before we lowered next_index.
|
* truncate_pagecache or generic_delete_inode did it, before we
|
||||||
* Also, though shmem_getpage checks i_size before adding to
|
* lowered next_index. Also, though shmem_getpage checks
|
||||||
* cache, no recheck after: so fix the narrow window there too.
|
* 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
|
* Recalling truncate_inode_pages_range and unmap_mapping_range
|
||||||
* every time for punch_hole (which never got a chance to clear
|
* every time for punch_hole (which never got a chance to clear
|
||||||
|
@ -760,19 +761,16 @@ done2:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shmem_truncate(struct inode *inode)
|
|
||||||
{
|
|
||||||
shmem_truncate_range(inode, inode->i_size, (loff_t)-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
|
static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
|
||||||
{
|
{
|
||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
struct page *page = NULL;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
|
if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
|
||||||
if (attr->ia_size < inode->i_size) {
|
loff_t newsize = attr->ia_size;
|
||||||
|
struct page *page = NULL;
|
||||||
|
|
||||||
|
if (newsize < inode->i_size) {
|
||||||
/*
|
/*
|
||||||
* If truncating down to a partial page, then
|
* If truncating down to a partial page, then
|
||||||
* if that page is already allocated, hold it
|
* if that page is already allocated, hold it
|
||||||
|
@ -780,9 +778,9 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
|
||||||
* truncate_partial_page cannnot miss it were
|
* truncate_partial_page cannnot miss it were
|
||||||
* it assigned to swap.
|
* it assigned to swap.
|
||||||
*/
|
*/
|
||||||
if (attr->ia_size & (PAGE_CACHE_SIZE-1)) {
|
if (newsize & (PAGE_CACHE_SIZE-1)) {
|
||||||
(void) shmem_getpage(inode,
|
(void) shmem_getpage(inode,
|
||||||
attr->ia_size>>PAGE_CACHE_SHIFT,
|
newsize >> PAGE_CACHE_SHIFT,
|
||||||
&page, SGP_READ, NULL);
|
&page, SGP_READ, NULL);
|
||||||
if (page)
|
if (page)
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
|
@ -794,24 +792,29 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
|
||||||
* if it's being fully truncated to zero-length: the
|
* if it's being fully truncated to zero-length: the
|
||||||
* nrpages check is efficient enough in that case.
|
* nrpages check is efficient enough in that case.
|
||||||
*/
|
*/
|
||||||
if (attr->ia_size) {
|
if (newsize) {
|
||||||
struct shmem_inode_info *info = SHMEM_I(inode);
|
struct shmem_inode_info *info = SHMEM_I(inode);
|
||||||
spin_lock(&info->lock);
|
spin_lock(&info->lock);
|
||||||
info->flags &= ~SHMEM_PAGEIN;
|
info->flags &= ~SHMEM_PAGEIN;
|
||||||
spin_unlock(&info->lock);
|
spin_unlock(&info->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error = simple_setsize(inode, newsize);
|
||||||
|
if (page)
|
||||||
|
page_cache_release(page);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
shmem_truncate_range(inode, newsize, (loff_t)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
error = inode_change_ok(inode, attr);
|
error = inode_change_ok(inode, attr);
|
||||||
if (!error)
|
if (!error)
|
||||||
error = inode_setattr(inode, attr);
|
generic_setattr(inode, attr);
|
||||||
#ifdef CONFIG_TMPFS_POSIX_ACL
|
#ifdef CONFIG_TMPFS_POSIX_ACL
|
||||||
if (!error && (attr->ia_valid & ATTR_MODE))
|
if (!error && (attr->ia_valid & ATTR_MODE))
|
||||||
error = generic_acl_chmod(inode);
|
error = generic_acl_chmod(inode);
|
||||||
#endif
|
#endif
|
||||||
if (page)
|
|
||||||
page_cache_release(page);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,11 +822,11 @@ static void shmem_delete_inode(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct shmem_inode_info *info = SHMEM_I(inode);
|
struct shmem_inode_info *info = SHMEM_I(inode);
|
||||||
|
|
||||||
if (inode->i_op->truncate == shmem_truncate) {
|
if (inode->i_mapping->a_ops == &shmem_aops) {
|
||||||
truncate_inode_pages(inode->i_mapping, 0);
|
truncate_inode_pages(inode->i_mapping, 0);
|
||||||
shmem_unacct_size(info->flags, inode->i_size);
|
shmem_unacct_size(info->flags, inode->i_size);
|
||||||
inode->i_size = 0;
|
inode->i_size = 0;
|
||||||
shmem_truncate(inode);
|
shmem_truncate_range(inode, 0, (loff_t)-1);
|
||||||
if (!list_empty(&info->swaplist)) {
|
if (!list_empty(&info->swaplist)) {
|
||||||
mutex_lock(&shmem_swaplist_mutex);
|
mutex_lock(&shmem_swaplist_mutex);
|
||||||
list_del_init(&info->swaplist);
|
list_del_init(&info->swaplist);
|
||||||
|
@ -2022,7 +2025,6 @@ static const struct inode_operations shmem_symlink_inline_operations = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct inode_operations shmem_symlink_inode_operations = {
|
static const struct inode_operations shmem_symlink_inode_operations = {
|
||||||
.truncate = shmem_truncate,
|
|
||||||
.readlink = generic_readlink,
|
.readlink = generic_readlink,
|
||||||
.follow_link = shmem_follow_link,
|
.follow_link = shmem_follow_link,
|
||||||
.put_link = shmem_put_link,
|
.put_link = shmem_put_link,
|
||||||
|
@ -2440,7 +2442,6 @@ static const struct file_operations shmem_file_operations = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct inode_operations shmem_inode_operations = {
|
static const struct inode_operations shmem_inode_operations = {
|
||||||
.truncate = shmem_truncate,
|
|
||||||
.setattr = shmem_notify_change,
|
.setattr = shmem_notify_change,
|
||||||
.truncate_range = shmem_truncate_range,
|
.truncate_range = shmem_truncate_range,
|
||||||
#ifdef CONFIG_TMPFS_POSIX_ACL
|
#ifdef CONFIG_TMPFS_POSIX_ACL
|
||||||
|
|
Loading…
Reference in New Issue
Block a user