diff options
author | Bob Peterson <rpeterso@redhat.com> | 2011-09-15 09:59:56 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2011-10-21 07:39:47 -0400 |
commit | bd5437a7d4307a35f2c7cc19cad706ec0e5d61f0 (patch) | |
tree | 3014bf500f6fc1aa90989d5ae956d1c45ff478d2 /fs/gfs2 | |
parent | f75bbfb4dda68c86eb33cde7e2b5c1343c6d5812 (diff) |
GFS2: speed up delete/unlink performance for large files
This patch improves the performance of delete/unlink
operations in a GFS2 file system where the files are large
by adding a layer of metadata read-ahead for indirect blocks.
Mileage will vary, but on my system, deleting an 8.6G file
dropped from 22 seconds to about 4.5 seconds.
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/bmap.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 22ad413213ca..834cd9442a1d 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -831,7 +831,7 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
831 | { | 831 | { |
832 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 832 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
833 | struct buffer_head *bh = NULL; | 833 | struct buffer_head *bh = NULL; |
834 | __be64 *top, *bottom; | 834 | __be64 *top, *bottom, *t2; |
835 | u64 bn; | 835 | u64 bn; |
836 | int error; | 836 | int error; |
837 | int mh_size = sizeof(struct gfs2_meta_header); | 837 | int mh_size = sizeof(struct gfs2_meta_header); |
@@ -859,7 +859,27 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
859 | if (error) | 859 | if (error) |
860 | goto out; | 860 | goto out; |
861 | 861 | ||
862 | if (height < ip->i_height - 1) | 862 | if (height < ip->i_height - 1) { |
863 | struct buffer_head *rabh; | ||
864 | |||
865 | for (t2 = top; t2 < bottom; t2++, first = 0) { | ||
866 | if (!*t2) | ||
867 | continue; | ||
868 | |||
869 | bn = be64_to_cpu(*t2); | ||
870 | rabh = gfs2_getbuf(ip->i_gl, bn, CREATE); | ||
871 | if (trylock_buffer(rabh)) { | ||
872 | if (buffer_uptodate(rabh)) { | ||
873 | unlock_buffer(rabh); | ||
874 | brelse(rabh); | ||
875 | continue; | ||
876 | } | ||
877 | rabh->b_end_io = end_buffer_read_sync; | ||
878 | submit_bh(READA | REQ_META, rabh); | ||
879 | continue; | ||
880 | } | ||
881 | brelse(rabh); | ||
882 | } | ||
863 | for (; top < bottom; top++, first = 0) { | 883 | for (; top < bottom; top++, first = 0) { |
864 | if (!*top) | 884 | if (!*top) |
865 | continue; | 885 | continue; |
@@ -871,7 +891,7 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
871 | if (error) | 891 | if (error) |
872 | break; | 892 | break; |
873 | } | 893 | } |
874 | 894 | } | |
875 | out: | 895 | out: |
876 | brelse(bh); | 896 | brelse(bh); |
877 | return error; | 897 | return error; |