[brcm47xx] add patches to workaround dcache realted fuse problems (#5186)
[openwrt/svn-archive/archive.git] / target / linux / brcm47xx / patches-2.6.28 / 302-kmod-fuse-dcache-bug-fuse.patch
1 diff -ru linux-2.6.28.10.orig/fs/fuse/dev.c linux-2.6.28.10/fs/fuse/dev.c
2 --- linux-2.6.28.10.orig/fs/fuse/dev.c 2009-05-02 20:54:43.000000000 +0200
3 +++ linux-2.6.28.10/fs/fuse/dev.c 2009-06-07 20:29:50.229816000 +0200
4 @@ -525,6 +525,11 @@
5 }
6 }
7
8 +#ifdef DCACHE_BUG
9 +extern void (*fuse_flush_cache_all)(void);
10 +extern void (*fuse_flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
11 +#endif
12 +
13 /*
14 * Get another pagefull of userspace buffer, and map it to kernel
15 * address space, and lock request
16 @@ -533,6 +538,9 @@
17 {
18 unsigned long offset;
19 int err;
20 +#ifdef DCACHE_BUG
21 + struct vm_area_struct *vma;
22 +#endif
23
24 unlock_request(cs->fc, cs->req);
25 fuse_copy_finish(cs);
26 @@ -544,14 +552,22 @@
27 cs->nr_segs --;
28 }
29 down_read(&current->mm->mmap_sem);
30 +#ifndef DCACHE_BUG
31 err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
32 &cs->pg, NULL);
33 +#else
34 + err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
35 + &cs->pg, &vma);
36 +#endif
37 up_read(&current->mm->mmap_sem);
38 if (err < 0)
39 return err;
40 BUG_ON(err != 1);
41 offset = cs->addr % PAGE_SIZE;
42 cs->mapaddr = kmap_atomic(cs->pg, KM_USER0);
43 +#ifdef DCACHE_BUG
44 + fuse_flush_cache_page(vma, cs->addr, page_to_pfn(cs->pg));
45 +#endif
46 cs->buf = cs->mapaddr + offset;
47 cs->len = min(PAGE_SIZE - offset, cs->seglen);
48 cs->seglen -= cs->len;
49 @@ -565,6 +581,11 @@
50 {
51 unsigned ncpy = min(*size, cs->len);
52 if (val) {
53 +#ifdef DCACHE_BUG
54 + // patch from mailing list, it is very important, otherwise,
55 + // can't mount, or ls mount point will hang
56 + fuse_flush_cache_all();
57 +#endif
58 if (cs->write)
59 memcpy(cs->buf, *val, ncpy);
60 else
61 diff -ru linux-2.6.28.10.orig/fs/fuse/fuse_i.h linux-2.6.28.10/fs/fuse/fuse_i.h
62 --- linux-2.6.28.10.orig/fs/fuse/fuse_i.h 2009-05-02 20:54:43.000000000 +0200
63 +++ linux-2.6.28.10/fs/fuse/fuse_i.h 2009-06-06 16:34:54.814468000 +0200
64 @@ -8,6 +8,7 @@
65
66 #ifndef _FS_FUSE_I_H
67 #define _FS_FUSE_I_H
68 +#define DCACHE_BUG
69
70 #include <linux/fuse.h>
71 #include <linux/fs.h>
72 diff -ru linux-2.6.28.10.orig/fs/fuse/inode.c linux-2.6.28.10/fs/fuse/inode.c
73 --- linux-2.6.28.10.orig/fs/fuse/inode.c 2009-05-02 20:54:43.000000000 +0200
74 +++ linux-2.6.28.10/fs/fuse/inode.c 2009-06-07 20:33:34.156611000 +0200
75 @@ -1038,6 +1038,10 @@
76 printk("fuse init (API version %i.%i)\n",
77 FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
78
79 +#ifdef DCACHE_BUG
80 +printk("fuse init: DCACHE_BUG enabled\n");
81 +#endif
82 +
83 INIT_LIST_HEAD(&fuse_conn_list);
84 res = fuse_fs_init();
85 if (res)