--- fs/hpfs/dir.c | 7 +- fs/hpfs/inode.c | 10 ++ fs/hpfs/namei.c | 195 ++++++++++++++++++++++++++++++++------------------------ fs/hpfs/super.c | 44 +++++++----- 4 files changed, 155 insertions(+), 101 deletions(-) diff -puN fs/hpfs/dir.c~HPFS3-hpfs_iget-RC4-rc1 fs/hpfs/dir.c --- 25/fs/hpfs/dir.c~HPFS3-hpfs_iget-RC4-rc1 2004-02-29 12:48:31.000000000 -0800 +++ 25-akpm/fs/hpfs/dir.c 2004-02-29 12:48:31.000000000 -0800 @@ -244,11 +244,16 @@ struct dentry *hpfs_lookup(struct inode */ hpfs_lock_iget(dir->i_sb, de->directory || (de->ea_size && hpfs_sb(dir->i_sb)->sb_eas) ? 1 : 2); - if (!(result = iget(dir->i_sb, ino))) { + result = iget_locked(dir->i_sb, ino); + if (!result) { hpfs_unlock_iget(dir->i_sb); hpfs_error(dir->i_sb, "hpfs_lookup: can't get inode"); goto bail1; } + if (result->i_state & I_NEW) { + hpfs_read_inode(result); + unlock_new_inode(result); + } hpfs_result = hpfs_i(result); if (!de->directory) hpfs_result->i_parent_dir = dir->i_ino; hpfs_unlock_iget(dir->i_sb); diff -puN fs/hpfs/inode.c~HPFS3-hpfs_iget-RC4-rc1 fs/hpfs/inode.c --- 25/fs/hpfs/inode.c~HPFS3-hpfs_iget-RC4-rc1 2004-02-29 12:48:31.000000000 -0800 +++ 25-akpm/fs/hpfs/inode.c 2004-02-29 12:48:31.000000000 -0800 @@ -242,7 +242,15 @@ void hpfs_write_inode(struct inode *i) } hpfs_inode->i_dirty = 0; hpfs_lock_iget(i->i_sb, 1); - parent = iget(i->i_sb, hpfs_inode->i_parent_dir); + parent = iget_locked(i->i_sb, hpfs_inode->i_parent_dir); + if (!parent) { + hpfs_unlock_iget(i->i_sb); + return; + } + if (parent->i_state & I_NEW) { + hpfs_read_inode(parent); + unlock_new_inode(parent); + } hpfs_unlock_iget(i->i_sb); hpfs_lock_inode(parent); hpfs_write_inode_nolock(i); diff -puN fs/hpfs/namei.c~HPFS3-hpfs_iget-RC4-rc1 fs/hpfs/namei.c --- 25/fs/hpfs/namei.c~HPFS3-hpfs_iget-RC4-rc1 2004-02-29 12:48:31.000000000 -0800 +++ 25-akpm/fs/hpfs/namei.c 2004-02-29 12:48:31.000000000 -0800 @@ -73,24 +73,32 @@ int hpfs_mkdir(struct inode *dir, struct hpfs_brelse4(&qbh0); dir->i_nlink++; hpfs_lock_iget(dir->i_sb, 1); - if ((result = iget(dir->i_sb, fno))) { - hpfs_i(result)->i_parent_dir = dir->i_ino; - result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); - result->i_ctime.tv_nsec = 0; - result->i_mtime.tv_nsec = 0; - result->i_atime.tv_nsec = 0; - hpfs_i(result)->i_ea_size = 0; - if (dee.read_only) result->i_mode &= ~0222; - if (result->i_uid != current->fsuid || - result->i_gid != current->fsgid || - result->i_mode != (mode | S_IFDIR)) { - result->i_uid = current->fsuid; - result->i_gid = current->fsgid; - result->i_mode = mode | S_IFDIR; - hpfs_write_inode_nolock(result); - } - d_instantiate(dentry, result); + + result = iget_locked(dir->i_sb, fno); + if (!result) + goto out; + + hpfs_read_inode(result); + unlock_new_inode(result); + + hpfs_i(result)->i_parent_dir = dir->i_ino; + result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); + result->i_ctime.tv_nsec = 0; + result->i_mtime.tv_nsec = 0; + result->i_atime.tv_nsec = 0; + hpfs_i(result)->i_ea_size = 0; + if (dee.read_only) result->i_mode &= ~0222; + if (result->i_uid != current->fsuid || + result->i_gid != current->fsgid || + result->i_mode != (mode | S_IFDIR)) { + result->i_uid = current->fsuid; + result->i_gid = current->fsgid; + result->i_mode = mode | S_IFDIR; + hpfs_write_inode_nolock(result); } + d_instantiate(dentry, result); + +out: hpfs_unlock_iget(dir->i_sb); hpfs_unlock_inode(dir); unlock_kernel(); @@ -145,31 +153,38 @@ int hpfs_create(struct inode *dir, struc mark_buffer_dirty(bh); brelse(bh); hpfs_lock_iget(dir->i_sb, 2); - if ((result = iget(dir->i_sb, fno))) { - hpfs_decide_conv(result, (char *)name, len); - hpfs_i(result)->i_parent_dir = dir->i_ino; - result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); - result->i_ctime.tv_nsec = 0; - result->i_mtime.tv_nsec = 0; - result->i_atime.tv_nsec = 0; - hpfs_i(result)->i_ea_size = 0; - if (dee.read_only) result->i_mode &= ~0222; - if (result->i_blocks == -1) result->i_blocks = 1; - if (result->i_size == -1) { - result->i_size = 0; - result->i_data.a_ops = &hpfs_aops; - hpfs_i(result)->mmu_private = 0; - } - if (result->i_uid != current->fsuid || - result->i_gid != current->fsgid || - result->i_mode != (mode | S_IFREG)) { - result->i_uid = current->fsuid; - result->i_gid = current->fsgid; - result->i_mode = mode | S_IFREG; - hpfs_write_inode_nolock(result); - } - d_instantiate(dentry, result); + + result = iget_locked(dir->i_sb, fno); + if (!result) + goto out; + + hpfs_read_inode(result); + unlock_new_inode(result); + + hpfs_decide_conv(result, (char *)name, len); + hpfs_i(result)->i_parent_dir = dir->i_ino; + result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); + result->i_ctime.tv_nsec = 0; + result->i_mtime.tv_nsec = 0; + result->i_atime.tv_nsec = 0; + hpfs_i(result)->i_ea_size = 0; + if (dee.read_only) result->i_mode &= ~0222; + if (result->i_blocks == -1) result->i_blocks = 1; + if (result->i_size == -1) { + result->i_size = 0; + result->i_data.a_ops = &hpfs_aops; + hpfs_i(result)->mmu_private = 0; } + if (result->i_uid != current->fsuid || + result->i_gid != current->fsgid || + result->i_mode != (mode | S_IFREG)) { + result->i_uid = current->fsuid; + result->i_gid = current->fsgid; + result->i_mode = mode | S_IFREG; + hpfs_write_inode_nolock(result); + } + d_instantiate(dentry, result); +out: hpfs_unlock_iget(dir->i_sb); hpfs_unlock_inode(dir); unlock_kernel(); @@ -222,24 +237,32 @@ int hpfs_mknod(struct inode *dir, struct fnode->up = dir->i_ino; mark_buffer_dirty(bh); hpfs_lock_iget(dir->i_sb, 2); - if ((result = iget(dir->i_sb, fno))) { - hpfs_i(result)->i_parent_dir = dir->i_ino; - result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); - result->i_ctime.tv_nsec = 0; - result->i_mtime.tv_nsec = 0; - result->i_atime.tv_nsec = 0; - hpfs_i(result)->i_ea_size = 0; - /*if (result->i_blocks == -1) result->i_blocks = 1; - if (result->i_size == -1) result->i_size = 0;*/ - result->i_uid = current->fsuid; - result->i_gid = current->fsgid; - result->i_nlink = 1; - result->i_size = 0; - result->i_blocks = 1; - init_special_inode(result, mode, rdev); - hpfs_write_inode_nolock(result); - d_instantiate(dentry, result); - } + + result = iget_locked(dir->i_sb, fno); + if (!result) + goto out; + + hpfs_read_inode(result); + unlock_new_inode(result); + + hpfs_i(result)->i_parent_dir = dir->i_ino; + result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); + result->i_ctime.tv_nsec = 0; + result->i_mtime.tv_nsec = 0; + result->i_atime.tv_nsec = 0; + hpfs_i(result)->i_ea_size = 0; + /*if (result->i_blocks == -1) result->i_blocks = 1; + if (result->i_size == -1) result->i_size = 0;*/ + result->i_uid = current->fsuid; + result->i_gid = current->fsgid; + result->i_nlink = 1; + result->i_size = 0; + result->i_blocks = 1; + init_special_inode(result, mode, rdev); + hpfs_write_inode_nolock(result); + d_instantiate(dentry, result); + +out: hpfs_unlock_iget(dir->i_sb); hpfs_unlock_inode(dir); brelse(bh); @@ -296,30 +319,38 @@ int hpfs_symlink(struct inode *dir, stru mark_buffer_dirty(bh); brelse(bh); hpfs_lock_iget(dir->i_sb, 2); - if ((result = iget(dir->i_sb, fno))) { - hpfs_i(result)->i_parent_dir = dir->i_ino; - result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); - result->i_ctime.tv_nsec = 0; - result->i_mtime.tv_nsec = 0; - result->i_atime.tv_nsec = 0; - hpfs_i(result)->i_ea_size = 0; - /*if (result->i_blocks == -1) result->i_blocks = 1; - if (result->i_size == -1) result->i_size = 0;*/ - result->i_mode = S_IFLNK | 0777; - result->i_uid = current->fsuid; - result->i_gid = current->fsgid; - result->i_blocks = 1; - result->i_size = strlen(symlink); - result->i_op = &page_symlink_inode_operations; - result->i_data.a_ops = &hpfs_symlink_aops; - if ((fnode = hpfs_map_fnode(dir->i_sb, fno, &bh))) { - hpfs_set_ea(result, fnode, "SYMLINK", (char *)symlink, strlen(symlink)); - mark_buffer_dirty(bh); - brelse(bh); - } - hpfs_write_inode_nolock(result); - d_instantiate(dentry, result); + + result = iget_locked(dir->i_sb, fno); + if (!result) + goto out; + + hpfs_read_inode(result); + unlock_new_inode(result); + + hpfs_i(result)->i_parent_dir = dir->i_ino; + result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date); + result->i_ctime.tv_nsec = 0; + result->i_mtime.tv_nsec = 0; + result->i_atime.tv_nsec = 0; + hpfs_i(result)->i_ea_size = 0; + /*if (result->i_blocks == -1) result->i_blocks = 1; + if (result->i_size == -1) result->i_size = 0;*/ + result->i_mode = S_IFLNK | 0777; + result->i_uid = current->fsuid; + result->i_gid = current->fsgid; + result->i_blocks = 1; + result->i_size = strlen(symlink); + result->i_op = &page_symlink_inode_operations; + result->i_data.a_ops = &hpfs_symlink_aops; + if ((fnode = hpfs_map_fnode(dir->i_sb, fno, &bh))) { + hpfs_set_ea(result, fnode, "SYMLINK", (char *)symlink, strlen(symlink)); + mark_buffer_dirty(bh); + brelse(bh); } + hpfs_write_inode_nolock(result); + d_instantiate(dentry, result); + +out: hpfs_unlock_iget(dir->i_sb); hpfs_unlock_inode(dir); unlock_kernel(); diff -puN fs/hpfs/super.c~HPFS3-hpfs_iget-RC4-rc1 fs/hpfs/super.c --- 25/fs/hpfs/super.c~HPFS3-hpfs_iget-RC4-rc1 2004-02-29 12:48:31.000000000 -0800 +++ 25-akpm/fs/hpfs/super.c 2004-02-29 12:48:31.000000000 -0800 @@ -448,6 +448,7 @@ static int hpfs_fill_super(struct super_ struct hpfs_super_block *superblock; struct hpfs_spare_block *spareblock; struct hpfs_sb_info *sbi; + struct inode *root; uid_t uid; gid_t gid; @@ -613,10 +614,17 @@ static int hpfs_fill_super(struct super_ brelse(bh0); hpfs_lock_iget(s, 1); - s->s_root = d_alloc_root(iget(s, sbi->sb_root)); + root = iget_locked(s, sbi->sb_root); + if (!root) { + hpfs_unlock_iget(s); + goto bail0; + } + hpfs_read_inode(root); + unlock_new_inode(root); hpfs_unlock_iget(s); - if (!s->s_root || !s->s_root->d_inode) { - printk("HPFS: iget failed. Why???\n"); + s->s_root = d_alloc_root(root); + if (!s->s_root) { + iput(root); goto bail0; } hpfs_set_dentry_operations(s->s_root); @@ -627,22 +635,24 @@ static int hpfs_fill_super(struct super_ root_dno = hpfs_fnode_dno(s, sbi->sb_root); if (root_dno) - de = map_dirent(s->s_root->d_inode, root_dno, "\001\001", 2, NULL, &qbh); - if (!root_dno || !de) hpfs_error(s, "unable to find root dir"); + de = map_dirent(root, root_dno, "\001\001", 2, NULL, &qbh); + if (!de) + hpfs_error(s, "unable to find root dir"); else { - s->s_root->d_inode->i_atime.tv_sec = local_to_gmt(s, de->read_date); - s->s_root->d_inode->i_atime.tv_nsec = 0; - s->s_root->d_inode->i_mtime.tv_sec = local_to_gmt(s, de->write_date); - s->s_root->d_inode->i_mtime.tv_nsec = 0; - s->s_root->d_inode->i_ctime.tv_sec = local_to_gmt(s, de->creation_date); - s->s_root->d_inode->i_ctime.tv_nsec = 0; - hpfs_i(s->s_root->d_inode)->i_ea_size = de->ea_size; - hpfs_i(s->s_root->d_inode)->i_parent_dir = s->s_root->d_inode->i_ino; - if (s->s_root->d_inode->i_size == -1) s->s_root->d_inode->i_size = 2048; - if (s->s_root->d_inode->i_blocks == -1) s->s_root->d_inode->i_blocks = 5; + root->i_atime.tv_sec = local_to_gmt(s, de->read_date); + root->i_atime.tv_nsec = 0; + root->i_mtime.tv_sec = local_to_gmt(s, de->write_date); + root->i_mtime.tv_nsec = 0; + root->i_ctime.tv_sec = local_to_gmt(s, de->creation_date); + root->i_ctime.tv_nsec = 0; + hpfs_i(root)->i_ea_size = de->ea_size; + hpfs_i(root)->i_parent_dir = root->i_ino; + if (root->i_size == -1) + root->i_size = 2048; + if (root->i_blocks == -1) + root->i_blocks = 5; + hpfs_brelse4(&qbh); } - if (de) hpfs_brelse4(&qbh); - return 0; bail4: brelse(bh2); _