--- /dev/null
+From 26c3679101dbccc054dcf370143941844ba70531 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@suse.cz>
+Date: Mon, 26 Jan 2009 15:00:59 +0100
+Subject: fuse: destroy bdi on umount
+
+From: Miklos Szeredi <mszeredi@suse.cz>
+
+commit 26c3679101dbccc054dcf370143941844ba70531 upstream.
+
+If a fuse filesystem is unmounted but the device file descriptor
+remains open and a new mount reuses the old device number, then the
+mount fails with EEXIST and the following warning is printed in the
+kernel log:
+
+ WARNING: at fs/sysfs/dir.c:462 sysfs_add_one+0x35/0x3d()
+ sysfs: duplicate filename '0:15' can not be created
+
+The cause is that the bdi belonging to the fuse filesystem was
+destoryed only after the device file was released. Fix this by
+calling bdi_destroy() from fuse_put_super() instead.
+
+Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/fuse/dev.c | 3 ++-
+ fs/fuse/inode.c | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -281,7 +281,8 @@ static void request_end(struct fuse_conn
+ fc->blocked = 0;
+ wake_up_all(&fc->blocked_waitq);
+ }
+- if (fc->num_background == FUSE_CONGESTION_THRESHOLD) {
++ if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
++ fc->connected) {
+ clear_bdi_congested(&fc->bdi, READ);
+ clear_bdi_congested(&fc->bdi, WRITE);
+ }
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -292,6 +292,7 @@ static void fuse_put_super(struct super_
+ list_del(&fc->entry);
+ fuse_ctl_remove_conn(fc);
+ mutex_unlock(&fuse_mutex);
++ bdi_destroy(&fc->bdi);
+ fuse_conn_put(fc);
+ }
+
+@@ -531,7 +532,6 @@ void fuse_conn_put(struct fuse_conn *fc)
+ if (fc->destroy_req)
+ fuse_request_free(fc->destroy_req);
+ mutex_destroy(&fc->inst_mutex);
+- bdi_destroy(&fc->bdi);
+ kfree(fc);
+ }
+ }
--- /dev/null
+From 3ddf1e7f57237ac7c5d5bfb7058f1ea4f970b661 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@suse.cz>
+Date: Mon, 26 Jan 2009 15:00:58 +0100
+Subject: fuse: fix missing fput on error
+
+From: Miklos Szeredi <mszeredi@suse.cz>
+
+commit 3ddf1e7f57237ac7c5d5bfb7058f1ea4f970b661 upstream.
+
+Fix the leaking file reference if allocation or initialization of
+fuse_conn failed.
+
+Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/fuse/inode.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -832,12 +832,16 @@ static int fuse_fill_super(struct super_
+ if (!file)
+ return -EINVAL;
+
+- if (file->f_op != &fuse_dev_operations)
++ if (file->f_op != &fuse_dev_operations) {
++ fput(file);
+ return -EINVAL;
++ }
+
+ fc = new_conn(sb);
+- if (!fc)
++ if (!fc) {
++ fput(file);
+ return -ENOMEM;
++ }
+
+ fc->flags = d.flags;
+ fc->user_id = d.user_id;
--- /dev/null
+From bb875b38dc5e343bdb696b2eab8233e4d195e208 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <error27@gmail.com>
+Date: Mon, 26 Jan 2009 15:00:58 +0100
+Subject: fuse: fix NULL deref in fuse_file_alloc()
+
+From: Dan Carpenter <error27@gmail.com>
+
+commit bb875b38dc5e343bdb696b2eab8233e4d195e208 upstream.
+
+ff is set to NULL and then dereferenced on line 65. Compile tested only.
+
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/fuse/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -54,7 +54,7 @@ struct fuse_file *fuse_file_alloc(void)
+ ff->reserved_req = fuse_request_alloc();
+ if (!ff->reserved_req) {
+ kfree(ff);
+- ff = NULL;
++ return NULL;
+ } else {
+ INIT_LIST_HEAD(&ff->write_entry);
+ atomic_set(&ff->count, 0);
--- /dev/null
+From 3632dee2f8b8a9720329f29eeaa4ec4669a3aff8 Mon Sep 17 00:00:00 2001
+From: Vegard Nossum <vegard.nossum@gmail.com>
+Date: Thu, 22 Jan 2009 15:29:45 +0100
+Subject: inotify: clean up inotify_read and fix locking problems
+
+From: Vegard Nossum <vegard.nossum@gmail.com>
+
+commit 3632dee2f8b8a9720329f29eeaa4ec4669a3aff8 upstream.
+
+If userspace supplies an invalid pointer to a read() of an inotify
+instance, the inotify device's event list mutex is unlocked twice.
+This causes an unbalance which effectively leaves the data structure
+unprotected, and we can trigger oopses by accessing the inotify
+instance from different tasks concurrently.
+
+The best fix (contributed largely by Linus) is a total rewrite
+of the function in question:
+
+On Thu, Jan 22, 2009 at 7:05 AM, Linus Torvalds wrote:
+> The thing to notice is that:
+>
+> - locking is done in just one place, and there is no question about it
+> not having an unlock.
+>
+> - that whole double-while(1)-loop thing is gone.
+>
+> - use multiple functions to make nesting and error handling sane
+>
+> - do error testing after doing the things you always need to do, ie do
+> this:
+>
+> mutex_lock(..)
+> ret = function_call();
+> mutex_unlock(..)
+>
+> .. test ret here ..
+>
+> instead of doing conditional exits with unlocking or freeing.
+>
+> So if the code is written in this way, it may still be buggy, but at least
+> it's not buggy because of subtle "forgot to unlock" or "forgot to free"
+> issues.
+>
+> This _always_ unlocks if it locked, and it always frees if it got a
+> non-error kevent.
+
+Cc: John McCutchan <ttb@tentacle.dhs.org>
+Cc: Robert Love <rlove@google.com>
+Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/inotify_user.c | 135 +++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 74 insertions(+), 61 deletions(-)
+
+--- a/fs/inotify_user.c
++++ b/fs/inotify_user.c
+@@ -427,10 +427,61 @@ static unsigned int inotify_poll(struct
+ return ret;
+ }
+
++/*
++ * Get an inotify_kernel_event if one exists and is small
++ * enough to fit in "count". Return an error pointer if
++ * not large enough.
++ *
++ * Called with the device ev_mutex held.
++ */
++static struct inotify_kernel_event *get_one_event(struct inotify_device *dev,
++ size_t count)
++{
++ size_t event_size = sizeof(struct inotify_event);
++ struct inotify_kernel_event *kevent;
++
++ if (list_empty(&dev->events))
++ return NULL;
++
++ kevent = inotify_dev_get_event(dev);
++ if (kevent->name)
++ event_size += kevent->event.len;
++
++ if (event_size > count)
++ return ERR_PTR(-EINVAL);
++
++ remove_kevent(dev, kevent);
++ return kevent;
++}
++
++/*
++ * Copy an event to user space, returning how much we copied.
++ *
++ * We already checked that the event size is smaller than the
++ * buffer we had in "get_one_event()" above.
++ */
++static ssize_t copy_event_to_user(struct inotify_kernel_event *kevent,
++ char __user *buf)
++{
++ size_t event_size = sizeof(struct inotify_event);
++
++ if (copy_to_user(buf, &kevent->event, event_size))
++ return -EFAULT;
++
++ if (kevent->name) {
++ buf += event_size;
++
++ if (copy_to_user(buf, kevent->name, kevent->event.len))
++ return -EFAULT;
++
++ event_size += kevent->event.len;
++ }
++ return event_size;
++}
++
+ static ssize_t inotify_read(struct file *file, char __user *buf,
+ size_t count, loff_t *pos)
+ {
+- size_t event_size = sizeof (struct inotify_event);
+ struct inotify_device *dev;
+ char __user *start;
+ int ret;
+@@ -440,81 +491,43 @@ static ssize_t inotify_read(struct file
+ dev = file->private_data;
+
+ while (1) {
++ struct inotify_kernel_event *kevent;
+
+ prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE);
+
+ mutex_lock(&dev->ev_mutex);
+- if (!list_empty(&dev->events)) {
+- ret = 0;
+- break;
+- }
++ kevent = get_one_event(dev, count);
+ mutex_unlock(&dev->ev_mutex);
+
+- if (file->f_flags & O_NONBLOCK) {
+- ret = -EAGAIN;
+- break;
+- }
+-
+- if (signal_pending(current)) {
+- ret = -EINTR;
+- break;
++ if (kevent) {
++ ret = PTR_ERR(kevent);
++ if (IS_ERR(kevent))
++ break;
++ ret = copy_event_to_user(kevent, buf);
++ free_kevent(kevent);
++ if (ret < 0)
++ break;
++ buf += ret;
++ count -= ret;
++ continue;
+ }
+
+- schedule();
+- }
+-
+- finish_wait(&dev->wq, &wait);
+- if (ret)
+- return ret;
+-
+- while (1) {
+- struct inotify_kernel_event *kevent;
+-
+- ret = buf - start;
+- if (list_empty(&dev->events))
++ ret = -EAGAIN;
++ if (file->f_flags & O_NONBLOCK)
+ break;
+-
+- kevent = inotify_dev_get_event(dev);
+- if (event_size + kevent->event.len > count) {
+- if (ret == 0 && count > 0) {
+- /*
+- * could not get a single event because we
+- * didn't have enough buffer space.
+- */
+- ret = -EINVAL;
+- }
++ ret = -EINTR;
++ if (signal_pending(current))
+ break;
+- }
+- remove_kevent(dev, kevent);
+
+- /*
+- * Must perform the copy_to_user outside the mutex in order
+- * to avoid a lock order reversal with mmap_sem.
+- */
+- mutex_unlock(&dev->ev_mutex);
+-
+- if (copy_to_user(buf, &kevent->event, event_size)) {
+- ret = -EFAULT;
++ if (start != buf)
+ break;
+- }
+- buf += event_size;
+- count -= event_size;
+-
+- if (kevent->name) {
+- if (copy_to_user(buf, kevent->name, kevent->event.len)){
+- ret = -EFAULT;
+- break;
+- }
+- buf += kevent->event.len;
+- count -= kevent->event.len;
+- }
+
+- free_kevent(kevent);
+-
+- mutex_lock(&dev->ev_mutex);
++ schedule();
+ }
+- mutex_unlock(&dev->ev_mutex);
+
++ finish_wait(&dev->wq, &wait);
++ if (start != buf && ret != -EFAULT)
++ ret = buf - start;
+ return ret;
+ }
+
--- /dev/null
+From 5dc306f3bd1d4cfdf79df39221b3036eab1ddcf3 Mon Sep 17 00:00:00 2001
+From: Brian Cavagnolo <brian@cozybit.com>
+Date: Fri, 16 Jan 2009 19:04:49 -0800
+Subject: mac80211: decrement ref count to netdev after launching mesh discovery
+
+From: Brian Cavagnolo <brian@cozybit.com>
+
+commit 5dc306f3bd1d4cfdf79df39221b3036eab1ddcf3 upstream.
+
+After launching mesh discovery in tx path, reference count was not being
+decremented. This was preventing module unload.
+
+Signed-off-by: Brian Cavagnolo <brian@cozybit.com>
+Signed-off-by: Andrey Yurovsky <andrey@cozybit.com>
+Acked-by: Johannes Berg <johannes@sipsolutions.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/mac80211/tx.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1335,8 +1335,10 @@ int ieee80211_master_start_xmit(struct s
+ if (is_multicast_ether_addr(hdr->addr3))
+ memcpy(hdr->addr1, hdr->addr3, ETH_ALEN);
+ else
+- if (mesh_nexthop_lookup(skb, odev))
++ if (mesh_nexthop_lookup(skb, odev)) {
++ dev_put(odev);
+ return 0;
++ }
+ if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0)
+ IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.sta,
+ fwded_frames);
--- /dev/null
+fuse-destroy-bdi-on-umount.patch
+fuse-fix-missing-fput-on-error.patch
+fuse-fix-null-deref-in-fuse_file_alloc.patch
+inotify-clean-up-inotify_read-and-fix-locking-problems.patch
+mac80211-decrement-ref-count-to-netdev-after-launching-mesh-discovery.patch
+sysfs-fix-problems-with-binary-files.patch
+x86-mm-fix-pte_free.patch
--- /dev/null
+From 4503efd0891c40e30928afb4b23dc3f99c62a6b2 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Date: Tue, 20 Jan 2009 15:51:16 -0800
+Subject: sysfs: fix problems with binary files
+
+From: Greg Kroah-Hartman <gregkh@suse.de>
+
+commit 4503efd0891c40e30928afb4b23dc3f99c62a6b2 upstream.
+
+Some sysfs binary files don't like having 0 passed to them as a size.
+Fix this up at the root by just returning to the vfs if userspace asks
+us for a zero sized buffer.
+
+Thanks to Pavel Roskin for pointing this out.
+
+Reported-by: Pavel Roskin <proski@gnu.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/sysfs/bin.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/fs/sysfs/bin.c
++++ b/fs/sysfs/bin.c
+@@ -62,6 +62,9 @@ read(struct file *file, char __user *use
+ loff_t offs = *off;
+ int count = min_t(size_t, bytes, PAGE_SIZE);
+
++ if (!bytes)
++ return 0;
++
+ if (size) {
+ if (offs > size)
+ return 0;
+@@ -119,6 +122,9 @@ static ssize_t write(struct file *file,
+ loff_t offs = *off;
+ int count = min_t(size_t, bytes, PAGE_SIZE);
+
++ if (!bytes)
++ return 0;
++
+ if (size) {
+ if (offs > size)
+ return 0;
--- /dev/null
+From 42ef73fe134732b2e91c0326df5fd568da17c4b2 Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Fri, 23 Jan 2009 17:37:49 +0100
+Subject: x86, mm: fix pte_free()
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+commit 42ef73fe134732b2e91c0326df5fd568da17c4b2 upstream.
+
+On -rt we were seeing spurious bad page states like:
+
+Bad page state in process 'firefox'
+page:c1bc2380 flags:0x40000000 mapping:c1bc2390 mapcount:0 count:0
+Trying to fix it up, but a reboot is needed
+Backtrace:
+Pid: 503, comm: firefox Not tainted 2.6.26.8-rt13 #3
+[<c043d0f3>] ? printk+0x14/0x19
+[<c0272d4e>] bad_page+0x4e/0x79
+[<c0273831>] free_hot_cold_page+0x5b/0x1d3
+[<c02739f6>] free_hot_page+0xf/0x11
+[<c0273a18>] __free_pages+0x20/0x2b
+[<c027d170>] __pte_alloc+0x87/0x91
+[<c027d25e>] handle_mm_fault+0xe4/0x733
+[<c043f680>] ? rt_mutex_down_read_trylock+0x57/0x63
+[<c043f680>] ? rt_mutex_down_read_trylock+0x57/0x63
+[<c0218875>] do_page_fault+0x36f/0x88a
+
+This is the case where a concurrent fault already installed the PTE and
+we get to free the newly allocated one.
+
+This is due to pgtable_page_ctor() doing the spin_lock_init(&page->ptl)
+which is overlaid with the {private, mapping} struct.
+
+union {
+ struct {
+ unsigned long private;
+ struct address_space *mapping;
+ };
+ spinlock_t ptl;
+ struct kmem_cache *slab;
+ struct page *first_page;
+};
+
+Normally the spinlock is small enough to not stomp on page->mapping, but
+PREEMPT_RT=y has huge 'spin'locks.
+
+But lockdep kernels should also be able to trigger this splat, as the
+lock tracking code grows the spinlock to cover page->mapping.
+
+The obvious fix is calling pgtable_page_dtor() like the regular pte free
+path __pte_free_tlb() does.
+
+It seems all architectures except x86 and nm10300 already do this, and
+nm10300 doesn't seem to use pgtable_page_ctor(), which suggests it
+doesn't do SMP or simply doesnt do MMU at all or something.
+
+Signed-off-by: Peter Zijlstra <a.p.zijlsta@chello.nl>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-x86/pgalloc.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/asm-x86/pgalloc.h
++++ b/include/asm-x86/pgalloc.h
+@@ -42,6 +42,7 @@ static inline void pte_free_kernel(struc
+
+ static inline void pte_free(struct mm_struct *mm, struct page *pte)
+ {
++ pgtable_page_dtor(pte);
+ __free_page(pte);
+ }
+