diff options
Diffstat (limited to 'target/linux/brcm47xx/patches-2.6.28/302-kmod-fuse-dcache-bug-fuse.patch')
-rw-r--r-- | target/linux/brcm47xx/patches-2.6.28/302-kmod-fuse-dcache-bug-fuse.patch | 85 |
1 files changed, 85 insertions, 0 deletions
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 0000000000..2ca57290c6 --- /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 <linux/fuse.h> + #include <linux/fs.h> +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) |