aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hpfs/alloc.c
diff options
context:
space:
mode:
authorMikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>2014-01-28 18:10:44 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-02-02 19:24:07 -0500
commit2cbe5c76fc5e38e9af4b709593146e4b8272b69e (patch)
treede283447508e3d0ef3645f65f5adb5f9becdaf30 /fs/hpfs/alloc.c
parent602456bf169926d331246de9cc5593b962cea0dc (diff)
hpfs: remember free space
Previously, hpfs scanned all bitmaps each time the user asked for free space using statfs. This patch changes it so that hpfs scans the bitmaps only once, remembes the free space and on next invocation of statfs it returns the value instantly. New versions of wine are hammering on the statfs syscall very heavily, making some games unplayable when they're stored on hpfs, with load times in minutes. This should be backported to the stable kernels because it fixes user-visible problem (excessive level load times in wine). Signed-off-by: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz> Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/hpfs/alloc.c')
-rw-r--r--fs/hpfs/alloc.c66
1 files changed, 64 insertions, 2 deletions
diff --git a/fs/hpfs/alloc.c b/fs/hpfs/alloc.c
index cdb84a838068..58b5106186d0 100644
--- a/fs/hpfs/alloc.c
+++ b/fs/hpfs/alloc.c
@@ -8,6 +8,58 @@
8 8
9#include "hpfs_fn.h" 9#include "hpfs_fn.h"
10 10
11static void hpfs_claim_alloc(struct super_block *s, secno sec)
12{
13 struct hpfs_sb_info *sbi = hpfs_sb(s);
14 if (sbi->sb_n_free != (unsigned)-1) {
15 if (unlikely(!sbi->sb_n_free)) {
16 hpfs_error(s, "free count underflow, allocating sector %08x", sec);
17 sbi->sb_n_free = -1;
18 return;
19 }
20 sbi->sb_n_free--;
21 }
22}
23
24static void hpfs_claim_free(struct super_block *s, secno sec)
25{
26 struct hpfs_sb_info *sbi = hpfs_sb(s);
27 if (sbi->sb_n_free != (unsigned)-1) {
28 if (unlikely(sbi->sb_n_free >= sbi->sb_fs_size)) {
29 hpfs_error(s, "free count overflow, freeing sector %08x", sec);
30 sbi->sb_n_free = -1;
31 return;
32 }
33 sbi->sb_n_free++;
34 }
35}
36
37static void hpfs_claim_dirband_alloc(struct super_block *s, secno sec)
38{
39 struct hpfs_sb_info *sbi = hpfs_sb(s);
40 if (sbi->sb_n_free_dnodes != (unsigned)-1) {
41 if (unlikely(!sbi->sb_n_free_dnodes)) {
42 hpfs_error(s, "dirband free count underflow, allocating sector %08x", sec);
43 sbi->sb_n_free_dnodes = -1;
44 return;
45 }
46 sbi->sb_n_free_dnodes--;
47 }
48}
49
50static void hpfs_claim_dirband_free(struct super_block *s, secno sec)
51{
52 struct hpfs_sb_info *sbi = hpfs_sb(s);
53 if (sbi->sb_n_free_dnodes != (unsigned)-1) {
54 if (unlikely(sbi->sb_n_free_dnodes >= sbi->sb_dirband_size / 4)) {
55 hpfs_error(s, "dirband free count overflow, freeing sector %08x", sec);
56 sbi->sb_n_free_dnodes = -1;
57 return;
58 }
59 sbi->sb_n_free_dnodes++;
60 }
61}
62
11/* 63/*
12 * Check if a sector is allocated in bitmap 64 * Check if a sector is allocated in bitmap
13 * This is really slow. Turned on only if chk==2 65 * This is really slow. Turned on only if chk==2
@@ -203,9 +255,15 @@ secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forwa
203 } 255 }
204 sec = 0; 256 sec = 0;
205 ret: 257 ret:
258 if (sec) {
259 i = 0;
260 do
261 hpfs_claim_alloc(s, sec + i);
262 while (unlikely(++i < n));
263 }
206 if (sec && f_p) { 264 if (sec && f_p) {
207 for (i = 0; i < forward; i++) { 265 for (i = 0; i < forward; i++) {
208 if (!hpfs_alloc_if_possible(s, sec + i + 1)) { 266 if (!hpfs_alloc_if_possible(s, sec + n + i)) {
209 hpfs_error(s, "Prealloc doesn't work! Wanted %d, allocated at %08x, can't allocate %d", forward, sec, i); 267 hpfs_error(s, "Prealloc doesn't work! Wanted %d, allocated at %08x, can't allocate %d", forward, sec, i);
210 sec = 0; 268 sec = 0;
211 break; 269 break;
@@ -228,6 +286,7 @@ static secno alloc_in_dirband(struct super_block *s, secno near)
228 nr >>= 2; 286 nr >>= 2;
229 sec = alloc_in_bmp(s, (~0x3fff) | nr, 1, 0); 287 sec = alloc_in_bmp(s, (~0x3fff) | nr, 1, 0);
230 if (!sec) return 0; 288 if (!sec) return 0;
289 hpfs_claim_dirband_alloc(s, sec);
231 return ((sec & 0x3fff) << 2) + sbi->sb_dirband_start; 290 return ((sec & 0x3fff) << 2) + sbi->sb_dirband_start;
232} 291}
233 292
@@ -242,6 +301,7 @@ int hpfs_alloc_if_possible(struct super_block *s, secno sec)
242 bmp[(sec & 0x3fff) >> 5] &= cpu_to_le32(~(1 << (sec & 0x1f))); 301 bmp[(sec & 0x3fff) >> 5] &= cpu_to_le32(~(1 << (sec & 0x1f)));
243 hpfs_mark_4buffers_dirty(&qbh); 302 hpfs_mark_4buffers_dirty(&qbh);
244 hpfs_brelse4(&qbh); 303 hpfs_brelse4(&qbh);
304 hpfs_claim_alloc(s, sec);
245 return 1; 305 return 1;
246 } 306 }
247 hpfs_brelse4(&qbh); 307 hpfs_brelse4(&qbh);
@@ -275,6 +335,7 @@ void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n)
275 return; 335 return;
276 } 336 }
277 bmp[(sec & 0x3fff) >> 5] |= cpu_to_le32(1 << (sec & 0x1f)); 337 bmp[(sec & 0x3fff) >> 5] |= cpu_to_le32(1 << (sec & 0x1f));
338 hpfs_claim_free(s, sec);
278 if (!--n) { 339 if (!--n) {
279 hpfs_mark_4buffers_dirty(&qbh); 340 hpfs_mark_4buffers_dirty(&qbh);
280 hpfs_brelse4(&qbh); 341 hpfs_brelse4(&qbh);
@@ -359,6 +420,7 @@ void hpfs_free_dnode(struct super_block *s, dnode_secno dno)
359 bmp[ssec >> 5] |= cpu_to_le32(1 << (ssec & 0x1f)); 420 bmp[ssec >> 5] |= cpu_to_le32(1 << (ssec & 0x1f));
360 hpfs_mark_4buffers_dirty(&qbh); 421 hpfs_mark_4buffers_dirty(&qbh);
361 hpfs_brelse4(&qbh); 422 hpfs_brelse4(&qbh);
423 hpfs_claim_dirband_free(s, dno);
362 } 424 }
363} 425}
364 426
@@ -366,7 +428,7 @@ struct dnode *hpfs_alloc_dnode(struct super_block *s, secno near,
366 dnode_secno *dno, struct quad_buffer_head *qbh) 428 dnode_secno *dno, struct quad_buffer_head *qbh)
367{ 429{
368 struct dnode *d; 430 struct dnode *d;
369 if (hpfs_count_one_bitmap(s, hpfs_sb(s)->sb_dmap) > FREE_DNODES_ADD) { 431 if (hpfs_get_free_dnodes(s) > FREE_DNODES_ADD) {
370 if (!(*dno = alloc_in_dirband(s, near))) 432 if (!(*dno = alloc_in_dirband(s, near)))
371 if (!(*dno = hpfs_alloc_sector(s, near, 4, 0))) return NULL; 433 if (!(*dno = hpfs_alloc_sector(s, near, 4, 0))) return NULL;
372 } else { 434 } else {