aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/file.c
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2012-07-19 08:12:40 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2012-07-19 09:51:08 -0400
commit8e2e00473598dd5379d8408cb974dade000acafc (patch)
tree1f7bfdf0d07b6c0315bbd11ffee174742d66a459 /fs/gfs2/file.c
parent294f2ad5a545eb71d397623743ddd8201131bdad (diff)
GFS2: Reduce file fragmentation
This patch reduces GFS2 file fragmentation by pre-reserving blocks. The resulting improved on disk layout greatly speeds up operations in cases which would have resulted in interlaced allocation of blocks previously. A typical example of this is 10 parallel dd processes, each writing to a file in a common dirctory. The implementation uses an rbtree of reservations attached to each resource group (and each inode). 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.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 6fbf3cbd974d..9f94832cefec 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -383,6 +383,9 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
383 if (ret) 383 if (ret)
384 return ret; 384 return ret;
385 385
386 atomic_set(&ip->i_res->rs_sizehint,
387 PAGE_CACHE_SIZE / sdp->sd_sb.sb_bsize);
388
386 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 389 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
387 ret = gfs2_glock_nq(&gh); 390 ret = gfs2_glock_nq(&gh);
388 if (ret) 391 if (ret)
@@ -571,22 +574,15 @@ fail:
571 574
572static int gfs2_release(struct inode *inode, struct file *file) 575static int gfs2_release(struct inode *inode, struct file *file)
573{ 576{
574 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
575 struct gfs2_file *fp;
576 struct gfs2_inode *ip = GFS2_I(inode); 577 struct gfs2_inode *ip = GFS2_I(inode);
577 578
578 fp = file->private_data; 579 kfree(file->private_data);
579 file->private_data = NULL; 580 file->private_data = NULL;
580 581
581 if ((file->f_mode & FMODE_WRITE) && ip->i_res && 582 if ((file->f_mode & FMODE_WRITE) &&
582 (atomic_read(&inode->i_writecount) == 1)) 583 (atomic_read(&inode->i_writecount) == 1))
583 gfs2_rs_delete(ip); 584 gfs2_rs_delete(ip);
584 585
585 if (gfs2_assert_warn(sdp, fp))
586 return -EIO;
587
588 kfree(fp);
589
590 return 0; 586 return 0;
591} 587}
592 588
@@ -662,14 +658,18 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
662 unsigned long nr_segs, loff_t pos) 658 unsigned long nr_segs, loff_t pos)
663{ 659{
664 struct file *file = iocb->ki_filp; 660 struct file *file = iocb->ki_filp;
661 size_t writesize = iov_length(iov, nr_segs);
665 struct dentry *dentry = file->f_dentry; 662 struct dentry *dentry = file->f_dentry;
666 struct gfs2_inode *ip = GFS2_I(dentry->d_inode); 663 struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
664 struct gfs2_sbd *sdp;
667 int ret; 665 int ret;
668 666
667 sdp = GFS2_SB(file->f_mapping->host);
669 ret = gfs2_rs_alloc(ip); 668 ret = gfs2_rs_alloc(ip);
670 if (ret) 669 if (ret)
671 return ret; 670 return ret;
672 671
672 atomic_set(&ip->i_res->rs_sizehint, writesize / sdp->sd_sb.sb_bsize);
673 if (file->f_flags & O_APPEND) { 673 if (file->f_flags & O_APPEND) {
674 struct gfs2_holder gh; 674 struct gfs2_holder gh;
675 675
@@ -795,6 +795,8 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
795 if (unlikely(error)) 795 if (unlikely(error))
796 goto out_uninit; 796 goto out_uninit;
797 797
798 atomic_set(&ip->i_res->rs_sizehint, len / sdp->sd_sb.sb_bsize);
799
798 while (len > 0) { 800 while (len > 0) {
799 if (len < bytes) 801 if (len < bytes)
800 bytes = len; 802 bytes = len;
@@ -803,10 +805,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
803 offset += bytes; 805 offset += bytes;
804 continue; 806 continue;
805 } 807 }
806 error = gfs2_rindex_update(sdp);
807 if (error)
808 goto out_unlock;
809
810 error = gfs2_quota_lock_check(ip); 808 error = gfs2_quota_lock_check(ip);
811 if (error) 809 if (error)
812 goto out_unlock; 810 goto out_unlock;