linux/fs/nilfs2/alloc.h
Ryusuke Konishi d0c14a9ee7 nilfs2: free unused dat file blocks during garbage collection
As a nilfs2 volume ages, the amount of available disk space decreases
little by little due to bloat of DAT (disk address translation) metadata
file.  Even if we delete all files in a file system and free their block
addresses from the DAT file through a garbage collection, empty DAT blocks
are not freed.

This fixes the issue by extending the deallocator of block addresses so
that empty data blocks and empty bitmap blocks of DAT are deleted.

The following comparison shows the effect of this patch.  Each shows disk
amount information of a nilfs2 volume that we cleaned out by deleting all
files and running gc after having filled 90% of its capacity.

Before:
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/sda1      500105212  3022844 472072192   1% /test

After:
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/sda1      500105212    16380 475078656   1% /test

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-11-06 17:50:42 -08:00

111 lines
3.9 KiB
C

/*
* alloc.h - persistent object (dat entry/disk inode) allocator/deallocator
*
* Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Original code was written by Koji Sato <koji@osrg.net>.
* Two allocators were unified by Ryusuke Konishi <ryusuke@osrg.net>,
* Amagai Yoshiji <amagai@osrg.net>.
*/
#ifndef _NILFS_ALLOC_H
#define _NILFS_ALLOC_H
#include <linux/types.h>
#include <linux/buffer_head.h>
#include <linux/fs.h>
/**
* nilfs_palloc_entries_per_group - get the number of entries per group
* @inode: inode of metadata file using this allocator
*
* The number of entries per group is defined by the number of bits
* that a bitmap block can maintain.
*/
static inline unsigned long
nilfs_palloc_entries_per_group(const struct inode *inode)
{
return 1UL << (inode->i_blkbits + 3 /* log2(8 = CHAR_BITS) */);
}
int nilfs_palloc_init_blockgroup(struct inode *, unsigned);
int nilfs_palloc_get_entry_block(struct inode *, __u64, int,
struct buffer_head **);
void *nilfs_palloc_block_get_entry(const struct inode *, __u64,
const struct buffer_head *, void *);
int nilfs_palloc_count_max_entries(struct inode *, u64, u64 *);
/**
* nilfs_palloc_req - persistent allocator request and reply
* @pr_entry_nr: entry number (vblocknr or inode number)
* @pr_desc_bh: buffer head of the buffer containing block group descriptors
* @pr_bitmap_bh: buffer head of the buffer containing a block group bitmap
* @pr_entry_bh: buffer head of the buffer containing translation entries
*/
struct nilfs_palloc_req {
__u64 pr_entry_nr;
struct buffer_head *pr_desc_bh;
struct buffer_head *pr_bitmap_bh;
struct buffer_head *pr_entry_bh;
};
int nilfs_palloc_prepare_alloc_entry(struct inode *,
struct nilfs_palloc_req *);
void nilfs_palloc_commit_alloc_entry(struct inode *,
struct nilfs_palloc_req *);
void nilfs_palloc_abort_alloc_entry(struct inode *, struct nilfs_palloc_req *);
void nilfs_palloc_commit_free_entry(struct inode *, struct nilfs_palloc_req *);
int nilfs_palloc_prepare_free_entry(struct inode *, struct nilfs_palloc_req *);
void nilfs_palloc_abort_free_entry(struct inode *, struct nilfs_palloc_req *);
int nilfs_palloc_freev(struct inode *, __u64 *, size_t);
#define nilfs_set_bit_atomic ext2_set_bit_atomic
#define nilfs_clear_bit_atomic ext2_clear_bit_atomic
#define nilfs_find_next_zero_bit find_next_zero_bit_le
#define nilfs_find_next_bit find_next_bit_le
/**
* struct nilfs_bh_assoc - block offset and buffer head association
* @blkoff: block offset
* @bh: buffer head
*/
struct nilfs_bh_assoc {
unsigned long blkoff;
struct buffer_head *bh;
};
/**
* struct nilfs_palloc_cache - persistent object allocator cache
* @lock: cache protecting lock
* @prev_desc: blockgroup descriptors cache
* @prev_bitmap: blockgroup bitmap cache
* @prev_entry: translation entries cache
*/
struct nilfs_palloc_cache {
spinlock_t lock;
struct nilfs_bh_assoc prev_desc;
struct nilfs_bh_assoc prev_bitmap;
struct nilfs_bh_assoc prev_entry;
};
void nilfs_palloc_setup_cache(struct inode *inode,
struct nilfs_palloc_cache *cache);
void nilfs_palloc_clear_cache(struct inode *inode);
void nilfs_palloc_destroy_cache(struct inode *inode);
#endif /* _NILFS_ALLOC_H */