--- linux-2.4.24/fs/dquot.c 2003-11-28 18:26:21.000000000 +0000 +++ linux-2.4.25-pre7/fs/dquot.c 2004-01-23 16:28:50.000000000 +0000 @@ -396,7 +396,7 @@ restart: if (dquot->dq_flags & DQ_LOCKED) wait_on_dquot(dquot); if (dquot_dirty(dquot)) - sb->dq_op->sync_dquot(dquot); + sb->dq_op->write_dquot(dquot); dqput(dquot); goto restart; } @@ -543,7 +543,7 @@ we_slept: return; } if (dquot_dirty(dquot)) { - commit_dqblk(dquot); + dquot->dq_sb->dq_op->write_dquot(dquot); goto we_slept; } @@ -1219,7 +1219,7 @@ struct dquot_operations dquot_operations free_space: dquot_free_space, free_inode: dquot_free_inode, transfer: dquot_transfer, - sync_dquot: commit_dqblk + write_dquot: commit_dqblk }; /* Function used by filesystems for initializing the dquot_operations structure */ @@ -1331,9 +1331,9 @@ int vfs_quota_on(struct super_block *sb, error = -EINVAL; if (!fmt->qf_ops->check_quota_file(sb, type)) goto out_f; - /* We don't want quota on quota files */ + /* We don't want quota and atime on quota files */ dquot_drop(inode); - inode->i_flags |= S_NOQUOTA; + inode->i_flags |= S_NOQUOTA | S_NOATIME; dqopt->ops[type] = fmt->qf_ops; dqopt->info[type].dqi_format = fmt; --- linux-2.4.24/fs/ext3/inode.c 2003-08-25 11:44:43.000000000 +0000 +++ linux-2.4.25-pre7/fs/ext3/inode.c 2004-01-23 16:28:46.000000000 +0000 @@ -39,6 +39,18 @@ */ #undef SEARCH_FROM_ZERO +/* + * Test whether an inode is a fast symlink. + */ +static inline int ext3_inode_is_fast_symlink(struct inode *inode) +{ + int ea_blocks = EXT3_I(inode)->i_file_acl ? + (inode->i_sb->s_blocksize >> 9) : 0; + + return (S_ISLNK(inode->i_mode) && + inode->i_blocks - ea_blocks == 0); +} + /* The ext3 forget function must perform a revoke if we are freeing data * which has been journaled. Metadata (eg. indirect blocks) must be * revoked in all cases. @@ -1870,6 +1882,8 @@ void ext3_truncate(struct inode * inode) if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) return; + if (ext3_inode_is_fast_symlink(inode)) + return; if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; @@ -2170,7 +2184,7 @@ void ext3_read_inode(struct inode * inod inode->i_op = &ext3_dir_inode_operations; inode->i_fop = &ext3_dir_operations; } else if (S_ISLNK(inode->i_mode)) { - if (!inode->i_blocks) + if (ext3_inode_is_fast_symlink(inode)) inode->i_op = &ext3_fast_symlink_inode_operations; else { inode->i_op = &page_symlink_inode_operations; @@ -2208,6 +2222,11 @@ static int ext3_do_update_inode(handle_t if (err) goto out_brelse; } + /* For fields not not tracking in the in-memory inode, + * initialise them to zero for new inodes. */ + if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) + memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size); + raw_inode->i_mode = cpu_to_le16(inode->i_mode); if(!(test_opt(inode->i_sb, NO_UID32))) { raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); @@ -2245,15 +2264,6 @@ static int ext3_do_update_inode(handle_t raw_inode->i_faddr = cpu_to_le32(inode->u.ext3_i.i_faddr); raw_inode->i_frag = inode->u.ext3_i.i_frag_no; raw_inode->i_fsize = inode->u.ext3_i.i_frag_size; -#else - /* If we are not tracking these fields in the in-memory inode, - * then preserve them on disk, but still initialise them to zero - * for new inodes. */ - if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) { - raw_inode->i_faddr = 0; - raw_inode->i_frag = 0; - raw_inode->i_fsize = 0; - } #endif raw_inode->i_file_acl = cpu_to_le32(inode->u.ext3_i.i_file_acl); if (!S_ISREG(inode->i_mode)) { --- linux-2.4.24/fs/ext3/super.c 2003-08-25 11:44:43.000000000 +0000 +++ linux-2.4.25-pre7/fs/ext3/super.c 2004-01-23 16:29:48.000000000 +0000 @@ -449,7 +449,6 @@ void ext3_put_super (struct super_block } static struct dquot_operations ext3_qops; -static int (*old_sync_dquot)(struct dquot *dquot); static struct super_operations ext3_sops = { read_inode: ext3_read_inode, /* BKL held */ @@ -795,6 +794,26 @@ static int ext3_check_descriptors (struc return 1; } +static unsigned long descriptor_loc(struct super_block *sb, + unsigned long logic_sb_block, + int nr) +{ + struct ext3_sb_info *sbi = EXT3_SB(sb); + unsigned long bg, first_data_block, first_meta_bg; + int has_super = 0; + + first_data_block = le32_to_cpu(sbi->s_es->s_first_data_block); + first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg); + + if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_META_BG) || + nr < first_meta_bg) + return (logic_sb_block + nr + 1); + bg = sbi->s_desc_per_block * nr; + if (ext3_bg_has_super(sb, bg)) + has_super = 1; + return (first_data_block + has_super + (bg * sbi->s_blocks_per_group)); +} + /* ext3_orphan_cleanup() walks a singly-linked list of inodes (starting at * the superblock) which were deleted from all directories, but held open by @@ -902,6 +921,7 @@ struct super_block * ext3_read_super (st struct buffer_head * bh; struct ext3_super_block *es = 0; struct ext3_sb_info *sbi = EXT3_SB(sb); + unsigned long block; unsigned long sb_block = 1; unsigned long logic_sb_block = 1; unsigned long offset = 0; @@ -1042,7 +1062,9 @@ struct super_block * ext3_read_super (st } else { sbi->s_inode_size = le16_to_cpu(es->s_inode_size); sbi->s_first_ino = le32_to_cpu(es->s_first_ino); - if (sbi->s_inode_size != EXT3_GOOD_OLD_INODE_SIZE) { + if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) || + (sbi->s_inode_size & (sbi->s_inode_size - 1)) || + (sbi->s_inode_size > blocksize)) { printk (KERN_ERR "EXT3-fs: unsupported inode size: %d\n", sbi->s_inode_size); @@ -1105,7 +1127,8 @@ struct super_block * ext3_read_super (st goto failed_mount; } for (i = 0; i < db_count; i++) { - sbi->s_group_desc[i] = sb_bread(sb, logic_sb_block + i + 1); + block = descriptor_loc(sb, logic_sb_block, i); + sbi->s_group_desc[i] = sb_bread(sb, block); if (!sbi->s_group_desc[i]) { printk (KERN_ERR "EXT3-fs: " "can't read group descriptor %d\n", i); @@ -1774,12 +1797,14 @@ int ext3_statfs (struct super_block * sb #ifdef CONFIG_QUOTA +static int (*old_write_dquot)(struct dquot *dquot); + /* Blocks: (2 data blocks) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */ #define EXT3_OLD_QFMT_BLOCKS 11 /* Blocks: quota info + (4 pointer blocks + 1 entry block) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */ #define EXT3_V0_QFMT_BLOCKS 27 -static int ext3_sync_dquot(struct dquot *dquot) +static int ext3_write_dquot(struct dquot *dquot) { int nblocks, ret; handle_t *handle; @@ -1804,7 +1829,7 @@ static int ext3_sync_dquot(struct dquot return PTR_ERR(handle); } unlock_kernel(); - ret = old_sync_dquot(dquot); + ret = old_write_dquot(dquot); lock_kernel(); ret = ext3_journal_stop(handle, qinode); unlock_kernel(); @@ -1818,8 +1843,8 @@ static int __init init_ext3_fs(void) { #ifdef CONFIG_QUOTA init_dquot_operations(&ext3_qops); - old_sync_dquot = ext3_qops.sync_dquot; - ext3_qops.sync_dquot = ext3_sync_dquot; + old_write_dquot = ext3_qops.write_dquot; + ext3_qops.write_dquot = ext3_write_dquot; #endif return register_filesystem(&ext3_fs_type); }