static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) { struct super_block *sb = dentry->d_sb; struct ext2_sb_info *sbi = EXT2_SB(sb); struct ext2_super_block *es = sbi->s_es; unsigned long overhead; int i; u64 fsid; if (test_opt (sb, MINIX_DF)) overhead = 0; else { /* * Compute the overhead (FS structures) */ /* * All of the blocks before first_data_block are * overhead */ overhead = le32_to_cpu(es->s_first_data_block); /* * Add the overhead attributed to the superblock and * block group descriptors. If the sparse superblocks * feature is turned on, then not all groups have this. */ for (i = 0; i < sbi->s_groups_count; i++) overhead += ext2_bg_has_super(sb, i) + ext2_bg_num_gdb(sb, i); /* * Every block group has an inode bitmap, a block * bitmap, and an inode table. */ overhead += (sbi->s_groups_count * (2 + sbi->s_itb_per_group)); } buf->f_type = EXT2_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; buf->f_bfree = ext2_count_free_blocks(sb); buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) buf->f_bavail = 0; buf->f_files = le32_to_cpu(es->s_inodes_count); buf->f_ffree = ext2_count_free_inodes(sb); buf->f_namelen = EXT2_NAME_LEN; fsid = le64_to_cpup((void *)es->s_uuid) ^ le64_to_cpup((void *)es->s_uuid + sizeof(u64)); buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; return 0; }
int op_statfs (const char *path, struct statvfs *buf) { unsigned long long i; unsigned long long s_gdb_count = 0; unsigned long long s_groups_count = 0; unsigned long long s_itb_per_group = 0; unsigned long long s_overhead_last = 0; unsigned long long s_inodes_per_block = 0; ext2_filsys e2fs; FUSE_EXT2_LOCK; e2fs = current_ext2fs(); debugf("enter"); memset(buf, 0, sizeof(struct statvfs)); if (e2fs->super->s_default_mount_opts & EXT2_MOUNT_MINIX_DF) { s_overhead_last = 0; } else { s_overhead_last = e2fs->super->s_first_data_block; s_groups_count = ((EXT2_BLOCKS_COUNT(e2fs->super) - e2fs->super->s_first_data_block - 1) / e2fs->super->s_blocks_per_group) + 1; s_gdb_count = (s_groups_count + EXT2_DESC_PER_BLOCK(e2fs->super) - 1) / EXT2_DESC_PER_BLOCK(e2fs->super); for (i = 0; i < s_groups_count; i++) { s_overhead_last += ext2_bg_has_super(e2fs, i) + ((ext2_bg_num_gdb(e2fs, i) == 0) ? 0 : s_gdb_count); } s_inodes_per_block = EXT2_BLOCK_SIZE(e2fs->super) / EXT2_INODE_SIZE(e2fs->super); s_itb_per_group = e2fs->super->s_inodes_per_group / s_inodes_per_block; s_overhead_last += (s_groups_count * (2 + s_itb_per_group)); } buf->f_bsize = EXT2_BLOCK_SIZE(e2fs->super); buf->f_frsize = /*EXT2_FRAG_SIZE(e2fs->super);*/ buf->f_bsize; buf->f_blocks = EXT2_BLOCKS_COUNT(e2fs->super) - s_overhead_last; buf->f_bfree = EXT2_FBLOCKS_COUNT(e2fs->super); if (EXT2_FBLOCKS_COUNT(e2fs->super) < EXT2_RBLOCKS_COUNT(e2fs->super)) { buf->f_bavail = 0; } else { buf->f_bavail = EXT2_FBLOCKS_COUNT(e2fs->super) - EXT2_RBLOCKS_COUNT(e2fs->super); } buf->f_files = e2fs->super->s_inodes_count; buf->f_ffree = e2fs->super->s_free_inodes_count; buf->f_favail = e2fs->super->s_free_inodes_count; buf->f_namemax = EXT2_NAME_LEN; debugf("leave"); FUSE_EXT2_UNLOCK; return 0; }
int ext2_statfs (struct super_block * sb, struct statfs * buf) { unsigned long overhead; int i; if (test_opt (sb, MINIX_DF)) overhead = 0; else { /* * Compute the overhead (FS structures) */ /* * All of the blocks before first_data_block are * overhead */ overhead = le32_to_cpu(sb->u.ext2_sb.s_es->s_first_data_block); /* * Add the overhead attributed to the superblock and * block group descriptors. If the sparse superblocks * feature is turned on, then not all groups have this. */ for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) overhead += ext2_bg_has_super(sb, i) + ext2_bg_num_gdb(sb, i); /* * Every block group has an inode bitmap, a block * bitmap, and an inode table. */ overhead += (sb->u.ext2_sb.s_groups_count * (2 + sb->u.ext2_sb.s_itb_per_group)); } buf->f_type = EXT2_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; buf->f_blocks = le32_to_cpu(sb->u.ext2_sb.s_es->s_blocks_count) - overhead; buf->f_bfree = ext2_count_free_blocks (sb); buf->f_bavail = buf->f_bfree - le32_to_cpu(sb->u.ext2_sb.s_es->s_r_blocks_count); if (buf->f_bfree < le32_to_cpu(sb->u.ext2_sb.s_es->s_r_blocks_count)) buf->f_bavail = 0; buf->f_files = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count); buf->f_ffree = ext2_count_free_inodes (sb); buf->f_namelen = EXT2_NAME_LEN; return 0; }
static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) { struct super_block *sb = dentry->d_sb; struct ext2_sb_info *sbi = EXT2_SB(sb); struct ext2_super_block *es = sbi->s_es; u64 fsid; spin_lock(&sbi->s_lock); if (test_opt (sb, MINIX_DF)) sbi->s_overhead_last = 0; else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) { unsigned long i, overhead = 0; smp_rmb(); /* * Compute the overhead (FS structures). This is constant * for a given filesystem unless the number of block groups * changes so we cache the previous value until it does. */ /* * All of the blocks before first_data_block are * overhead */ overhead = le32_to_cpu(es->s_first_data_block); /* * Add the overhead attributed to the superblock and * block group descriptors. If the sparse superblocks * feature is turned on, then not all groups have this. */ for (i = 0; i < sbi->s_groups_count; i++) overhead += ext2_bg_has_super(sb, i) + ext2_bg_num_gdb(sb, i); /* * Every block group has an inode bitmap, a block * bitmap, and an inode table. */ overhead += (sbi->s_groups_count * (2 + sbi->s_itb_per_group)); sbi->s_overhead_last = overhead; smp_wmb(); sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); } buf->f_type = EXT2_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last; buf->f_bfree = ext2_count_free_blocks(sb); es->s_free_blocks_count = cpu_to_le32(buf->f_bfree); buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) buf->f_bavail = 0; buf->f_files = le32_to_cpu(es->s_inodes_count); buf->f_ffree = ext2_count_free_inodes(sb); es->s_free_inodes_count = cpu_to_le32(buf->f_ffree); buf->f_namelen = EXT2_NAME_LEN; fsid = le64_to_cpup((void *)es->s_uuid) ^ le64_to_cpup((void *)es->s_uuid + sizeof(u64)); buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; spin_unlock(&sbi->s_lock); return 0; }