diff options
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/balloc.c | 86 | ||||
-rw-r--r-- | fs/ext3/bitmap.c | 2 | ||||
-rw-r--r-- | fs/ext3/bitmap.h | 8 | ||||
-rw-r--r-- | fs/ext3/ialloc.c | 73 | ||||
-rw-r--r-- | fs/ext3/inode.c | 17 | ||||
-rw-r--r-- | fs/ext3/namei.c | 2 | ||||
-rw-r--r-- | fs/ext3/namei.h | 8 | ||||
-rw-r--r-- | fs/ext3/resize.c | 17 | ||||
-rw-r--r-- | fs/ext3/super.c | 50 | ||||
-rw-r--r-- | fs/ext3/xattr.c | 8 |
10 files changed, 93 insertions, 178 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index e463dca..ae1148c 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c @@ -20,6 +20,8 @@ #include <linux/quotaops.h> #include <linux/buffer_head.h> +#include "bitmap.h" + /* * balloc.c contains the blocks allocation and deallocation routines */ @@ -1010,7 +1012,7 @@ retry: * allocation within the reservation window. * * This will avoid keeping on searching the reservation list again and - * again when someboday is looking for a free block (without + * again when somebody is looking for a free block (without * reservation), and there are lots of free blocks, but they are all * being reserved. * @@ -1410,18 +1412,19 @@ unsigned long ext3_count_free_blocks(struct super_block *sb) unsigned long desc_count; struct ext3_group_desc *gdp; int i; - unsigned long ngroups; + unsigned long ngroups = EXT3_SB(sb)->s_groups_count; #ifdef EXT3FS_DEBUG struct ext3_super_block *es; 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; gdp = NULL; - for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) { + + smp_rmb(); + for (i = 0; i < ngroups; i++) { gdp = ext3_get_group_desc(sb, i, NULL); if (!gdp) continue; @@ -1439,11 +1442,9 @@ unsigned long ext3_count_free_blocks(struct super_block *sb) brelse(bitmap_bh); printk("ext3_count_free_blocks: stored = %u, computed = %lu, %lu\n", le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count); - unlock_super(sb); return bitmap_count; #else desc_count = 0; - ngroups = EXT3_SB(sb)->s_groups_count; smp_rmb(); for (i = 0; i < ngroups; i++) { gdp = ext3_get_group_desc(sb, i, NULL); @@ -1516,76 +1517,3 @@ unsigned long ext3_bg_num_gdb(struct super_block *sb, int group) return EXT3_SB(sb)->s_gdb_count; } -#ifdef CONFIG_EXT3_CHECK -/* Called at mount-time, super-block is locked */ -void ext3_check_blocks_bitmap (struct super_block * sb) -{ - struct ext3_super_block *es; - unsigned long desc_count, bitmap_count, x, j; - unsigned long desc_blocks; - 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_blocks_count); - brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, i); - if (bitmap_bh == NULL) - continue; - - if (ext3_bg_has_super(sb, i) && - !ext3_test_bit(0, bitmap_bh->b_data)) - ext3_error(sb, __FUNCTION__, - "Superblock in group %d is marked free", i); - - desc_blocks = ext3_bg_num_gdb(sb, i); - for (j = 0; j < desc_blocks; j++) - if (!ext3_test_bit(j + 1, bitmap_bh->b_data)) - ext3_error(sb, __FUNCTION__, - "Descriptor block #%ld in group " - "%d is marked free", j, i); - - if (!block_in_use (le32_to_cpu(gdp->bg_block_bitmap), - sb, bitmap_bh->b_data)) - ext3_error (sb, "ext3_check_blocks_bitmap", - "Block bitmap for group %d is marked free", - i); - - if (!block_in_use (le32_to_cpu(gdp->bg_inode_bitmap), - sb, bitmap_bh->b_data)) - ext3_error (sb, "ext3_check_blocks_bitmap", - "Inode bitmap for group %d is marked free", - i); - - for (j = 0; j < EXT3_SB(sb)->s_itb_per_group; j++) - if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j, - sb, bitmap_bh->b_data)) - ext3_error (sb, "ext3_check_blocks_bitmap", - "Block #%d of the inode table in " - "group %d is marked free", j, i); - - x = ext3_count_free(bitmap_bh, sb->s_blocksize); - if (le16_to_cpu(gdp->bg_free_blocks_count) != x) - ext3_error (sb, "ext3_check_blocks_bitmap", - "Wrong free blocks count for group %d, " - "stored = %d, counted = %lu", i, - le16_to_cpu(gdp->bg_free_blocks_count), x); - bitmap_count += x; - } - brelse(bitmap_bh); - if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count) - ext3_error (sb, "ext3_check_blocks_bitmap", - "Wrong free blocks count in super block, " - "stored = %lu, counted = %lu", - (unsigned long)le32_to_cpu(es->s_free_blocks_count), - bitmap_count); -} -#endif diff --git a/fs/ext3/bitmap.c b/fs/ext3/bitmap.c index 6c419b9..5b4ba3e 100644 --- a/fs/ext3/bitmap.c +++ b/fs/ext3/bitmap.c @@ -8,7 +8,7 @@ */ #include <linux/buffer_head.h> - +#include "bitmap.h" static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; diff --git a/fs/ext3/bitmap.h b/fs/ext3/bitmap.h new file mode 100644 index 0000000..6ee503a --- /dev/null +++ b/fs/ext3/bitmap.h @@ -0,0 +1,8 @@ +/* linux/fs/ext3/bitmap.c + * + * Copyright (C) 2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * +*/ + +extern unsigned long ext3_count_free (struct buffer_head *, unsigned int ); diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 9655276..9e4a243 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -26,6 +26,7 @@ #include <asm/byteorder.h> +#include "bitmap.h" #include "xattr.h" #include "acl.h" @@ -597,27 +598,22 @@ 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); - DQUOT_DROP(inode); - goto fail2; - } + if (err) + goto fail_free_drop; + err = ext3_init_security(handle,inode, dir); - if (err) { - DQUOT_FREE_INODE(inode); - goto fail2; - } + if (err) + goto fail_free_drop; + err = ext3_mark_inode_dirty(handle, inode); if (err) { ext3_std_error(sb, err); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); - goto fail2; + goto fail_free_drop; } ext3_debug("allocating inode %lu\n", inode->i_ino); @@ -631,7 +627,11 @@ really_out: brelse(bitmap_bh); return ret; -fail2: +fail_free_drop: + DQUOT_FREE_INODE(inode); + +fail_drop: + DQUOT_DROP(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; iput(inode); @@ -705,7 +705,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; @@ -728,7 +727,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; @@ -758,44 +756,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 diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index b5177c9..8824e84 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -491,7 +491,7 @@ static unsigned long ext3_find_goal(struct inode *inode, long block, * the same format as ext3_get_branch() would do. We are calling it after * we had read the existing part of chain and partial points to the last * triple of that (one with zero ->key). Upon the exit we have the same - * picture as after the successful ext3_get_block(), excpet that in one + * picture as after the successful ext3_get_block(), except that in one * place chain is disconnected - *branch->p is still zero (we did not * set the last link), but branch->key contains the number that should * be placed into *branch->p to fill that gap. @@ -523,7 +523,6 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode, if (!nr) break; branch[n].key = cpu_to_le32(nr); - keys = n+1; /* * Get buffer_head for parent block, zero it out @@ -531,6 +530,9 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode, * parent to disk. */ bh = sb_getblk(inode->i_sb, parent); + if (!bh) + break; + keys = n+1; branch[n].bh = bh; lock_buffer(bh); BUFFER_TRACE(bh, "call get_create_access"); @@ -864,6 +866,10 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode, if (!*errp && buffer_mapped(&dummy)) { struct buffer_head *bh; bh = sb_getblk(inode->i_sb, dummy.b_blocknr); + if (!bh) { + *errp = -EIO; + goto err; + } if (buffer_new(&dummy)) { J_ASSERT(create != 0); J_ASSERT(handle != 0); @@ -896,6 +902,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode, } return bh; } +err: return NULL; } @@ -1377,8 +1384,10 @@ static int ext3_journalled_writepage(struct page *page, ClearPageChecked(page); ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, ext3_get_block); - if (ret != 0) + if (ret != 0) { + ext3_journal_stop(handle); goto out_unlock; + } ret = walk_page_buffers(handle, page_buffers(page), 0, PAGE_CACHE_SIZE, NULL, do_journal_get_write_access); @@ -1434,7 +1443,7 @@ static int ext3_invalidatepage(struct page *page, unsigned long offset) return journal_invalidatepage(journal, page, offset); } -static int ext3_releasepage(struct page *page, int wait) +static int ext3_releasepage(struct page *page, gfp_t wait) { journal_t *journal = EXT3_JOURNAL(page->mapping->host); diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 50378d8..b3c690a 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -36,6 +36,8 @@ #include <linux/quotaops.h> #include <linux/buffer_head.h> #include <linux/smp_lock.h> + +#include "namei.h" #include "xattr.h" #include "acl.h" diff --git a/fs/ext3/namei.h b/fs/ext3/namei.h new file mode 100644 index 0000000..f2ce2b0 --- /dev/null +++ b/fs/ext3/namei.h @@ -0,0 +1,8 @@ +/* linux/fs/ext3/namei.h + * + * Copyright (C) 2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * +*/ + +extern struct dentry *ext3_get_parent(struct dentry *child); diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 2c9f812..6104ad3 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c @@ -118,6 +118,8 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, int err; bh = sb_getblk(sb, blk); + if (!bh) + return ERR_PTR(-EIO); if ((err = ext3_journal_get_write_access(handle, bh))) { brelse(bh); bh = ERR_PTR(err); @@ -202,6 +204,10 @@ static int setup_new_group_blocks(struct super_block *sb, ext3_debug("update backup group %#04lx (+%d)\n", block, bit); gdb = sb_getblk(sb, block); + if (!gdb) { + err = -EIO; + goto exit_bh; + } if ((err = ext3_journal_get_write_access(handle, gdb))) { brelse(gdb); goto exit_bh; @@ -242,7 +248,7 @@ static int setup_new_group_blocks(struct super_block *sb, i < sbi->s_itb_per_group; i++, bit++, block++) { struct buffer_head *it; - ext3_debug("clear inode block %#04x (+%ld)\n", block, bit); + ext3_debug("clear inode block %#04lx (+%d)\n", block, bit); if (IS_ERR(it = bclean(handle, sb, block))) { err = PTR_ERR(it); goto exit_bh; @@ -643,8 +649,12 @@ static void update_backups(struct super_block *sb, break; bh = sb_getblk(sb, group * bpg + blk_off); - ext3_debug(sb, __FUNCTION__, "update metadata backup %#04lx\n", - bh->b_blocknr); + if (!bh) { + err = -EIO; + break; + } + ext3_debug("update metadata backup %#04lx\n", + (unsigned long)bh->b_blocknr); if ((err = ext3_journal_get_write_access(handle, bh))) break; lock_buffer(bh); @@ -757,6 +767,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) if (input->group != EXT3_SB(sb)->s_groups_count) { ext3_warning(sb, __FUNCTION__, "multiple resizers run on filesystem!\n"); + err = -EBUSY; goto exit_journal; } diff --git a/fs/ext3/super.c b/fs/ext3/super.c index a93c360..4e67306 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -36,9 +36,12 @@ #include <linux/namei.h> #include <linux/quotaops.h> #include <linux/seq_file.h> + #include <asm/uaccess.h> + #include "xattr.h" #include "acl.h" +#include "namei.h" static int ext3_load_journal(struct super_block *, struct ext3_super_block *); static int ext3_create_journal(struct super_block *, struct ext3_super_block *, @@ -510,20 +513,11 @@ static void ext3_clear_inode(struct inode *inode) kfree(rsv); } -static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) +static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb) { - struct ext3_sb_info *sbi = EXT3_SB(vfs->mnt_sb); - - if (sbi->s_mount_opt & EXT3_MOUNT_JOURNAL_DATA) - seq_puts(seq, ",data=journal"); - - if (sbi->s_mount_opt & EXT3_MOUNT_ORDERED_DATA) - seq_puts(seq, ",data=ordered"); - - if (sbi->s_mount_opt & EXT3_MOUNT_WRITEBACK_DATA) - seq_puts(seq, ",data=writeback"); - #if defined(CONFIG_QUOTA) + struct ext3_sb_info *sbi = EXT3_SB(sb); + if (sbi->s_jquota_fmt) seq_printf(seq, ",jqfmt=%s", (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0"); @@ -540,6 +534,20 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) if (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA) seq_puts(seq, ",grpquota"); #endif +} + +static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) +{ + struct super_block *sb = vfs->mnt_sb; + + if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) + seq_puts(seq, ",data=journal"); + else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) + seq_puts(seq, ",data=ordered"); + else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) + seq_puts(seq, ",data=writeback"); + + ext3_show_quota_options(seq, sb); return 0; } @@ -610,7 +618,6 @@ static struct super_operations ext3_sops = { #endif }; -struct dentry *ext3_get_parent(struct dentry *child); static struct export_operations ext3_export_ops = { .get_parent = ext3_get_parent, }; @@ -618,7 +625,7 @@ static struct export_operations ext3_export_ops = { enum { Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, - Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, + Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_commit, Opt_journal_update, Opt_journal_inum, @@ -645,7 +652,6 @@ static match_table_t tokens = { {Opt_nouid32, "nouid32"}, {Opt_nocheck, "nocheck"}, {Opt_nocheck, "check=none"}, - {Opt_check, "check"}, {Opt_debug, "debug"}, {Opt_oldalloc, "oldalloc"}, {Opt_orlov, "orlov"}, @@ -766,14 +772,6 @@ static int parse_options (char * options, struct super_block *sb, case Opt_nouid32: set_opt (sbi->s_mount_opt, NO_UID32); break; - case Opt_check: -#ifdef CONFIG_EXT3_CHECK - set_opt (sbi->s_mount_opt, CHECK); -#else - printk(KERN_ERR - "EXT3 Check option not supported\n"); -#endif - break; case Opt_nocheck: clear_opt (sbi->s_mount_opt, CHECK); break; @@ -1108,12 +1106,6 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es, } else { printk("internal journal\n"); } -#ifdef CONFIG_EXT3_CHECK - if (test_opt (sb, CHECK)) { - ext3_check_blocks_bitmap (sb); - ext3_check_inodes_bitmap (sb); - } -#endif return res; } diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 269c7b9..430de9f 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c @@ -210,7 +210,7 @@ ext3_xattr_find_entry(struct ext3_xattr_entry **pentry, int name_index, return cmp ? -ENODATA : 0; } -int +static int ext3_xattr_block_get(struct inode *inode, int name_index, const char *name, void *buffer, size_t buffer_size) { @@ -354,7 +354,7 @@ ext3_xattr_list_entries(struct inode *inode, struct ext3_xattr_entry *entry, return buffer_size - rest; } -int +static int ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size) { struct buffer_head *bh = NULL; @@ -626,7 +626,7 @@ struct ext3_xattr_block_find { struct buffer_head *bh; }; -int +static int ext3_xattr_block_find(struct inode *inode, struct ext3_xattr_info *i, struct ext3_xattr_block_find *bs) { @@ -859,7 +859,7 @@ struct ext3_xattr_ibody_find { struct ext3_iloc iloc; }; -int +static int ext3_xattr_ibody_find(struct inode *inode, struct ext3_xattr_info *i, struct ext3_xattr_ibody_find *is) { |