From c1244f64917cf9f861402dc16a42f157326f1e94 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 1 Mar 2013 08:58:22 -0800 Subject: [PATCH] 3.8-stable patches added patches: fuse-don-t-warn-when-nlink-is-zero.patch hid-add-support-for-sony-rf-receiver-with-usb-product-id-0x0374.patch hid-clean-up-quirk-for-sony-rf-receivers.patch nfsd-fix-memleak.patch svcrpc-fix-rpc-server-shutdown-races.patch svcrpc-make-svc_age_temp_xprts-enqueue-under-sv_lock.patch --- .../fuse-don-t-warn-when-nlink-is-zero.patch | 39 +++++ ...-receiver-with-usb-product-id-0x0374.patch | 124 +++++++++++++++ ...clean-up-quirk-for-sony-rf-receivers.patch | 45 ++++++ queue-3.8/nfsd-fix-memleak.patch | 30 ++++ queue-3.8/series | 6 + ...svcrpc-fix-rpc-server-shutdown-races.patch | 149 ++++++++++++++++++ ...age_temp_xprts-enqueue-under-sv_lock.patch | 66 ++++++++ 7 files changed, 459 insertions(+) create mode 100644 queue-3.8/fuse-don-t-warn-when-nlink-is-zero.patch create mode 100644 queue-3.8/hid-add-support-for-sony-rf-receiver-with-usb-product-id-0x0374.patch create mode 100644 queue-3.8/hid-clean-up-quirk-for-sony-rf-receivers.patch create mode 100644 queue-3.8/nfsd-fix-memleak.patch create mode 100644 queue-3.8/svcrpc-fix-rpc-server-shutdown-races.patch create mode 100644 queue-3.8/svcrpc-make-svc_age_temp_xprts-enqueue-under-sv_lock.patch diff --git a/queue-3.8/fuse-don-t-warn-when-nlink-is-zero.patch b/queue-3.8/fuse-don-t-warn-when-nlink-is-zero.patch new file mode 100644 index 00000000000..8f35ee0476c --- /dev/null +++ b/queue-3.8/fuse-don-t-warn-when-nlink-is-zero.patch @@ -0,0 +1,39 @@ +From dfca7cebc2679f3d129f8e680a8f199a7ad16e38 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Mon, 4 Feb 2013 15:57:42 +0100 +Subject: fuse: don't WARN when nlink is zero + +From: Miklos Szeredi + +commit dfca7cebc2679f3d129f8e680a8f199a7ad16e38 upstream. + +drop_nlink() warns if nlink is already zero. This is triggerable by a buggy +userspace filesystem. The cure, I think, is worse than the disease so disable +the warning. + +Reported-by: Tero Roponen +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dir.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -682,7 +682,14 @@ static int fuse_unlink(struct inode *dir + + spin_lock(&fc->lock); + fi->attr_version = ++fc->attr_version; +- drop_nlink(inode); ++ /* ++ * If i_nlink == 0 then unlink doesn't make sense, yet this can ++ * happen if userspace filesystem is careless. It would be ++ * difficult to enforce correct nlink usage so just ignore this ++ * condition here ++ */ ++ if (inode->i_nlink > 0) ++ drop_nlink(inode); + spin_unlock(&fc->lock); + fuse_invalidate_attr(inode); + fuse_invalidate_attr(dir); diff --git a/queue-3.8/hid-add-support-for-sony-rf-receiver-with-usb-product-id-0x0374.patch b/queue-3.8/hid-add-support-for-sony-rf-receiver-with-usb-product-id-0x0374.patch new file mode 100644 index 00000000000..ce376fda3f3 --- /dev/null +++ b/queue-3.8/hid-add-support-for-sony-rf-receiver-with-usb-product-id-0x0374.patch @@ -0,0 +1,124 @@ +From a464918419f94a0043d2f549d6defb4c3f69f68a Mon Sep 17 00:00:00 2001 +From: Fernando Luis Vázquez Cao +Date: Tue, 15 Jan 2013 19:40:48 +0900 +Subject: HID: add support for Sony RF receiver with USB product id 0x0374 + +From: Fernando Luis Vázquez Cao + +commit a464918419f94a0043d2f549d6defb4c3f69f68a upstream. + +Some Vaio desktop computers, among them the VGC-LN51JGB multimedia PC, have +a RF receiver, multi-interface USB device 054c:0374, that is used to connect +a wireless keyboard and a wireless mouse. + +The keyboard works flawlessly, but the mouse (VGP-WMS3 in my case) does not +seem to be generating any pointer events. The problem is that the mouse pointer +is wrongly declared as a constant non-data variable in the report descriptor +(see lsusb and usbhid-dump output below), with the consequence that it is +ignored by the HID code. + +Add this device to the have-special-driver list and fix up the report +descriptor in the Sony-specific driver which happens to already have a fixup +for a similar firmware bug. + +# lsusb -vd 054C:0374 +Bus 003 Device 002: ID 054c:0374 Sony Corp. +Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.00 + bDeviceClass 0 (Defined at Interface level) + bDeviceSubClass 0 + bDeviceProtocol 0 + bMaxPacketSize0 8 + idVendor 0x054c Sony Corp. + idProduct 0x0374 + iSerial 0 +[...] + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 1 + bAlternateSetting 0 + bNumEndpoints 1 + bInterfaceClass 3 Human Interface Device + bInterfaceSubClass 1 Boot Interface Subclass + bInterfaceProtocol 2 Mouse + iInterface 2 RF Receiver +[...] + Report Descriptor: (length is 100) +[...] + Item(Global): Usage Page, data= [ 0x01 ] 1 + Generic Desktop Controls + Item(Local ): Usage, data= [ 0x30 ] 48 + Direction-X + Item(Local ): Usage, data= [ 0x31 ] 49 + Direction-Y + Item(Global): Report Count, data= [ 0x02 ] 2 + Item(Global): Report Size, data= [ 0x08 ] 8 + Item(Global): Logical Minimum, data= [ 0x81 ] 129 + Item(Global): Logical Maximum, data= [ 0x7f ] 127 + Item(Main ): Input, data= [ 0x07 ] 7 + Constant Variable Relative No_Wrap Linear + Preferred_State No_Null_Position Non_Volatile Bitfield + +# usbhid-dump +003:002:001:DESCRIPTOR 1357910009.758544 + 05 01 09 02 A1 01 05 01 09 02 A1 02 85 01 09 01 + A1 00 05 09 19 01 29 05 95 05 75 01 15 00 25 01 + 81 02 75 03 95 01 81 01 05 01 09 30 09 31 95 02 + 75 08 15 81 25 7F 81 07 A1 02 85 01 09 38 35 00 + 45 00 15 81 25 7F 95 01 75 08 81 06 C0 A1 02 85 + 01 05 0C 15 81 25 7F 95 01 75 08 0A 38 02 81 06 + C0 C0 C0 C0 + +Signed-off-by: Fernando Luis Vazquez Cao +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-core.c | 1 + + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-sony.c | 4 +++- + 3 files changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1697,6 +1697,7 @@ static const struct hid_device_id hid_ha + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -709,6 +709,7 @@ + + #define USB_VENDOR_ID_SONY 0x054c + #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b ++#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374 + #define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306 + #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 + #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f +--- a/drivers/hid/hid-sony.c ++++ b/drivers/hid/hid-sony.c +@@ -45,7 +45,7 @@ static __u8 *sony_report_fixup(struct hi + + if ((sc->quirks & VAIO_RDESC_CONSTANT) && + *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { +- hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n"); ++ hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); + rdesc[55] = 0x06; + } + +@@ -217,6 +217,8 @@ static const struct hid_device_id sony_d + .driver_data = SIXAXIS_CONTROLLER_BT }, + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), + .driver_data = VAIO_RDESC_CONSTANT }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), ++ .driver_data = VAIO_RDESC_CONSTANT }, + { } + }; + MODULE_DEVICE_TABLE(hid, sony_devices); diff --git a/queue-3.8/hid-clean-up-quirk-for-sony-rf-receivers.patch b/queue-3.8/hid-clean-up-quirk-for-sony-rf-receivers.patch new file mode 100644 index 00000000000..b6e2ed35a6e --- /dev/null +++ b/queue-3.8/hid-clean-up-quirk-for-sony-rf-receivers.patch @@ -0,0 +1,45 @@ +From 99d249021abd4341771523ed8dd7946276103432 Mon Sep 17 00:00:00 2001 +From: Fernando Luis Vázquez Cao +Date: Tue, 22 Jan 2013 15:20:38 +0900 +Subject: HID: clean up quirk for Sony RF receivers + +From: Fernando Luis Vázquez Cao + +commit 99d249021abd4341771523ed8dd7946276103432 upstream. + +Document what the fix-up is does and make it more robust by ensuring +that it is only applied to the USB interface that corresponds to the +mouse (sony_report_fixup() is called once per interface during probing). + +Signed-off-by: Fernando Luis Vazquez Cao +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-sony.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/hid/hid-sony.c ++++ b/drivers/hid/hid-sony.c +@@ -43,9 +43,19 @@ static __u8 *sony_report_fixup(struct hi + { + struct sony_sc *sc = hid_get_drvdata(hdev); + +- if ((sc->quirks & VAIO_RDESC_CONSTANT) && +- *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { ++ /* ++ * Some Sony RF receivers wrongly declare the mouse pointer as a ++ * a constant non-data variable. ++ */ ++ if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && ++ /* usage page: generic desktop controls */ ++ /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ ++ /* usage: mouse */ ++ rdesc[2] == 0x09 && rdesc[3] == 0x02 && ++ /* input (usage page for x,y axes): constant, variable, relative */ ++ rdesc[54] == 0x81 && rdesc[55] == 0x07) { + hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); ++ /* input: data, variable, relative */ + rdesc[55] = 0x06; + } + diff --git a/queue-3.8/nfsd-fix-memleak.patch b/queue-3.8/nfsd-fix-memleak.patch new file mode 100644 index 00000000000..4a02480ef48 --- /dev/null +++ b/queue-3.8/nfsd-fix-memleak.patch @@ -0,0 +1,30 @@ +From 2d32b29a1c2830f7c42caa8258c714acd983961f Mon Sep 17 00:00:00 2001 +From: majianpeng +Date: Tue, 29 Jan 2013 13:16:06 +0800 +Subject: nfsd: Fix memleak + +From: majianpeng + +commit 2d32b29a1c2830f7c42caa8258c714acd983961f upstream. + +When free nfs-client, it must free the ->cl_stateids. + +Signed-off-by: Jianpeng Ma +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4state.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -1060,6 +1060,8 @@ free_client(struct nfs4_client *clp) + } + free_svc_cred(&clp->cl_cred); + kfree(clp->cl_name.data); ++ idr_remove_all(&clp->cl_stateids); ++ idr_destroy(&clp->cl_stateids); + kfree(clp); + } + diff --git a/queue-3.8/series b/queue-3.8/series index 7956af3bc60..b18d86bee1a 100644 --- a/queue-3.8/series +++ b/queue-3.8/series @@ -51,3 +51,9 @@ ext4-release-sysfs-kobject-when-failing-to-enable-quotas-on-mount.patch ext4-fix-race-in-ext4_mb_add_n_trim.patch ext4-fix-xattr-block-allocation-release-with-bigalloc.patch ext4-fix-free-clusters-calculation-in-bigalloc-filesystem.patch +nfsd-fix-memleak.patch +svcrpc-make-svc_age_temp_xprts-enqueue-under-sv_lock.patch +svcrpc-fix-rpc-server-shutdown-races.patch +hid-add-support-for-sony-rf-receiver-with-usb-product-id-0x0374.patch +hid-clean-up-quirk-for-sony-rf-receivers.patch +fuse-don-t-warn-when-nlink-is-zero.patch diff --git a/queue-3.8/svcrpc-fix-rpc-server-shutdown-races.patch b/queue-3.8/svcrpc-fix-rpc-server-shutdown-races.patch new file mode 100644 index 00000000000..ddc4d7d9f9d --- /dev/null +++ b/queue-3.8/svcrpc-fix-rpc-server-shutdown-races.patch @@ -0,0 +1,149 @@ +From cc630d9f476445927fca599f81182c7f06f79058 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Sun, 10 Feb 2013 16:08:11 -0500 +Subject: svcrpc: fix rpc server shutdown races + +From: "J. Bruce Fields" + +commit cc630d9f476445927fca599f81182c7f06f79058 upstream. + +Rewrite server shutdown to remove the assumption that there are no +longer any threads running (no longer true, for example, when shutting +down the service in one network namespace while it's still running in +others). + +Do that by doing what we'd do in normal circumstances: just CLOSE each +socket, then enqueue it. + +Since there may not be threads to handle the resulting queued xprts, +also run a simplified version of the svc_recv() loop run by a server to +clean up any closed xprts afterwards. + +Tested-by: Jason Tibbitts +Tested-by: Paweł Sikora +Acked-by: Stanislav Kinsbursky +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/svc.c | 9 ------- + net/sunrpc/svc_xprt.c | 57 ++++++++++++++++++++++++++++---------------------- + 2 files changed, 32 insertions(+), 34 deletions(-) + +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -515,15 +515,6 @@ EXPORT_SYMBOL_GPL(svc_create_pooled); + + void svc_shutdown_net(struct svc_serv *serv, struct net *net) + { +- /* +- * The set of xprts (contained in the sv_tempsocks and +- * sv_permsocks lists) is now constant, since it is modified +- * only by accepting new sockets (done by service threads in +- * svc_recv) or aging old ones (done by sv_temptimer), or +- * configuration changes (excluded by whatever locking the +- * caller is using--nfsd_mutex in the case of nfsd). So it's +- * safe to traverse those lists and shut everything down: +- */ + svc_close_net(serv, net); + + if (serv->sv_shutdown) +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -948,21 +948,24 @@ void svc_close_xprt(struct svc_xprt *xpr + } + EXPORT_SYMBOL_GPL(svc_close_xprt); + +-static void svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net) ++static int svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net) + { + struct svc_xprt *xprt; ++ int ret = 0; + + spin_lock(&serv->sv_lock); + list_for_each_entry(xprt, xprt_list, xpt_list) { + if (xprt->xpt_net != net) + continue; ++ ret++; + set_bit(XPT_CLOSE, &xprt->xpt_flags); +- set_bit(XPT_BUSY, &xprt->xpt_flags); ++ svc_xprt_enqueue(xprt); + } + spin_unlock(&serv->sv_lock); ++ return ret; + } + +-static void svc_clear_pools(struct svc_serv *serv, struct net *net) ++static struct svc_xprt *svc_dequeue_net(struct svc_serv *serv, struct net *net) + { + struct svc_pool *pool; + struct svc_xprt *xprt; +@@ -977,42 +980,46 @@ static void svc_clear_pools(struct svc_s + if (xprt->xpt_net != net) + continue; + list_del_init(&xprt->xpt_ready); ++ spin_unlock_bh(&pool->sp_lock); ++ return xprt; + } + spin_unlock_bh(&pool->sp_lock); + } ++ return NULL; + } + +-static void svc_clear_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net) ++static void svc_clean_up_xprts(struct svc_serv *serv, struct net *net) + { + struct svc_xprt *xprt; +- struct svc_xprt *tmp; +- LIST_HEAD(victims); +- +- spin_lock(&serv->sv_lock); +- list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { +- if (xprt->xpt_net != net) +- continue; +- list_move(&xprt->xpt_list, &victims); +- } +- spin_unlock(&serv->sv_lock); + +- list_for_each_entry_safe(xprt, tmp, &victims, xpt_list) ++ while ((xprt = svc_dequeue_net(serv, net))) { ++ set_bit(XPT_CLOSE, &xprt->xpt_flags); + svc_delete_xprt(xprt); ++ } + } + ++/* ++ * Server threads may still be running (especially in the case where the ++ * service is still running in other network namespaces). ++ * ++ * So we shut down sockets the same way we would on a running server, by ++ * setting XPT_CLOSE, enqueuing, and letting a thread pick it up to do ++ * the close. In the case there are no such other threads, ++ * threads running, svc_clean_up_xprts() does a simple version of a ++ * server's main event loop, and in the case where there are other ++ * threads, we may need to wait a little while and then check again to ++ * see if they're done. ++ */ + void svc_close_net(struct svc_serv *serv, struct net *net) + { +- svc_close_list(serv, &serv->sv_tempsocks, net); +- svc_close_list(serv, &serv->sv_permsocks, net); ++ int delay = 0; ++ ++ while (svc_close_list(serv, &serv->sv_permsocks, net) + ++ svc_close_list(serv, &serv->sv_tempsocks, net)) { + +- svc_clear_pools(serv, net); +- /* +- * At this point the sp_sockets lists will stay empty, since +- * svc_xprt_enqueue will not add new entries without taking the +- * sp_lock and checking XPT_BUSY. +- */ +- svc_clear_list(serv, &serv->sv_tempsocks, net); +- svc_clear_list(serv, &serv->sv_permsocks, net); ++ svc_clean_up_xprts(serv, net); ++ msleep(delay++); ++ } + } + + /* diff --git a/queue-3.8/svcrpc-make-svc_age_temp_xprts-enqueue-under-sv_lock.patch b/queue-3.8/svcrpc-make-svc_age_temp_xprts-enqueue-under-sv_lock.patch new file mode 100644 index 00000000000..73d94549d54 --- /dev/null +++ b/queue-3.8/svcrpc-make-svc_age_temp_xprts-enqueue-under-sv_lock.patch @@ -0,0 +1,66 @@ +From e75bafbff2270993926abcc31358361db74a9bc2 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Sun, 10 Feb 2013 11:33:48 -0500 +Subject: svcrpc: make svc_age_temp_xprts enqueue under sv_lock + +From: "J. Bruce Fields" + +commit e75bafbff2270993926abcc31358361db74a9bc2 upstream. + +svc_age_temp_xprts expires xprts in a two-step process: first it takes +the sv_lock and moves the xprts to expire off their server-wide list +(sv_tempsocks or sv_permsocks) to a local list. Then it drops the +sv_lock and enqueues and puts each one. + +I see no reason for this: svc_xprt_enqueue() will take sp_lock, but the +sv_lock and sp_lock are not otherwise nested anywhere (and documentation +at the top of this file claims it's correct to nest these with sp_lock +inside.) + +Tested-by: Jason Tibbitts +Tested-by: Paweł Sikora +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/svc_xprt.c | 15 ++------------- + 1 file changed, 2 insertions(+), 13 deletions(-) + +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -856,7 +856,6 @@ static void svc_age_temp_xprts(unsigned + struct svc_serv *serv = (struct svc_serv *)closure; + struct svc_xprt *xprt; + struct list_head *le, *next; +- LIST_HEAD(to_be_aged); + + dprintk("svc_age_temp_xprts\n"); + +@@ -877,25 +876,15 @@ static void svc_age_temp_xprts(unsigned + if (atomic_read(&xprt->xpt_ref.refcount) > 1 || + test_bit(XPT_BUSY, &xprt->xpt_flags)) + continue; +- svc_xprt_get(xprt); +- list_move(le, &to_be_aged); ++ list_del_init(le); + set_bit(XPT_CLOSE, &xprt->xpt_flags); + set_bit(XPT_DETACHED, &xprt->xpt_flags); +- } +- spin_unlock_bh(&serv->sv_lock); +- +- while (!list_empty(&to_be_aged)) { +- le = to_be_aged.next; +- /* fiddling the xpt_list node is safe 'cos we're XPT_DETACHED */ +- list_del_init(le); +- xprt = list_entry(le, struct svc_xprt, xpt_list); +- + dprintk("queuing xprt %p for closing\n", xprt); + + /* a thread will dequeue and close it soon */ + svc_xprt_enqueue(xprt); +- svc_xprt_put(xprt); + } ++ spin_unlock_bh(&serv->sv_lock); + + mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); + } -- 2.47.3