]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] tmpfs oops fix
authorJames McMechan <james_mcmechan@hotmail.com>
Sun, 7 Dec 2003 13:57:40 +0000 (05:57 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Sun, 7 Dec 2003 13:57:40 +0000 (05:57 -0800)
The problem was that the cursor was in the list being walked, and when
the pointer pointed to the cursor the list_del/list_add_tail pair would
oops trying to find the entry pointed to by the prev pointer of the
deleted cursor element.

The solution I found was to move the list_del earlier, before the
beginning of the list walk. since it is not used during the list walk and
should not count in the list enumeration it can be deleted, then the
list pointer cannot point to it so it can be added safely with the
list_add_tail without oopsing, and everything works as expected.

I am unable to oops this version with any of my test programs.

Patch acked by Al Viro.

fs/libfs.c

index bf7229c96fc9393e4b7bee6e63573d15624be9fa..68002d64552e7ce1735be4740937f0dc9bad4f55 100644 (file)
@@ -79,6 +79,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
                        loff_t n = file->f_pos - 2;
 
                        spin_lock(&dcache_lock);
+                       list_del(&cursor->d_child);
                        p = file->f_dentry->d_subdirs.next;
                        while (n && p != &file->f_dentry->d_subdirs) {
                                struct dentry *next;
@@ -87,7 +88,6 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
                                        n--;
                                p = p->next;
                        }
-                       list_del(&cursor->d_child);
                        list_add_tail(&cursor->d_child, p);
                        spin_unlock(&dcache_lock);
                }