X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fext2%2Fsuper.c;fp=fs%2Fext2%2Fsuper.c;h=6bd5bfda6b93ff07fb7cdee959613bce6280271a;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=22993252ed5c62a415dcbb1874014203c7302f45;hpb=4e76c8a9fa413ccc09d3f7f664183dcce3555d57;p=linux-2.6.git diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 22993252e..6bd5bfda6 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -16,7 +16,6 @@ * David S. Miller (davem@caip.rutgers.edu), 1995 */ -#include #include #include #include @@ -39,7 +38,7 @@ static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es); static int ext2_remount (struct super_block * sb, int * flags, char * data); -static int ext2_statfs (struct super_block * sb, struct kstatfs * buf); +static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf); void ext2_error (struct super_block * sb, const char * function, const char * fmt, ...) @@ -260,7 +259,7 @@ static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp) struct inode *inode; struct dentry *result; - if (ino != EXT2_ROOT_INO && ino < EXT2_FIRST_INO(sb)) + if (ino < EXT2_FIRST_INO(sb) && ino != EXT2_ROOT_INO) return ERR_PTR(-ESTALE); if (ino > le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count)) return ERR_PTR(-ESTALE); @@ -273,9 +272,8 @@ static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp) inode = iget(sb, ino); if (inode == NULL) return ERR_PTR(-ENOMEM); - if (is_bad_inode(inode) - || (generation && inode->i_generation != generation) - ) { + if (is_bad_inode(inode) || + (generation && inode->i_generation != generation)) { /* we didn't find the right inode.. */ iput(inode); return ERR_PTR(-ESTALE); @@ -291,7 +289,6 @@ static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp) return result; } - /* Yes, most of these are left as NULL!! * A NULL value implies the default, which works with ext2-like file * systems, but can be improved upon. @@ -825,7 +822,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) if (EXT2_INODE_SIZE(sb) == 0) goto cantfind_ext2; sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb); - if (sbi->s_inodes_per_block == 0) + if (sbi->s_inodes_per_block == 0 || sbi->s_inodes_per_group == 0) goto cantfind_ext2; sbi->s_itb_per_group = sbi->s_inodes_per_group / sbi->s_inodes_per_block; @@ -883,9 +880,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) printk ("EXT2-fs: not enough memory\n"); goto failed_mount; } - percpu_counter_init(&sbi->s_freeblocks_counter); - percpu_counter_init(&sbi->s_freeinodes_counter); - percpu_counter_init(&sbi->s_dirs_counter); bgl_lock_init(&sbi->s_blockgroup_lock); sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts), GFP_KERNEL); @@ -906,12 +900,18 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) } if (!ext2_check_descriptors (sb)) { printk ("EXT2-fs: group descriptors corrupted!\n"); - db_count = i; goto failed_mount2; } sbi->s_gdb_count = db_count; get_random_bytes(&sbi->s_next_generation, sizeof(u32)); spin_lock_init(&sbi->s_next_gen_lock); + + percpu_counter_init(&sbi->s_freeblocks_counter, + ext2_count_free_blocks(sb)); + percpu_counter_init(&sbi->s_freeinodes_counter, + ext2_count_free_inodes(sb)); + percpu_counter_init(&sbi->s_dirs_counter, + ext2_count_dirs(sb)); /* * set up enough so that it can read an inode */ @@ -923,24 +923,18 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) if (!sb->s_root) { iput(root); printk(KERN_ERR "EXT2-fs: get root inode failed\n"); - goto failed_mount2; + goto failed_mount3; } if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { dput(sb->s_root); sb->s_root = NULL; printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n"); - goto failed_mount2; + goto failed_mount3; } if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) ext2_warning(sb, __FUNCTION__, "mounting ext3 filesystem as ext2"); ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY); - percpu_counter_mod(&sbi->s_freeblocks_counter, - ext2_count_free_blocks(sb)); - percpu_counter_mod(&sbi->s_freeinodes_counter, - ext2_count_free_inodes(sb)); - percpu_counter_mod(&sbi->s_dirs_counter, - ext2_count_dirs(sb)); return 0; cantfind_ext2: @@ -948,7 +942,10 @@ cantfind_ext2: printk("VFS: Can't find an ext2 filesystem on dev %s.\n", sb->s_id); goto failed_mount; - +failed_mount3: + percpu_counter_destroy(&sbi->s_freeblocks_counter); + percpu_counter_destroy(&sbi->s_freeinodes_counter); + percpu_counter_destroy(&sbi->s_dirs_counter); failed_mount2: for (i = 0; i < db_count; i++) brelse(sbi->s_group_desc[i]); @@ -1094,8 +1091,9 @@ restore_opts: return err; } -static int ext2_statfs (struct super_block * sb, struct kstatfs * buf) +static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) { + struct super_block *sb = dentry->d_sb; struct ext2_sb_info *sbi = EXT2_SB(sb); unsigned long overhead; int i; @@ -1143,10 +1141,10 @@ static int ext2_statfs (struct super_block * sb, struct kstatfs * buf) return 0; } -static struct super_block *ext2_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +static int ext2_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super); + return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super, mnt); } #ifdef CONFIG_QUOTA @@ -1211,7 +1209,7 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type, struct buffer_head tmp_bh; struct buffer_head *bh; - mutex_lock(&inode->i_mutex); + mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); while (towrite > 0) { tocopy = sb->s_blocksize - offset < towrite ? sb->s_blocksize - offset : towrite;