diff options
author | Tao Ma <tao.ma@oracle.com> | 2010-07-22 01:56:45 -0400 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2010-08-07 13:44:49 -0400 |
commit | 8a2e70c40ff58f82dde67770e6623ca45f0cb0c8 (patch) | |
tree | ce05111dbb00fae81d0c0b7726ddac5c0117ec34 /fs/ocfs2/refcounttree.c | |
parent | 7beaf243787f85a2ef9213ccf13ab4a243283fde (diff) |
ocfs2: Count more refcount records in file system fragmentation.
The refcount record calculation in ocfs2_calc_refcount_meta_credits
is too optimistic that we can always allocate contiguous clusters
and handle an already existed refcount rec as a whole. Actually
because of file system fragmentation, we may have the chance to split
a refcount record into 3 parts during the transaction. So consider
the worst case in record calculation.
Cc: stable@kernel.org
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/refcounttree.c')
-rw-r--r-- | fs/ocfs2/refcounttree.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 3ac5aa733e9c..73a11ccfd4c2 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
@@ -2436,16 +2436,26 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, | |||
2436 | len = min((u64)cpos + clusters, le64_to_cpu(rec.r_cpos) + | 2436 | len = min((u64)cpos + clusters, le64_to_cpu(rec.r_cpos) + |
2437 | le32_to_cpu(rec.r_clusters)) - cpos; | 2437 | le32_to_cpu(rec.r_clusters)) - cpos; |
2438 | /* | 2438 | /* |
2439 | * If the refcount rec already exist, cool. We just need | ||
2440 | * to check whether there is a split. Otherwise we just need | ||
2441 | * to increase the refcount. | ||
2442 | * If we will insert one, increases recs_add. | ||
2443 | * | ||
2444 | * We record all the records which will be inserted to the | 2439 | * We record all the records which will be inserted to the |
2445 | * same refcount block, so that we can tell exactly whether | 2440 | * same refcount block, so that we can tell exactly whether |
2446 | * we need a new refcount block or not. | 2441 | * we need a new refcount block or not. |
2442 | * | ||
2443 | * If we will insert a new one, this is easy and only happens | ||
2444 | * during adding refcounted flag to the extent, so we don't | ||
2445 | * have a chance of spliting. We just need one record. | ||
2446 | * | ||
2447 | * If the refcount rec already exists, that would be a little | ||
2448 | * complicated. we may have to: | ||
2449 | * 1) split at the beginning if the start pos isn't aligned. | ||
2450 | * we need 1 more record in this case. | ||
2451 | * 2) split int the end if the end pos isn't aligned. | ||
2452 | * we need 1 more record in this case. | ||
2453 | * 3) split in the middle because of file system fragmentation. | ||
2454 | * we need 2 more records in this case(we can't detect this | ||
2455 | * beforehand, so always think of the worst case). | ||
2447 | */ | 2456 | */ |
2448 | if (rec.r_refcount) { | 2457 | if (rec.r_refcount) { |
2458 | recs_add += 2; | ||
2449 | /* Check whether we need a split at the beginning. */ | 2459 | /* Check whether we need a split at the beginning. */ |
2450 | if (cpos == start_cpos && | 2460 | if (cpos == start_cpos && |
2451 | cpos != le64_to_cpu(rec.r_cpos)) | 2461 | cpos != le64_to_cpu(rec.r_cpos)) |