X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fext3%2Fialloc.c;h=9885ff8fa1500ec235a6301046efd4aabb21c3dd;hb=refs%2Fheads%2Fvserver;hp=58dbb6e606179ee51d871ff9196d69f34392c3ee;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 58dbb6e60..9885ff8fa 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -126,9 +127,9 @@ void ext3_free_inode (handle_t *handle, struct inode * inode) */ DQUOT_INIT(inode); ext3_xattr_delete_inode(handle, inode); - DLIMIT_FREE_INODE(sb, inode->i_xid); DQUOT_FREE_INODE(inode); DQUOT_DROP(inode); + DLIMIT_FREE_INODE(inode); is_directory = S_ISDIR(inode->i_mode); @@ -204,7 +205,7 @@ error_return: static int find_group_dir(struct super_block *sb, struct inode *parent) { int ngroups = EXT3_SB(sb)->s_groups_count; - int freei, avefreei; + unsigned int freei, avefreei; struct ext3_group_desc *desc, *best_desc = NULL; struct buffer_head *bh; int group, best_group = -1; @@ -218,7 +219,7 @@ static int find_group_dir(struct super_block *sb, struct inode *parent) continue; if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei) continue; - if (!best_desc || + if (!best_desc || (le16_to_cpu(desc->bg_free_blocks_count) > le16_to_cpu(best_desc->bg_free_blocks_count))) { best_group = group; @@ -228,30 +229,30 @@ static int find_group_dir(struct super_block *sb, struct inode *parent) return best_group; } -/* - * Orlov's allocator for directories. - * +/* + * Orlov's allocator for directories. + * * We always try to spread first-level directories. * - * If there are blockgroups with both free inodes and free blocks counts - * not worse than average we return one with smallest directory count. - * Otherwise we simply return a random group. - * - * For the rest rules look so: - * - * It's OK to put directory into a group unless - * it has too many directories already (max_dirs) or - * it has too few free inodes left (min_inodes) or - * it has too few free blocks left (min_blocks) or - * it's already running too large debt (max_debt). - * Parent's group is prefered, if it doesn't satisfy these - * conditions we search cyclically through the rest. If none - * of the groups look good we just look for a group with more - * free inodes than average (starting at parent's group). - * - * Debt is incremented each time we allocate a directory and decremented - * when we allocate an inode, within 0--255. - */ + * If there are blockgroups with both free inodes and free blocks counts + * not worse than average we return one with smallest directory count. + * Otherwise we simply return a random group. + * + * For the rest rules look so: + * + * It's OK to put directory into a group unless + * it has too many directories already (max_dirs) or + * it has too few free inodes left (min_inodes) or + * it has too few free blocks left (min_blocks) or + * it's already running too large debt (max_debt). + * Parent's group is prefered, if it doesn't satisfy these + * conditions we search cyclically through the rest. If none + * of the groups look good we just look for a group with more + * free inodes than average (starting at parent's group). + * + * Debt is incremented each time we allocate a directory and decremented + * when we allocate an inode, within 0--255. + */ #define INODE_COST 64 #define BLOCK_COST 256 @@ -263,10 +264,12 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent) struct ext3_super_block *es = sbi->s_es; int ngroups = sbi->s_groups_count; int inodes_per_group = EXT3_INODES_PER_GROUP(sb); - int freei, avefreei; - int freeb, avefreeb; - int blocks_per_dir, ndirs; - int max_debt, max_dirs, min_blocks, min_inodes; + unsigned int freei, avefreei; + ext3_fsblk_t freeb, avefreeb; + ext3_fsblk_t blocks_per_dir; + unsigned int ndirs; + int max_debt, max_dirs, min_inodes; + ext3_grpblk_t min_blocks; int group = -1, i; struct ext3_group_desc *desc; struct buffer_head *bh; @@ -309,7 +312,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent) min_inodes = avefreei - inodes_per_group / 4; min_blocks = avefreeb - EXT3_BLOCKS_PER_GROUP(sb) / 4; - max_debt = EXT3_BLOCKS_PER_GROUP(sb) / max(blocks_per_dir, BLOCK_COST); + max_debt = EXT3_BLOCKS_PER_GROUP(sb) / max(blocks_per_dir, (ext3_fsblk_t)BLOCK_COST); if (max_debt * INODE_COST > inodes_per_group) max_debt = inodes_per_group / INODE_COST; if (max_debt > 255) @@ -446,14 +449,10 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode) if (!inode) return ERR_PTR(-ENOMEM); - if (sb->s_flags & MS_TAGXID) - inode->i_xid = vx_current_xid(); - else - inode->i_xid = 0; - - if (DLIMIT_ALLOC_INODE(sb, inode->i_xid)) { + inode->i_tag = dx_current_fstag(sb); + if (DLIMIT_ALLOC_INODE(inode)) { err = -ENOSPC; - goto out; + goto out_dlimit; } ei = EXT3_I(inode); @@ -464,7 +463,7 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode) group = find_group_dir(sb, dir); else group = find_group_orlov(sb, dir); - } else + } else group = find_group_other(sb, dir); err = -ENOSPC; @@ -472,9 +471,12 @@ struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode) goto out; for (i = 0; i < sbi->s_groups_count; i++) { + err = -EIO; + gdp = ext3_get_group_desc(sb, group, &bh2); + if (!gdp) + goto fail; - err = -EIO; brelse(bitmap_bh); bitmap_bh = read_inode_bitmap(sb, group); if (!bitmap_bh) @@ -486,11 +488,9 @@ repeat_in_this_group: ino = ext3_find_next_zero_bit((unsigned long *) bitmap_bh->b_data, EXT3_INODES_PER_GROUP(sb), ino); if (ino < EXT3_INODES_PER_GROUP(sb)) { - int credits = 0; BUFFER_TRACE(bitmap_bh, "get_write_access"); - err = ext3_journal_get_write_access_credits(handle, - bitmap_bh, &credits); + err = ext3_journal_get_write_access(handle, bitmap_bh); if (err) goto fail; @@ -506,7 +506,7 @@ repeat_in_this_group: goto got; } /* we lost it */ - journal_release_buffer(handle, bitmap_bh, credits); + journal_release_buffer(handle, bitmap_bh); if (++ino < EXT3_INODES_PER_GROUP(sb)) goto repeat_in_this_group; @@ -568,13 +568,10 @@ got: inode->i_ino = ino; /* This is the optimal IO size (for stat), not the fs block size */ - inode->i_blksize = PAGE_SIZE; inode->i_blocks = 0; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; memset(ei->i_data, 0, sizeof(ei->i_data)); - ei->i_next_alloc_block = 0; - ei->i_next_alloc_goal = 0; ei->i_dir_start_lookup = 0; ei->i_disksize = 0; @@ -593,11 +590,7 @@ got: ei->i_file_acl = 0; ei->i_dir_acl = 0; ei->i_dtime = 0; - ei->i_rsv_window.rsv_start = EXT3_RESERVE_WINDOW_NOT_ALLOCATED; - ei->i_rsv_window.rsv_end = EXT3_RESERVE_WINDOW_NOT_ALLOCATED; - atomic_set(&ei->i_rsv_window.rsv_goal_size, EXT3_DEFAULT_RESERVE_BLOCKS); - atomic_set(&ei->i_rsv_window.rsv_alloc_hit, 0); - seqlock_init(&ei->i_rsv_window.rsv_seqlock); + ei->i_block_alloc_info = NULL; ei->i_block_group = group; ext3_set_inode_flags(inode); @@ -615,36 +608,43 @@ got: ret = inode; if(DQUOT_ALLOC_INODE(inode)) { - DQUOT_DROP(inode); err = -EDQUOT; - goto fail2; + goto fail_drop; } + err = ext3_init_acl(handle, inode, dir); - if (err) { - DQUOT_FREE_INODE(inode); - goto fail2; - } + if (err) + goto fail_free_drop; + + err = ext3_init_security(handle,inode, dir); + if (err) + goto fail_free_drop; + err = ext3_mark_inode_dirty(handle, inode); if (err) { ext3_std_error(sb, err); - DQUOT_FREE_INODE(inode); - goto fail2; + goto fail_free_drop; } ext3_debug("allocating inode %lu\n", inode->i_ino); goto really_out; fail: - DLIMIT_FREE_INODE(sb, inode->i_xid); ext3_std_error(sb, err); out: + DLIMIT_FREE_INODE(inode); +out_dlimit: iput(inode); ret = ERR_PTR(err); really_out: brelse(bitmap_bh); return ret; -fail2: - DLIMIT_FREE_INODE(sb, inode->i_xid); +fail_free_drop: + DQUOT_FREE_INODE(inode); + +fail_drop: + DQUOT_DROP(inode); + DLIMIT_FREE_INODE(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; iput(inode); @@ -664,7 +664,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) /* Error cases - e2fsck has already cleaned up for us */ if (ino > max_ino) { ext3_warning(sb, __FUNCTION__, - "bad orphan ino %lu! e2fsck was run?\n", ino); + "bad orphan ino %lu! e2fsck was run?", ino); goto out; } @@ -673,7 +673,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) bitmap_bh = read_inode_bitmap(sb, block_group); if (!bitmap_bh) { ext3_warning(sb, __FUNCTION__, - "inode bitmap error for orphan %lu\n", ino); + "inode bitmap error for orphan %lu", ino); goto out; } @@ -685,7 +685,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) !(inode = iget(sb, ino)) || is_bad_inode(inode) || NEXT_ORPHAN(inode) > max_ino) { ext3_warning(sb, __FUNCTION__, - "bad orphan inode %lu! e2fsck was run?\n", ino); + "bad orphan inode %lu! e2fsck was run?", ino); printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n", bit, (unsigned long long)bitmap_bh->b_blocknr, ext3_test_bit(bit, bitmap_bh->b_data)); @@ -718,7 +718,6 @@ unsigned long ext3_count_free_inodes (struct super_block * sb) unsigned long bitmap_count, x; struct buffer_head *bitmap_bh = NULL; - lock_super (sb); es = EXT3_SB(sb)->s_es; desc_count = 0; bitmap_count = 0; @@ -741,7 +740,6 @@ unsigned long ext3_count_free_inodes (struct super_block * sb) brelse(bitmap_bh); printk("ext3_count_free_inodes: stored = %u, computed = %lu, %lu\n", le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count); - unlock_super(sb); return desc_count; #else desc_count = 0; @@ -771,44 +769,3 @@ unsigned long ext3_count_dirs (struct super_block * sb) return count; } -#ifdef CONFIG_EXT3_CHECK -/* Called at mount-time, super-block is locked */ -void ext3_check_inodes_bitmap (struct super_block * sb) -{ - struct ext3_super_block * es; - unsigned long desc_count, bitmap_count, x; - struct buffer_head *bitmap_bh = NULL; - struct ext3_group_desc * gdp; - int i; - - es = EXT3_SB(sb)->s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; - for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) { - gdp = ext3_get_group_desc (sb, i, NULL); - if (!gdp) - continue; - desc_count += le16_to_cpu(gdp->bg_free_inodes_count); - brelse(bitmap_bh); - bitmap_bh = read_inode_bitmap(sb, i); - if (!bitmap_bh) - continue; - - x = ext3_count_free(bitmap_bh, EXT3_INODES_PER_GROUP(sb) / 8); - if (le16_to_cpu(gdp->bg_free_inodes_count) != x) - ext3_error (sb, "ext3_check_inodes_bitmap", - "Wrong free inodes count in group %d, " - "stored = %d, counted = %lu", i, - le16_to_cpu(gdp->bg_free_inodes_count), x); - bitmap_count += x; - } - brelse(bitmap_bh); - if (le32_to_cpu(es->s_free_inodes_count) != bitmap_count) - ext3_error (sb, "ext3_check_inodes_bitmap", - "Wrong free inodes count in super block, " - "stored = %lu, counted = %lu", - (unsigned long)le32_to_cpu(es->s_free_inodes_count), - bitmap_count); -} -#endif