Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/ericvh/v9fs

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
  9p: fix put_data error handling
  9p: use an IS_ERR test rather than a NULL test
  9p: introduce missing kfree
  9p-trans_fd: fix and clean up module init/exit paths
  9p-trans_fd: don't do fs segment mangling in p9_fd_poll()
  9p-trans_fd: clean up p9_conn_create()
  9p-trans_fd: fix trans_fd::p9_conn_destroy()
  9p: implement proper trans module refcounting and unregistration
  • Loading branch information
torvalds committed Sep 24, 2008
2 parents fb478da + 16ec470 commit 7a52815
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 100 deletions.
3 changes: 1 addition & 2 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,8 +626,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
return NULL;

error:
if (fid)
p9_client_clunk(fid);
p9_client_clunk(fid);

return ERR_PTR(result);
}
Expand Down
1 change: 1 addition & 0 deletions include/net/9p/9p.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,4 +596,5 @@ 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 */
9 changes: 7 additions & 2 deletions include/net/9p/transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#ifndef NET_9P_TRANSPORT_H
#define NET_9P_TRANSPORT_H

#include <linux/module.h>

/**
* enum p9_trans_status - different states of underlying transports
* @Connected: transport is connected and healthy
Expand Down Expand Up @@ -91,9 +93,12 @@ 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);
struct p9_trans_module *v9fs_match_trans(const substring_t *name);
struct p9_trans_module *v9fs_default_trans(void);
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);
#endif /* NET_9P_TRANSPORT_H */
10 changes: 8 additions & 2 deletions net/9p/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ 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;

Expand Down Expand Up @@ -108,7 +107,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
clnt->msize = option;
break;
case Opt_trans:
clnt->trans_mod = v9fs_match_trans(&args[0]);
clnt->trans_mod = v9fs_get_trans_by_name(&args[0]);
break;
case Opt_legacy:
clnt->dotu = 0;
Expand All @@ -117,6 +116,10 @@ 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;
}
Expand Down Expand Up @@ -150,6 +153,7 @@ 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);
Expand Down Expand Up @@ -235,6 +239,8 @@ 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);

Expand Down
6 changes: 5 additions & 1 deletion net/9p/conv.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,15 +451,19 @@ 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 count;
return 0;
}

static int
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);
}

Expand Down
92 changes: 67 additions & 25 deletions net/9p/mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/parser.h>
#include <net/9p/transport.h>
#include <linux/list.h>
#include <linux/spinlock.h>

#ifdef CONFIG_NET_9P_DEBUG
unsigned int p9_debug_level = 0; /* feature-rific global debug level */
Expand All @@ -44,8 +45,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
Expand All @@ -54,48 +55,87 @@ static struct p9_trans_module *v9fs_default_transport;
*/
void v9fs_register_trans(struct p9_trans_module *m)
{
spin_lock(&v9fs_trans_lock);
list_add_tail(&m->list, &v9fs_trans_list);
if (m->def)
v9fs_default_transport = m;
spin_unlock(&v9fs_trans_lock);
}
EXPORT_SYMBOL(v9fs_register_trans);

/**
* v9fs_match_trans - match transport versus registered transports
* 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
* @name: string identifying transport
*
*/
struct p9_trans_module *v9fs_match_trans(const substring_t *name)
struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name)
{
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;
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;
}
EXPORT_SYMBOL(v9fs_match_trans);
EXPORT_SYMBOL(v9fs_get_trans_by_name);

/**
* v9fs_default_trans - returns pointer to default transport
* v9fs_get_default_trans - get the default transport
*
*/

struct p9_trans_module *v9fs_default_trans(void)
struct p9_trans_module *v9fs_get_default_trans(void)
{
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;
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;
}
EXPORT_SYMBOL(v9fs_default_trans);
EXPORT_SYMBOL(v9fs_get_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
Expand All @@ -120,6 +160,8 @@ 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)
Expand Down
Loading

0 comments on commit 7a52815

Please sign in to comment.