Commit 2b3dcf35 authored by Bob Peterson's avatar Bob Peterson Committed by Steven Whitehouse

GFS2: Increase i_writecount during gfs2_setattr_size

This patch calls get_write_access in a few functions. This
merely increases inode->i_writecount for the duration of the function.
That will ensure that any file closes won't delete the inode's
multi-block reservation while the function is running.
Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent 4a586812
...@@ -1286,17 +1286,26 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize) ...@@ -1286,17 +1286,26 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize)
if (ret) if (ret)
return ret; return ret;
ret = get_write_access(inode);
if (ret)
return ret;
inode_dio_wait(inode); inode_dio_wait(inode);
ret = gfs2_rs_alloc(GFS2_I(inode)); ret = gfs2_rs_alloc(GFS2_I(inode));
if (ret) if (ret)
return ret; goto out;
oldsize = inode->i_size; oldsize = inode->i_size;
if (newsize >= oldsize) if (newsize >= oldsize) {
return do_grow(inode, newsize); ret = do_grow(inode, newsize);
goto out;
}
return do_shrink(inode, oldsize, newsize); ret = do_shrink(inode, oldsize, newsize);
out:
put_write_access(inode);
return ret;
} }
int gfs2_truncatei_resume(struct gfs2_inode *ip) int gfs2_truncatei_resume(struct gfs2_inode *ip)
......
...@@ -402,16 +402,20 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -402,16 +402,20 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
/* Update file times before taking page lock */ /* Update file times before taking page lock */
file_update_time(vma->vm_file); file_update_time(vma->vm_file);
ret = get_write_access(inode);
if (ret)
goto out;
ret = gfs2_rs_alloc(ip); ret = gfs2_rs_alloc(ip);
if (ret) if (ret)
return ret; goto out_write_access;
gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE); gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE);
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
ret = gfs2_glock_nq(&gh); ret = gfs2_glock_nq(&gh);
if (ret) if (ret)
goto out; goto out_uninit;
set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
set_bit(GIF_SW_PAGED, &ip->i_flags); set_bit(GIF_SW_PAGED, &ip->i_flags);
...@@ -480,12 +484,15 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -480,12 +484,15 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
gfs2_quota_unlock(ip); gfs2_quota_unlock(ip);
out_unlock: out_unlock:
gfs2_glock_dq(&gh); gfs2_glock_dq(&gh);
out: out_uninit:
gfs2_holder_uninit(&gh); gfs2_holder_uninit(&gh);
if (ret == 0) { if (ret == 0) {
set_page_dirty(page); set_page_dirty(page);
wait_for_stable_page(page); wait_for_stable_page(page);
} }
out_write_access:
put_write_access(inode);
out:
sb_end_pagefault(inode->i_sb); sb_end_pagefault(inode->i_sb);
return block_page_mkwrite_return(ret); return block_page_mkwrite_return(ret);
} }
...@@ -594,10 +601,10 @@ static int gfs2_release(struct inode *inode, struct file *file) ...@@ -594,10 +601,10 @@ static int gfs2_release(struct inode *inode, struct file *file)
kfree(file->private_data); kfree(file->private_data);
file->private_data = NULL; file->private_data = NULL;
if ((file->f_mode & FMODE_WRITE) && if (!(file->f_mode & FMODE_WRITE))
(atomic_read(&inode->i_writecount) == 1)) return 0;
gfs2_rs_delete(ip);
gfs2_rs_delete(ip);
return 0; return 0;
} }
......
...@@ -638,8 +638,10 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs) ...@@ -638,8 +638,10 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
*/ */
void gfs2_rs_delete(struct gfs2_inode *ip) void gfs2_rs_delete(struct gfs2_inode *ip)
{ {
struct inode *inode = &ip->i_inode;
down_write(&ip->i_rw_mutex); down_write(&ip->i_rw_mutex);
if (ip->i_res) { if (ip->i_res && atomic_read(&inode->i_writecount) <= 1) {
gfs2_rs_deltree(ip->i_res); gfs2_rs_deltree(ip->i_res);
BUG_ON(ip->i_res->rs_free); BUG_ON(ip->i_res->rs_free);
kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment