From: Roman Zippel --- 25-akpm/fs/hfsplus/catalog.c | 23 +++++++++++++++-------- 25-akpm/fs/hfsplus/dir.c | 28 ++++++++++++++++++---------- 2 files changed, 33 insertions(+), 18 deletions(-) diff -puN fs/hfsplus/catalog.c~hfsplus-dir-rename-fix fs/hfsplus/catalog.c --- 25/fs/hfsplus/catalog.c~hfsplus-dir-rename-fix 2004-05-16 16:33:17.403924384 -0700 +++ 25-akpm/fs/hfsplus/catalog.c 2004-05-16 16:33:17.408923624 -0700 @@ -165,11 +165,11 @@ int hfsplus_create_cat(u32 cnid, struct if (err != -ENOENT) { if (!err) err = -EEXIST; - goto out; + goto err2; } err = hfs_brec_insert(&fd, &entry, entry_size); if (err) - goto out; + goto err2; hfsplus_cat_build_key(fd.search_key, dir->i_ino, str); entry_size = hfsplus_cat_build_record(&entry, cnid, inode); @@ -178,16 +178,23 @@ int hfsplus_create_cat(u32 cnid, struct /* panic? */ if (!err) err = -EEXIST; - goto out; + goto err1; } err = hfs_brec_insert(&fd, &entry, entry_size); - if (!err) { - dir->i_size++; - mark_inode_dirty(dir); - } -out: + if (err) + goto err1; + + dir->i_size++; + mark_inode_dirty(dir); hfs_find_exit(&fd); + return 0; +err1: + hfsplus_cat_build_key(fd.search_key, cnid, NULL); + if (!hfs_brec_find(&fd)) + hfs_brec_remove(&fd); +err2: + hfs_find_exit(&fd); return err; } diff -puN fs/hfsplus/dir.c~hfsplus-dir-rename-fix fs/hfsplus/dir.c --- 25/fs/hfsplus/dir.c~hfsplus-dir-rename-fix 2004-05-16 16:33:17.405924080 -0700 +++ 25-akpm/fs/hfsplus/dir.c 2004-05-16 16:33:17.409923472 -0700 @@ -18,6 +18,13 @@ #include "hfsplus_fs.h" #include "hfsplus_raw.h" +static inline void hfsplus_instantiate(struct dentry *dentry, + struct inode *inode, u32 cnid) +{ + dentry->d_fsdata = (void *)(unsigned long)cnid; + d_instantiate(dentry, inode); +} + /* Find the entry inside dir named dentry->d_name */ static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) @@ -52,6 +59,7 @@ again: goto fail; } cnid = be32_to_cpu(entry.folder.id); + dentry->d_fsdata = (void *)(unsigned long)cnid; } else if (type == HFSPLUS_FILE) { if (fd.entrylength < sizeof(struct hfsplus_cat_file)) { err = -EIO; @@ -233,11 +241,11 @@ int hfsplus_create(struct inode *dir, st res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); if (res) { inode->i_nlink = 0; + hfsplus_delete_inode(inode); iput(inode); return res; } - dentry->d_fsdata = (void *)inode->i_ino; - d_instantiate(dentry, inode); + hfsplus_instantiate(dentry, inode, inode->i_ino); mark_inode_dirty(inode); return 0; } @@ -284,8 +292,7 @@ int hfsplus_link(struct dentry *src_dent return res; inode->i_nlink++; - dst_dentry->d_fsdata = (void *)(unsigned long)cnid; - d_instantiate(dst_dentry, inode); + hfsplus_instantiate(dst_dentry, inode, cnid); atomic_inc(&inode->i_count); inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); @@ -351,10 +358,11 @@ int hfsplus_mkdir(struct inode *dir, str res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); if (res) { inode->i_nlink = 0; + hfsplus_delete_inode(inode); iput(inode); return res; } - d_instantiate(dentry, inode); + hfsplus_instantiate(dentry, inode, inode->i_ino); mark_inode_dirty(inode); return 0; } @@ -391,7 +399,8 @@ int hfsplus_symlink(struct inode *dir, s res = page_symlink(inode, symname, strlen(symname) + 1); if (res) { inode->i_nlink = 0; - iput (inode); + hfsplus_delete_inode(inode); + iput(inode); return res; } @@ -399,8 +408,7 @@ int hfsplus_symlink(struct inode *dir, s res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); if (!res) { - dentry->d_fsdata = (void *)inode->i_ino; - d_instantiate(dentry, inode); + hfsplus_instantiate(dentry, inode, inode->i_ino); mark_inode_dirty(inode); } @@ -421,12 +429,12 @@ int hfsplus_mknod(struct inode *dir, str res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); if (res) { inode->i_nlink = 0; + hfsplus_delete_inode(inode); iput(inode); return res; } init_special_inode(inode, mode, rdev); - dentry->d_fsdata = (void *)inode->i_ino; - d_instantiate(dentry, inode); + hfsplus_instantiate(dentry, inode, inode->i_ino); mark_inode_dirty(inode); return 0; _