diff options
| author | David Woodhouse <David.Woodhouse@intel.com> | 2008-10-13 12:13:56 -0400 |
|---|---|---|
| committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-10-13 12:13:56 -0400 |
| commit | e758936e02700ff88a0b08b722a3847b95283ef2 (patch) | |
| tree | 50c919bef1b459a778b85159d5929de95b6c4a01 /fs/ext4/ialloc.c | |
| parent | 239cfbde1f5843c4a24199f117d5f67f637d72d5 (diff) | |
| parent | 4480f15b3306f43bbb0310d461142b4e897ca45b (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
include/asm-x86/statfs.h
Diffstat (limited to 'fs/ext4/ialloc.c')
| -rw-r--r-- | fs/ext4/ialloc.c | 71 |
1 files changed, 37 insertions, 34 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index f344834bbf58..fe34d74cfb19 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -115,9 +115,11 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
| 115 | block_group, bitmap_blk); | 115 | block_group, bitmap_blk); |
| 116 | return NULL; | 116 | return NULL; |
| 117 | } | 117 | } |
| 118 | if (bh_uptodate_or_lock(bh)) | 118 | if (buffer_uptodate(bh) && |
| 119 | !(desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) | ||
| 119 | return bh; | 120 | return bh; |
| 120 | 121 | ||
| 122 | lock_buffer(bh); | ||
| 121 | spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 123 | spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); |
| 122 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { | 124 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { |
| 123 | ext4_init_inode_bitmap(sb, bh, block_group, desc); | 125 | ext4_init_inode_bitmap(sb, bh, block_group, desc); |
| @@ -154,39 +156,40 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
| 154 | * though), and then we'd have two inodes sharing the | 156 | * though), and then we'd have two inodes sharing the |
| 155 | * same inode number and space on the harddisk. | 157 | * same inode number and space on the harddisk. |
| 156 | */ | 158 | */ |
| 157 | void ext4_free_inode (handle_t *handle, struct inode * inode) | 159 | void ext4_free_inode(handle_t *handle, struct inode *inode) |
| 158 | { | 160 | { |
| 159 | struct super_block * sb = inode->i_sb; | 161 | struct super_block *sb = inode->i_sb; |
| 160 | int is_directory; | 162 | int is_directory; |
| 161 | unsigned long ino; | 163 | unsigned long ino; |
| 162 | struct buffer_head *bitmap_bh = NULL; | 164 | struct buffer_head *bitmap_bh = NULL; |
| 163 | struct buffer_head *bh2; | 165 | struct buffer_head *bh2; |
| 164 | ext4_group_t block_group; | 166 | ext4_group_t block_group; |
| 165 | unsigned long bit; | 167 | unsigned long bit; |
| 166 | struct ext4_group_desc * gdp; | 168 | struct ext4_group_desc *gdp; |
| 167 | struct ext4_super_block * es; | 169 | struct ext4_super_block *es; |
| 168 | struct ext4_sb_info *sbi; | 170 | struct ext4_sb_info *sbi; |
| 169 | int fatal = 0, err; | 171 | int fatal = 0, err; |
| 170 | ext4_group_t flex_group; | 172 | ext4_group_t flex_group; |
| 171 | 173 | ||
| 172 | if (atomic_read(&inode->i_count) > 1) { | 174 | if (atomic_read(&inode->i_count) > 1) { |
| 173 | printk ("ext4_free_inode: inode has count=%d\n", | 175 | printk(KERN_ERR "ext4_free_inode: inode has count=%d\n", |
| 174 | atomic_read(&inode->i_count)); | 176 | atomic_read(&inode->i_count)); |
| 175 | return; | 177 | return; |
| 176 | } | 178 | } |
| 177 | if (inode->i_nlink) { | 179 | if (inode->i_nlink) { |
| 178 | printk ("ext4_free_inode: inode has nlink=%d\n", | 180 | printk(KERN_ERR "ext4_free_inode: inode has nlink=%d\n", |
| 179 | inode->i_nlink); | 181 | inode->i_nlink); |
| 180 | return; | 182 | return; |
| 181 | } | 183 | } |
| 182 | if (!sb) { | 184 | if (!sb) { |
| 183 | printk("ext4_free_inode: inode on nonexistent device\n"); | 185 | printk(KERN_ERR "ext4_free_inode: inode on " |
| 186 | "nonexistent device\n"); | ||
| 184 | return; | 187 | return; |
| 185 | } | 188 | } |
| 186 | sbi = EXT4_SB(sb); | 189 | sbi = EXT4_SB(sb); |
| 187 | 190 | ||
| 188 | ino = inode->i_ino; | 191 | ino = inode->i_ino; |
| 189 | ext4_debug ("freeing inode %lu\n", ino); | 192 | ext4_debug("freeing inode %lu\n", ino); |
| 190 | 193 | ||
| 191 | /* | 194 | /* |
| 192 | * Note: we must free any quota before locking the superblock, | 195 | * Note: we must free any quota before locking the superblock, |
| @@ -200,12 +203,12 @@ void ext4_free_inode (handle_t *handle, struct inode * inode) | |||
| 200 | is_directory = S_ISDIR(inode->i_mode); | 203 | is_directory = S_ISDIR(inode->i_mode); |
| 201 | 204 | ||
| 202 | /* Do this BEFORE marking the inode not in use or returning an error */ | 205 | /* Do this BEFORE marking the inode not in use or returning an error */ |
| 203 | clear_inode (inode); | 206 | clear_inode(inode); |
| 204 | 207 | ||
| 205 | es = EXT4_SB(sb)->s_es; | 208 | es = EXT4_SB(sb)->s_es; |
| 206 | if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { | 209 | if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { |
| 207 | ext4_error (sb, "ext4_free_inode", | 210 | ext4_error(sb, "ext4_free_inode", |
| 208 | "reserved or nonexistent inode %lu", ino); | 211 | "reserved or nonexistent inode %lu", ino); |
| 209 | goto error_return; | 212 | goto error_return; |
| 210 | } | 213 | } |
| 211 | block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); | 214 | block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); |
| @@ -222,10 +225,10 @@ void ext4_free_inode (handle_t *handle, struct inode * inode) | |||
| 222 | /* Ok, now we can actually update the inode bitmaps.. */ | 225 | /* Ok, now we can actually update the inode bitmaps.. */ |
| 223 | if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), | 226 | if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), |
| 224 | bit, bitmap_bh->b_data)) | 227 | bit, bitmap_bh->b_data)) |
| 225 | ext4_error (sb, "ext4_free_inode", | 228 | ext4_error(sb, "ext4_free_inode", |
| 226 | "bit already cleared for inode %lu", ino); | 229 | "bit already cleared for inode %lu", ino); |
| 227 | else { | 230 | else { |
| 228 | gdp = ext4_get_group_desc (sb, block_group, &bh2); | 231 | gdp = ext4_get_group_desc(sb, block_group, &bh2); |
| 229 | 232 | ||
| 230 | BUFFER_TRACE(bh2, "get_write_access"); | 233 | BUFFER_TRACE(bh2, "get_write_access"); |
| 231 | fatal = ext4_journal_get_write_access(handle, bh2); | 234 | fatal = ext4_journal_get_write_access(handle, bh2); |
| @@ -287,7 +290,7 @@ static int find_group_dir(struct super_block *sb, struct inode *parent, | |||
| 287 | avefreei = freei / ngroups; | 290 | avefreei = freei / ngroups; |
| 288 | 291 | ||
| 289 | for (group = 0; group < ngroups; group++) { | 292 | for (group = 0; group < ngroups; group++) { |
| 290 | desc = ext4_get_group_desc (sb, group, NULL); | 293 | desc = ext4_get_group_desc(sb, group, NULL); |
| 291 | if (!desc || !desc->bg_free_inodes_count) | 294 | if (!desc || !desc->bg_free_inodes_count) |
| 292 | continue; | 295 | continue; |
| 293 | if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei) | 296 | if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei) |
| @@ -576,16 +579,16 @@ static int find_group_other(struct super_block *sb, struct inode *parent, | |||
| 576 | * For other inodes, search forward from the parent directory's block | 579 | * For other inodes, search forward from the parent directory's block |
| 577 | * group to find a free inode. | 580 | * group to find a free inode. |
| 578 | */ | 581 | */ |
| 579 | struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) | 582 | struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) |
| 580 | { | 583 | { |
| 581 | struct super_block *sb; | 584 | struct super_block *sb; |
| 582 | struct buffer_head *bitmap_bh = NULL; | 585 | struct buffer_head *bitmap_bh = NULL; |
| 583 | struct buffer_head *bh2; | 586 | struct buffer_head *bh2; |
| 584 | ext4_group_t group = 0; | 587 | ext4_group_t group = 0; |
| 585 | unsigned long ino = 0; | 588 | unsigned long ino = 0; |
| 586 | struct inode * inode; | 589 | struct inode *inode; |
| 587 | struct ext4_group_desc * gdp = NULL; | 590 | struct ext4_group_desc *gdp = NULL; |
| 588 | struct ext4_super_block * es; | 591 | struct ext4_super_block *es; |
| 589 | struct ext4_inode_info *ei; | 592 | struct ext4_inode_info *ei; |
| 590 | struct ext4_sb_info *sbi; | 593 | struct ext4_sb_info *sbi; |
| 591 | int ret2, err = 0; | 594 | int ret2, err = 0; |
| @@ -613,7 +616,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) | |||
| 613 | } | 616 | } |
| 614 | 617 | ||
| 615 | if (S_ISDIR(mode)) { | 618 | if (S_ISDIR(mode)) { |
| 616 | if (test_opt (sb, OLDALLOC)) | 619 | if (test_opt(sb, OLDALLOC)) |
| 617 | ret2 = find_group_dir(sb, dir, &group); | 620 | ret2 = find_group_dir(sb, dir, &group); |
| 618 | else | 621 | else |
| 619 | ret2 = find_group_orlov(sb, dir, &group); | 622 | ret2 = find_group_orlov(sb, dir, &group); |
| @@ -783,7 +786,7 @@ got: | |||
| 783 | } | 786 | } |
| 784 | 787 | ||
| 785 | inode->i_uid = current->fsuid; | 788 | inode->i_uid = current->fsuid; |
| 786 | if (test_opt (sb, GRPID)) | 789 | if (test_opt(sb, GRPID)) |
| 787 | inode->i_gid = dir->i_gid; | 790 | inode->i_gid = dir->i_gid; |
| 788 | else if (dir->i_mode & S_ISGID) { | 791 | else if (dir->i_mode & S_ISGID) { |
| 789 | inode->i_gid = dir->i_gid; | 792 | inode->i_gid = dir->i_gid; |
| @@ -816,7 +819,6 @@ got: | |||
| 816 | ei->i_flags &= ~EXT4_DIRSYNC_FL; | 819 | ei->i_flags &= ~EXT4_DIRSYNC_FL; |
| 817 | ei->i_file_acl = 0; | 820 | ei->i_file_acl = 0; |
| 818 | ei->i_dtime = 0; | 821 | ei->i_dtime = 0; |
| 819 | ei->i_block_alloc_info = NULL; | ||
| 820 | ei->i_block_group = group; | 822 | ei->i_block_group = group; |
| 821 | 823 | ||
| 822 | ext4_set_inode_flags(inode); | 824 | ext4_set_inode_flags(inode); |
| @@ -832,7 +834,7 @@ got: | |||
| 832 | ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize; | 834 | ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize; |
| 833 | 835 | ||
| 834 | ret = inode; | 836 | ret = inode; |
| 835 | if(DQUOT_ALLOC_INODE(inode)) { | 837 | if (DQUOT_ALLOC_INODE(inode)) { |
| 836 | err = -EDQUOT; | 838 | err = -EDQUOT; |
| 837 | goto fail_drop; | 839 | goto fail_drop; |
| 838 | } | 840 | } |
| @@ -841,7 +843,7 @@ got: | |||
| 841 | if (err) | 843 | if (err) |
| 842 | goto fail_free_drop; | 844 | goto fail_free_drop; |
| 843 | 845 | ||
| 844 | err = ext4_init_security(handle,inode, dir); | 846 | err = ext4_init_security(handle, inode, dir); |
| 845 | if (err) | 847 | if (err) |
| 846 | goto fail_free_drop; | 848 | goto fail_free_drop; |
| 847 | 849 | ||
| @@ -959,7 +961,7 @@ error: | |||
| 959 | return ERR_PTR(err); | 961 | return ERR_PTR(err); |
| 960 | } | 962 | } |
| 961 | 963 | ||
| 962 | unsigned long ext4_count_free_inodes (struct super_block * sb) | 964 | unsigned long ext4_count_free_inodes(struct super_block *sb) |
| 963 | { | 965 | { |
| 964 | unsigned long desc_count; | 966 | unsigned long desc_count; |
| 965 | struct ext4_group_desc *gdp; | 967 | struct ext4_group_desc *gdp; |
| @@ -974,7 +976,7 @@ unsigned long ext4_count_free_inodes (struct super_block * sb) | |||
| 974 | bitmap_count = 0; | 976 | bitmap_count = 0; |
| 975 | gdp = NULL; | 977 | gdp = NULL; |
| 976 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 978 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { |
| 977 | gdp = ext4_get_group_desc (sb, i, NULL); | 979 | gdp = ext4_get_group_desc(sb, i, NULL); |
| 978 | if (!gdp) | 980 | if (!gdp) |
| 979 | continue; | 981 | continue; |
| 980 | desc_count += le16_to_cpu(gdp->bg_free_inodes_count); | 982 | desc_count += le16_to_cpu(gdp->bg_free_inodes_count); |
| @@ -989,13 +991,14 @@ unsigned long ext4_count_free_inodes (struct super_block * sb) | |||
| 989 | bitmap_count += x; | 991 | bitmap_count += x; |
| 990 | } | 992 | } |
| 991 | brelse(bitmap_bh); | 993 | brelse(bitmap_bh); |
| 992 | printk("ext4_count_free_inodes: stored = %u, computed = %lu, %lu\n", | 994 | printk(KERN_DEBUG "ext4_count_free_inodes: " |
| 993 | le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count); | 995 | "stored = %u, computed = %lu, %lu\n", |
| 996 | le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count); | ||
| 994 | return desc_count; | 997 | return desc_count; |
| 995 | #else | 998 | #else |
| 996 | desc_count = 0; | 999 | desc_count = 0; |
| 997 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 1000 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { |
| 998 | gdp = ext4_get_group_desc (sb, i, NULL); | 1001 | gdp = ext4_get_group_desc(sb, i, NULL); |
| 999 | if (!gdp) | 1002 | if (!gdp) |
| 1000 | continue; | 1003 | continue; |
| 1001 | desc_count += le16_to_cpu(gdp->bg_free_inodes_count); | 1004 | desc_count += le16_to_cpu(gdp->bg_free_inodes_count); |
| @@ -1006,13 +1009,13 @@ unsigned long ext4_count_free_inodes (struct super_block * sb) | |||
| 1006 | } | 1009 | } |
| 1007 | 1010 | ||
| 1008 | /* Called at mount-time, super-block is locked */ | 1011 | /* Called at mount-time, super-block is locked */ |
| 1009 | unsigned long ext4_count_dirs (struct super_block * sb) | 1012 | unsigned long ext4_count_dirs(struct super_block * sb) |
| 1010 | { | 1013 | { |
| 1011 | unsigned long count = 0; | 1014 | unsigned long count = 0; |
| 1012 | ext4_group_t i; | 1015 | ext4_group_t i; |
| 1013 | 1016 | ||
| 1014 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 1017 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { |
| 1015 | struct ext4_group_desc *gdp = ext4_get_group_desc (sb, i, NULL); | 1018 | struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); |
| 1016 | if (!gdp) | 1019 | if (!gdp) |
| 1017 | continue; | 1020 | continue; |
| 1018 | count += le16_to_cpu(gdp->bg_used_dirs_count); | 1021 | count += le16_to_cpu(gdp->bg_used_dirs_count); |
