From: Greg Kroah-Hartman Date: Mon, 6 Aug 2012 21:40:30 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.5.1~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8353e24ee2825e43e28c57ce14ccd88a6c94d88b;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: ext4-pass-a-char-to-ext4_count_free-instead-of-a-buffer_head-ptr.patch nfsd4-our-filesystems-are-normally-case-sensitive.patch nfs-skip-commit-in-releasepage-if-we-re-freeing-memory-for-fs-related-reasons.patch --- diff --git a/queue-3.0/ext4-pass-a-char-to-ext4_count_free-instead-of-a-buffer_head-ptr.patch b/queue-3.0/ext4-pass-a-char-to-ext4_count_free-instead-of-a-buffer_head-ptr.patch new file mode 100644 index 00000000000..8c1028f6263 --- /dev/null +++ b/queue-3.0/ext4-pass-a-char-to-ext4_count_free-instead-of-a-buffer_head-ptr.patch @@ -0,0 +1,78 @@ +From f6fb99cadcd44660c68e13f6eab28333653621e6 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sat, 30 Jun 2012 19:14:57 -0400 +Subject: ext4: pass a char * to ext4_count_free() instead of a buffer_head ptr + +From: Theodore Ts'o + +commit f6fb99cadcd44660c68e13f6eab28333653621e6 upstream. + +Make it possible for ext4_count_free to operate on buffers and not +just data in buffer_heads. + +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/balloc.c | 3 ++- + fs/ext4/bitmap.c | 8 +++----- + fs/ext4/ext4.h | 2 +- + fs/ext4/ialloc.c | 3 ++- + 4 files changed, 8 insertions(+), 8 deletions(-) + +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -514,7 +514,8 @@ ext4_fsblk_t ext4_count_free_blocks(stru + if (bitmap_bh == NULL) + continue; + +- x = ext4_count_free(bitmap_bh, sb->s_blocksize); ++ x = ext4_count_free(bitmap_bh->b_data, ++ EXT4_BLOCKS_PER_GROUP(sb) / 8); + printk(KERN_DEBUG "group %u: stored = %d, counted = %u\n", + i, ext4_free_blks_count(sb, gdp), x); + bitmap_count += x; +--- a/fs/ext4/bitmap.c ++++ b/fs/ext4/bitmap.c +@@ -15,15 +15,13 @@ + + static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; + +-unsigned int ext4_count_free(struct buffer_head *map, unsigned int numchars) ++unsigned int ext4_count_free(char *bitmap, unsigned int numchars) + { + unsigned int i, sum = 0; + +- if (!map) +- return 0; + for (i = 0; i < numchars; i++) +- sum += nibblemap[map->b_data[i] & 0xf] + +- nibblemap[(map->b_data[i] >> 4) & 0xf]; ++ sum += nibblemap[bitmap[i] & 0xf] + ++ nibblemap[(bitmap[i] >> 4) & 0xf]; + return sum; + } + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1713,7 +1713,7 @@ struct mmpd_data { + # define NORET_AND noreturn, + + /* bitmap.c */ +-extern unsigned int ext4_count_free(struct buffer_head *, unsigned); ++extern unsigned int ext4_count_free(char *bitmap, unsigned numchars); + + /* balloc.c */ + extern unsigned int ext4_block_group(struct super_block *sb, +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -1193,7 +1193,8 @@ unsigned long ext4_count_free_inodes(str + if (!bitmap_bh) + continue; + +- x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8); ++ x = ext4_count_free(bitmap_bh->b_data, ++ EXT4_INODES_PER_GROUP(sb) / 8); + printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n", + (unsigned long) i, ext4_free_inodes_count(sb, gdp), x); + bitmap_count += x; diff --git a/queue-3.0/nfs-skip-commit-in-releasepage-if-we-re-freeing-memory-for-fs-related-reasons.patch b/queue-3.0/nfs-skip-commit-in-releasepage-if-we-re-freeing-memory-for-fs-related-reasons.patch new file mode 100644 index 00000000000..719a7a024dd --- /dev/null +++ b/queue-3.0/nfs-skip-commit-in-releasepage-if-we-re-freeing-memory-for-fs-related-reasons.patch @@ -0,0 +1,173 @@ +From 5cf02d09b50b1ee1c2d536c9cf64af5a7d433f56 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Mon, 23 Jul 2012 13:58:51 -0400 +Subject: nfs: skip commit in releasepage if we're freeing memory for fs-related reasons + +From: Jeff Layton + +commit 5cf02d09b50b1ee1c2d536c9cf64af5a7d433f56 upstream. + +We've had some reports of a deadlock where rpciod ends up with a stack +trace like this: + + PID: 2507 TASK: ffff88103691ab40 CPU: 14 COMMAND: "rpciod/14" + #0 [ffff8810343bf2f0] schedule at ffffffff814dabd9 + #1 [ffff8810343bf3b8] nfs_wait_bit_killable at ffffffffa038fc04 [nfs] + #2 [ffff8810343bf3c8] __wait_on_bit at ffffffff814dbc2f + #3 [ffff8810343bf418] out_of_line_wait_on_bit at ffffffff814dbcd8 + #4 [ffff8810343bf488] nfs_commit_inode at ffffffffa039e0c1 [nfs] + #5 [ffff8810343bf4f8] nfs_release_page at ffffffffa038bef6 [nfs] + #6 [ffff8810343bf528] try_to_release_page at ffffffff8110c670 + #7 [ffff8810343bf538] shrink_page_list.clone.0 at ffffffff81126271 + #8 [ffff8810343bf668] shrink_inactive_list at ffffffff81126638 + #9 [ffff8810343bf818] shrink_zone at ffffffff8112788f + #10 [ffff8810343bf8c8] do_try_to_free_pages at ffffffff81127b1e + #11 [ffff8810343bf958] try_to_free_pages at ffffffff8112812f + #12 [ffff8810343bfa08] __alloc_pages_nodemask at ffffffff8111fdad + #13 [ffff8810343bfb28] kmem_getpages at ffffffff81159942 + #14 [ffff8810343bfb58] fallback_alloc at ffffffff8115a55a + #15 [ffff8810343bfbd8] ____cache_alloc_node at ffffffff8115a2d9 + #16 [ffff8810343bfc38] kmem_cache_alloc at ffffffff8115b09b + #17 [ffff8810343bfc78] sk_prot_alloc at ffffffff81411808 + #18 [ffff8810343bfcb8] sk_alloc at ffffffff8141197c + #19 [ffff8810343bfce8] inet_create at ffffffff81483ba6 + #20 [ffff8810343bfd38] __sock_create at ffffffff8140b4a7 + #21 [ffff8810343bfd98] xs_create_sock at ffffffffa01f649b [sunrpc] + #22 [ffff8810343bfdd8] xs_tcp_setup_socket at ffffffffa01f6965 [sunrpc] + #23 [ffff8810343bfe38] worker_thread at ffffffff810887d0 + #24 [ffff8810343bfee8] kthread at ffffffff8108dd96 + #25 [ffff8810343bff48] kernel_thread at ffffffff8100c1ca + +rpciod is trying to allocate memory for a new socket to talk to the +server. The VM ends up calling ->releasepage to get more memory, and it +tries to do a blocking commit. That commit can't succeed however without +a connected socket, so we deadlock. + +Fix this by setting PF_FSTRANS on the workqueue task prior to doing the +socket allocation, and having nfs_release_page check for that flag when +deciding whether to do a commit call. Also, set PF_FSTRANS +unconditionally in rpc_async_schedule since that function can also do +allocations sometimes. + +Signed-off-by: Jeff Layton +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/file.c | 7 +++++-- + net/sunrpc/sched.c | 2 ++ + net/sunrpc/xprtrdma/transport.c | 3 ++- + net/sunrpc/xprtsock.c | 10 ++++++++++ + 4 files changed, 19 insertions(+), 3 deletions(-) + +--- a/fs/nfs/file.c ++++ b/fs/nfs/file.c +@@ -493,8 +493,11 @@ static int nfs_release_page(struct page + + dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); + +- /* Only do I/O if gfp is a superset of GFP_KERNEL */ +- if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL) { ++ /* Only do I/O if gfp is a superset of GFP_KERNEL, and we're not ++ * doing this memory reclaim for a fs-related allocation. ++ */ ++ if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL && ++ !(current->flags & PF_FSTRANS)) { + int how = FLUSH_SYNC; + + /* Don't let kswapd deadlock waiting for OOM RPC calls */ +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -713,7 +713,9 @@ void rpc_execute(struct rpc_task *task) + + static void rpc_async_schedule(struct work_struct *work) + { ++ current->flags |= PF_FSTRANS; + __rpc_execute(container_of(work, struct rpc_task, u.tk_work)); ++ current->flags &= ~PF_FSTRANS; + } + + /** +--- a/net/sunrpc/xprtrdma/transport.c ++++ b/net/sunrpc/xprtrdma/transport.c +@@ -200,6 +200,7 @@ xprt_rdma_connect_worker(struct work_str + int rc = 0; + + if (!xprt->shutdown) { ++ current->flags |= PF_FSTRANS; + xprt_clear_connected(xprt); + + dprintk("RPC: %s: %sconnect\n", __func__, +@@ -212,10 +213,10 @@ xprt_rdma_connect_worker(struct work_str + + out: + xprt_wake_pending_tasks(xprt, rc); +- + out_clear: + dprintk("RPC: %s: exit\n", __func__); + xprt_clear_connecting(xprt); ++ current->flags &= ~PF_FSTRANS; + } + + /* +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -1882,6 +1882,8 @@ static void xs_local_setup_socket(struct + if (xprt->shutdown) + goto out; + ++ current->flags |= PF_FSTRANS; ++ + clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); + status = __sock_create(xprt->xprt_net, AF_LOCAL, + SOCK_STREAM, 0, &sock, 1); +@@ -1915,6 +1917,7 @@ static void xs_local_setup_socket(struct + out: + xprt_clear_connecting(xprt); + xprt_wake_pending_tasks(xprt, status); ++ current->flags &= ~PF_FSTRANS; + } + + static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) +@@ -1957,6 +1960,8 @@ static void xs_udp_setup_socket(struct w + if (xprt->shutdown) + goto out; + ++ current->flags |= PF_FSTRANS; ++ + /* Start by resetting any existing state */ + xs_reset_transport(transport); + sock = xs_create_sock(xprt, transport, +@@ -1975,6 +1980,7 @@ static void xs_udp_setup_socket(struct w + out: + xprt_clear_connecting(xprt); + xprt_wake_pending_tasks(xprt, status); ++ current->flags &= ~PF_FSTRANS; + } + + /* +@@ -2100,6 +2106,8 @@ static void xs_tcp_setup_socket(struct w + if (xprt->shutdown) + goto out; + ++ current->flags |= PF_FSTRANS; ++ + if (!sock) { + clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); + sock = xs_create_sock(xprt, transport, +@@ -2149,6 +2157,7 @@ static void xs_tcp_setup_socket(struct w + case -EINPROGRESS: + case -EALREADY: + xprt_clear_connecting(xprt); ++ current->flags &= ~PF_FSTRANS; + return; + case -EINVAL: + /* Happens, for instance, if the user specified a link +@@ -2161,6 +2170,7 @@ out_eagain: + out: + xprt_clear_connecting(xprt); + xprt_wake_pending_tasks(xprt, status); ++ current->flags &= ~PF_FSTRANS; + } + + /** diff --git a/queue-3.0/nfsd4-our-filesystems-are-normally-case-sensitive.patch b/queue-3.0/nfsd4-our-filesystems-are-normally-case-sensitive.patch new file mode 100644 index 00000000000..77fce2de76c --- /dev/null +++ b/queue-3.0/nfsd4-our-filesystems-are-normally-case-sensitive.patch @@ -0,0 +1,30 @@ +From 2930d381d22b9c56f40dd4c63a8fa59719ca2c3c Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Tue, 5 Jun 2012 16:52:06 -0400 +Subject: nfsd4: our filesystems are normally case sensitive + +From: "J. Bruce Fields" + +commit 2930d381d22b9c56f40dd4c63a8fa59719ca2c3c upstream. + +Actually, xfs and jfs can optionally be case insensitive; we'll handle +that case in later patches. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4xdr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -2010,7 +2010,7 @@ out_acl: + if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) { + if ((buflen -= 4) < 0) + goto out_resource; +- WRITE32(1); ++ WRITE32(0); + } + if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) { + if ((buflen -= 4) < 0) diff --git a/queue-3.0/series b/queue-3.0/series index ec17c1bcbd9..974c1dc9b24 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -21,3 +21,6 @@ drm-radeon-try-harder-to-avoid-hw-cursor-ending-on-a-multiple-of-128-columns.pat drm-radeon-fix-non-revealent-error-message.patch drm-radeon-fix-hotplug-of-dp-to-dvi-hdmi-passive-adapters-v2.patch drm-radeon-on-hotplug-force-link-training-to-happen-v2.patch +nfsd4-our-filesystems-are-normally-case-sensitive.patch +nfs-skip-commit-in-releasepage-if-we-re-freeing-memory-for-fs-related-reasons.patch +ext4-pass-a-char-to-ext4_count_free-instead-of-a-buffer_head-ptr.patch