| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * net/sunrpc/rpc_pipe.c |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 13 | 14 | #include <linux/string.h> |
|---|
| 14 | 15 | #include <linux/pagemap.h> |
|---|
| 15 | 16 | #include <linux/mount.h> |
|---|
| 17 | +#include <linux/fs_context.h> |
|---|
| 16 | 18 | #include <linux/namei.h> |
|---|
| 17 | 19 | #include <linux/fsnotify.h> |
|---|
| 18 | 20 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 49 | 51 | |
|---|
| 50 | 52 | int rpc_pipefs_notifier_register(struct notifier_block *nb) |
|---|
| 51 | 53 | { |
|---|
| 52 | | - return blocking_notifier_chain_cond_register(&rpc_pipefs_notifier_list, nb); |
|---|
| 54 | + return blocking_notifier_chain_register(&rpc_pipefs_notifier_list, nb); |
|---|
| 53 | 55 | } |
|---|
| 54 | 56 | EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_register); |
|---|
| 55 | 57 | |
|---|
| .. | .. |
|---|
| 202 | 204 | } |
|---|
| 203 | 205 | |
|---|
| 204 | 206 | static void |
|---|
| 205 | | -rpc_i_callback(struct rcu_head *head) |
|---|
| 207 | +rpc_free_inode(struct inode *inode) |
|---|
| 206 | 208 | { |
|---|
| 207 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
|---|
| 208 | 209 | kmem_cache_free(rpc_inode_cachep, RPC_I(inode)); |
|---|
| 209 | | -} |
|---|
| 210 | | - |
|---|
| 211 | | -static void |
|---|
| 212 | | -rpc_destroy_inode(struct inode *inode) |
|---|
| 213 | | -{ |
|---|
| 214 | | - call_rcu(&inode->i_rcu, rpc_i_callback); |
|---|
| 215 | 210 | } |
|---|
| 216 | 211 | |
|---|
| 217 | 212 | static int |
|---|
| .. | .. |
|---|
| 483 | 478 | inode->i_fop = &simple_dir_operations; |
|---|
| 484 | 479 | inode->i_op = &simple_dir_inode_operations; |
|---|
| 485 | 480 | inc_nlink(inode); |
|---|
| 481 | + break; |
|---|
| 486 | 482 | default: |
|---|
| 487 | 483 | break; |
|---|
| 488 | 484 | } |
|---|
| .. | .. |
|---|
| 604 | 600 | |
|---|
| 605 | 601 | dget(dentry); |
|---|
| 606 | 602 | ret = simple_rmdir(dir, dentry); |
|---|
| 607 | | - d_delete(dentry); |
|---|
| 603 | + d_drop(dentry); |
|---|
| 604 | + if (!ret) |
|---|
| 605 | + fsnotify_rmdir(dir, dentry); |
|---|
| 608 | 606 | dput(dentry); |
|---|
| 609 | 607 | return ret; |
|---|
| 610 | 608 | } |
|---|
| .. | .. |
|---|
| 615 | 613 | |
|---|
| 616 | 614 | dget(dentry); |
|---|
| 617 | 615 | ret = simple_unlink(dir, dentry); |
|---|
| 618 | | - d_delete(dentry); |
|---|
| 616 | + d_drop(dentry); |
|---|
| 617 | + if (!ret) |
|---|
| 618 | + fsnotify_unlink(dir, dentry); |
|---|
| 619 | 619 | dput(dentry); |
|---|
| 620 | 620 | return ret; |
|---|
| 621 | 621 | } |
|---|
| .. | .. |
|---|
| 1123 | 1123 | */ |
|---|
| 1124 | 1124 | static const struct super_operations s_ops = { |
|---|
| 1125 | 1125 | .alloc_inode = rpc_alloc_inode, |
|---|
| 1126 | | - .destroy_inode = rpc_destroy_inode, |
|---|
| 1126 | + .free_inode = rpc_free_inode, |
|---|
| 1127 | 1127 | .statfs = simple_statfs, |
|---|
| 1128 | 1128 | }; |
|---|
| 1129 | 1129 | |
|---|
| .. | .. |
|---|
| 1266 | 1266 | * that this file will be there and have a certain format. |
|---|
| 1267 | 1267 | */ |
|---|
| 1268 | 1268 | static int |
|---|
| 1269 | | -rpc_show_dummy_info(struct seq_file *m, void *v) |
|---|
| 1269 | +rpc_dummy_info_show(struct seq_file *m, void *v) |
|---|
| 1270 | 1270 | { |
|---|
| 1271 | 1271 | seq_printf(m, "RPC server: %s\n", utsname()->nodename); |
|---|
| 1272 | 1272 | seq_printf(m, "service: foo (1) version 0\n"); |
|---|
| .. | .. |
|---|
| 1275 | 1275 | seq_printf(m, "port: 0\n"); |
|---|
| 1276 | 1276 | return 0; |
|---|
| 1277 | 1277 | } |
|---|
| 1278 | | - |
|---|
| 1279 | | -static int |
|---|
| 1280 | | -rpc_dummy_info_open(struct inode *inode, struct file *file) |
|---|
| 1281 | | -{ |
|---|
| 1282 | | - return single_open(file, rpc_show_dummy_info, NULL); |
|---|
| 1283 | | -} |
|---|
| 1284 | | - |
|---|
| 1285 | | -static const struct file_operations rpc_dummy_info_operations = { |
|---|
| 1286 | | - .owner = THIS_MODULE, |
|---|
| 1287 | | - .open = rpc_dummy_info_open, |
|---|
| 1288 | | - .read = seq_read, |
|---|
| 1289 | | - .llseek = seq_lseek, |
|---|
| 1290 | | - .release = single_release, |
|---|
| 1291 | | -}; |
|---|
| 1278 | +DEFINE_SHOW_ATTRIBUTE(rpc_dummy_info); |
|---|
| 1292 | 1279 | |
|---|
| 1293 | 1280 | static const struct rpc_filelist gssd_dummy_info_file[] = { |
|---|
| 1294 | 1281 | [0] = { |
|---|
| 1295 | 1282 | .name = "info", |
|---|
| 1296 | | - .i_fop = &rpc_dummy_info_operations, |
|---|
| 1283 | + .i_fop = &rpc_dummy_info_fops, |
|---|
| 1297 | 1284 | .mode = S_IFREG | 0400, |
|---|
| 1298 | 1285 | }, |
|---|
| 1299 | 1286 | }; |
|---|
| .. | .. |
|---|
| 1368 | 1355 | } |
|---|
| 1369 | 1356 | |
|---|
| 1370 | 1357 | static int |
|---|
| 1371 | | -rpc_fill_super(struct super_block *sb, void *data, int silent) |
|---|
| 1358 | +rpc_fill_super(struct super_block *sb, struct fs_context *fc) |
|---|
| 1372 | 1359 | { |
|---|
| 1373 | 1360 | struct inode *inode; |
|---|
| 1374 | 1361 | struct dentry *root, *gssd_dentry; |
|---|
| 1375 | | - struct net *net = get_net(sb->s_fs_info); |
|---|
| 1362 | + struct net *net = sb->s_fs_info; |
|---|
| 1376 | 1363 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); |
|---|
| 1377 | 1364 | int err; |
|---|
| 1378 | 1365 | |
|---|
| .. | .. |
|---|
| 1429 | 1416 | } |
|---|
| 1430 | 1417 | EXPORT_SYMBOL_GPL(gssd_running); |
|---|
| 1431 | 1418 | |
|---|
| 1432 | | -static struct dentry * |
|---|
| 1433 | | -rpc_mount(struct file_system_type *fs_type, |
|---|
| 1434 | | - int flags, const char *dev_name, void *data) |
|---|
| 1419 | +static int rpc_fs_get_tree(struct fs_context *fc) |
|---|
| 1435 | 1420 | { |
|---|
| 1436 | | - struct net *net = current->nsproxy->net_ns; |
|---|
| 1437 | | - return mount_ns(fs_type, flags, data, net, net->user_ns, rpc_fill_super); |
|---|
| 1421 | + return get_tree_keyed(fc, rpc_fill_super, get_net(fc->net_ns)); |
|---|
| 1422 | +} |
|---|
| 1423 | + |
|---|
| 1424 | +static void rpc_fs_free_fc(struct fs_context *fc) |
|---|
| 1425 | +{ |
|---|
| 1426 | + if (fc->s_fs_info) |
|---|
| 1427 | + put_net(fc->s_fs_info); |
|---|
| 1428 | +} |
|---|
| 1429 | + |
|---|
| 1430 | +static const struct fs_context_operations rpc_fs_context_ops = { |
|---|
| 1431 | + .free = rpc_fs_free_fc, |
|---|
| 1432 | + .get_tree = rpc_fs_get_tree, |
|---|
| 1433 | +}; |
|---|
| 1434 | + |
|---|
| 1435 | +static int rpc_init_fs_context(struct fs_context *fc) |
|---|
| 1436 | +{ |
|---|
| 1437 | + put_user_ns(fc->user_ns); |
|---|
| 1438 | + fc->user_ns = get_user_ns(fc->net_ns->user_ns); |
|---|
| 1439 | + fc->ops = &rpc_fs_context_ops; |
|---|
| 1440 | + return 0; |
|---|
| 1438 | 1441 | } |
|---|
| 1439 | 1442 | |
|---|
| 1440 | 1443 | static void rpc_kill_sb(struct super_block *sb) |
|---|
| .. | .. |
|---|
| 1462 | 1465 | static struct file_system_type rpc_pipe_fs_type = { |
|---|
| 1463 | 1466 | .owner = THIS_MODULE, |
|---|
| 1464 | 1467 | .name = "rpc_pipefs", |
|---|
| 1465 | | - .mount = rpc_mount, |
|---|
| 1468 | + .init_fs_context = rpc_init_fs_context, |
|---|
| 1466 | 1469 | .kill_sb = rpc_kill_sb, |
|---|
| 1467 | 1470 | }; |
|---|
| 1468 | 1471 | MODULE_ALIAS_FS("rpc_pipefs"); |
|---|
| .. | .. |
|---|
| 1508 | 1511 | void unregister_rpc_pipefs(void) |
|---|
| 1509 | 1512 | { |
|---|
| 1510 | 1513 | rpc_clients_notifier_unregister(); |
|---|
| 1511 | | - kmem_cache_destroy(rpc_inode_cachep); |
|---|
| 1512 | 1514 | unregister_filesystem(&rpc_pipe_fs_type); |
|---|
| 1515 | + kmem_cache_destroy(rpc_inode_cachep); |
|---|
| 1513 | 1516 | } |
|---|