summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2015-11-06 19:31:56 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-06 20:50:42 -0500
commitd0c14a9ee79467cd6a04b281577e1e6f74806ab2 (patch)
treea757000613b5d690b972ead91eb5a5adefc8c4b5
parentda019954dd821682d6b2a8330c9c90acb943c456 (diff)
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>
-rw-r--r--fs/nilfs2/alloc.c91
-rw-r--r--fs/nilfs2/alloc.h1
2 files changed, 75 insertions, 17 deletions
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c
index 225b79768865..b335a32e9561 100644
--- a/fs/nilfs2/alloc.c
+++ b/fs/nilfs2/alloc.c
@@ -154,13 +154,17 @@ nilfs_palloc_group_desc_nfrees(const struct nilfs_palloc_group_desc *desc,
154 * @lock: spin lock protecting @desc 154 * @lock: spin lock protecting @desc
155 * @n: delta to be added 155 * @n: delta to be added
156 */ 156 */
157static void 157static u32
158nilfs_palloc_group_desc_add_entries(struct nilfs_palloc_group_desc *desc, 158nilfs_palloc_group_desc_add_entries(struct nilfs_palloc_group_desc *desc,
159 spinlock_t *lock, u32 n) 159 spinlock_t *lock, u32 n)
160{ 160{
161 u32 nfree;
162
161 spin_lock(lock); 163 spin_lock(lock);
162 le32_add_cpu(&desc->pg_nfrees, n); 164 le32_add_cpu(&desc->pg_nfrees, n);
165 nfree = le32_to_cpu(desc->pg_nfrees);
163 spin_unlock(lock); 166 spin_unlock(lock);
167 return nfree;
164} 168}
165 169
166/** 170/**
@@ -735,12 +739,18 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
735 unsigned char *bitmap; 739 unsigned char *bitmap;
736 void *desc_kaddr, *bitmap_kaddr; 740 void *desc_kaddr, *bitmap_kaddr;
737 unsigned long group, group_offset; 741 unsigned long group, group_offset;
738 __u64 group_min_nr; 742 __u64 group_min_nr, last_nrs[8];
739 const unsigned long epg = nilfs_palloc_entries_per_group(inode); 743 const unsigned long epg = nilfs_palloc_entries_per_group(inode);
744 const unsigned epb = NILFS_MDT(inode)->mi_entries_per_block;
745 unsigned entry_start, end, pos;
740 spinlock_t *lock; 746 spinlock_t *lock;
741 int i, j, n, ret; 747 int i, j, k, ret;
748 u32 nfree;
742 749
743 for (i = 0; i < nitems; i = j) { 750 for (i = 0; i < nitems; i = j) {
751 int change_group = false;
752 int nempties = 0, n = 0;
753
744 group = nilfs_palloc_group(inode, entry_nrs[i], &group_offset); 754 group = nilfs_palloc_group(inode, entry_nrs[i], &group_offset);
745 ret = nilfs_palloc_get_desc_block(inode, group, 0, &desc_bh); 755 ret = nilfs_palloc_get_desc_block(inode, group, 0, &desc_bh);
746 if (ret < 0) 756 if (ret < 0)
@@ -755,17 +765,13 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
755 /* Get the first entry number of the group */ 765 /* Get the first entry number of the group */
756 group_min_nr = (__u64)group * epg; 766 group_min_nr = (__u64)group * epg;
757 767
758 desc_kaddr = kmap(desc_bh->b_page);
759 desc = nilfs_palloc_block_get_group_desc(
760 inode, group, desc_bh, desc_kaddr);
761 bitmap_kaddr = kmap(bitmap_bh->b_page); 768 bitmap_kaddr = kmap(bitmap_bh->b_page);
762 bitmap = bitmap_kaddr + bh_offset(bitmap_bh); 769 bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
763 lock = nilfs_mdt_bgl_lock(inode, group); 770 lock = nilfs_mdt_bgl_lock(inode, group);
764 for (j = i, n = 0; 771
765 j < nitems && entry_nrs[j] >= group_min_nr && 772 j = i;
766 entry_nrs[j] < group_min_nr + epg; 773 entry_start = rounddown(group_offset, epb);
767 j++) { 774 do {
768 group_offset = entry_nrs[j] - group_min_nr;
769 if (!nilfs_clear_bit_atomic(lock, group_offset, 775 if (!nilfs_clear_bit_atomic(lock, group_offset,
770 bitmap)) { 776 bitmap)) {
771 nilfs_warning(inode->i_sb, __func__, 777 nilfs_warning(inode->i_sb, __func__,
@@ -775,18 +781,69 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
775 } else { 781 } else {
776 n++; 782 n++;
777 } 783 }
778 } 784
779 nilfs_palloc_group_desc_add_entries(desc, lock, n); 785 j++;
786 if (j >= nitems || entry_nrs[j] < group_min_nr ||
787 entry_nrs[j] >= group_min_nr + epg) {
788 change_group = true;
789 } else {
790 group_offset = entry_nrs[j] - group_min_nr;
791 if (group_offset >= entry_start &&
792 group_offset < entry_start + epb) {
793 /* This entry is in the same block */
794 continue;
795 }
796 }
797
798 /* Test if the entry block is empty or not */
799 end = entry_start + epb;
800 pos = nilfs_find_next_bit(bitmap, end, entry_start);
801 if (pos >= end) {
802 last_nrs[nempties++] = entry_nrs[j - 1];
803 if (nempties >= ARRAY_SIZE(last_nrs))
804 break;
805 }
806
807 if (change_group)
808 break;
809
810 /* Go on to the next entry block */
811 entry_start = rounddown(group_offset, epb);
812 } while (true);
780 813
781 kunmap(bitmap_bh->b_page); 814 kunmap(bitmap_bh->b_page);
782 kunmap(desc_bh->b_page); 815 mark_buffer_dirty(bitmap_bh);
816 brelse(bitmap_bh);
783 817
818 for (k = 0; k < nempties; k++) {
819 ret = nilfs_palloc_delete_entry_block(inode,
820 last_nrs[k]);
821 if (ret && ret != -ENOENT) {
822 nilfs_warning(inode->i_sb, __func__,
823 "failed to delete block of entry %llu: ino=%lu, err=%d\n",
824 (unsigned long long)last_nrs[k],
825 (unsigned long)inode->i_ino, ret);
826 }
827 }
828
829 desc_kaddr = kmap_atomic(desc_bh->b_page);
830 desc = nilfs_palloc_block_get_group_desc(
831 inode, group, desc_bh, desc_kaddr);
832 nfree = nilfs_palloc_group_desc_add_entries(desc, lock, n);
833 kunmap_atomic(desc_kaddr);
784 mark_buffer_dirty(desc_bh); 834 mark_buffer_dirty(desc_bh);
785 mark_buffer_dirty(bitmap_bh);
786 nilfs_mdt_mark_dirty(inode); 835 nilfs_mdt_mark_dirty(inode);
787
788 brelse(bitmap_bh);
789 brelse(desc_bh); 836 brelse(desc_bh);
837
838 if (nfree == nilfs_palloc_entries_per_group(inode)) {
839 ret = nilfs_palloc_delete_bitmap_block(inode, group);
840 if (ret && ret != -ENOENT) {
841 nilfs_warning(inode->i_sb, __func__,
842 "failed to delete bitmap block of group %lu: ino=%lu, err=%d\n",
843 group,
844 (unsigned long)inode->i_ino, ret);
845 }
846 }
790 } 847 }
791 return 0; 848 return 0;
792} 849}
diff --git a/fs/nilfs2/alloc.h b/fs/nilfs2/alloc.h
index 4bd6451b5703..6e6f49aa53df 100644
--- a/fs/nilfs2/alloc.h
+++ b/fs/nilfs2/alloc.h
@@ -77,6 +77,7 @@ int nilfs_palloc_freev(struct inode *, __u64 *, size_t);
77#define nilfs_set_bit_atomic ext2_set_bit_atomic 77#define nilfs_set_bit_atomic ext2_set_bit_atomic
78#define nilfs_clear_bit_atomic ext2_clear_bit_atomic 78#define nilfs_clear_bit_atomic ext2_clear_bit_atomic
79#define nilfs_find_next_zero_bit find_next_zero_bit_le 79#define nilfs_find_next_zero_bit find_next_zero_bit_le
80#define nilfs_find_next_bit find_next_bit_le
80 81
81/** 82/**
82 * struct nilfs_bh_assoc - block offset and buffer head association 83 * struct nilfs_bh_assoc - block offset and buffer head association