diff options
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 0b74c61db7b4..5d973b25b5b0 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/fsnotify.h> | 17 | #include <linux/fsnotify.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/rcupdate.h> | 19 | #include <linux/rcupdate.h> |
20 | #include <linux/utsname.h> | ||
20 | 21 | ||
21 | #include <asm/ioctls.h> | 22 | #include <asm/ioctls.h> |
22 | #include <linux/poll.h> | 23 | #include <linux/poll.h> |
@@ -1275,6 +1276,44 @@ static const struct rpc_pipe_ops gssd_dummy_pipe_ops = { | |||
1275 | .downcall = dummy_downcall, | 1276 | .downcall = dummy_downcall, |
1276 | }; | 1277 | }; |
1277 | 1278 | ||
1279 | /* | ||
1280 | * Here we present a bogus "info" file to keep rpc.gssd happy. We don't expect | ||
1281 | * that it will ever use this info to handle an upcall, but rpc.gssd expects | ||
1282 | * that this file will be there and have a certain format. | ||
1283 | */ | ||
1284 | static int | ||
1285 | rpc_show_dummy_info(struct seq_file *m, void *v) | ||
1286 | { | ||
1287 | seq_printf(m, "RPC server: %s\n", utsname()->nodename); | ||
1288 | seq_printf(m, "service: foo (1) version 0\n"); | ||
1289 | seq_printf(m, "address: 127.0.0.1\n"); | ||
1290 | seq_printf(m, "protocol: tcp\n"); | ||
1291 | seq_printf(m, "port: 0\n"); | ||
1292 | return 0; | ||
1293 | } | ||
1294 | |||
1295 | static int | ||
1296 | rpc_dummy_info_open(struct inode *inode, struct file *file) | ||
1297 | { | ||
1298 | return single_open(file, rpc_show_dummy_info, NULL); | ||
1299 | } | ||
1300 | |||
1301 | static const struct file_operations rpc_dummy_info_operations = { | ||
1302 | .owner = THIS_MODULE, | ||
1303 | .open = rpc_dummy_info_open, | ||
1304 | .read = seq_read, | ||
1305 | .llseek = seq_lseek, | ||
1306 | .release = single_release, | ||
1307 | }; | ||
1308 | |||
1309 | static const struct rpc_filelist gssd_dummy_info_file[] = { | ||
1310 | [0] = { | ||
1311 | .name = "info", | ||
1312 | .i_fop = &rpc_dummy_info_operations, | ||
1313 | .mode = S_IFREG | S_IRUSR, | ||
1314 | }, | ||
1315 | }; | ||
1316 | |||
1278 | /** | 1317 | /** |
1279 | * rpc_gssd_dummy_populate - create a dummy gssd pipe | 1318 | * rpc_gssd_dummy_populate - create a dummy gssd pipe |
1280 | * @root: root of the rpc_pipefs filesystem | 1319 | * @root: root of the rpc_pipefs filesystem |
@@ -1312,9 +1351,18 @@ rpc_gssd_dummy_populate(struct dentry *root, struct rpc_pipe *pipe_data) | |||
1312 | goto out; | 1351 | goto out; |
1313 | } | 1352 | } |
1314 | 1353 | ||
1354 | ret = rpc_populate(clnt_dentry, gssd_dummy_info_file, 0, 1, NULL); | ||
1355 | if (ret) { | ||
1356 | __rpc_depopulate(gssd_dentry, gssd_dummy_clnt_dir, 0, 1); | ||
1357 | pipe_dentry = ERR_PTR(ret); | ||
1358 | goto out; | ||
1359 | } | ||
1360 | |||
1315 | pipe_dentry = rpc_mkpipe_dentry(clnt_dentry, "gssd", NULL, pipe_data); | 1361 | pipe_dentry = rpc_mkpipe_dentry(clnt_dentry, "gssd", NULL, pipe_data); |
1316 | if (IS_ERR(pipe_dentry)) | 1362 | if (IS_ERR(pipe_dentry)) { |
1363 | __rpc_depopulate(clnt_dentry, gssd_dummy_info_file, 0, 1); | ||
1317 | __rpc_depopulate(gssd_dentry, gssd_dummy_clnt_dir, 0, 1); | 1364 | __rpc_depopulate(gssd_dentry, gssd_dummy_clnt_dir, 0, 1); |
1365 | } | ||
1318 | out: | 1366 | out: |
1319 | dput(clnt_dentry); | 1367 | dput(clnt_dentry); |
1320 | dput(gssd_dentry); | 1368 | dput(gssd_dentry); |