nilfs2: implement calculation of free inodes count

Currently, NILFS2 returns 0 as free inodes count (f_ffree) and current
used inodes count as total file nodes in file system (f_files):

df -i
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/loop0           2      2       0  100% /mnt/nilfs2

This patch implements real calculation of free inodes count.  First of
all, it is calculated total file nodes in file system as
(desc_blocks_count * groups_per_desc_block * entries_per_group).  Then, it
is calculated free inodes count as difference the total file nodes and
used inodes count.  As a result, we have such output for NILFS2:

df -i
Filesystem       Inodes   IUsed    IFree IUse% Mounted on
/dev/loop0      4194304 2114701  2079603   51% /mnt/nilfs2

Reported-by: Clemens Eisserer <linuxhippy@gmail.com>
Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Tested-by: Vyacheslav Dubeyko <slava@dubeyko.com>
Cc: Joern Engel <joern@logfs.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Vyacheslav Dubeyko
2013-07-03 15:08:05 -07:00
committed by Linus Torvalds
parent e88b815e01
commit c7ef972c44
5 changed files with 112 additions and 2 deletions

View File

@@ -397,6 +397,69 @@ nilfs_palloc_rest_groups_in_desc_block(const struct inode *inode,
max - curr + 1);
}
/**
* nilfs_palloc_count_desc_blocks - count descriptor blocks number
* @inode: inode of metadata file using this allocator
* @desc_blocks: descriptor blocks number [out]
*/
static int nilfs_palloc_count_desc_blocks(struct inode *inode,
unsigned long *desc_blocks)
{
unsigned long blknum;
int ret;
ret = nilfs_bmap_last_key(NILFS_I(inode)->i_bmap, &blknum);
if (likely(!ret))
*desc_blocks = DIV_ROUND_UP(
blknum, NILFS_MDT(inode)->mi_blocks_per_desc_block);
return ret;
}
/**
* nilfs_palloc_mdt_file_can_grow - check potential opportunity for
* MDT file growing
* @inode: inode of metadata file using this allocator
* @desc_blocks: known current descriptor blocks count
*/
static inline bool nilfs_palloc_mdt_file_can_grow(struct inode *inode,
unsigned long desc_blocks)
{
return (nilfs_palloc_groups_per_desc_block(inode) * desc_blocks) <
nilfs_palloc_groups_count(inode);
}
/**
* nilfs_palloc_count_max_entries - count max number of entries that can be
* described by descriptor blocks count
* @inode: inode of metadata file using this allocator
* @nused: current number of used entries
* @nmaxp: max number of entries [out]
*/
int nilfs_palloc_count_max_entries(struct inode *inode, u64 nused, u64 *nmaxp)
{
unsigned long desc_blocks = 0;
u64 entries_per_desc_block, nmax;
int err;
err = nilfs_palloc_count_desc_blocks(inode, &desc_blocks);
if (unlikely(err))
return err;
entries_per_desc_block = (u64)nilfs_palloc_entries_per_group(inode) *
nilfs_palloc_groups_per_desc_block(inode);
nmax = entries_per_desc_block * desc_blocks;
if (nused == nmax &&
nilfs_palloc_mdt_file_can_grow(inode, desc_blocks))
nmax += entries_per_desc_block;
if (nused > nmax)
return -ERANGE;
*nmaxp = nmax;
return 0;
}
/**
* nilfs_palloc_prepare_alloc_entry - prepare to allocate a persistent object
* @inode: inode of metadata file using this allocator