From: Greg Kroah-Hartman Date: Sat, 18 Sep 2010 17:44:27 +0000 (-0700) Subject: .35 patches X-Git-Tag: v2.6.27.54~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=75d76a45e0e220ac95730ed61b14c4e22a78c6a3;p=thirdparty%2Fkernel%2Fstable-queue.git .35 patches --- diff --git a/queue-2.6.35/apm_power-add-missing-break-statement.patch b/queue-2.6.35/apm_power-add-missing-break-statement.patch new file mode 100644 index 00000000000..0ff6f973787 --- /dev/null +++ b/queue-2.6.35/apm_power-add-missing-break-statement.patch @@ -0,0 +1,30 @@ +From 1d220334d6a8a711149234dc5f98d34ae02226b8 Mon Sep 17 00:00:00 2001 +From: Anton Vorontsov +Date: Wed, 8 Sep 2010 00:10:26 +0400 +Subject: apm_power: Add missing break statement + +From: Anton Vorontsov + +commit 1d220334d6a8a711149234dc5f98d34ae02226b8 upstream. + +The missing break statement causes wrong capacity calculation for +batteries that report energy. + +Reported-by: d binderman +Signed-off-by: Anton Vorontsov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/apm_power.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/power/apm_power.c ++++ b/drivers/power/apm_power.c +@@ -233,6 +233,7 @@ static int calculate_capacity(enum apm_s + empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN; + now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; + avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; ++ break; + case SOURCE_VOLTAGE: + full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX; + empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN; diff --git a/queue-2.6.35/arm-fix-really-nasty-sigreturn-bug.patch b/queue-2.6.35/arm-fix-really-nasty-sigreturn-bug.patch new file mode 100644 index 00000000000..6a95ffa415b --- /dev/null +++ b/queue-2.6.35/arm-fix-really-nasty-sigreturn-bug.patch @@ -0,0 +1,95 @@ +From 653d48b22166db2d8b1515ebe6f9f0f7c95dfc86 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 17 Sep 2010 14:34:39 +0100 +Subject: arm: fix really nasty sigreturn bug + +From: Al Viro + +commit 653d48b22166db2d8b1515ebe6f9f0f7c95dfc86 upstream. + +If a signal hits us outside of a syscall and another gets delivered +when we are in sigreturn (e.g. because it had been in sa_mask for +the first one and got sent to us while we'd been in the first handler), +we have a chance of returning from the second handler to location one +insn prior to where we ought to return. If r0 happens to contain -513 +(-ERESTARTNOINTR), sigreturn will get confused into doing restart +syscall song and dance. + +Incredible joy to debug, since it manifests as random, infrequent and +very hard to reproduce double execution of instructions in userland +code... + +The fix is simple - mark it "don't bother with restarts" in wrapper, +i.e. set r8 to 0 in sys_sigreturn and sys_rt_sigreturn wrappers, +suppressing the syscall restart handling on return from these guys. +They can't legitimately return a restart-worthy error anyway. + +Testcase: + #include + #include + #include + #include + #include + + void f(int n) + { + __asm__ __volatile__( + "ldr r0, [%0]\n" + "b 1f\n" + "b 2f\n" + "1:b .\n" + "2:\n" : : "r"(&n)); + } + + void handler1(int sig) { } + void handler2(int sig) { raise(1); } + void handler3(int sig) { exit(0); } + + main() + { + struct sigaction s = {.sa_handler = handler2}; + struct itimerval t1 = { .it_value = {1} }; + struct itimerval t2 = { .it_value = {2} }; + + signal(1, handler1); + + sigemptyset(&s.sa_mask); + sigaddset(&s.sa_mask, 1); + sigaction(SIGALRM, &s, NULL); + + signal(SIGVTALRM, handler3); + + setitimer(ITIMER_REAL, &t1, NULL); + setitimer(ITIMER_VIRTUAL, &t2, NULL); + + f(-513); /* -ERESTARTNOINTR */ + + write(1, "buggered\n", 9); + return 1; + } + +Signed-off-by: Al Viro +Acked-by: Russell King +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/kernel/entry-common.S | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arm/kernel/entry-common.S ++++ b/arch/arm/kernel/entry-common.S +@@ -382,11 +382,13 @@ ENDPROC(sys_clone_wrapper) + + sys_sigreturn_wrapper: + add r0, sp, #S_OFF ++ mov why, #0 @ prevent syscall restart handling + b sys_sigreturn + ENDPROC(sys_sigreturn_wrapper) + + sys_rt_sigreturn_wrapper: + add r0, sp, #S_OFF ++ mov why, #0 @ prevent syscall restart handling + b sys_rt_sigreturn + ENDPROC(sys_rt_sigreturn_wrapper) + diff --git a/queue-2.6.35/cifs-fix-potential-double-put-of-tcp-session-reference.patch b/queue-2.6.35/cifs-fix-potential-double-put-of-tcp-session-reference.patch new file mode 100644 index 00000000000..06cf4625af1 --- /dev/null +++ b/queue-2.6.35/cifs-fix-potential-double-put-of-tcp-session-reference.patch @@ -0,0 +1,54 @@ +From 460cf3411b858ad509d5255e0dfaf862a83c0299 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Tue, 14 Sep 2010 11:38:24 -0400 +Subject: cifs: fix potential double put of TCP session reference + +From: Jeff Layton + +commit 460cf3411b858ad509d5255e0dfaf862a83c0299 upstream. + +cifs_get_smb_ses must be called on a server pointer on which it holds an +active reference. It first does a search for an existing SMB session. If +it finds one, it'll put the server reference and then try to ensure that +the negprot is done, etc. + +If it encounters an error at that point then it'll return an error. +There's a potential problem here though. When cifs_get_smb_ses returns +an error, the caller will also put the TCP server reference leading to a +double-put. + +Fix this by having cifs_get_smb_ses only put the server reference if +it found an existing session that it could use and isn't returning an +error. + +Reviewed-by: Suresh Jayaraman +Signed-off-by: Jeff Layton +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/connect.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -1647,9 +1647,6 @@ cifs_get_smb_ses(struct TCP_Server_Info + if (ses) { + cFYI(1, "Existing smb sess found (status=%d)", ses->status); + +- /* existing SMB ses has a server reference already */ +- cifs_put_tcp_session(server); +- + mutex_lock(&ses->session_mutex); + rc = cifs_negotiate_protocol(xid, ses); + if (rc) { +@@ -1672,6 +1669,9 @@ cifs_get_smb_ses(struct TCP_Server_Info + } + } + mutex_unlock(&ses->session_mutex); ++ ++ /* existing SMB ses has a server reference already */ ++ cifs_put_tcp_session(server); + FreeXid(xid); + return ses; + } diff --git a/queue-2.6.35/hwmon-emc1403-remove-unnecessary-hwmon_device_unregister.patch b/queue-2.6.35/hwmon-emc1403-remove-unnecessary-hwmon_device_unregister.patch new file mode 100644 index 00000000000..db37efcd9e9 --- /dev/null +++ b/queue-2.6.35/hwmon-emc1403-remove-unnecessary-hwmon_device_unregister.patch @@ -0,0 +1,31 @@ +From f17c811d1433aa1966f9c5a744841427e9a97ecf Mon Sep 17 00:00:00 2001 +From: Yong Wang +Date: Fri, 17 Sep 2010 17:24:12 +0200 +Subject: hwmon: (emc1403) Remove unnecessary hwmon_device_unregister + +From: Yong Wang + +commit f17c811d1433aa1966f9c5a744841427e9a97ecf upstream. + +It is unnecessary and wrong to call hwmon_device_unregister in error +handling before hwmon_device_register is called. + +Signed-off-by: Yong Wang +Reviewed-by: Guenter Roeck +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/emc1403.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/hwmon/emc1403.c ++++ b/drivers/hwmon/emc1403.c +@@ -275,7 +275,6 @@ static int emc1403_probe(struct i2c_clie + res = sysfs_create_group(&client->dev.kobj, &m_thermal_gr); + if (res) { + dev_warn(&client->dev, "create group failed\n"); +- hwmon_device_unregister(data->hwmon_dev); + goto thermal_error1; + } + data->hwmon_dev = hwmon_device_register(&client->dev); diff --git a/queue-2.6.35/hwmon-f75375s-do-not-overwrite-values-read-from-registers.patch b/queue-2.6.35/hwmon-f75375s-do-not-overwrite-values-read-from-registers.patch new file mode 100644 index 00000000000..2161d5cea3a --- /dev/null +++ b/queue-2.6.35/hwmon-f75375s-do-not-overwrite-values-read-from-registers.patch @@ -0,0 +1,42 @@ +From c3b327d60bbba3f5ff8fd87d1efc0e95eb6c121b Mon Sep 17 00:00:00 2001 +From: Guillem Jover +Date: Fri, 17 Sep 2010 17:24:12 +0200 +Subject: hwmon: (f75375s) Do not overwrite values read from registers + +From: Guillem Jover + +commit c3b327d60bbba3f5ff8fd87d1efc0e95eb6c121b upstream. + +All bits in the values read from registers to be used for the next +write were getting overwritten, avoid doing so to not mess with the +current configuration. + +Signed-off-by: Guillem Jover +Cc: Riku Voipio +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/f75375s.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/hwmon/f75375s.c ++++ b/drivers/hwmon/f75375s.c +@@ -298,7 +298,7 @@ static int set_pwm_enable_direct(struct + return -EINVAL; + + fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); +- fanmode = ~(3 << FAN_CTRL_MODE(nr)); ++ fanmode &= ~(3 << FAN_CTRL_MODE(nr)); + + switch (val) { + case 0: /* Full speed */ +@@ -350,7 +350,7 @@ static ssize_t set_pwm_mode(struct devic + + mutex_lock(&data->update_lock); + conf = f75375_read8(client, F75375_REG_CONFIG1); +- conf = ~(1 << FAN_CTRL_LINEAR(nr)); ++ conf &= ~(1 << FAN_CTRL_LINEAR(nr)); + + if (val == 0) + conf |= (1 << FAN_CTRL_LINEAR(nr)) ; diff --git a/queue-2.6.35/hwmon-f75375s-shift-control-mode-to-the-correct-bit-position.patch b/queue-2.6.35/hwmon-f75375s-shift-control-mode-to-the-correct-bit-position.patch new file mode 100644 index 00000000000..191c618988a --- /dev/null +++ b/queue-2.6.35/hwmon-f75375s-shift-control-mode-to-the-correct-bit-position.patch @@ -0,0 +1,33 @@ +From 96f3640894012be7dd15a384566bfdc18297bc6c Mon Sep 17 00:00:00 2001 +From: Guillem Jover +Date: Fri, 17 Sep 2010 17:24:11 +0200 +Subject: hwmon: (f75375s) Shift control mode to the correct bit position + +From: Guillem Jover + +commit 96f3640894012be7dd15a384566bfdc18297bc6c upstream. + +The spec notes that fan0 and fan1 control mode bits are located in bits +7-6 and 5-4 respectively, but the FAN_CTRL_MODE macro was making the +bits shift by 5 instead of by 4. + +Signed-off-by: Guillem Jover +Cc: Riku Voipio +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/f75375s.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwmon/f75375s.c ++++ b/drivers/hwmon/f75375s.c +@@ -79,7 +79,7 @@ enum chips { f75373, f75375 }; + #define F75375_REG_PWM2_DROP_DUTY 0x6C + + #define FAN_CTRL_LINEAR(nr) (4 + nr) +-#define FAN_CTRL_MODE(nr) (5 + ((nr) * 2)) ++#define FAN_CTRL_MODE(nr) (4 + ((nr) * 2)) + + /* + * Data structures and manipulation thereof diff --git a/queue-2.6.35/nfs-fix-a-typo-in-nfs_sockaddr_match_ipaddr6.patch b/queue-2.6.35/nfs-fix-a-typo-in-nfs_sockaddr_match_ipaddr6.patch new file mode 100644 index 00000000000..8256929a048 --- /dev/null +++ b/queue-2.6.35/nfs-fix-a-typo-in-nfs_sockaddr_match_ipaddr6.patch @@ -0,0 +1,28 @@ +From b20d37ca9561711c6a3c4b859c2855f49565e061 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Sun, 12 Sep 2010 19:55:26 -0400 +Subject: NFS: Fix a typo in nfs_sockaddr_match_ipaddr6 + +From: Trond Myklebust + +commit b20d37ca9561711c6a3c4b859c2855f49565e061 upstream. + +Reported-by: Ben Greear +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/client.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/client.c ++++ b/fs/nfs/client.c +@@ -274,7 +274,7 @@ static int nfs_sockaddr_match_ipaddr6(co + sin1->sin6_scope_id != sin2->sin6_scope_id) + return 0; + +- return ipv6_addr_equal(&sin1->sin6_addr, &sin1->sin6_addr); ++ return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr); + } + #else /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */ + static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1, diff --git a/queue-2.6.35/series b/queue-2.6.35/series index c078d03510d..fb8e2c0d0c2 100644 --- a/queue-2.6.35/series +++ b/queue-2.6.35/series @@ -102,3 +102,12 @@ compat-make-compat_alloc_user_space-incorporate-the-access_ok.patch x86-64-compat-retruncate-rax-after-ia32-syscall-entry-tracing.patch alsa-hda-enable-internal-speaker-on-dell-m101z.patch x86-hpet-work-around-hardware-stupidity.patch +arm-fix-really-nasty-sigreturn-bug.patch +hwmon-emc1403-remove-unnecessary-hwmon_device_unregister.patch +hwmon-f75375s-shift-control-mode-to-the-correct-bit-position.patch +hwmon-f75375s-do-not-overwrite-values-read-from-registers.patch +apm_power-add-missing-break-statement.patch +cifs-fix-potential-double-put-of-tcp-session-reference.patch +nfs-fix-a-typo-in-nfs_sockaddr_match_ipaddr6.patch +sunrpc-fix-race-corrupting-rpc-upcall.patch +sunrpc-fix-a-race-in-rpc_info_open.patch diff --git a/queue-2.6.35/sunrpc-fix-a-race-in-rpc_info_open.patch b/queue-2.6.35/sunrpc-fix-a-race-in-rpc_info_open.patch new file mode 100644 index 00000000000..f839e28f978 --- /dev/null +++ b/queue-2.6.35/sunrpc-fix-a-race-in-rpc_info_open.patch @@ -0,0 +1,147 @@ +From 006abe887c5e637d059c44310de6c92f36aded3b Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Sun, 12 Sep 2010 19:55:25 -0400 +Subject: SUNRPC: Fix a race in rpc_info_open + +From: Trond Myklebust + +commit 006abe887c5e637d059c44310de6c92f36aded3b upstream. + +There is a race between rpc_info_open and rpc_release_client() +in that nothing stops a process from opening the file after +the clnt->cl_kref goes to zero. + +Fix this by using atomic_inc_unless_zero()... + +Reported-by: J. Bruce Fields +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/sunrpc/clnt.h | 2 +- + net/sunrpc/clnt.c | 24 +++++++++++------------- + net/sunrpc/rpc_pipe.c | 14 ++++++++------ + 3 files changed, 20 insertions(+), 20 deletions(-) + +--- a/include/linux/sunrpc/clnt.h ++++ b/include/linux/sunrpc/clnt.h +@@ -30,7 +30,7 @@ struct rpc_inode; + * The high-level client handle + */ + struct rpc_clnt { +- struct kref cl_kref; /* Number of references */ ++ atomic_t cl_count; /* Number of references */ + struct list_head cl_clients; /* Global list of clients */ + struct list_head cl_tasks; /* List of tasks */ + spinlock_t cl_lock; /* spinlock */ +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -226,7 +226,7 @@ static struct rpc_clnt * rpc_new_client( + goto out_no_principal; + } + +- kref_init(&clnt->cl_kref); ++ atomic_set(&clnt->cl_count, 1); + + err = rpc_setup_pipedir(clnt, program->pipe_dir_name); + if (err < 0) +@@ -390,14 +390,14 @@ rpc_clone_client(struct rpc_clnt *clnt) + if (new->cl_principal == NULL) + goto out_no_principal; + } +- kref_init(&new->cl_kref); ++ atomic_set(&new->cl_count, 1); + err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); + if (err != 0) + goto out_no_path; + if (new->cl_auth) + atomic_inc(&new->cl_auth->au_count); + xprt_get(clnt->cl_xprt); +- kref_get(&clnt->cl_kref); ++ atomic_inc(&clnt->cl_count); + rpc_register_client(new); + rpciod_up(); + return new; +@@ -436,10 +436,8 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); + * Free an RPC client + */ + static void +-rpc_free_client(struct kref *kref) ++rpc_free_client(struct rpc_clnt *clnt) + { +- struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); +- + dprintk("RPC: destroying %s client for %s\n", + clnt->cl_protname, clnt->cl_server); + if (!IS_ERR(clnt->cl_path.dentry)) { +@@ -466,12 +464,10 @@ out_free: + * Free an RPC client + */ + static void +-rpc_free_auth(struct kref *kref) ++rpc_free_auth(struct rpc_clnt *clnt) + { +- struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); +- + if (clnt->cl_auth == NULL) { +- rpc_free_client(kref); ++ rpc_free_client(clnt); + return; + } + +@@ -480,10 +476,11 @@ rpc_free_auth(struct kref *kref) + * release remaining GSS contexts. This mechanism ensures + * that it can do so safely. + */ +- kref_init(kref); ++ atomic_inc(&clnt->cl_count); + rpcauth_release(clnt->cl_auth); + clnt->cl_auth = NULL; +- kref_put(kref, rpc_free_client); ++ if (atomic_dec_and_test(&clnt->cl_count)) ++ rpc_free_client(clnt); + } + + /* +@@ -496,7 +493,8 @@ rpc_release_client(struct rpc_clnt *clnt + + if (list_empty(&clnt->cl_tasks)) + wake_up(&destroy_wait); +- kref_put(&clnt->cl_kref, rpc_free_auth); ++ if (atomic_dec_and_test(&clnt->cl_count)) ++ rpc_free_auth(clnt); + } + + /** +--- a/net/sunrpc/rpc_pipe.c ++++ b/net/sunrpc/rpc_pipe.c +@@ -371,21 +371,23 @@ rpc_show_info(struct seq_file *m, void * + static int + rpc_info_open(struct inode *inode, struct file *file) + { +- struct rpc_clnt *clnt; ++ struct rpc_clnt *clnt = NULL; + int ret = single_open(file, rpc_show_info, NULL); + + if (!ret) { + struct seq_file *m = file->private_data; +- mutex_lock(&inode->i_mutex); +- clnt = RPC_I(inode)->private; +- if (clnt) { +- kref_get(&clnt->cl_kref); ++ ++ spin_lock(&file->f_path.dentry->d_lock); ++ if (!d_unhashed(file->f_path.dentry)) ++ clnt = RPC_I(inode)->private; ++ if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) { ++ spin_unlock(&file->f_path.dentry->d_lock); + m->private = clnt; + } else { ++ spin_unlock(&file->f_path.dentry->d_lock); + single_release(inode, file); + ret = -EINVAL; + } +- mutex_unlock(&inode->i_mutex); + } + return ret; + } diff --git a/queue-2.6.35/sunrpc-fix-race-corrupting-rpc-upcall.patch b/queue-2.6.35/sunrpc-fix-race-corrupting-rpc-upcall.patch new file mode 100644 index 00000000000..2920d73191e --- /dev/null +++ b/queue-2.6.35/sunrpc-fix-race-corrupting-rpc-upcall.patch @@ -0,0 +1,81 @@ +From 5a67657a2e90c9e4a48518f95d4ba7777aa20fbb Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Sun, 12 Sep 2010 19:55:25 -0400 +Subject: SUNRPC: Fix race corrupting rpc upcall + +From: Trond Myklebust + +commit 5a67657a2e90c9e4a48518f95d4ba7777aa20fbb upstream. + +If rpc_queue_upcall() adds a new upcall to the rpci->pipe list just +after rpc_pipe_release calls rpc_purge_list(), but before it calls +gss_pipe_release (as rpci->ops->release_pipe(inode)), then the latter +will free a message without deleting it from the rpci->pipe list. + +We will be left with a freed object on the rpc->pipe list. Most +frequent symptoms are kernel crashes in rpc.gssd system calls on the +pipe in question. + +Reported-by: J. Bruce Fields +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/auth_gss/auth_gss.c | 9 +++++---- + net/sunrpc/rpc_pipe.c | 6 +++--- + 2 files changed, 8 insertions(+), 7 deletions(-) + +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -745,17 +745,18 @@ gss_pipe_release(struct inode *inode) + struct rpc_inode *rpci = RPC_I(inode); + struct gss_upcall_msg *gss_msg; + ++restart: + spin_lock(&inode->i_lock); +- while (!list_empty(&rpci->in_downcall)) { ++ list_for_each_entry(gss_msg, &rpci->in_downcall, list) { + +- gss_msg = list_entry(rpci->in_downcall.next, +- struct gss_upcall_msg, list); ++ if (!list_empty(&gss_msg->msg.list)) ++ continue; + gss_msg->msg.errno = -EPIPE; + atomic_inc(&gss_msg->count); + __gss_unhash_msg(gss_msg); + spin_unlock(&inode->i_lock); + gss_release_msg(gss_msg); +- spin_lock(&inode->i_lock); ++ goto restart; + } + spin_unlock(&inode->i_lock); + +--- a/net/sunrpc/rpc_pipe.c ++++ b/net/sunrpc/rpc_pipe.c +@@ -48,7 +48,7 @@ static void rpc_purge_list(struct rpc_in + return; + do { + msg = list_entry(head->next, struct rpc_pipe_msg, list); +- list_del(&msg->list); ++ list_del_init(&msg->list); + msg->errno = err; + destroy_msg(msg); + } while (!list_empty(head)); +@@ -208,7 +208,7 @@ rpc_pipe_release(struct inode *inode, st + if (msg != NULL) { + spin_lock(&inode->i_lock); + msg->errno = -EAGAIN; +- list_del(&msg->list); ++ list_del_init(&msg->list); + spin_unlock(&inode->i_lock); + rpci->ops->destroy_msg(msg); + } +@@ -268,7 +268,7 @@ rpc_pipe_read(struct file *filp, char __ + if (res < 0 || msg->len == msg->copied) { + filp->private_data = NULL; + spin_lock(&inode->i_lock); +- list_del(&msg->list); ++ list_del_init(&msg->list); + spin_unlock(&inode->i_lock); + rpci->ops->destroy_msg(msg); + }