From ad072e9ee4420e3a4ee818c85c168f4bedee9335 Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Tue, 20 Apr 2010 21:44:10 +0200 Subject: [PATCH] --- yaml --- r: 190091 b: refs/heads/master c: b6349ac89eacb813f6963f7263da05bc3f483351 h: refs/heads/master i: 190089: 564d75f1d74b1a293afb5d6bfd5237521f750fdd 190087: ba8e433c4d61b412cd01a7cc1157243927f393e8 v: v3 --- [refs] | 2 +- trunk/fs/logfs/readwrite.c | 34 ++++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index ea52e39721b7..6d8693edb979 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b8639077abf034824046ed09e779b74c4393031f +refs/heads/master: b6349ac89eacb813f6963f7263da05bc3f483351 diff --git a/trunk/fs/logfs/readwrite.c b/trunk/fs/logfs/readwrite.c index aca6c56a107a..7e3a1e5fd76d 100644 --- a/trunk/fs/logfs/readwrite.c +++ b/trunk/fs/logfs/readwrite.c @@ -1837,19 +1837,37 @@ static int __logfs_truncate(struct inode *inode, u64 size) return logfs_truncate_direct(inode, size); } -int logfs_truncate(struct inode *inode, u64 size) +/* + * Truncate, by changing the segment file, can consume a fair amount + * of resources. So back off from time to time and do some GC. + * 8 or 2048 blocks should be well within safety limits even if + * every single block resided in a different segment. + */ +#define TRUNCATE_STEP (8 * 1024 * 1024) +int logfs_truncate(struct inode *inode, u64 target) { struct super_block *sb = inode->i_sb; - int err; + u64 size = i_size_read(inode); + int err = 0; - logfs_get_wblocks(sb, NULL, 1); - err = __logfs_truncate(inode, size); - if (!err) - err = __logfs_write_inode(inode, 0); - logfs_put_wblocks(sb, NULL, 1); + size = ALIGN(size, TRUNCATE_STEP); + while (size > target) { + if (size > TRUNCATE_STEP) + size -= TRUNCATE_STEP; + else + size = 0; + if (size < target) + size = target; + + logfs_get_wblocks(sb, NULL, 1); + err = __logfs_truncate(inode, target); + if (!err) + err = __logfs_write_inode(inode, 0); + logfs_put_wblocks(sb, NULL, 1); + } if (!err) - err = vmtruncate(inode, size); + err = vmtruncate(inode, target); /* I don't trust error recovery yet. */ WARN_ON(err);