[kernel] r16954 - in dists/squeeze/linux-2.6/debian: . patches/features/all/openvz patches/series
Maximilian Attems
maks at alioth.debian.org
Mon Feb 28 08:48:16 UTC 2011
Author: maks
Date: Mon Feb 28 08:48:08 2011
New Revision: 16954
Log:
openvz: add nfs fixes from openvz git
Tested-by: Steven Chamberlain <steven at pyro.eu.org>
Signed-off-by: maximilian attems <max at stro.at>
Added:
dists/squeeze/linux-2.6/debian/patches/features/all/openvz/0001-sunrpc-ve-semaphore-deadlock-fixed.patch
dists/squeeze/linux-2.6/debian/patches/features/all/openvz/0002-venfs-Backport-some-patches-from-rhel6-branch.patch
Modified:
dists/squeeze/linux-2.6/debian/changelog
dists/squeeze/linux-2.6/debian/patches/series/31-extra
Modified: dists/squeeze/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze/linux-2.6/debian/changelog Mon Feb 28 07:32:43 2011 (r16953)
+++ dists/squeeze/linux-2.6/debian/changelog Mon Feb 28 08:48:08 2011 (r16954)
@@ -46,6 +46,7 @@
[ maximilian attems]
* Update openvz patch to 07aaa2e9fb25 (ipv6, checkpointing, stability,
ipsec, ppp, tc). (closes: #607041, #613501)
+ * Add openvz nfs fixes. (closes: #613170)
[ Aurelien Jarno ]
* init: fix race between init and kthreadd, fixes a kernel panic on
Added: dists/squeeze/linux-2.6/debian/patches/features/all/openvz/0001-sunrpc-ve-semaphore-deadlock-fixed.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/openvz/0001-sunrpc-ve-semaphore-deadlock-fixed.patch Mon Feb 28 08:48:08 2011 (r16954)
@@ -0,0 +1,32 @@
+From 8bdd534e665fcdea94d9b3ff903e6a001b0ffa33 Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky at parallels.com>
+Date: Mon, 14 Feb 2011 17:44:41 +0300
+Subject: [PATCH 1/2] sunrpc: ve semaphore deadlock fixed
+
+Backported from rhel6
+We need to release semaphore before return from xs_tcp_setup_socket
+
+http://bugzilla.openvz.org/show_bug.cgi?id=1626
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky at parallels.com>
+Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
+---
+ net/sunrpc/xprtsock.c | 2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index 8907690..2548df3 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -1971,6 +1971,8 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt,
+ case -EINPROGRESS:
+ case -EALREADY:
+ xprt_clear_connecting(xprt);
++ up_read(&xprt->owner_env->op_sem);
++ (void)set_exec_env(ve);
+ return;
+ case -EINVAL:
+ /* Happens, for instance, if the user specified a link
+--
+1.7.4.1
+
Added: dists/squeeze/linux-2.6/debian/patches/features/all/openvz/0002-venfs-Backport-some-patches-from-rhel6-branch.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/openvz/0002-venfs-Backport-some-patches-from-rhel6-branch.patch Mon Feb 28 08:48:08 2011 (r16954)
@@ -0,0 +1,834 @@
+From 837466b643a74e0e61f5a3af09ef8c98f8f256a6 Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky at parallels.com>
+Date: Mon, 14 Feb 2011 17:44:55 +0300
+Subject: [PATCH 2/2] venfs: Backport some patches from rhel6 branch
+
+Combined NFS patch consist of:
+
+diff-ve-nfs-printk-veid-in-error-msgs
+diff-ve-nfs-safe-iterator-on-lockd-shutdown
+diff-ve-nfs-lockd-stop-fix-hosts-count-20081124-3
+diff-ve-nfs-superblock-list-20090312
+diff-ve-nfs-fix-sb_lock-usage-20090217
+diff-ve-nfs-abort-hard-at-init-death-20090210
+diff-ve-sanitize-feature-bits
+diff-ve-lockd-per-ct-grace-detection
+diff-ve-nfs-dont-make-xprt-sock-disapear-20090512
+diff-ve-nfs-remove-goto-restart
+diff-ve-nfs-clients-killing-helper
+diff-ve-nfs-shutdown-acl-client
+diff-ve-nfs-serialize-async-rpc-exec-vs-kill
+diff-ve-nfs-handle-rpc-task-errors-in-callbacks-tmp
+diff-ve-nfs-rpc-kill-task-if-clnt-is-broken
+diff-ve-nfs-stop-rework
+diff-nfs-dont-check-clnt-in-rpc-run-task
+diff-ve-nfs-lockd_down-at-proper-context
+diff-ve-nfs-dont-break-from-lockd-loop
+diff-ve-nfs-sunrpc-more-debug
+diff-ve-nfs-cleanup-clnt-task-killing
+diff-ve-nfs-lockd-stop-before-rpc
+diff-ve-umount-nfs-at-stop-20100112-2
+
+http://bugzilla.openvz.org/show_bug.cgi?id=1626
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky at parallels.com>
+Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
+---
+ fs/filesystems.c | 2 +-
+ fs/lockd/clntlock.c | 4 +++
+ fs/lockd/grace.c | 16 ++++++++++++
+ fs/lockd/host.c | 55 ++++++++++++++++++++++++++++-------------
+ fs/lockd/svc.c | 31 ++++++++++++-----------
+ fs/namespace.c | 5 +++-
+ fs/nfs/super.c | 37 ++++++++++++++++------------
+ include/linux/fs.h | 2 +-
+ include/linux/sunrpc/sched.h | 2 +
+ include/linux/ve.h | 1 +
+ include/linux/ve_proto.h | 1 +
+ include/linux/vzcalluser.h | 1 +
+ kernel/pid_namespace.c | 27 ++++++++++++--------
+ kernel/ve/ve.c | 3 +-
+ net/bridge/br.c | 2 -
+ net/sunrpc/clnt.c | 37 +++++++++-------------------
+ net/sunrpc/sched.c | 27 ++++++++++++++++++++
+ net/sunrpc/xprt.c | 2 +
+ 18 files changed, 163 insertions(+), 92 deletions(-)
+
+diff --git a/fs/filesystems.c b/fs/filesystems.c
+index bd5c213..da9f5ff 100644
+--- a/fs/filesystems.c
++++ b/fs/filesystems.c
+@@ -209,7 +209,7 @@ void unregister_ve_fs_type(struct file_system_type *local_fs_type,
+ return;
+
+ unregister_filesystem(local_fs_type);
+- umount_ve_fs_type(local_fs_type);
++ umount_ve_fs_type(local_fs_type, -1);
+ if (local_fs_mount)
+ kern_umount(local_fs_mount); /* alias to mntput, drop our ref */
+ put_filesystem(local_fs_type);
+diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
+index fc9032d..d54a216 100644
+--- a/fs/lockd/clntlock.c
++++ b/fs/lockd/clntlock.c
+@@ -78,8 +78,12 @@ EXPORT_SYMBOL_GPL(nlmclnt_init);
+ */
+ void nlmclnt_done(struct nlm_host *host)
+ {
++ struct ve_struct *old_ve;
++
+ nlm_release_host(host);
++ old_ve = set_exec_env(host->owner_env);
+ lockd_down();
++ (void)set_exec_env(old_ve);
+ }
+ EXPORT_SYMBOL_GPL(nlmclnt_done);
+
+diff --git a/fs/lockd/grace.c b/fs/lockd/grace.c
+index 183cc1f..afccd92 100644
+--- a/fs/lockd/grace.c
++++ b/fs/lockd/grace.c
+@@ -4,9 +4,13 @@
+
+ #include <linux/module.h>
+ #include <linux/lockd/bind.h>
++#include <linux/sched.h>
++#include <linux/ve.h>
+
++#ifndef CONFIG_VE
+ static LIST_HEAD(grace_list);
+ static DEFINE_SPINLOCK(grace_lock);
++#endif
+
+ /**
+ * locks_start_grace
+@@ -21,9 +25,13 @@ static DEFINE_SPINLOCK(grace_lock);
+ */
+ void locks_start_grace(struct lock_manager *lm)
+ {
++#ifdef CONFIG_VE
++ atomic_inc(&get_exec_env()->locks_in_grace);
++#else
+ spin_lock(&grace_lock);
+ list_add(&lm->list, &grace_list);
+ spin_unlock(&grace_lock);
++#endif
+ }
+ EXPORT_SYMBOL_GPL(locks_start_grace);
+
+@@ -39,9 +47,13 @@ EXPORT_SYMBOL_GPL(locks_start_grace);
+ */
+ void locks_end_grace(struct lock_manager *lm)
+ {
++#ifdef CONFIG_VE
++ atomic_dec(&get_exec_env()->locks_in_grace);
++#else
+ spin_lock(&grace_lock);
+ list_del_init(&lm->list);
+ spin_unlock(&grace_lock);
++#endif
+ }
+ EXPORT_SYMBOL_GPL(locks_end_grace);
+
+@@ -54,6 +66,10 @@ EXPORT_SYMBOL_GPL(locks_end_grace);
+ */
+ int locks_in_grace(void)
+ {
++#ifdef CONFIG_VE
++ return atomic_read(&get_exec_env()->locks_in_grace) != 0;
++#else
+ return !list_empty(&grace_list);
++#endif
+ }
+ EXPORT_SYMBOL_GPL(locks_in_grace);
+diff --git a/fs/lockd/host.c b/fs/lockd/host.c
+index 55cc770..3373909 100644
+--- a/fs/lockd/host.c
++++ b/fs/lockd/host.c
+@@ -30,7 +30,7 @@ static unsigned long next_gc;
+ static int nrhosts;
+ static DEFINE_MUTEX(nlm_host_mutex);
+
+-static void nlm_gc_hosts(void);
++static int nlm_gc_hosts(struct ve_struct *ve);
+
+ struct nlm_lookup_host_info {
+ const int server; /* search for server|client */
+@@ -98,10 +98,11 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
+ struct nsm_handle *nsm = NULL;
+ struct ve_struct *ve;
+
++ ve = get_exec_env();
+ mutex_lock(&nlm_host_mutex);
+
+ if (time_after_eq(jiffies, next_gc))
+- nlm_gc_hosts();
++ nlm_gc_hosts(ve);
+
+ /* We may keep several nlm_host objects for a peer, because each
+ * nlm_host is identified by
+@@ -111,7 +112,6 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
+ * This would allow us to have one nlm_host per address.
+ */
+
+- ve = get_exec_env();
+ chain = &nlm_hosts[nlm_hash_address(ni->sap)];
+ hlist_for_each_entry(host, pos, chain, h_hash) {
+ if (!rpc_cmp_addr(nlm_addr(host), ni->sap))
+@@ -499,6 +499,11 @@ nlm_shutdown_hosts(void)
+ struct hlist_head *chain;
+ struct hlist_node *pos;
+ struct nlm_host *host;
++ int nr_hosts_local;
++ struct ve_struct *ve;
++
++ ve = get_exec_env();
++ nr_hosts_local = 0;
+
+ dprintk("lockd: shutting down host module\n");
+ mutex_lock(&nlm_host_mutex);
+@@ -507,24 +512,29 @@ nlm_shutdown_hosts(void)
+ dprintk("lockd: nuking all hosts...\n");
+ for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+ hlist_for_each_entry(host, pos, chain, h_hash) {
++ if (!ve_accessible_strict(host->owner_env, ve))
++ continue;
+ host->h_expires = jiffies - 1;
+ if (host->h_rpcclnt) {
+ rpc_shutdown_client(host->h_rpcclnt);
+ host->h_rpcclnt = NULL;
+ }
++ nr_hosts_local++;
+ }
+ }
+
+ /* Then, perform a garbage collection pass */
+- nlm_gc_hosts();
++ nr_hosts_local -= nlm_gc_hosts(ve);
+ mutex_unlock(&nlm_host_mutex);
+
+ /* complain if any hosts are left */
+- if (nrhosts) {
++ if (nr_hosts_local) {
+ printk(KERN_WARNING "lockd: couldn't shutdown host module!\n");
+- dprintk("lockd: %d hosts left:\n", nrhosts);
++ dprintk("lockd: %d hosts left:\n", nr_hosts_local);
+ for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+ hlist_for_each_entry(host, pos, chain, h_hash) {
++ if (!ve_accessible_strict(host->owner_env, ve))
++ continue;
+ dprintk(" %s (cnt %d use %d exp %ld)\n",
+ host->h_name, atomic_read(&host->h_count),
+ host->h_inuse, host->h_expires);
+@@ -538,17 +548,23 @@ nlm_shutdown_hosts(void)
+ * This GC combines reference counting for async operations with
+ * mark & sweep for resources held by remote clients.
+ */
+-static void
+-nlm_gc_hosts(void)
++static int
++nlm_gc_hosts(struct ve_struct *ve)
+ {
+ struct hlist_head *chain;
+ struct hlist_node *pos, *next;
+ struct nlm_host *host;
++ int freed;
++
++ freed = 0;
+
+ dprintk("lockd: host garbage collection\n");
+ for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+- hlist_for_each_entry(host, pos, chain, h_hash)
++ hlist_for_each_entry(host, pos, chain, h_hash) {
++ if (!ve_accessible_strict(host->owner_env, ve))
++ continue;
+ host->h_inuse = 0;
++ }
+ }
+
+ /* Mark all hosts that hold locks, blocks or shares */
+@@ -557,7 +573,8 @@ nlm_gc_hosts(void)
+ for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+ hlist_for_each_entry_safe(host, pos, next, chain, h_hash) {
+ if (atomic_read(&host->h_count) || host->h_inuse
+- || time_before(jiffies, host->h_expires)) {
++ || time_before(jiffies, host->h_expires)
++ || !ve_accessible_strict(host->owner_env, ve)) {
+ dprintk("nlm_gc_hosts skipping %s (cnt %d use %d exp %ld)\n",
+ host->h_name, atomic_read(&host->h_count),
+ host->h_inuse, host->h_expires);
+@@ -568,10 +585,12 @@ nlm_gc_hosts(void)
+
+ nlm_destroy_host(host);
+ nrhosts--;
++ freed++;
+ }
+ }
+
+ next_gc = jiffies + NLM_HOST_COLLECT;
++ return freed;
+ }
+
+ #ifdef CONFIG_VE
+@@ -583,12 +602,15 @@ void ve_nlm_shutdown_hosts(struct ve_struct *ve)
+ dprintk("lockd: shutting down host module for ve %d\n", veid);
+ mutex_lock(&nlm_host_mutex);
+
++ /* Make sure no async RPC task is in progress */
++ down_write(&rpc_async_task_lock);
++
+ /* Perform a garbage collection pass */
+ for (i = 0; i < NLM_HOST_NRHASH; i++) {
+ struct nlm_host *host;
+- struct hlist_node *pos;
++ struct hlist_node *pos, *tmp;
+
+- hlist_for_each_entry(host, pos, &nlm_hosts[i], h_hash) {
++ hlist_for_each_entry_safe(host, pos, tmp, &nlm_hosts[i], h_hash) {
+ struct rpc_clnt *clnt;
+
+ if (ve != host->owner_env)
+@@ -601,14 +623,9 @@ void ve_nlm_shutdown_hosts(struct ve_struct *ve)
+ veid);
+ if ((clnt = host->h_rpcclnt) != NULL) {
+ if (!list_empty(&clnt->cl_tasks)) {
+- struct rpc_xprt *xprt;
+-
+ printk(KERN_WARNING
+ "lockd: active RPC handle\n");
+- rpc_killall_tasks(clnt);
+- xprt = clnt->cl_xprt;
+- xprt_disconnect_done(xprt);
+- xprt->ops->close(xprt);
++ rpc_kill_client(clnt);
+ } else
+ rpc_shutdown_client(clnt);
+ }
+@@ -617,6 +634,8 @@ void ve_nlm_shutdown_hosts(struct ve_struct *ve)
+ }
+ }
+
++ up_write(&rpc_async_task_lock);
++
+ mutex_unlock(&nlm_host_mutex);
+ }
+ #endif
+diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
+index b0cde74..e9e884a 100644
+--- a/fs/lockd/svc.c
++++ b/fs/lockd/svc.c
+@@ -176,17 +176,14 @@ lockd(void *vrqstp)
+ */
+ err = svc_recv(rqstp, timeout);
+ if (err == -EAGAIN || err == -EINTR) {
+-#ifdef CONFIG_VE
+- if (!get_exec_env()->is_running)
+- break;
+-#endif
+ preverr = err;
+ continue;
+ }
+ if (err < 0) {
+ if (err != preverr) {
+- printk(KERN_WARNING "%s: unexpected error "
+- "from svc_recv (%d)\n", __func__, err);
++ printk(KERN_WARNING "%s: ct%d unexpected error "
++ "from svc_recv (%d)\n", __func__,
++ get_exec_env()->veid, err);
+ preverr = err;
+ }
+ schedule_timeout_interruptible(HZ);
+@@ -289,12 +286,14 @@ int lockd_up(void)
+ */
+ if (nlmsvc_users)
+ printk(KERN_WARNING
+- "lockd_up: no pid, %d users??\n", nlmsvc_users);
++ "lockd_up: ct%d no pid, %d users??\n",
++ get_exec_env()->veid, nlmsvc_users);
+
+ error = -ENOMEM;
+ serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
+ if (!serv) {
+- printk(KERN_WARNING "lockd_up: create service failed\n");
++ printk(KERN_WARNING "lockd_up: ct%d create service failed\n",
++ get_exec_env()->veid);
+ goto out;
+ }
+
+@@ -310,8 +309,8 @@ int lockd_up(void)
+ error = PTR_ERR(nlmsvc_rqst);
+ nlmsvc_rqst = NULL;
+ printk(KERN_WARNING
+- "lockd_up: svc_rqst allocation failed, error=%d\n",
+- error);
++ "lockd_up: ct%d svc_rqst allocation failed, error=%d\n",
++ get_exec_env()->veid, error);
+ goto destroy_and_out;
+ }
+
+@@ -325,7 +324,8 @@ int lockd_up(void)
+ nlmsvc_task = NULL;
+ nlmsvc_rqst = NULL;
+ printk(KERN_WARNING
+- "lockd_up: kthread_run failed, error=%d\n", error);
++ "lockd_up: ct%d kthread_run failed, error=%d\n",
++ get_exec_env()->veid, error);
+ goto destroy_and_out;
+ }
+
+@@ -354,13 +354,14 @@ lockd_down(void)
+ if (--nlmsvc_users)
+ goto out;
+ } else {
+- printk(KERN_ERR "lockd_down: no users! task=%p\n",
+- nlmsvc_task);
++ printk(KERN_ERR "lockd_down: ct%d no users! task=%p\n",
++ get_exec_env()->veid, nlmsvc_task);
+ goto out;
+ }
+
+ if (!nlmsvc_task) {
+- printk(KERN_ERR "lockd_down: no lockd running.\n");
++ printk(KERN_ERR "lockd_down: ct%d no lockd running.\n",
++ get_exec_env()->veid);
+ goto out;
+ }
+ kthread_stop(nlmsvc_task);
+@@ -526,7 +527,7 @@ static struct ve_hook lockd_hook = {
+ .init = ve_lockd_start,
+ .fini = ve_lockd_stop,
+ .owner = THIS_MODULE,
+- .priority = HOOK_PRIO_FS,
++ .priority = HOOK_PRIO_NET,
+ };
+ #endif
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index b76df5d..d19de10 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1158,7 +1158,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
+ }
+
+ #ifdef CONFIG_VE
+-void umount_ve_fs_type(struct file_system_type *local_fs_type)
++void umount_ve_fs_type(struct file_system_type *local_fs_type, int veid)
+ {
+ struct vfsmount *mnt;
+ struct list_head *p, *q;
+@@ -1171,6 +1171,8 @@ void umount_ve_fs_type(struct file_system_type *local_fs_type)
+ mnt = list_entry(p, struct vfsmount, mnt_list);
+ if (mnt->mnt_sb->s_type != local_fs_type)
+ continue;
++ if (veid >= 0 && mnt->owner != veid)
++ continue;
+ list_del(p);
+ list_add(p, &kill);
+ }
+@@ -1185,6 +1187,7 @@ void umount_ve_fs_type(struct file_system_type *local_fs_type)
+ up_write(&namespace_sem);
+ release_mounts(&umount_list);
+ }
++EXPORT_SYMBOL(umount_ve_fs_type);
+ #endif
+
+ /*
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index 8ffb55b..724133c 100644
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -375,24 +375,29 @@ static void ve_nfs_stop(void *data)
+ force the client to stop.
+ Lock daemon is already dead.
+ Only superblock client remains. Den */
++
++ down_write(&rpc_async_task_lock);
++
+ spin_lock(&sb_lock);
+- list_for_each_entry(sb, &super_blocks, s_list) {
+- struct rpc_clnt *clnt;
+- struct rpc_xprt *xprt;
+- if (sb->s_type != &nfs_fs_type)
+- continue;
+- clnt = NFS_SB(sb)->client;
+- if (!ve_accessible_strict(clnt->cl_xprt->owner_env, ve))
+- continue;
+- clnt->cl_broken = 1;
+- rpc_killall_tasks(clnt);
++ list_for_each_entry(sb, &nfs_fs_type.fs_supers, s_instances) {
++ struct nfs_server *srv;
++ struct ve_struct *owner_env;
+
+- xprt = clnt->cl_xprt;
+- xprt_disconnect_done(xprt);
+- xprt->ops->close(xprt);
++ srv = NFS_SB(sb);
++ owner_env = srv->client->cl_xprt->owner_env;
++
++ if (ve_accessible_strict(owner_env, ve)) {
++ rpc_kill_client(srv->client);
++ rpc_kill_client(srv->client_acl);
++ }
+ }
+ spin_unlock(&sb_lock);
+
++ /* Make sure no async RPC task is in progress */
++ up_write(&rpc_async_task_lock);
++
++ umount_ve_fs_type(&nfs_fs_type, ve->veid);
++
+ flush_scheduled_work();
+ }
+
+@@ -424,7 +429,7 @@ int __init register_nfs_fs(void)
+ goto error_2;
+ #endif
+ register_shrinker(&acl_shrinker);
+- ve_hook_register(VE_SS_CHAIN, &nfs_hook);
++ ve_hook_register(VE_INIT_EXIT_CHAIN, &nfs_hook);
+ return 0;
+
+ #ifdef CONFIG_NFS_V4
+@@ -2196,7 +2201,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
+ struct ve_struct *ve;
+
+ ve = get_exec_env();
+- if (!ve_is_super(ve) && !(ve->features & VE_FEATURE_NFS))
++ if (!(ve->features & VE_FEATURE_NFS))
+ return -ENODEV;
+
+ data = nfs_alloc_parsed_mount_data(3);
+@@ -2331,7 +2336,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
+ struct ve_struct *ve;
+
+ ve = get_exec_env();
+- if (!ve_is_super(ve) && !(ve->features & VE_FEATURE_NFS))
++ if (!(ve->features & VE_FEATURE_NFS))
+ return -ENODEV;
+
+ dprintk("--> nfs_xdev_get_sb()\n");
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 6c4a03b..c4f5e61 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1836,7 +1836,7 @@ extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
+ extern int register_ve_fs_type(struct ve_struct *, struct file_system_type *,
+ struct file_system_type **, struct vfsmount **);
+ extern void unregister_ve_fs_type(struct file_system_type *, struct vfsmount *);
+-extern void umount_ve_fs_type(struct file_system_type *local_fs_type);
++extern void umount_ve_fs_type(struct file_system_type *local_fs_type, int veid);
+ #define kern_umount mntput
+ extern int may_umount_tree(struct vfsmount *);
+ extern struct vfsmount *next_mnt(struct vfsmount *p, struct vfsmount *root);
+diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
+index 4010977..b378ef3 100644
+--- a/include/linux/sunrpc/sched.h
++++ b/include/linux/sunrpc/sched.h
+@@ -216,6 +216,7 @@ void rpc_put_task(struct rpc_task *);
+ void rpc_exit_task(struct rpc_task *);
+ void rpc_release_calldata(const struct rpc_call_ops *, void *);
+ void rpc_killall_tasks(struct rpc_clnt *);
++void rpc_kill_client(struct rpc_clnt *);
+ void rpc_execute(struct rpc_task *);
+ void rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *);
+ void rpc_init_wait_queue(struct rpc_wait_queue *, const char *);
+@@ -239,6 +240,7 @@ void rpc_show_tasks(void);
+ int rpc_init_mempool(void);
+ void rpc_destroy_mempool(void);
+ extern struct workqueue_struct *rpciod_workqueue;
++extern struct rw_semaphore rpc_async_task_lock;
+ void rpc_prepare_task(struct rpc_task *task);
+
+ static inline void rpc_exit(struct rpc_task *task, int status)
+diff --git a/include/linux/ve.h b/include/linux/ve.h
+index c4ba1d0..c9a59e2 100644
+--- a/include/linux/ve.h
++++ b/include/linux/ve.h
+@@ -281,6 +281,7 @@ struct ve_struct {
+ int bm_entry_count;
+ struct list_head bm_entries;
+ #endif
++ atomic_t locks_in_grace;
+
+ struct nsproxy *ve_ns;
+ struct user_namespace *user_ns;
+diff --git a/include/linux/ve_proto.h b/include/linux/ve_proto.h
+index 5bb93e8..001c72f 100644
+--- a/include/linux/ve_proto.h
++++ b/include/linux/ve_proto.h
+@@ -50,6 +50,7 @@ int devperms_seq_show(struct seq_file *m, void *v);
+
+ enum {
+ VE_SS_CHAIN,
++ VE_INIT_EXIT_CHAIN,
+
+ VE_MAX_CHAINS
+ };
+diff --git a/include/linux/vzcalluser.h b/include/linux/vzcalluser.h
+index d093112..c55f977 100644
+--- a/include/linux/vzcalluser.h
++++ b/include/linux/vzcalluser.h
+@@ -109,6 +109,7 @@ struct env_create_param3 {
+ #define VE_FEATURE_PPP (1ULL << 5)
+ #define VE_FEATURE_IPGRE (1ULL << 6)
+ #define VE_FEATURE_BRIDGE (1ULL << 7)
++#define VE_FEATURE_NFSD (1ULL << 8)
+
+ #define VE_FEATURES_OLD (VE_FEATURE_SYSFS)
+ #define VE_FEATURES_DEF (VE_FEATURE_SYSFS | \
+diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
+index 6d3f029..19a9c6a 100644
+--- a/kernel/pid_namespace.c
++++ b/kernel/pid_namespace.c
+@@ -14,6 +14,7 @@
+ #include <linux/err.h>
+ #include <linux/acct.h>
+ #include <linux/module.h>
++#include <linux/ve_proto.h>
+
+ #include <bc/kmem.h>
+
+@@ -241,17 +242,6 @@ static noinline void show_lost_task(struct task_struct *p)
+
+ static void zap_ve_processes(struct ve_struct *env)
+ {
+- /*
+- * Here the VE changes its state into "not running".
+- * op_sem taken for write is a barrier to all VE manipulations from
+- * ioctl: it waits for operations currently in progress and blocks all
+- * subsequent operations until is_running is set to 0 and op_sem is
+- * released.
+- */
+- down_write(&env->op_sem);
+- env->is_running = 0;
+- up_write(&env->op_sem);
+-
+ /* wait for all init childs exit */
+ while (atomic_read(&env->pcounter) > 1) {
+ struct task_struct *g, *p;
+@@ -294,6 +284,21 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
+ int nr;
+ int rc;
+ struct task_struct *task;
++ struct ve_struct *env = get_exec_env();
++
++ /*
++ * Here the VE changes its state into "not running".
++ * op_sem taken for write is a barrier to all VE manipulations from
++ * ioctl: it waits for operations currently in progress and blocks all
++ * subsequent operations until is_running is set to 0 and op_sem is
++ * released.
++ */
++
++ down_write(&env->op_sem);
++ env->is_running = 0;
++ up_write(&env->op_sem);
++
++ ve_hook_iterate_fini(VE_INIT_EXIT_CHAIN, env);
+
+ /*
+ * The last thread in the cgroup-init thread group is terminating.
+diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
+index 907d944..ce829c7 100644
+--- a/kernel/ve/ve.c
++++ b/kernel/ve/ve.c
+@@ -79,8 +79,7 @@ struct ve_struct ve0 = {
+ .ipt_mask = VE_IP_ALL,
+ ._iptables_modules = VE_IP_ALL,
+ #endif
+- .features = VE_FEATURE_SIT | VE_FEATURE_IPIP |
+- VE_FEATURE_PPP,
++ .features = -1,
+ ._randomize_va_space =
+ #ifdef CONFIG_COMPAT_BRK
+ 1,
+diff --git a/net/bridge/br.c b/net/bridge/br.c
+index 455a4e6..fedf0dc 100644
+--- a/net/bridge/br.c
++++ b/net/bridge/br.c
+@@ -62,8 +62,6 @@ static int __init br_init(void)
+ if (err)
+ goto err_out4;
+
+- get_ve0()->features |= VE_FEATURE_BRIDGE;
+-
+ brioctl_set(br_ioctl_deviceless_stub);
+ br_handle_frame_hook = br_handle_frame;
+ br_hard_xmit_hook = br_xmit;
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index fad3e2b..b32b4ce 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -115,6 +115,9 @@ static int rpc_abort_hard(struct rpc_task *task)
+ if (time_before(jiffies, clnt->cl_pr_time + xprt_abort_timeout * HZ))
+ return 0;
+
++ printk(KERN_ERR "CT#%u: RPC client %p (server %s) is marked 'broken'. "
++ "Unmount/mount to get it working again.\n",
++ get_exec_env()->veid, clnt, clnt->cl_server);
+ clnt->cl_broken = 1;
+ rpc_killall_tasks(clnt);
+ return -ETIMEDOUT;
+@@ -591,9 +594,6 @@ struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
+ {
+ struct rpc_task *task, *ret;
+
+- if (task_setup_data->rpc_client->cl_broken)
+- return ERR_PTR(-EIO);
+-
+ task = rpc_new_task(task_setup_data);
+ if (task == NULL) {
+ rpc_release_calldata(task_setup_data->callback_ops,
+@@ -1364,8 +1364,8 @@ call_status(struct rpc_task *task)
+ break;
+ default:
+ if (clnt->cl_chatty)
+- printk("%s: RPC call returned error %d\n",
+- clnt->cl_protname, -status);
++ printk("ct%d %s: RPC call returned error %d\n",
++ get_exec_env()->veid, clnt->cl_protname, -status);
+ rpc_exit(task, status);
+ }
+ }
+@@ -1390,8 +1390,8 @@ call_timeout(struct rpc_task *task)
+
+ if (RPC_IS_SOFT(task) || rpc_abort_hard(task)) {
+ if (clnt->cl_chatty)
+- printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
+- clnt->cl_protname, clnt->cl_server);
++ printk(KERN_NOTICE "ct%d %s: server %s not responding, timed out\n",
++ get_exec_env()->veid, clnt->cl_protname, clnt->cl_server);
+ rpc_exit(task, -EIO);
+ return;
+ }
+@@ -1399,8 +1399,8 @@ call_timeout(struct rpc_task *task)
+ if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) {
+ task->tk_flags |= RPC_CALL_MAJORSEEN;
+ if (clnt->cl_chatty)
+- printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
+- clnt->cl_protname, clnt->cl_server);
++ printk(KERN_NOTICE "ct%d %s: server %s not responding, still trying\n",
++ get_exec_env()->veid, clnt->cl_protname, clnt->cl_server);
+ }
+ rpc_force_rebind(clnt);
+ /*
+@@ -1431,8 +1431,8 @@ call_decode(struct rpc_task *task)
+
+ if (task->tk_flags & RPC_CALL_MAJORSEEN) {
+ if (clnt->cl_chatty)
+- printk(KERN_NOTICE "%s: server %s OK\n",
+- clnt->cl_protname, clnt->cl_server);
++ printk(KERN_NOTICE "ct%d %s: server %s OK\n",
++ get_exec_env()->veid, clnt->cl_protname, clnt->cl_server);
+ task->tk_flags &= ~RPC_CALL_MAJORSEEN;
+ }
+
+@@ -1808,7 +1808,6 @@ void ve_sunrpc_stop(void *data)
+ {
+ struct ve_struct *ve = (struct ve_struct *)data;
+ struct rpc_clnt *clnt;
+- struct rpc_task *rovr;
+
+ dprintk("RPC: killing all tasks for VE %d\n", ve->veid);
+
+@@ -1817,19 +1816,7 @@ void ve_sunrpc_stop(void *data)
+ if (clnt->cl_xprt->owner_env != ve)
+ continue;
+
+- spin_lock(&clnt->cl_lock);
+- list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) {
+- if (!RPC_IS_ACTIVATED(rovr))
+- continue;
+- printk(KERN_WARNING "RPC: Killing task %d client %p\n",
+- rovr->tk_pid, clnt);
+-
+- rovr->tk_flags |= RPC_TASK_KILLED;
+- rpc_exit(rovr, -EIO);
+- rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr);
+- }
+- schedule_work(&clnt->cl_xprt->task_cleanup);
+- spin_unlock(&clnt->cl_lock);
++ rpc_killall_tasks(clnt);
+ }
+ spin_unlock(&rpc_client_lock);
+
+diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
+index fba30fe..2f64305 100644
+--- a/net/sunrpc/sched.c
++++ b/net/sunrpc/sched.c
+@@ -52,6 +52,8 @@ static struct rpc_wait_queue delay_queue;
+ * rpciod-related stuff
+ */
+ struct workqueue_struct *rpciod_workqueue;
++DECLARE_RWSEM(rpc_async_task_lock);
++EXPORT_SYMBOL(rpc_async_task_lock);
+
+ /*
+ * Disable the timer for a given RPC task. Should be called with
+@@ -617,6 +619,19 @@ static void __rpc_execute(struct rpc_task *task)
+ for (;;) {
+
+ /*
++ * Finish this task with error state if RPC client is already
++ * broken.
++ */
++ if (task->tk_client->cl_broken) {
++ dprintk("RPC: client 0x%p is broken. Drop task %d "
++ "with EIO.",
++ task->tk_client, task->tk_pid);
++ task->tk_flags |= RPC_TASK_KILLED;
++ rpc_exit(task, -EIO);
++ break;
++ }
++
++ /*
+ * Execute any pending callback.
+ */
+ if (task->tk_callback) {
+@@ -715,7 +730,9 @@ void rpc_execute(struct rpc_task *task)
+
+ static void rpc_async_schedule(struct work_struct *work)
+ {
++ down_read(&rpc_async_task_lock);
+ __rpc_execute(container_of(work, struct rpc_task, u.tk_work));
++ up_read(&rpc_async_task_lock);
+ }
+
+ /**
+@@ -951,6 +968,16 @@ void rpc_killall_tasks(struct rpc_clnt *clnt)
+ }
+ EXPORT_SYMBOL_GPL(rpc_killall_tasks);
+
++void rpc_kill_client(struct rpc_clnt *clnt)
++{
++ if (!IS_ERR(clnt)) {
++ clnt->cl_broken = 1;
++ clnt->cl_pr_time = jiffies - xprt_abort_timeout * HZ - 1;
++ rpc_killall_tasks(clnt);
++ }
++}
++EXPORT_SYMBOL_GPL(rpc_kill_client);
++
+ int rpciod_up(void)
+ {
+ return try_module_get(THIS_MODULE) ? 0 : -EINVAL;
+diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
+index 48d4f3e..0268167 100644
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -1154,6 +1154,7 @@ void xprt_put(struct rpc_xprt *xprt)
+ {
+ kref_put(&xprt->kref, xprt_destroy);
+ }
++EXPORT_SYMBOL(xprt_put);
+
+ /**
+ * xprt_get - return a reference to an RPC transport.
+@@ -1165,3 +1166,4 @@ struct rpc_xprt *xprt_get(struct rpc_xprt *xprt)
+ kref_get(&xprt->kref);
+ return xprt;
+ }
++EXPORT_SYMBOL(xprt_get);
+--
+1.7.4.1
+
Modified: dists/squeeze/linux-2.6/debian/patches/series/31-extra
==============================================================================
--- dists/squeeze/linux-2.6/debian/patches/series/31-extra Mon Feb 28 07:32:43 2011 (r16953)
+++ dists/squeeze/linux-2.6/debian/patches/series/31-extra Mon Feb 28 08:48:08 2011 (r16954)
@@ -1,5 +1,7 @@
+ debian/revert-sched-changes-in-2.6.32.29.patch featureset=openvz
+ features/all/openvz/openvz.patch featureset=openvz
++ features/all/openvz/0001-sunrpc-ve-semaphore-deadlock-fixed.patch featureset=openvz
++ features/all/openvz/0002-venfs-Backport-some-patches-from-rhel6-branch.patch featureset=openvz
+ debian/revert-sched-changes-in-2.6.32.29.patch featureset=vserver
+ features/all/vserver/vs2.3.0.36.29.6.patch featureset=vserver
More information about the Kernel-svn-changes
mailing list