diff --git a/target/linux/brcm47xx/patches-2.6.28/301-kmod-fuse-dcache-bug-r4k.patch b/target/linux/brcm47xx/patches-2.6.28/301-kmod-fuse-dcache-bug-r4k.patch new file mode 100644 index 000000000..b77fdf1a4 --- /dev/null +++ b/target/linux/brcm47xx/patches-2.6.28/301-kmod-fuse-dcache-bug-r4k.patch @@ -0,0 +1,31 @@ +--- linux-2.6.28.10.orig/arch/mips/mm/c-r4k.c 2009-05-02 20:54:43.000000000 +0200 ++++ linux-2.6.28.10/arch/mips/mm/c-r4k.c 2009-06-07 20:36:01.667918000 +0200 +@@ -348,7 +348,7 @@ + } + } + +-static void r4k___flush_cache_all(void) ++void r4k___flush_cache_all(void) + { + r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1); + } +@@ -512,7 +512,7 @@ + } + } + +-static void r4k_flush_cache_page(struct vm_area_struct *vma, ++void r4k_flush_cache_page(struct vm_area_struct *vma, + unsigned long addr, unsigned long pfn) + { + struct flush_cache_page_args args; +@@ -1401,3 +1401,10 @@ + #endif + coherency_setup(); + } ++ ++// fuse package DCACHE BUG patch exports ++void (*fuse_flush_cache_all)(void) = r4k___flush_cache_all; ++void (*fuse_flush_cache_page)(struct vm_area_struct *vma, unsigned long page, ++ unsigned long pfn) = r4k_flush_cache_page; ++EXPORT_SYMBOL(fuse_flush_cache_page); ++EXPORT_SYMBOL(fuse_flush_cache_all); diff --git a/target/linux/brcm47xx/patches-2.6.28/302-kmod-fuse-dcache-bug-fuse.patch b/target/linux/brcm47xx/patches-2.6.28/302-kmod-fuse-dcache-bug-fuse.patch new file mode 100644 index 000000000..2ca57290c --- /dev/null +++ b/target/linux/brcm47xx/patches-2.6.28/302-kmod-fuse-dcache-bug-fuse.patch @@ -0,0 +1,85 @@ +diff -ru linux-2.6.28.10.orig/fs/fuse/dev.c linux-2.6.28.10/fs/fuse/dev.c +--- linux-2.6.28.10.orig/fs/fuse/dev.c 2009-05-02 20:54:43.000000000 +0200 ++++ linux-2.6.28.10/fs/fuse/dev.c 2009-06-07 20:29:50.229816000 +0200 +@@ -525,6 +525,11 @@ + } + } + ++#ifdef DCACHE_BUG ++extern void (*fuse_flush_cache_all)(void); ++extern void (*fuse_flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); ++#endif ++ + /* + * Get another pagefull of userspace buffer, and map it to kernel + * address space, and lock request +@@ -533,6 +538,9 @@ + { + unsigned long offset; + int err; ++#ifdef DCACHE_BUG ++ struct vm_area_struct *vma; ++#endif + + unlock_request(cs->fc, cs->req); + fuse_copy_finish(cs); +@@ -544,14 +552,22 @@ + cs->nr_segs --; + } + down_read(¤t->mm->mmap_sem); ++#ifndef DCACHE_BUG + err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0, + &cs->pg, NULL); ++#else ++ err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0, ++ &cs->pg, &vma); ++#endif + up_read(¤t->mm->mmap_sem); + if (err < 0) + return err; + BUG_ON(err != 1); + offset = cs->addr % PAGE_SIZE; + cs->mapaddr = kmap_atomic(cs->pg, KM_USER0); ++#ifdef DCACHE_BUG ++ fuse_flush_cache_page(vma, cs->addr, page_to_pfn(cs->pg)); ++#endif + cs->buf = cs->mapaddr + offset; + cs->len = min(PAGE_SIZE - offset, cs->seglen); + cs->seglen -= cs->len; +@@ -565,6 +581,11 @@ + { + unsigned ncpy = min(*size, cs->len); + if (val) { ++#ifdef DCACHE_BUG ++ // patch from mailing list, it is very important, otherwise, ++ // can't mount, or ls mount point will hang ++ fuse_flush_cache_all(); ++#endif + if (cs->write) + memcpy(cs->buf, *val, ncpy); + else +diff -ru linux-2.6.28.10.orig/fs/fuse/fuse_i.h linux-2.6.28.10/fs/fuse/fuse_i.h +--- linux-2.6.28.10.orig/fs/fuse/fuse_i.h 2009-05-02 20:54:43.000000000 +0200 ++++ linux-2.6.28.10/fs/fuse/fuse_i.h 2009-06-06 16:34:54.814468000 +0200 +@@ -8,6 +8,7 @@ + + #ifndef _FS_FUSE_I_H + #define _FS_FUSE_I_H ++#define DCACHE_BUG + + #include + #include +diff -ru linux-2.6.28.10.orig/fs/fuse/inode.c linux-2.6.28.10/fs/fuse/inode.c +--- linux-2.6.28.10.orig/fs/fuse/inode.c 2009-05-02 20:54:43.000000000 +0200 ++++ linux-2.6.28.10/fs/fuse/inode.c 2009-06-07 20:33:34.156611000 +0200 +@@ -1038,6 +1038,10 @@ + printk("fuse init (API version %i.%i)\n", + FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); + ++#ifdef DCACHE_BUG ++printk("fuse init: DCACHE_BUG enabled\n"); ++#endif ++ + INIT_LIST_HEAD(&fuse_conn_list); + res = fuse_fs_init(); + if (res)