From 6263da03d7ff92efc9e4fd2be5c300bd42beaf91 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 23 Sep 2008 19:48:36 +0200 Subject: [PATCH] --- yaml --- r: 110019 b: refs/heads/master c: 44ce17192a01218b242e032237e1d2e52ef50429 h: refs/heads/master i: 110017: cc23f3be02611f36e664d1aeb9c9720443c36318 110015: 71b4f73157132dd36b4c1f53f6d686793adf8208 v: v3 --- [refs] | 2 +- trunk/arch/arm/mach-pxa/time.c | 2 +- trunk/arch/arm/mach-sa1100/generic.c | 2 +- trunk/arch/arm/mach-versatile/core.c | 2 +- trunk/arch/mips/au1000/common/gpio.c | 4 +- trunk/arch/mn10300/kernel/time.c | 52 +++----------- trunk/fs/9p/vfs_inode.c | 3 +- trunk/include/linux/cnt32_to_63.h | 80 --------------------- trunk/include/net/9p/9p.h | 1 - trunk/include/net/9p/transport.h | 9 +-- trunk/net/9p/client.c | 10 +-- trunk/net/9p/conv.c | 6 +- trunk/net/9p/mod.c | 92 +++++++----------------- trunk/net/9p/trans_fd.c | 104 +++++++++++++++++---------- trunk/net/9p/trans_virtio.c | 2 - 15 files changed, 118 insertions(+), 253 deletions(-) delete mode 100644 trunk/include/linux/cnt32_to_63.h diff --git a/[refs] b/[refs] index da7205b0a793..3cbb71908ac9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 08ec3c2d45bac41c782acb4e3331ac5881b2c68a +refs/heads/master: 44ce17192a01218b242e032237e1d2e52ef50429 diff --git a/trunk/arch/arm/mach-pxa/time.c b/trunk/arch/arm/mach-pxa/time.c index b0d6b32654cf..67e18509d7bf 100644 --- a/trunk/arch/arm/mach-pxa/time.c +++ b/trunk/arch/arm/mach-pxa/time.c @@ -17,9 +17,9 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/trunk/arch/arm/mach-sa1100/generic.c b/trunk/arch/arm/mach-sa1100/generic.c index b422526f6d8b..1362994c78aa 100644 --- a/trunk/arch/arm/mach-sa1100/generic.c +++ b/trunk/arch/arm/mach-sa1100/generic.c @@ -18,9 +18,9 @@ #include #include /* just for sched_clock() - funny that */ #include -#include #include +#include #include #include #include diff --git a/trunk/arch/arm/mach-versatile/core.c b/trunk/arch/arm/mach-versatile/core.c index b638f10411e8..d75e795c893e 100644 --- a/trunk/arch/arm/mach-versatile/core.c +++ b/trunk/arch/arm/mach-versatile/core.c @@ -28,8 +28,8 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/arch/mips/au1000/common/gpio.c b/trunk/arch/mips/au1000/common/gpio.c index b485d94ce8a5..1f058434b726 100644 --- a/trunk/arch/mips/au1000/common/gpio.c +++ b/trunk/arch/mips/au1000/common/gpio.c @@ -61,7 +61,8 @@ static int au1xxx_gpio2_direction_input(unsigned gpio) static int au1xxx_gpio2_direction_output(unsigned gpio, int value) { gpio -= AU1XXX_GPIO_BASE; - gpio2->dir = (0x01 << gpio) | (value << gpio); + gpio2->dir |= 0x01 << gpio; + gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | (value << gpio); return 0; } @@ -90,6 +91,7 @@ static int au1xxx_gpio1_direction_input(unsigned gpio) static int au1xxx_gpio1_direction_output(unsigned gpio, int value) { gpio1->trioutclr = (0x01 & gpio); + au1xxx_gpio1_write(gpio, value); return 0; } diff --git a/trunk/arch/mn10300/kernel/time.c b/trunk/arch/mn10300/kernel/time.c index e4606586f94c..babb7c2ac377 100644 --- a/trunk/arch/mn10300/kernel/time.c +++ b/trunk/arch/mn10300/kernel/time.c @@ -1,6 +1,6 @@ /* MN10300 Low level time management * - * Copyright (C) 2007-2008 Red Hat, Inc. All Rights Reserved. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * - Derived from arch/i386/kernel/time.c * @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -41,54 +40,27 @@ static struct irqaction timer_irq = { .name = "timer", }; -static unsigned long sched_clock_multiplier; - /* * scheduler clock - returns current time in nanosec units. */ unsigned long long sched_clock(void) { union { - unsigned long long ll; - unsigned l[2]; - } tsc64, result; - unsigned long tsc, tmp; - unsigned product[3]; /* 96-bit intermediate value */ - - /* read the TSC value - */ - tsc = 0 - get_cycles(); /* get_cycles() counts down */ + unsigned long long l; + u32 w[2]; + } quot; - /* expand to 64-bits. - * - sched_clock() must be called once a minute or better or the - * following will go horribly wrong - see cnt32_to_63() - */ - tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL; + quot.w[0] = mn10300_last_tsc - get_cycles(); + quot.w[1] = 1000000000; - /* scale the 64-bit TSC value to a nanosecond value via a 96-bit - * intermediate - */ - asm("mulu %2,%0,%3,%0 \n" /* LSW * mult -> 0:%3:%0 */ - "mulu %2,%1,%2,%1 \n" /* MSW * mult -> %2:%1:0 */ - "add %3,%1 \n" - "addc 0,%2 \n" /* result in %2:%1:%0 */ - : "=r"(product[0]), "=r"(product[1]), "=r"(product[2]), "=r"(tmp) - : "0"(tsc64.l[0]), "1"(tsc64.l[1]), "2"(sched_clock_multiplier) + asm("mulu %2,%3,%0,%1" + : "=r"(quot.w[1]), "=r"(quot.w[0]) + : "0"(quot.w[1]), "1"(quot.w[0]) : "cc"); - result.l[0] = product[1] << 16 | product[0] >> 16; - result.l[1] = product[2] << 16 | product[1] >> 16; + do_div(quot.l, MN10300_TSCCLK); - return result.ll; -} - -/* - * initialise the scheduler clock - */ -static void __init mn10300_sched_clock_init(void) -{ - sched_clock_multiplier = - __muldiv64u(NSEC_PER_SEC, 1 << 16, MN10300_TSCCLK); + return quot.l; } /* @@ -156,6 +128,4 @@ void __init time_init(void) /* start the watchdog timer */ watchdog_go(); #endif - - mn10300_sched_clock_init(); } diff --git a/trunk/fs/9p/vfs_inode.c b/trunk/fs/9p/vfs_inode.c index e83aa5ebe861..c95295c65045 100644 --- a/trunk/fs/9p/vfs_inode.c +++ b/trunk/fs/9p/vfs_inode.c @@ -626,7 +626,8 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, return NULL; error: - p9_client_clunk(fid); + if (fid) + p9_client_clunk(fid); return ERR_PTR(result); } diff --git a/trunk/include/linux/cnt32_to_63.h b/trunk/include/linux/cnt32_to_63.h deleted file mode 100644 index 8c0f9505b48c..000000000000 --- a/trunk/include/linux/cnt32_to_63.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Extend a 32-bit counter to 63 bits - * - * Author: Nicolas Pitre - * Created: December 3, 2006 - * Copyright: MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - */ - -#ifndef __LINUX_CNT32_TO_63_H__ -#define __LINUX_CNT32_TO_63_H__ - -#include -#include -#include - -/* this is used only to give gcc a clue about good code generation */ -union cnt32_to_63 { - struct { -#if defined(__LITTLE_ENDIAN) - u32 lo, hi; -#elif defined(__BIG_ENDIAN) - u32 hi, lo; -#endif - }; - u64 val; -}; - - -/** - * cnt32_to_63 - Expand a 32-bit counter to a 63-bit counter - * @cnt_lo: The low part of the counter - * - * Many hardware clock counters are only 32 bits wide and therefore have - * a relatively short period making wrap-arounds rather frequent. This - * is a problem when implementing sched_clock() for example, where a 64-bit - * non-wrapping monotonic value is expected to be returned. - * - * To overcome that limitation, let's extend a 32-bit counter to 63 bits - * in a completely lock free fashion. Bits 0 to 31 of the clock are provided - * by the hardware while bits 32 to 62 are stored in memory. The top bit in - * memory is used to synchronize with the hardware clock half-period. When - * the top bit of both counters (hardware and in memory) differ then the - * memory is updated with a new value, incrementing it when the hardware - * counter wraps around. - * - * Because a word store in memory is atomic then the incremented value will - * always be in synch with the top bit indicating to any potential concurrent - * reader if the value in memory is up to date or not with regards to the - * needed increment. And any race in updating the value in memory is harmless - * as the same value would simply be stored more than once. - * - * The only restriction for the algorithm to work properly is that this - * code must be executed at least once per each half period of the 32-bit - * counter to properly update the state bit in memory. This is usually not a - * problem in practice, but if it is then a kernel timer could be scheduled - * to manage for this code to be executed often enough. - * - * Note that the top bit (bit 63) in the returned value should be considered - * as garbage. It is not cleared here because callers are likely to use a - * multiplier on the returned value which can get rid of the top bit - * implicitly by making the multiplier even, therefore saving on a runtime - * clear-bit instruction. Otherwise caller must remember to clear the top - * bit explicitly. - */ -#define cnt32_to_63(cnt_lo) \ -({ \ - static volatile u32 __m_cnt_hi; \ - union cnt32_to_63 __x; \ - __x.hi = __m_cnt_hi; \ - __x.lo = (cnt_lo); \ - if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \ - __m_cnt_hi = __x.hi = (__x.hi ^ 0x80000000) + (__x.hi >> 31); \ - __x.val; \ -}) - -#endif diff --git a/trunk/include/net/9p/9p.h b/trunk/include/net/9p/9p.h index c3626c0ba9d3..b3d3e27c6299 100644 --- a/trunk/include/net/9p/9p.h +++ b/trunk/include/net/9p/9p.h @@ -596,5 +596,4 @@ int p9_idpool_check(int id, struct p9_idpool *p); int p9_error_init(void); int p9_errstr2errno(char *, int); int p9_trans_fd_init(void); -void p9_trans_fd_exit(void); #endif /* NET_9P_H */ diff --git a/trunk/include/net/9p/transport.h b/trunk/include/net/9p/transport.h index 3ca737120a90..0db3a4038dc0 100644 --- a/trunk/include/net/9p/transport.h +++ b/trunk/include/net/9p/transport.h @@ -26,8 +26,6 @@ #ifndef NET_9P_TRANSPORT_H #define NET_9P_TRANSPORT_H -#include - /** * enum p9_trans_status - different states of underlying transports * @Connected: transport is connected and healthy @@ -93,12 +91,9 @@ struct p9_trans_module { int maxsize; /* max message size of transport */ int def; /* this transport should be default */ struct p9_trans * (*create)(const char *, char *, int, unsigned char); - struct module *owner; }; void v9fs_register_trans(struct p9_trans_module *m); -void v9fs_unregister_trans(struct p9_trans_module *m); -struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name); -struct p9_trans_module *v9fs_get_default_trans(void); -void v9fs_put_trans(struct p9_trans_module *m); +struct p9_trans_module *v9fs_match_trans(const substring_t *name); +struct p9_trans_module *v9fs_default_trans(void); #endif /* NET_9P_TRANSPORT_H */ diff --git a/trunk/net/9p/client.c b/trunk/net/9p/client.c index 10e320307ec0..2ffe40cf2f01 100644 --- a/trunk/net/9p/client.c +++ b/trunk/net/9p/client.c @@ -75,6 +75,7 @@ static int parse_opts(char *opts, struct p9_client *clnt) int option; int ret = 0; + clnt->trans_mod = v9fs_default_trans(); clnt->dotu = 1; clnt->msize = 8192; @@ -107,7 +108,7 @@ static int parse_opts(char *opts, struct p9_client *clnt) clnt->msize = option; break; case Opt_trans: - clnt->trans_mod = v9fs_get_trans_by_name(&args[0]); + clnt->trans_mod = v9fs_match_trans(&args[0]); break; case Opt_legacy: clnt->dotu = 0; @@ -116,10 +117,6 @@ static int parse_opts(char *opts, struct p9_client *clnt) continue; } } - - if (!clnt->trans_mod) - clnt->trans_mod = v9fs_get_default_trans(); - kfree(options); return ret; } @@ -153,7 +150,6 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) if (!clnt) return ERR_PTR(-ENOMEM); - clnt->trans_mod = NULL; clnt->trans = NULL; spin_lock_init(&clnt->lock); INIT_LIST_HEAD(&clnt->fidlist); @@ -239,8 +235,6 @@ void p9_client_destroy(struct p9_client *clnt) clnt->trans = NULL; } - v9fs_put_trans(clnt->trans_mod); - list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) p9_fid_destroy(fid); diff --git a/trunk/net/9p/conv.c b/trunk/net/9p/conv.c index 5ad3a3bd73b2..44547201f5bc 100644 --- a/trunk/net/9p/conv.c +++ b/trunk/net/9p/conv.c @@ -451,10 +451,8 @@ p9_put_data(struct cbuf *bufp, const char *data, int count, unsigned char **pdata) { *pdata = buf_alloc(bufp, count); - if (*pdata == NULL) - return -ENOMEM; memmove(*pdata, data, count); - return 0; + return count; } static int @@ -462,8 +460,6 @@ p9_put_user_data(struct cbuf *bufp, const char __user *data, int count, unsigned char **pdata) { *pdata = buf_alloc(bufp, count); - if (*pdata == NULL) - return -ENOMEM; return copy_from_user(*pdata, data, count); } diff --git a/trunk/net/9p/mod.c b/trunk/net/9p/mod.c index 1084feb24cb0..bdee1fb7cc62 100644 --- a/trunk/net/9p/mod.c +++ b/trunk/net/9p/mod.c @@ -31,7 +31,6 @@ #include #include #include -#include #ifdef CONFIG_NET_9P_DEBUG unsigned int p9_debug_level = 0; /* feature-rific global debug level */ @@ -45,8 +44,8 @@ MODULE_PARM_DESC(debug, "9P debugging level"); * */ -static DEFINE_SPINLOCK(v9fs_trans_lock); static LIST_HEAD(v9fs_trans_list); +static struct p9_trans_module *v9fs_default_transport; /** * v9fs_register_trans - register a new transport with 9p @@ -55,87 +54,48 @@ static LIST_HEAD(v9fs_trans_list); */ void v9fs_register_trans(struct p9_trans_module *m) { - spin_lock(&v9fs_trans_lock); list_add_tail(&m->list, &v9fs_trans_list); - spin_unlock(&v9fs_trans_lock); + if (m->def) + v9fs_default_transport = m; } EXPORT_SYMBOL(v9fs_register_trans); /** - * v9fs_unregister_trans - unregister a 9p transport - * @m: the transport to remove - * - */ -void v9fs_unregister_trans(struct p9_trans_module *m) -{ - spin_lock(&v9fs_trans_lock); - list_del_init(&m->list); - spin_unlock(&v9fs_trans_lock); -} -EXPORT_SYMBOL(v9fs_unregister_trans); - -/** - * v9fs_get_trans_by_name - get transport with the matching name + * v9fs_match_trans - match transport versus registered transports * @name: string identifying transport * */ -struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name) +struct p9_trans_module *v9fs_match_trans(const substring_t *name) { - struct p9_trans_module *t, *found = NULL; - - spin_lock(&v9fs_trans_lock); - - list_for_each_entry(t, &v9fs_trans_list, list) - if (strncmp(t->name, name->from, name->to-name->from) == 0 && - try_module_get(t->owner)) { - found = t; - break; - } - - spin_unlock(&v9fs_trans_lock); - return found; + struct list_head *p; + struct p9_trans_module *t = NULL; + + list_for_each(p, &v9fs_trans_list) { + t = list_entry(p, struct p9_trans_module, list); + if (strncmp(t->name, name->from, name->to-name->from) == 0) + return t; + } + return NULL; } -EXPORT_SYMBOL(v9fs_get_trans_by_name); +EXPORT_SYMBOL(v9fs_match_trans); /** - * v9fs_get_default_trans - get the default transport + * v9fs_default_trans - returns pointer to default transport * */ -struct p9_trans_module *v9fs_get_default_trans(void) +struct p9_trans_module *v9fs_default_trans(void) { - struct p9_trans_module *t, *found = NULL; - - spin_lock(&v9fs_trans_lock); - - list_for_each_entry(t, &v9fs_trans_list, list) - if (t->def && try_module_get(t->owner)) { - found = t; - break; - } - - if (!found) - list_for_each_entry(t, &v9fs_trans_list, list) - if (try_module_get(t->owner)) { - found = t; - break; - } - - spin_unlock(&v9fs_trans_lock); - return found; + if (v9fs_default_transport) + return v9fs_default_transport; + else if (!list_empty(&v9fs_trans_list)) + return list_first_entry(&v9fs_trans_list, + struct p9_trans_module, list); + else + return NULL; } -EXPORT_SYMBOL(v9fs_get_default_trans); +EXPORT_SYMBOL(v9fs_default_trans); -/** - * v9fs_put_trans - put trans - * @m: transport to put - * - */ -void v9fs_put_trans(struct p9_trans_module *m) -{ - if (m) - module_put(m->owner); -} /** * v9fs_init - Initialize module @@ -160,8 +120,6 @@ static int __init init_p9(void) static void __exit exit_p9(void) { printk(KERN_INFO "Unloading 9P2000 support\n"); - - p9_trans_fd_exit(); } module_init(init_p9) diff --git a/trunk/net/9p/trans_fd.c b/trunk/net/9p/trans_fd.c index d652baf5ff91..cdf137af7adc 100644 --- a/trunk/net/9p/trans_fd.c +++ b/trunk/net/9p/trans_fd.c @@ -151,6 +151,7 @@ struct p9_mux_poll_task { * @trans: reference to transport instance for this connection * @tagpool: id accounting for transactions * @err: error state + * @equeue: event wait_q (?) * @req_list: accounting for requests which have been sent * @unsent_req_list: accounting for requests that haven't been sent * @rcall: current response &p9_fcall structure @@ -177,6 +178,7 @@ struct p9_conn { struct p9_trans *trans; struct p9_idpool *tagpool; int err; + wait_queue_head_t equeue; struct list_head req_list; struct list_head unsent_req_list; struct p9_fcall *rcall; @@ -238,6 +240,22 @@ static int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, static void p9_conn_cancel(struct p9_conn *m, int err); +static int p9_mux_global_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) + p9_mux_poll_tasks[i].task = NULL; + + p9_mux_wq = create_workqueue("v9fs"); + if (!p9_mux_wq) { + printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); + return -ENOMEM; + } + + return 0; +} + static u16 p9_mux_get_tag(struct p9_conn *m) { int tag; @@ -391,11 +409,11 @@ static void p9_mux_poll_stop(struct p9_conn *m) static struct p9_conn *p9_conn_create(struct p9_trans *trans) { int i, n; - struct p9_conn *m; + struct p9_conn *m, *mtmp; P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans, trans->msize); - m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL); + m = kmalloc(sizeof(struct p9_conn), GFP_KERNEL); if (!m) return ERR_PTR(-ENOMEM); @@ -406,14 +424,25 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans) m->trans = trans; m->tagpool = p9_idpool_create(); if (IS_ERR(m->tagpool)) { + mtmp = ERR_PTR(-ENOMEM); kfree(m); - return ERR_PTR(-ENOMEM); + return mtmp; } + m->err = 0; + init_waitqueue_head(&m->equeue); INIT_LIST_HEAD(&m->req_list); INIT_LIST_HEAD(&m->unsent_req_list); + m->rcall = NULL; + m->rpos = 0; + m->rbuf = NULL; + m->wpos = m->wsize = 0; + m->wbuf = NULL; INIT_WORK(&m->rq, p9_read_work); INIT_WORK(&m->wq, p9_write_work); + m->wsched = 0; + memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); + m->poll_task = NULL; n = p9_mux_poll_start(m); if (n) { kfree(m); @@ -434,8 +463,10 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans) for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { if (IS_ERR(m->poll_waddr[i])) { p9_mux_poll_stop(m); + mtmp = (void *)m->poll_waddr; /* the error code */ kfree(m); - return (void *)m->poll_waddr; /* the error code */ + m = mtmp; + break; } } @@ -452,13 +483,18 @@ static void p9_conn_destroy(struct p9_conn *m) { P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m, m->mux_list.prev, m->mux_list.next); - - p9_mux_poll_stop(m); - cancel_work_sync(&m->rq); - cancel_work_sync(&m->wq); - p9_conn_cancel(m, -ECONNRESET); + if (!list_empty(&m->req_list)) { + /* wait until all processes waiting on this session exit */ + P9_DPRINTK(P9_DEBUG_MUX, + "mux %p waiting for empty request queue\n", m); + wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000); + P9_DPRINTK(P9_DEBUG_MUX, "mux %p request queue empty: %d\n", m, + list_empty(&m->req_list)); + } + + p9_mux_poll_stop(m); m->trans = NULL; p9_idpool_destroy(m->tagpool); kfree(m); @@ -804,6 +840,8 @@ static void p9_read_work(struct work_struct *work) (*req->cb) (req, req->cba); else kfree(req->rcall); + + wake_up(&m->equeue); } } else { if (err >= 0 && rcall->id != P9_RFLUSH) @@ -870,10 +908,8 @@ static struct p9_req *p9_send_request(struct p9_conn *m, else n = p9_mux_get_tag(m); - if (n < 0) { - kfree(req); + if (n < 0) return ERR_PTR(-ENOMEM); - } p9_set_tag(tc, n); @@ -948,6 +984,8 @@ static void p9_mux_flush_cb(struct p9_req *freq, void *a) (*req->cb) (req, req->cba); else kfree(req->rcall); + + wake_up(&m->equeue); } kfree(freq->tcall); @@ -1153,6 +1191,8 @@ void p9_conn_cancel(struct p9_conn *m, int err) else kfree(req->rcall); } + + wake_up(&m->equeue); } /** @@ -1330,6 +1370,7 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt) { int ret, n; struct p9_trans_fd *ts = NULL; + mm_segment_t oldfs; if (trans && trans->status == Connected) ts = trans->priv; @@ -1343,17 +1384,24 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt) if (!ts->wr->f_op || !ts->wr->f_op->poll) return -EIO; + oldfs = get_fs(); + set_fs(get_ds()); + ret = ts->rd->f_op->poll(ts->rd, pt); if (ret < 0) - return ret; + goto end; if (ts->rd != ts->wr) { n = ts->wr->f_op->poll(ts->wr, pt); - if (n < 0) - return n; + if (n < 0) { + ret = n; + goto end; + } ret = (ret & ~POLLOUT) | (n & ~POLLIN); } +end: + set_fs(oldfs); return ret; } @@ -1581,7 +1629,6 @@ static struct p9_trans_module p9_tcp_trans = { .maxsize = MAX_SOCK_BUF, .def = 1, .create = p9_trans_create_tcp, - .owner = THIS_MODULE, }; static struct p9_trans_module p9_unix_trans = { @@ -1589,7 +1636,6 @@ static struct p9_trans_module p9_unix_trans = { .maxsize = MAX_SOCK_BUF, .def = 0, .create = p9_trans_create_unix, - .owner = THIS_MODULE, }; static struct p9_trans_module p9_fd_trans = { @@ -1597,20 +1643,14 @@ static struct p9_trans_module p9_fd_trans = { .maxsize = MAX_SOCK_BUF, .def = 0, .create = p9_trans_create_fd, - .owner = THIS_MODULE, }; int p9_trans_fd_init(void) { - int i; - - for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) - p9_mux_poll_tasks[i].task = NULL; - - p9_mux_wq = create_workqueue("v9fs"); - if (!p9_mux_wq) { - printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); - return -ENOMEM; + int ret = p9_mux_global_init(); + if (ret) { + printk(KERN_WARNING "9p: starting mux failed\n"); + return ret; } v9fs_register_trans(&p9_tcp_trans); @@ -1619,12 +1659,4 @@ int p9_trans_fd_init(void) return 0; } - -void p9_trans_fd_exit(void) -{ - v9fs_unregister_trans(&p9_tcp_trans); - v9fs_unregister_trans(&p9_unix_trans); - v9fs_unregister_trans(&p9_fd_trans); - - destroy_workqueue(p9_mux_wq); -} +EXPORT_SYMBOL(p9_trans_fd_init); diff --git a/trunk/net/9p/trans_virtio.c b/trunk/net/9p/trans_virtio.c index 94912e077a55..42adc052b149 100644 --- a/trunk/net/9p/trans_virtio.c +++ b/trunk/net/9p/trans_virtio.c @@ -528,7 +528,6 @@ static struct p9_trans_module p9_virtio_trans = { .create = p9_virtio_create, .maxsize = PAGE_SIZE*16, .def = 0, - .owner = THIS_MODULE, }; /* The standard init function */ @@ -546,7 +545,6 @@ static int __init p9_virtio_init(void) static void __exit p9_virtio_cleanup(void) { unregister_virtio_driver(&p9_virtio_drv); - v9fs_unregister_trans(&p9_virtio_trans); } module_init(p9_virtio_init);