mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	NFS: add superblock sysfs entries
Create a sysfs directory for each mount that corresponds to the mount's nfs_server struct. As the mount is being constructed, use the name "server-n", but rename it to the "MAJOR:MINOR" of the mount after assigning a device_id. The rename approach allows us to populate the mount's directory with links to the various rpc_client objects during the mount's construction. The naming convention (MAJOR:MINOR) can be used to reference a particular NFS mount's sysfs tree. Signed-off-by: Benjamin Coddington <bcodding@redhat.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
		
							parent
							
								
									e96f9268ee
								
							
						
					
					
						commit
						1c7251187d
					
				
					 6 changed files with 90 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -698,6 +698,7 @@ static int nfs_init_server(struct nfs_server *server,
 | 
			
		|||
		return PTR_ERR(clp);
 | 
			
		||||
 | 
			
		||||
	server->nfs_client = clp;
 | 
			
		||||
	nfs_sysfs_add_server(server);
 | 
			
		||||
 | 
			
		||||
	/* Initialise the client representation from the mount data */
 | 
			
		||||
	server->flags = ctx->flags;
 | 
			
		||||
| 
						 | 
				
			
			@ -952,6 +953,8 @@ void nfs_server_remove_lists(struct nfs_server *server)
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(nfs_server_remove_lists);
 | 
			
		||||
 | 
			
		||||
static DEFINE_IDA(s_sysfs_ids);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Allocate and initialise a server record
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -963,6 +966,12 @@ struct nfs_server *nfs_alloc_server(void)
 | 
			
		|||
	if (!server)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	server->s_sysfs_id = ida_alloc(&s_sysfs_ids, GFP_KERNEL);
 | 
			
		||||
	if (server->s_sysfs_id < 0) {
 | 
			
		||||
		kfree(server);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	server->client = server->client_acl = ERR_PTR(-EINVAL);
 | 
			
		||||
 | 
			
		||||
	/* Zero out the NFS state stuff */
 | 
			
		||||
| 
						 | 
				
			
			@ -1009,6 +1018,10 @@ void nfs_free_server(struct nfs_server *server)
 | 
			
		|||
 | 
			
		||||
	nfs_put_client(server->nfs_client);
 | 
			
		||||
 | 
			
		||||
	nfs_sysfs_remove_server(server);
 | 
			
		||||
	kobject_put(&server->kobj);
 | 
			
		||||
	ida_free(&s_sysfs_ids, server->s_sysfs_id);
 | 
			
		||||
 | 
			
		||||
	ida_destroy(&server->lockowner_id);
 | 
			
		||||
	ida_destroy(&server->openowner_id);
 | 
			
		||||
	nfs_free_iostats(server->io_stats);
 | 
			
		||||
| 
						 | 
				
			
			@ -1110,6 +1123,8 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
 | 
			
		|||
 | 
			
		||||
	server->fsid = fattr->fsid;
 | 
			
		||||
 | 
			
		||||
	nfs_sysfs_add_server(server);
 | 
			
		||||
 | 
			
		||||
	error = nfs_init_server_rpcclient(server,
 | 
			
		||||
			source->client->cl_timeout,
 | 
			
		||||
			flavor);
 | 
			
		||||
| 
						 | 
				
			
			@ -1393,6 +1408,7 @@ int __init nfs_fs_proc_init(void)
 | 
			
		|||
void nfs_fs_proc_exit(void)
 | 
			
		||||
{
 | 
			
		||||
	remove_proc_subtree("fs/nfsfs", NULL);
 | 
			
		||||
	ida_destroy(&s_sysfs_ids);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* CONFIG_PROC_FS */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
#include "nfs4idmap.h"
 | 
			
		||||
#include "pnfs.h"
 | 
			
		||||
#include "netns.h"
 | 
			
		||||
#include "sysfs.h"
 | 
			
		||||
 | 
			
		||||
#define NFSDBG_FACILITY		NFSDBG_CLIENT
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -952,6 +953,8 @@ static int nfs4_set_client(struct nfs_server *server,
 | 
			
		|||
	set_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state);
 | 
			
		||||
 | 
			
		||||
	server->nfs_client = clp;
 | 
			
		||||
	nfs_sysfs_add_server(server);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,6 +70,8 @@
 | 
			
		|||
#include "nfs4session.h"
 | 
			
		||||
#include "pnfs.h"
 | 
			
		||||
#include "nfs.h"
 | 
			
		||||
#include "netns.h"
 | 
			
		||||
#include "sysfs.h"
 | 
			
		||||
 | 
			
		||||
#define NFSDBG_FACILITY		NFSDBG_VFS
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1089,6 +1091,7 @@ static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx)
 | 
			
		|||
						 &sb->s_blocksize_bits);
 | 
			
		||||
 | 
			
		||||
	nfs_super_set_maxbytes(sb, server->maxfilesize);
 | 
			
		||||
	nfs_sysfs_move_server_to_sb(sb);
 | 
			
		||||
	server->has_sec_mnt_opts = ctx->has_sec_mnt_opts;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1331,13 +1334,14 @@ int nfs_get_tree_common(struct fs_context *fc)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Destroy an NFS2/3 superblock
 | 
			
		||||
 * Destroy an NFS superblock
 | 
			
		||||
 */
 | 
			
		||||
void nfs_kill_super(struct super_block *s)
 | 
			
		||||
{
 | 
			
		||||
	struct nfs_server *server = NFS_SB(s);
 | 
			
		||||
	dev_t dev = s->s_dev;
 | 
			
		||||
 | 
			
		||||
	nfs_sysfs_move_sb_to_server(server);
 | 
			
		||||
	generic_shutdown_super(s);
 | 
			
		||||
 | 
			
		||||
	nfs_fscache_release_super_cookie(s);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -215,3 +215,62 @@ void nfs_netns_sysfs_destroy(struct nfs_net *netns)
 | 
			
		|||
		netns->nfs_client = NULL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void nfs_sysfs_sb_release(struct kobject *kobj)
 | 
			
		||||
{
 | 
			
		||||
	/* no-op: why? see lib/kobject.c kobject_cleanup() */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const void *nfs_netns_server_namespace(const struct kobject *kobj)
 | 
			
		||||
{
 | 
			
		||||
	return container_of(kobj, struct nfs_server, kobj)->nfs_client->cl_net;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct kobj_type nfs_sb_ktype = {
 | 
			
		||||
	.release = nfs_sysfs_sb_release,
 | 
			
		||||
	.sysfs_ops = &kobj_sysfs_ops,
 | 
			
		||||
	.namespace = nfs_netns_server_namespace,
 | 
			
		||||
	.child_ns_type = nfs_netns_object_child_ns_type,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void nfs_sysfs_add_server(struct nfs_server *server)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	ret = kobject_init_and_add(&server->kobj, &nfs_sb_ktype,
 | 
			
		||||
				&nfs_kset->kobj, "server-%d", server->s_sysfs_id);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		pr_warn("NFS: nfs sysfs add server-%d failed (%d)\n",
 | 
			
		||||
					server->s_sysfs_id, ret);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(nfs_sysfs_add_server);
 | 
			
		||||
 | 
			
		||||
void nfs_sysfs_move_server_to_sb(struct super_block *s)
 | 
			
		||||
{
 | 
			
		||||
	struct nfs_server *server = s->s_fs_info;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	ret = kobject_rename(&server->kobj, s->s_id);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		pr_warn("NFS: rename sysfs %s failed (%d)\n",
 | 
			
		||||
					server->kobj.name, ret);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nfs_sysfs_move_sb_to_server(struct nfs_server *server)
 | 
			
		||||
{
 | 
			
		||||
	const char *s;
 | 
			
		||||
	int ret = -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	s = kasprintf(GFP_KERNEL, "server-%d", server->s_sysfs_id);
 | 
			
		||||
	if (s)
 | 
			
		||||
		ret = kobject_rename(&server->kobj, s);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		pr_warn("NFS: rename sysfs %s failed (%d)\n",
 | 
			
		||||
					server->kobj.name, ret);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* unlink, not dec-ref */
 | 
			
		||||
void nfs_sysfs_remove_server(struct nfs_server *server)
 | 
			
		||||
{
 | 
			
		||||
	kobject_del(&server->kobj);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,4 +23,9 @@ extern void nfs_sysfs_exit(void);
 | 
			
		|||
void nfs_netns_sysfs_setup(struct nfs_net *netns, struct net *net);
 | 
			
		||||
void nfs_netns_sysfs_destroy(struct nfs_net *netns);
 | 
			
		||||
 | 
			
		||||
void nfs_sysfs_add_server(struct nfs_server *s);
 | 
			
		||||
void nfs_sysfs_move_server_to_sb(struct super_block *s);
 | 
			
		||||
void nfs_sysfs_move_sb_to_server(struct nfs_server *s);
 | 
			
		||||
void nfs_sysfs_remove_server(struct nfs_server *s);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -184,6 +184,7 @@ struct nfs_server {
 | 
			
		|||
				change_attr_type;/* Description of change attribute */
 | 
			
		||||
 | 
			
		||||
	struct nfs_fsid		fsid;
 | 
			
		||||
	int			s_sysfs_id;	/* sysfs dentry index */
 | 
			
		||||
	__u64			maxfilesize;	/* maximum file size */
 | 
			
		||||
	struct timespec64	time_delta;	/* smallest time granularity */
 | 
			
		||||
	unsigned long		mount_time;	/* when this fs was mounted */
 | 
			
		||||
| 
						 | 
				
			
			@ -260,6 +261,7 @@ struct nfs_server {
 | 
			
		|||
	/* User namespace info */
 | 
			
		||||
	const struct cred	*cred;
 | 
			
		||||
	bool			has_sec_mnt_opts;
 | 
			
		||||
	struct kobject		kobj;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Server capabilities */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue