Skip to content

Commit

Permalink
GFS2: Clean up reservation removal
Browse files Browse the repository at this point in the history
The reservation for an inode should be cleared when it is truncated so
that we can start again at a different offset for future allocations.
We could try and do better than that, by resetting the search based on
where the truncation started from, but this is only a first step.

In addition, there are three callers of gfs2_rs_delete() but only one
of those should really be testing the value of i_writecount. While
we get away with that in the other cases currently, I think it would
be better if we made that test specific to the one case which
requires it.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
  • Loading branch information
Steven Whitehouse committed Sep 27, 2013
1 parent 5ca1db4 commit af5c269
Show file tree
Hide file tree
Showing 6 changed files with 10 additions and 9 deletions.
4 changes: 3 additions & 1 deletion fs/gfs2/bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,7 @@ static int do_grow(struct inode *inode, u64 size)

int gfs2_setattr_size(struct inode *inode, u64 newsize)
{
struct gfs2_inode *ip = GFS2_I(inode);
int ret;
u64 oldsize;

Expand All @@ -1294,7 +1295,7 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize)

inode_dio_wait(inode);

ret = gfs2_rs_alloc(GFS2_I(inode));
ret = gfs2_rs_alloc(ip);
if (ret)
goto out;

Expand All @@ -1304,6 +1305,7 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize)
goto out;
}

gfs2_rs_deltree(ip->i_res);
ret = do_shrink(inode, oldsize, newsize);
out:
put_write_access(inode);
Expand Down
2 changes: 1 addition & 1 deletion fs/gfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ static int gfs2_release(struct inode *inode, struct file *file)
if (!(file->f_mode & FMODE_WRITE))
return 0;

gfs2_rs_delete(ip);
gfs2_rs_delete(ip, &inode->i_writecount);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion fs/gfs2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
fail_free_inode:
if (ip->i_gl)
gfs2_glock_put(ip->i_gl);
gfs2_rs_delete(ip);
gfs2_rs_delete(ip, NULL);
free_inode_nonrcu(inode);
inode = NULL;
fail_gunlock:
Expand Down
7 changes: 3 additions & 4 deletions fs/gfs2/rgrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,14 +661,13 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
/**
* gfs2_rs_delete - delete a multi-block reservation
* @ip: The inode for this reservation
* @wcount: The inode's write count, or NULL
*
*/
void gfs2_rs_delete(struct gfs2_inode *ip)
void gfs2_rs_delete(struct gfs2_inode *ip, atomic_t *wcount)
{
struct inode *inode = &ip->i_inode;

down_write(&ip->i_rw_mutex);
if (ip->i_res && atomic_read(&inode->i_writecount) <= 1) {
if (ip->i_res && ((wcount == NULL) || (atomic_read(wcount) <= 1))) {
gfs2_rs_deltree(ip->i_res);
BUG_ON(ip->i_res->rs_free);
kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
Expand Down
2 changes: 1 addition & 1 deletion fs/gfs2/rgrp.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,

extern int gfs2_rs_alloc(struct gfs2_inode *ip);
extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs);
extern void gfs2_rs_delete(struct gfs2_inode *ip);
extern void gfs2_rs_delete(struct gfs2_inode *ip, atomic_t *wcount);
extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta);
extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen);
extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
Expand Down
2 changes: 1 addition & 1 deletion fs/gfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1526,7 +1526,7 @@ static void gfs2_evict_inode(struct inode *inode)
out:
/* Case 3 starts here */
truncate_inode_pages(&inode->i_data, 0);
gfs2_rs_delete(ip);
gfs2_rs_delete(ip, NULL);
gfs2_ordered_del_inode(ip);
clear_inode(inode);
gfs2_dir_hash_inval(ip);
Expand Down

0 comments on commit af5c269

Please sign in to comment.