aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/hpfs/alloc.c66
-rw-r--r--fs/hpfs/hpfs_fn.h2
-rw-r--r--fs/hpfs/super.c29
3 files changed, 87 insertions, 10 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 {
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index 6797bf80f6e2..3ba49c080e42 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -312,7 +312,7 @@ static inline struct hpfs_sb_info *hpfs_sb(struct super_block *sb)
312__printf(2, 3) 312__printf(2, 3)
313void hpfs_error(struct super_block *, const char *, ...); 313void hpfs_error(struct super_block *, const char *, ...);
314int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *); 314int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *);
315unsigned hpfs_count_one_bitmap(struct super_block *, secno); 315unsigned hpfs_get_free_dnodes(struct super_block *);
316 316
317/* 317/*
318 * local time (HPFS) to GMT (Unix) 318 * local time (HPFS) to GMT (Unix)
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index b8d01ef6f531..4534ff688b76 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -121,7 +121,7 @@ static void hpfs_put_super(struct super_block *s)
121 call_rcu(&hpfs_sb(s)->rcu, lazy_free_sbi); 121 call_rcu(&hpfs_sb(s)->rcu, lazy_free_sbi);
122} 122}
123 123
124unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno) 124static unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno)
125{ 125{
126 struct quad_buffer_head qbh; 126 struct quad_buffer_head qbh;
127 unsigned long *bits; 127 unsigned long *bits;
@@ -129,7 +129,7 @@ unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno)
129 129
130 bits = hpfs_map_4sectors(s, secno, &qbh, 0); 130 bits = hpfs_map_4sectors(s, secno, &qbh, 0);
131 if (!bits) 131 if (!bits)
132 return 0; 132 return (unsigned)-1;
133 count = bitmap_weight(bits, 2048 * BITS_PER_BYTE); 133 count = bitmap_weight(bits, 2048 * BITS_PER_BYTE);
134 hpfs_brelse4(&qbh); 134 hpfs_brelse4(&qbh);
135 return count; 135 return count;
@@ -144,30 +144,45 @@ static unsigned count_bitmaps(struct super_block *s)
144 hpfs_prefetch_bitmap(s, n); 144 hpfs_prefetch_bitmap(s, n);
145 } 145 }
146 for (n = 0; n < n_bands; n++) { 146 for (n = 0; n < n_bands; n++) {
147 unsigned c;
147 hpfs_prefetch_bitmap(s, n + COUNT_RD_AHEAD); 148 hpfs_prefetch_bitmap(s, n + COUNT_RD_AHEAD);
148 count += hpfs_count_one_bitmap(s, le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[n])); 149 c = hpfs_count_one_bitmap(s, le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[n]));
150 if (c != (unsigned)-1)
151 count += c;
149 } 152 }
150 return count; 153 return count;
151} 154}
152 155
156unsigned hpfs_get_free_dnodes(struct super_block *s)
157{
158 struct hpfs_sb_info *sbi = hpfs_sb(s);
159 if (sbi->sb_n_free_dnodes == (unsigned)-1) {
160 unsigned c = hpfs_count_one_bitmap(s, sbi->sb_dmap);
161 if (c == (unsigned)-1)
162 return 0;
163 sbi->sb_n_free_dnodes = c;
164 }
165 return sbi->sb_n_free_dnodes;
166}
167
153static int hpfs_statfs(struct dentry *dentry, struct kstatfs *buf) 168static int hpfs_statfs(struct dentry *dentry, struct kstatfs *buf)
154{ 169{
155 struct super_block *s = dentry->d_sb; 170 struct super_block *s = dentry->d_sb;
156 struct hpfs_sb_info *sbi = hpfs_sb(s); 171 struct hpfs_sb_info *sbi = hpfs_sb(s);
157 u64 id = huge_encode_dev(s->s_bdev->bd_dev); 172 u64 id = huge_encode_dev(s->s_bdev->bd_dev);
173
158 hpfs_lock(s); 174 hpfs_lock(s);
159 175
160 /*if (sbi->sb_n_free == -1) {*/ 176 if (sbi->sb_n_free == (unsigned)-1)
161 sbi->sb_n_free = count_bitmaps(s); 177 sbi->sb_n_free = count_bitmaps(s);
162 sbi->sb_n_free_dnodes = hpfs_count_one_bitmap(s, sbi->sb_dmap); 178
163 /*}*/
164 buf->f_type = s->s_magic; 179 buf->f_type = s->s_magic;
165 buf->f_bsize = 512; 180 buf->f_bsize = 512;
166 buf->f_blocks = sbi->sb_fs_size; 181 buf->f_blocks = sbi->sb_fs_size;
167 buf->f_bfree = sbi->sb_n_free; 182 buf->f_bfree = sbi->sb_n_free;
168 buf->f_bavail = sbi->sb_n_free; 183 buf->f_bavail = sbi->sb_n_free;
169 buf->f_files = sbi->sb_dirband_size / 4; 184 buf->f_files = sbi->sb_dirband_size / 4;
170 buf->f_ffree = sbi->sb_n_free_dnodes; 185 buf->f_ffree = hpfs_get_free_dnodes(s);
171 buf->f_fsid.val[0] = (u32)id; 186 buf->f_fsid.val[0] = (u32)id;
172 buf->f_fsid.val[1] = (u32)(id >> 32); 187 buf->f_fsid.val[1] = (u32)(id >> 32);
173 buf->f_namelen = 254; 188 buf->f_namelen = 254;