aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/ialloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/ialloc.c')
-rw-r--r--fs/ext4/ialloc.c90
1 files changed, 80 insertions, 10 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 8bf5999875ee..137193ff389b 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -70,18 +70,16 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb,
70 ext4_group_t block_group, 70 ext4_group_t block_group,
71 struct ext4_group_desc *gdp) 71 struct ext4_group_desc *gdp)
72{ 72{
73 struct ext4_group_info *grp;
73 J_ASSERT_BH(bh, buffer_locked(bh)); 74 J_ASSERT_BH(bh, buffer_locked(bh));
74 75
75 /* If checksum is bad mark all blocks and inodes use to prevent 76 /* If checksum is bad mark all blocks and inodes use to prevent
76 * allocation, essentially implementing a per-group read-only flag. */ 77 * allocation, essentially implementing a per-group read-only flag. */
77 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { 78 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
78 ext4_error(sb, "Checksum bad for group %u", block_group); 79 ext4_error(sb, "Checksum bad for group %u", block_group);
79 ext4_free_group_clusters_set(sb, gdp, 0); 80 grp = ext4_get_group_info(sb, block_group);
80 ext4_free_inodes_set(sb, gdp, 0); 81 set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
81 ext4_itable_unused_set(sb, gdp, 0); 82 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
82 memset(bh->b_data, 0xff, sb->s_blocksize);
83 ext4_inode_bitmap_csum_set(sb, block_group, gdp, bh,
84 EXT4_INODES_PER_GROUP(sb) / 8);
85 return 0; 83 return 0;
86 } 84 }
87 85
@@ -117,6 +115,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
117 struct ext4_group_desc *desc; 115 struct ext4_group_desc *desc;
118 struct buffer_head *bh = NULL; 116 struct buffer_head *bh = NULL;
119 ext4_fsblk_t bitmap_blk; 117 ext4_fsblk_t bitmap_blk;
118 struct ext4_group_info *grp;
120 119
121 desc = ext4_get_group_desc(sb, block_group, NULL); 120 desc = ext4_get_group_desc(sb, block_group, NULL);
122 if (!desc) 121 if (!desc)
@@ -185,6 +184,8 @@ verify:
185 put_bh(bh); 184 put_bh(bh);
186 ext4_error(sb, "Corrupt inode bitmap - block_group = %u, " 185 ext4_error(sb, "Corrupt inode bitmap - block_group = %u, "
187 "inode_bitmap = %llu", block_group, bitmap_blk); 186 "inode_bitmap = %llu", block_group, bitmap_blk);
187 grp = ext4_get_group_info(sb, block_group);
188 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
188 return NULL; 189 return NULL;
189 } 190 }
190 ext4_unlock_group(sb, block_group); 191 ext4_unlock_group(sb, block_group);
@@ -221,6 +222,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
221 struct ext4_super_block *es; 222 struct ext4_super_block *es;
222 struct ext4_sb_info *sbi; 223 struct ext4_sb_info *sbi;
223 int fatal = 0, err, count, cleared; 224 int fatal = 0, err, count, cleared;
225 struct ext4_group_info *grp;
224 226
225 if (!sb) { 227 if (!sb) {
226 printk(KERN_ERR "EXT4-fs: %s:%d: inode on " 228 printk(KERN_ERR "EXT4-fs: %s:%d: inode on "
@@ -266,7 +268,9 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
266 block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); 268 block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
267 bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb); 269 bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
268 bitmap_bh = ext4_read_inode_bitmap(sb, block_group); 270 bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
269 if (!bitmap_bh) 271 /* Don't bother if the inode bitmap is corrupt. */
272 grp = ext4_get_group_info(sb, block_group);
273 if (unlikely(EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) || !bitmap_bh)
270 goto error_return; 274 goto error_return;
271 275
272 BUFFER_TRACE(bitmap_bh, "get_write_access"); 276 BUFFER_TRACE(bitmap_bh, "get_write_access");
@@ -315,8 +319,10 @@ out:
315 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); 319 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
316 if (!fatal) 320 if (!fatal)
317 fatal = err; 321 fatal = err;
318 } else 322 } else {
319 ext4_error(sb, "bit already cleared for inode %lu", ino); 323 ext4_error(sb, "bit already cleared for inode %lu", ino);
324 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
325 }
320 326
321error_return: 327error_return:
322 brelse(bitmap_bh); 328 brelse(bitmap_bh);
@@ -625,6 +631,51 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
625} 631}
626 632
627/* 633/*
634 * In no journal mode, if an inode has recently been deleted, we want
635 * to avoid reusing it until we're reasonably sure the inode table
636 * block has been written back to disk. (Yes, these values are
637 * somewhat arbitrary...)
638 */
639#define RECENTCY_MIN 5
640#define RECENTCY_DIRTY 30
641
642static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino)
643{
644 struct ext4_group_desc *gdp;
645 struct ext4_inode *raw_inode;
646 struct buffer_head *bh;
647 unsigned long dtime, now;
648 int inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
649 int offset, ret = 0, recentcy = RECENTCY_MIN;
650
651 gdp = ext4_get_group_desc(sb, group, NULL);
652 if (unlikely(!gdp))
653 return 0;
654
655 bh = sb_getblk(sb, ext4_inode_table(sb, gdp) +
656 (ino / inodes_per_block));
657 if (unlikely(!bh) || !buffer_uptodate(bh))
658 /*
659 * If the block is not in the buffer cache, then it
660 * must have been written out.
661 */
662 goto out;
663
664 offset = (ino % inodes_per_block) * EXT4_INODE_SIZE(sb);
665 raw_inode = (struct ext4_inode *) (bh->b_data + offset);
666 dtime = le32_to_cpu(raw_inode->i_dtime);
667 now = get_seconds();
668 if (buffer_dirty(bh))
669 recentcy += RECENTCY_DIRTY;
670
671 if (dtime && (dtime < now) && (now < dtime + recentcy))
672 ret = 1;
673out:
674 brelse(bh);
675 return ret;
676}
677
678/*
628 * There are two policies for allocating an inode. If the new inode is 679 * There are two policies for allocating an inode. If the new inode is
629 * a directory, then a forward search is made for a block group with both 680 * a directory, then a forward search is made for a block group with both
630 * free space and a low directory-to-inode ratio; if that fails, then of 681 * free space and a low directory-to-inode ratio; if that fails, then of
@@ -652,6 +703,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
652 struct inode *ret; 703 struct inode *ret;
653 ext4_group_t i; 704 ext4_group_t i;
654 ext4_group_t flex_group; 705 ext4_group_t flex_group;
706 struct ext4_group_info *grp;
655 707
656 /* Cannot create files in a deleted directory */ 708 /* Cannot create files in a deleted directory */
657 if (!dir || !dir->i_nlink) 709 if (!dir || !dir->i_nlink)
@@ -725,10 +777,22 @@ got_group:
725 continue; 777 continue;
726 } 778 }
727 779
780 grp = ext4_get_group_info(sb, group);
781 /* Skip groups with already-known suspicious inode tables */
782 if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
783 if (++group == ngroups)
784 group = 0;
785 continue;
786 }
787
728 brelse(inode_bitmap_bh); 788 brelse(inode_bitmap_bh);
729 inode_bitmap_bh = ext4_read_inode_bitmap(sb, group); 789 inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);
730 if (!inode_bitmap_bh) 790 /* Skip groups with suspicious inode tables */
731 goto out; 791 if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp) || !inode_bitmap_bh) {
792 if (++group == ngroups)
793 group = 0;
794 continue;
795 }
732 796
733repeat_in_this_group: 797repeat_in_this_group:
734 ino = ext4_find_next_zero_bit((unsigned long *) 798 ino = ext4_find_next_zero_bit((unsigned long *)
@@ -741,6 +805,11 @@ repeat_in_this_group:
741 "inode=%lu", ino + 1); 805 "inode=%lu", ino + 1);
742 continue; 806 continue;
743 } 807 }
808 if ((EXT4_SB(sb)->s_journal == NULL) &&
809 recently_deleted(sb, group, ino)) {
810 ino++;
811 goto next_inode;
812 }
744 if (!handle) { 813 if (!handle) {
745 BUG_ON(nblocks <= 0); 814 BUG_ON(nblocks <= 0);
746 handle = __ext4_journal_start_sb(dir->i_sb, line_no, 815 handle = __ext4_journal_start_sb(dir->i_sb, line_no,
@@ -764,6 +833,7 @@ repeat_in_this_group:
764 ino++; /* the inode bitmap is zero-based */ 833 ino++; /* the inode bitmap is zero-based */
765 if (!ret2) 834 if (!ret2)
766 goto got; /* we grabbed the inode! */ 835 goto got; /* we grabbed the inode! */
836next_inode:
767 if (ino < EXT4_INODES_PER_GROUP(sb)) 837 if (ino < EXT4_INODES_PER_GROUP(sb))
768 goto repeat_in_this_group; 838 goto repeat_in_this_group;
769next_group: 839next_group: