Skip to content

Commit

Permalink
9p: fix error path during early mount
Browse files Browse the repository at this point in the history
There was some cleanup issues during early mount which would trigger
a kernel bug for certain types of failure.  This patch reorganizes the
cleanup to get rid of the bad behavior.

This also merges the 9pnet and 9pnet_fd modules for the purpose of
configuration and initialization.  Keeping the fd transport separate
from the core 9pnet code seemed like a good idea at the time, but in
practice has caused more harm and confusion than good.

Signed-off-by: Eric Van Hensbergen <[email protected]>
  • Loading branch information
Eric Van Hensbergen committed May 15, 2008
1 parent 332c421 commit 887b3ec
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 45 deletions.
13 changes: 7 additions & 6 deletions fs/9p/v9fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,14 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
v9ses->uid = ~0;
v9ses->dfltuid = V9FS_DEFUID;
v9ses->dfltgid = V9FS_DEFGID;
v9ses->options = kstrdup(data, GFP_KERNEL);
if (!v9ses->options) {
P9_DPRINTK(P9_DEBUG_ERROR,
if (data) {
v9ses->options = kstrdup(data, GFP_KERNEL);
if (!v9ses->options) {
P9_DPRINTK(P9_DEBUG_ERROR,
"failed to allocate copy of option string\n");
retval = -ENOMEM;
goto error;
retval = -ENOMEM;
goto error;
}
}

rc = v9fs_parse_options(v9ses);
Expand Down Expand Up @@ -260,7 +262,6 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
return fid;

error:
v9fs_session_close(v9ses);
return ERR_PTR(retval);
}

Expand Down
34 changes: 16 additions & 18 deletions fs/9p/vfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,29 +128,26 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
fid = v9fs_session_init(v9ses, dev_name, data);
if (IS_ERR(fid)) {
retval = PTR_ERR(fid);
fid = NULL;
kfree(v9ses);
v9ses = NULL;
goto error;
goto close_session;
}

st = p9_client_stat(fid);
if (IS_ERR(st)) {
retval = PTR_ERR(st);
goto error;
goto clunk_fid;
}

sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
if (IS_ERR(sb)) {
retval = PTR_ERR(sb);
goto error;
goto free_stat;
}
v9fs_fill_super(sb, v9ses, flags);

inode = v9fs_get_inode(sb, S_IFDIR | mode);
if (IS_ERR(inode)) {
retval = PTR_ERR(inode);
goto error;
goto release_sb;
}

inode->i_uid = uid;
Expand All @@ -159,7 +156,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
root = d_alloc_root(inode);
if (!root) {
retval = -ENOMEM;
goto error;
goto release_sb;
}

sb->s_root = root;
Expand All @@ -170,21 +167,22 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,

return simple_set_mnt(mnt, sb);

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

if (v9ses) {
v9fs_session_close(v9ses);
kfree(v9ses);
}

release_sb:
if (sb) {
up_write(&sb->s_umount);
deactivate_super(sb);
}

free_stat:
kfree(st);

clunk_fid:
p9_client_clunk(fid);

close_session:
v9fs_session_close(v9ses);
kfree(v9ses);

return retval;
}

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 @@ -595,4 +595,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);
#endif /* NET_9P_H */
1 change: 0 additions & 1 deletion include/net/9p/transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,4 @@ struct p9_trans_module {
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);

#endif /* NET_9P_TRANSPORT_H */
10 changes: 0 additions & 10 deletions net/9p/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@ menuconfig NET_9P

If unsure, say N.

config NET_9P_FD
depends on NET_9P
default y if NET_9P
tristate "9P File Descriptor Transports (Experimental)"
help
This builds support for file descriptor transports for 9p
which includes support for TCP/IP, named pipes, or passed
file descriptors. TCP/IP is the default transport for 9p,
so if you are going to use 9p, you'll likely want this.

config NET_9P_VIRTIO
depends on NET_9P && EXPERIMENTAL && VIRTIO
tristate "9P Virtio Transport (Experimental)"
Expand Down
3 changes: 0 additions & 3 deletions net/9p/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
obj-$(CONFIG_NET_9P) := 9pnet.o
obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o

9pnet-objs := \
Expand All @@ -9,8 +8,6 @@ obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
error.o \
fcprint.o \
util.o \

9pnet_fd-objs := \
trans_fd.o \

9pnet_virtio-objs := \
Expand Down
1 change: 1 addition & 0 deletions net/9p/mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ static int __init init_p9(void)

p9_error_init();
printk(KERN_INFO "Installing 9P2000 support\n");
p9_trans_fd_init();

return ret;
}
Expand Down
29 changes: 22 additions & 7 deletions net/9p/trans_fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,23 @@ static void p9_fd_close(struct p9_trans *trans)
kfree(ts);
}

/*
* stolen from NFS - maybe should be made a generic function?
*/
static inline int valid_ipaddr4(const char *buf)
{
int rc, count, in[4];

rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
if (rc != 4)
return -EINVAL;
for (count = 0; count < 4; count++) {
if (in[count] > 255)
return -EINVAL;
}
return 0;
}

static struct p9_trans *
p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
{
Expand All @@ -1447,6 +1464,9 @@ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
if (err < 0)
return ERR_PTR(err);

if (valid_ipaddr4(addr) < 0)
return ERR_PTR(-EINVAL);

csocket = NULL;
trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
if (!trans)
Expand Down Expand Up @@ -1625,7 +1645,7 @@ static struct p9_trans_module p9_fd_trans = {
.create = p9_trans_create_fd,
};

static int __init p9_trans_fd_init(void)
int p9_trans_fd_init(void)
{
int ret = p9_mux_global_init();
if (ret) {
Expand All @@ -1639,9 +1659,4 @@ static int __init p9_trans_fd_init(void)

return 0;
}

module_init(p9_trans_fd_init);

MODULE_AUTHOR("Latchesar Ionkov <[email protected]>");
MODULE_AUTHOR("Eric Van Hensbergen <[email protected]>");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(p9_trans_fd_init);

0 comments on commit 887b3ec

Please sign in to comment.