Skip to content

Commit

Permalink
truncate: use new helpers
Browse files Browse the repository at this point in the history
Update some fs code to make use of new helper functions introduced
in the previous patch. Should be no significant change in behaviour
(except CIFS now calls send_sig under i_lock, via inode_newsize_ok).

Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Miklos Szeredi <miklos@szeredi.hu>
Cc: linux-nfs@vger.kernel.org
Cc: Trond.Myklebust@netapp.com
Cc: linux-cifs-client@lists.samba.org
Cc: sfrench@samba.org
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
npiggin@suse.de authored and al committed Sep 24, 2009
1 parent 25d9e2d commit c08d3b0
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 127 deletions.
10 changes: 2 additions & 8 deletions fs/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2239,16 +2239,10 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size)
struct address_space *mapping = inode->i_mapping;
struct page *page;
void *fsdata;
unsigned long limit;
int err;

err = -EFBIG;
limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
if (limit != RLIM_INFINITY && size > (loff_t)limit) {
send_sig(SIGXFSZ, current, 0);
goto out;
}
if (size > inode->i_sb->s_maxbytes)
err = inode_newsize_ok(inode, size);
if (err)
goto out;

err = pagecache_write_begin(NULL, mapping, size, 0,
Expand Down
53 changes: 10 additions & 43 deletions fs/cifs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1557,57 +1557,24 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from)

static int cifs_vmtruncate(struct inode *inode, loff_t offset)
{
struct address_space *mapping = inode->i_mapping;
unsigned long limit;
loff_t oldsize;
int err;

spin_lock(&inode->i_lock);
if (inode->i_size < offset)
goto do_expand;
/*
* truncation of in-use swapfiles is disallowed - it would cause
* subsequent swapout to scribble on the now-freed blocks.
*/
if (IS_SWAPFILE(inode)) {
spin_unlock(&inode->i_lock);
goto out_busy;
}
i_size_write(inode, offset);
spin_unlock(&inode->i_lock);
/*
* unmap_mapping_range is called twice, first simply for efficiency
* so that truncate_inode_pages does fewer single-page unmaps. However
* after this first call, and before truncate_inode_pages finishes,
* it is possible for private pages to be COWed, which remain after
* truncate_inode_pages finishes, hence the second unmap_mapping_range
* call must be made for correctness.
*/
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
truncate_inode_pages(mapping, offset);
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
goto out_truncate;

do_expand:
limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
if (limit != RLIM_INFINITY && offset > limit) {
err = inode_newsize_ok(inode, offset);
if (err) {
spin_unlock(&inode->i_lock);
goto out_sig;
}
if (offset > inode->i_sb->s_maxbytes) {
spin_unlock(&inode->i_lock);
goto out_big;
goto out;
}

oldsize = inode->i_size;
i_size_write(inode, offset);
spin_unlock(&inode->i_lock);
out_truncate:
truncate_pagecache(inode, oldsize, offset);
if (inode->i_op->truncate)
inode->i_op->truncate(inode);
return 0;
out_sig:
send_sig(SIGXFSZ, current, 0);
out_big:
return -EFBIG;
out_busy:
return -ETXTBSY;
out:
return err;
}

static int
Expand Down
14 changes: 4 additions & 10 deletions fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1276,14 +1276,9 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
return 0;

if (attr->ia_valid & ATTR_SIZE) {
unsigned long limit;
if (IS_SWAPFILE(inode))
return -ETXTBSY;
limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
send_sig(SIGXFSZ, current, 0);
return -EFBIG;
}
err = inode_newsize_ok(inode, attr->ia_size);
if (err)
return err;
is_truncate = true;
}

Expand Down Expand Up @@ -1350,8 +1345,7 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
* FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
*/
if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
if (outarg.attr.size < oldsize)
fuse_truncate(inode->i_mapping, outarg.attr.size);
truncate_pagecache(inode, oldsize, outarg.attr.size);
invalidate_inode_pages2(inode->i_mapping);
}

Expand Down
2 changes: 0 additions & 2 deletions fs/fuse/fuse_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,6 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
u64 attr_valid);

void fuse_truncate(struct address_space *mapping, loff_t offset);

/**
* Initialize the client device
*/
Expand Down
11 changes: 1 addition & 10 deletions fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,6 @@ static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
return 0;
}

void fuse_truncate(struct address_space *mapping, loff_t offset)
{
/* See vmtruncate() */
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
truncate_inode_pages(mapping, offset);
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
}

void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
u64 attr_valid)
{
Expand Down Expand Up @@ -205,8 +197,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
spin_unlock(&fc->lock);

if (S_ISREG(inode->i_mode) && oldsize != attr->size) {
if (attr->size < oldsize)
fuse_truncate(inode->i_mapping, attr->size);
truncate_pagecache(inode, oldsize, attr->size);
invalidate_inode_pages2(inode->i_mapping);
}
}
Expand Down
54 changes: 13 additions & 41 deletions fs/nfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,49 +458,21 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
*/
static int nfs_vmtruncate(struct inode * inode, loff_t offset)
{
if (i_size_read(inode) < offset) {
unsigned long limit;

limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
if (limit != RLIM_INFINITY && offset > limit)
goto out_sig;
if (offset > inode->i_sb->s_maxbytes)
goto out_big;
spin_lock(&inode->i_lock);
i_size_write(inode, offset);
spin_unlock(&inode->i_lock);
} else {
struct address_space *mapping = inode->i_mapping;
loff_t oldsize;
int err;

/*
* truncation of in-use swapfiles is disallowed - it would
* cause subsequent swapout to scribble on the now-freed
* blocks.
*/
if (IS_SWAPFILE(inode))
return -ETXTBSY;
spin_lock(&inode->i_lock);
i_size_write(inode, offset);
spin_unlock(&inode->i_lock);
err = inode_newsize_ok(inode, offset);
if (err)
goto out;

/*
* unmap_mapping_range is called twice, first simply for
* efficiency so that truncate_inode_pages does fewer
* single-page unmaps. However after this first call, and
* before truncate_inode_pages finishes, it is possible for
* private pages to be COWed, which remain after
* truncate_inode_pages finishes, hence the second
* unmap_mapping_range call must be made for correctness.
*/
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
truncate_inode_pages(mapping, offset);
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
}
return 0;
out_sig:
send_sig(SIGXFSZ, current, 0);
out_big:
return -EFBIG;
spin_lock(&inode->i_lock);
oldsize = inode->i_size;
i_size_write(inode, offset);
spin_unlock(&inode->i_lock);

truncate_pagecache(inode, oldsize, offset);
out:
return err;
}

/**
Expand Down
18 changes: 5 additions & 13 deletions fs/ramfs/file-nommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,11 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
/* make various checks */
order = get_order(newsize);
if (unlikely(order >= MAX_ORDER))
goto too_big;
return -EFBIG;

limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
if (limit != RLIM_INFINITY && newsize > limit)
goto fsize_exceeded;

if (newsize > inode->i_sb->s_maxbytes)
goto too_big;
ret = inode_newsize_ok(inode, newsize);
if (ret)
return ret;

i_size_write(inode, newsize);

Expand Down Expand Up @@ -118,12 +115,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)

return 0;

fsize_exceeded:
send_sig(SIGXFSZ, current, 0);
too_big:
return -EFBIG;

add_error:
add_error:
while (loop < npages)
__free_page(pages + loop++);
return ret;
Expand Down

0 comments on commit c08d3b0

Please sign in to comment.