diff options
Diffstat (limited to 'fs/logfs/readwrite.c')
-rw-r--r-- | fs/logfs/readwrite.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index aca6c56a107a..7e3a1e5fd76d 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
@@ -1837,19 +1837,37 @@ static int __logfs_truncate(struct inode *inode, u64 size) | |||
1837 | return logfs_truncate_direct(inode, size); | 1837 | return logfs_truncate_direct(inode, size); |
1838 | } | 1838 | } |
1839 | 1839 | ||
1840 | int logfs_truncate(struct inode *inode, u64 size) | 1840 | /* |
1841 | * Truncate, by changing the segment file, can consume a fair amount | ||
1842 | * of resources. So back off from time to time and do some GC. | ||
1843 | * 8 or 2048 blocks should be well within safety limits even if | ||
1844 | * every single block resided in a different segment. | ||
1845 | */ | ||
1846 | #define TRUNCATE_STEP (8 * 1024 * 1024) | ||
1847 | int logfs_truncate(struct inode *inode, u64 target) | ||
1841 | { | 1848 | { |
1842 | struct super_block *sb = inode->i_sb; | 1849 | struct super_block *sb = inode->i_sb; |
1843 | int err; | 1850 | u64 size = i_size_read(inode); |
1851 | int err = 0; | ||
1844 | 1852 | ||
1845 | logfs_get_wblocks(sb, NULL, 1); | 1853 | size = ALIGN(size, TRUNCATE_STEP); |
1846 | err = __logfs_truncate(inode, size); | 1854 | while (size > target) { |
1847 | if (!err) | 1855 | if (size > TRUNCATE_STEP) |
1848 | err = __logfs_write_inode(inode, 0); | 1856 | size -= TRUNCATE_STEP; |
1849 | logfs_put_wblocks(sb, NULL, 1); | 1857 | else |
1858 | size = 0; | ||
1859 | if (size < target) | ||
1860 | size = target; | ||
1861 | |||
1862 | logfs_get_wblocks(sb, NULL, 1); | ||
1863 | err = __logfs_truncate(inode, target); | ||
1864 | if (!err) | ||
1865 | err = __logfs_write_inode(inode, 0); | ||
1866 | logfs_put_wblocks(sb, NULL, 1); | ||
1867 | } | ||
1850 | 1868 | ||
1851 | if (!err) | 1869 | if (!err) |
1852 | err = vmtruncate(inode, size); | 1870 | err = vmtruncate(inode, target); |
1853 | 1871 | ||
1854 | /* I don't trust error recovery yet. */ | 1872 | /* I don't trust error recovery yet. */ |
1855 | WARN_ON(err); | 1873 | WARN_ON(err); |