diff options
author | Bob Peterson <rpeterso@redhat.com> | 2012-07-19 08:12:40 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2012-07-19 09:51:08 -0400 |
commit | 8e2e00473598dd5379d8408cb974dade000acafc (patch) | |
tree | 1f7bfdf0d07b6c0315bbd11ffee174742d66a459 /fs/gfs2/file.c | |
parent | 294f2ad5a545eb71d397623743ddd8201131bdad (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.c | 24 |
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 | ||
572 | static int gfs2_release(struct inode *inode, struct file *file) | 575 | static 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; |