diff options
Diffstat (limited to 'fs/hpfs/super.c')
-rw-r--r-- | fs/hpfs/super.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index b8d01ef..4534ff6 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -121,7 +121,7 @@ static void hpfs_put_super(struct super_block *s) call_rcu(&hpfs_sb(s)->rcu, lazy_free_sbi); } -unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno) +static unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno) { struct quad_buffer_head qbh; unsigned long *bits; @@ -129,7 +129,7 @@ unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno) bits = hpfs_map_4sectors(s, secno, &qbh, 0); if (!bits) - return 0; + return (unsigned)-1; count = bitmap_weight(bits, 2048 * BITS_PER_BYTE); hpfs_brelse4(&qbh); return count; @@ -144,30 +144,45 @@ static unsigned count_bitmaps(struct super_block *s) hpfs_prefetch_bitmap(s, n); } for (n = 0; n < n_bands; n++) { + unsigned c; hpfs_prefetch_bitmap(s, n + COUNT_RD_AHEAD); - count += hpfs_count_one_bitmap(s, le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[n])); + c = hpfs_count_one_bitmap(s, le32_to_cpu(hpfs_sb(s)->sb_bmp_dir[n])); + if (c != (unsigned)-1) + count += c; } return count; } +unsigned hpfs_get_free_dnodes(struct super_block *s) +{ + struct hpfs_sb_info *sbi = hpfs_sb(s); + if (sbi->sb_n_free_dnodes == (unsigned)-1) { + unsigned c = hpfs_count_one_bitmap(s, sbi->sb_dmap); + if (c == (unsigned)-1) + return 0; + sbi->sb_n_free_dnodes = c; + } + return sbi->sb_n_free_dnodes; +} + static int hpfs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct super_block *s = dentry->d_sb; struct hpfs_sb_info *sbi = hpfs_sb(s); u64 id = huge_encode_dev(s->s_bdev->bd_dev); + hpfs_lock(s); - /*if (sbi->sb_n_free == -1) {*/ + if (sbi->sb_n_free == (unsigned)-1) sbi->sb_n_free = count_bitmaps(s); - sbi->sb_n_free_dnodes = hpfs_count_one_bitmap(s, sbi->sb_dmap); - /*}*/ + buf->f_type = s->s_magic; buf->f_bsize = 512; buf->f_blocks = sbi->sb_fs_size; buf->f_bfree = sbi->sb_n_free; buf->f_bavail = sbi->sb_n_free; buf->f_files = sbi->sb_dirband_size / 4; - buf->f_ffree = sbi->sb_n_free_dnodes; + buf->f_ffree = hpfs_get_free_dnodes(s); buf->f_fsid.val[0] = (u32)id; buf->f_fsid.val[1] = (u32)(id >> 32); buf->f_namelen = 254; |