
From: Roman Zippel <zippel@linux-m68k.org>



---

 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;

_
