Skip to content

Commit 887b3ec

Browse files
author
Eric Van Hensbergen
committed
9p: fix error path during early mount
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 <ericvh@gmail.com>
1 parent 332c421 commit 887b3ec

File tree

8 files changed

+47
-45
lines changed

8 files changed

+47
-45
lines changed

fs/9p/v9fs.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,14 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
206206
v9ses->uid = ~0;
207207
v9ses->dfltuid = V9FS_DEFUID;
208208
v9ses->dfltgid = V9FS_DEFGID;
209-
v9ses->options = kstrdup(data, GFP_KERNEL);
210-
if (!v9ses->options) {
211-
P9_DPRINTK(P9_DEBUG_ERROR,
209+
if (data) {
210+
v9ses->options = kstrdup(data, GFP_KERNEL);
211+
if (!v9ses->options) {
212+
P9_DPRINTK(P9_DEBUG_ERROR,
212213
"failed to allocate copy of option string\n");
213-
retval = -ENOMEM;
214-
goto error;
214+
retval = -ENOMEM;
215+
goto error;
216+
}
215217
}
216218

217219
rc = v9fs_parse_options(v9ses);
@@ -260,7 +262,6 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
260262
return fid;
261263

262264
error:
263-
v9fs_session_close(v9ses);
264265
return ERR_PTR(retval);
265266
}
266267

fs/9p/vfs_super.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -128,29 +128,26 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
128128
fid = v9fs_session_init(v9ses, dev_name, data);
129129
if (IS_ERR(fid)) {
130130
retval = PTR_ERR(fid);
131-
fid = NULL;
132-
kfree(v9ses);
133-
v9ses = NULL;
134-
goto error;
131+
goto close_session;
135132
}
136133

137134
st = p9_client_stat(fid);
138135
if (IS_ERR(st)) {
139136
retval = PTR_ERR(st);
140-
goto error;
137+
goto clunk_fid;
141138
}
142139

143140
sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
144141
if (IS_ERR(sb)) {
145142
retval = PTR_ERR(sb);
146-
goto error;
143+
goto free_stat;
147144
}
148145
v9fs_fill_super(sb, v9ses, flags);
149146

150147
inode = v9fs_get_inode(sb, S_IFDIR | mode);
151148
if (IS_ERR(inode)) {
152149
retval = PTR_ERR(inode);
153-
goto error;
150+
goto release_sb;
154151
}
155152

156153
inode->i_uid = uid;
@@ -159,7 +156,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
159156
root = d_alloc_root(inode);
160157
if (!root) {
161158
retval = -ENOMEM;
162-
goto error;
159+
goto release_sb;
163160
}
164161

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

171168
return simple_set_mnt(mnt, sb);
172169

173-
error:
174-
kfree(st);
175-
if (fid)
176-
p9_client_clunk(fid);
177-
178-
if (v9ses) {
179-
v9fs_session_close(v9ses);
180-
kfree(v9ses);
181-
}
182-
170+
release_sb:
183171
if (sb) {
184172
up_write(&sb->s_umount);
185173
deactivate_super(sb);
186174
}
187175

176+
free_stat:
177+
kfree(st);
178+
179+
clunk_fid:
180+
p9_client_clunk(fid);
181+
182+
close_session:
183+
v9fs_session_close(v9ses);
184+
kfree(v9ses);
185+
188186
return retval;
189187
}
190188

include/net/9p/9p.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,4 +595,5 @@ int p9_idpool_check(int id, struct p9_idpool *p);
595595

596596
int p9_error_init(void);
597597
int p9_errstr2errno(char *, int);
598+
int p9_trans_fd_init(void);
598599
#endif /* NET_9P_H */

include/net/9p/transport.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,4 @@ struct p9_trans_module {
9696
void v9fs_register_trans(struct p9_trans_module *m);
9797
struct p9_trans_module *v9fs_match_trans(const substring_t *name);
9898
struct p9_trans_module *v9fs_default_trans(void);
99-
10099
#endif /* NET_9P_TRANSPORT_H */

net/9p/Kconfig

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,6 @@ menuconfig NET_9P
1313

1414
If unsure, say N.
1515

16-
config NET_9P_FD
17-
depends on NET_9P
18-
default y if NET_9P
19-
tristate "9P File Descriptor Transports (Experimental)"
20-
help
21-
This builds support for file descriptor transports for 9p
22-
which includes support for TCP/IP, named pipes, or passed
23-
file descriptors. TCP/IP is the default transport for 9p,
24-
so if you are going to use 9p, you'll likely want this.
25-
2616
config NET_9P_VIRTIO
2717
depends on NET_9P && EXPERIMENTAL && VIRTIO
2818
tristate "9P Virtio Transport (Experimental)"

net/9p/Makefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
obj-$(CONFIG_NET_9P) := 9pnet.o
2-
obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
32
obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
43

54
9pnet-objs := \
@@ -9,8 +8,6 @@ obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
98
error.o \
109
fcprint.o \
1110
util.o \
12-
13-
9pnet_fd-objs := \
1411
trans_fd.o \
1512

1613
9pnet_virtio-objs := \

net/9p/mod.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ static int __init init_p9(void)
107107

108108
p9_error_init();
109109
printk(KERN_INFO "Installing 9P2000 support\n");
110+
p9_trans_fd_init();
110111

111112
return ret;
112113
}

net/9p/trans_fd.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,23 @@ static void p9_fd_close(struct p9_trans *trans)
14331433
kfree(ts);
14341434
}
14351435

1436+
/*
1437+
* stolen from NFS - maybe should be made a generic function?
1438+
*/
1439+
static inline int valid_ipaddr4(const char *buf)
1440+
{
1441+
int rc, count, in[4];
1442+
1443+
rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
1444+
if (rc != 4)
1445+
return -EINVAL;
1446+
for (count = 0; count < 4; count++) {
1447+
if (in[count] > 255)
1448+
return -EINVAL;
1449+
}
1450+
return 0;
1451+
}
1452+
14361453
static struct p9_trans *
14371454
p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
14381455
{
@@ -1447,6 +1464,9 @@ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
14471464
if (err < 0)
14481465
return ERR_PTR(err);
14491466

1467+
if (valid_ipaddr4(addr) < 0)
1468+
return ERR_PTR(-EINVAL);
1469+
14501470
csocket = NULL;
14511471
trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
14521472
if (!trans)
@@ -1625,7 +1645,7 @@ static struct p9_trans_module p9_fd_trans = {
16251645
.create = p9_trans_create_fd,
16261646
};
16271647

1628-
static int __init p9_trans_fd_init(void)
1648+
int p9_trans_fd_init(void)
16291649
{
16301650
int ret = p9_mux_global_init();
16311651
if (ret) {
@@ -1639,9 +1659,4 @@ static int __init p9_trans_fd_init(void)
16391659

16401660
return 0;
16411661
}
1642-
1643-
module_init(p9_trans_fd_init);
1644-
1645-
MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
1646-
MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
1647-
MODULE_LICENSE("GPL");
1662+
EXPORT_SYMBOL(p9_trans_fd_init);

0 commit comments

Comments
 (0)