mtd/fs/jffs2 dir.c,1.69,1.70

David Woodhouse dwmw2 at infradead.org
Thu Jun 20 19:33:14 EDT 2002


Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv24850

Modified Files:
	dir.c 
Log Message:
Ensure nlink is decremented on victim in jffs2_rename()


Index: dir.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/dir.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- dir.c	20 May 2002 14:56:38 -0000	1.69
+++ dir.c	20 Jun 2002 23:33:12 -0000	1.70
@@ -716,8 +716,30 @@
 {
 	int ret;
 	struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
+	struct jffs2_inode_info *victim_f = NULL;
 	uint8_t type;
 
+	/* The VFS will check for us and prevent trying to rename a 
+	 * file over a directory and vice versa, but if it's a directory,
+	 * the VFS can't check whether the victim is empty. The filesystem
+	 * needs to do that for itself.
+	 */
+	if (new_dentry->d_inode) {
+		victim_f = JFFS2_INODE_INFO(new_dentry->d_inode);
+		if (S_ISDIR(new_dentry->d_inode->i_mode)) {
+			struct jffs2_full_dirent *fd;
+
+			down(&victim_f->sem);
+			for (fd = victim_f->dents; fd; fd = fd->next) {
+				if (fd->ino) {
+					up(&victim_f->sem);
+					return -ENOTEMPTY;
+				}
+			}
+			up(&victim_f->sem);
+		}
+	}
+
 	/* XXX: We probably ought to alloc enough space for
 	   both nodes at the same time. Writing the new link, 
 	   then getting -ENOSPC, is quite bad :)
@@ -736,7 +758,21 @@
 	if (ret)
 		return ret;
 
-	if (S_ISDIR(old_dentry->d_inode->i_mode))
+	if (victim_f) {
+		/* There was a victim. Kill it off nicely */
+		new_dentry->d_inode->i_nlink--;
+		/* Don't oops if the victim was a dirent pointing to an
+		   inode which didn't exist. */
+		if (victim_f->inocache) {
+			down(&victim_f->sem);
+			victim_f->inocache->nlink--;
+			up(&victim_f->sem);
+		}
+	}
+
+	/* If it was a directory we moved, and there was no victim, 
+	   increase i_nlink on its new parent */
+	if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f)
 		new_dir_i->i_nlink++;
 
 	/* Unlink the original */





More information about the linux-mtd-cvs mailing list