summaryrefslogtreecommitdiffstats
path: root/fs/gfs2/file.c
diff options
context:
space:
mode:
authorBob Peterson2012-06-06 12:17:59 +0200
committerSteven Whitehouse2012-06-06 12:17:59 +0200
commit0a305e496059a113f93bdd3ad27a5aaa917fe34d (patch)
treeb0b6ce3997fef4c4e28f598a98e2e08c939414a6 /fs/gfs2/file.c
parentMerge tag 'please-pull-mce' of git://git.kernel.org/pub/scm/linux/kernel/git/... (diff)
downloadkernel-qcow2-linux-0a305e496059a113f93bdd3ad27a5aaa917fe34d.tar.gz
kernel-qcow2-linux-0a305e496059a113f93bdd3ad27a5aaa917fe34d.tar.xz
kernel-qcow2-linux-0a305e496059a113f93bdd3ad27a5aaa917fe34d.zip
GFS2: Extend the life of the reservations
This patch lengthens the lifespan of the reservations structure for inodes. Before, they were allocated and deallocated for every write operation. With this patch, they are allocated when the first write occurs, and deallocated when the last process closes the file. It's more efficient to do it this way because it saves GFS2 a lot of unnecessary allocates and frees. It also gives us more flexibility for the future: (1) we can now fold the qadata structure back into the structure and save those alloc/frees, (2) we can use this for multi-block reservations. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/file.c')
-rw-r--r--fs/gfs2/file.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 31b199f6efc1..37906174d417 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -376,6 +376,10 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
*/
vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
+ ret = gfs2_rs_alloc(ip);
+ if (ret)
+ return ret;
+
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
ret = gfs2_glock_nq(&gh);
if (ret)
@@ -569,10 +573,15 @@ static int gfs2_release(struct inode *inode, struct file *file)
{
struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
struct gfs2_file *fp;
+ struct gfs2_inode *ip = GFS2_I(inode);
fp = file->private_data;
file->private_data = NULL;
+ if ((file->f_mode & FMODE_WRITE) && ip->i_res &&
+ (atomic_read(&inode->i_writecount) == 1))
+ gfs2_rs_delete(ip);
+
if (gfs2_assert_warn(sdp, fp))
return -EIO;
@@ -653,12 +662,16 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
struct file *file = iocb->ki_filp;
+ struct dentry *dentry = file->f_dentry;
+ struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
+ int ret;
+
+ ret = gfs2_rs_alloc(ip);
+ if (ret)
+ return ret;
if (file->f_flags & O_APPEND) {
- struct dentry *dentry = file->f_dentry;
- struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
struct gfs2_holder gh;
- int ret;
ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
if (ret)
@@ -774,6 +787,10 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
if (bytes == 0)
bytes = sdp->sd_sb.sb_bsize;
+ error = gfs2_rs_alloc(ip);
+ if (error)
+ return error;
+
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
error = gfs2_glock_nq(&ip->i_gh);
if (unlikely(error))