public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] 2.2.18: d_move() with self-root dentries
@ 2000-11-21  9:17 Chip Salzenberg
  2000-11-21 18:18 ` [PATCH] 2.2.18: d_move() with self-root dentries (Dentry Corruption!) Chip Salzenberg
  0 siblings, 1 reply; 4+ messages in thread
From: Chip Salzenberg @ 2000-11-21  9:17 UTC (permalink / raw)
  To: Linux Kernel; +Cc: nfs

The d_move() function doesn't correctly handle dentries that have no
parents (i.e. 'x->d_parent==x').  This patch lets it do so.

Normally, the only parentless dentries are filesystem roots.  However,
the NFS server creates (temporary) parentless dentries whenever dentry
pruning has deleted the dentries referring to clients' open files.

Making nfsd's d_splice() compensate for d_move's limitations is not
only a kludge, but also it harder to keep nfsd correct.  Besides,
someday, nfsd may not be the only creator of this kind of dentry.

Thus, this patch.  If you apply this, you'll also want to patch
fs/nfsd/nfsfh.c to stop compensating for d_move's old limitations.
(Alan, this is 2.2.19 material [if then].)

Index: fs/dcache.c
--- fs/dcache.c.prev
+++ fs/dcache.c	Mon Nov 20 22:31:09 2000
@@ -749,16 +749,28 @@ void d_move(struct dentry * dentry, stru
 	INIT_LIST_HEAD(&target->d_hash);
 
+	/* Switch the names */
+	switch_names(dentry, target);
+	do_switch(dentry->d_name.len, target->d_name.len);
+	do_switch(dentry->d_name.hash, target->d_name.hash);
+
+	/* Switch parentage, allowing for self-parents */
+
 	list_del(&dentry->d_child);
 	list_del(&target->d_child);
 
-	/* Switch the parents and the names.. */
-	switch_names(dentry, target);
 	do_switch(dentry->d_parent, target->d_parent);
-	do_switch(dentry->d_name.len, target->d_name.len);
-	do_switch(dentry->d_name.hash, target->d_name.hash);
 
-	/* And add them back to the (new) parent lists */
-	list_add(&target->d_child, &target->d_parent->d_subdirs);
-	list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
+	if (dentry->d_parent != target)
+		list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
+	else {
+		INIT_LIST_HEAD(&dentry->d_child);
+		dentry->d_parent = dentry;
+	}
+	if (target->d_parent != dentry)
+		list_add(&target->d_child, &target->d_parent->d_subdirs);
+	else {
+		INIT_LIST_HEAD(&target->d_child);
+		target->d_parent = target;
+	}
 }
 

-- 
Chip Salzenberg            - a.k.a. -            <chip@valinux.com>
   "Give me immortality, or give me death!"  // Firesign Theatre
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2000-11-24  5:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-11-21  9:17 [PATCH] 2.2.18: d_move() with self-root dentries Chip Salzenberg
2000-11-21 18:18 ` [PATCH] 2.2.18: d_move() with self-root dentries (Dentry Corruption!) Chip Salzenberg
2000-11-24  1:34   ` Neil Brown
2000-11-24  4:56     ` NFSD dentry manipulation (was Re: d_move()) Chip Salzenberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox