aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hpfs/alloc.c
diff options
context:
space:
mode:
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 {