1*996bc4f4STrond Myklebust // SPDX-License-Identifier: GPL-2.0 2*996bc4f4STrond Myklebust /* 3*996bc4f4STrond Myklebust * Copyright (c) 2019 Hammerspace Inc 4*996bc4f4STrond Myklebust */ 5*996bc4f4STrond Myklebust 6*996bc4f4STrond Myklebust #include <linux/module.h> 7*996bc4f4STrond Myklebust #include <linux/kobject.h> 8*996bc4f4STrond Myklebust #include <linux/sysfs.h> 9*996bc4f4STrond Myklebust #include <linux/fs.h> 10*996bc4f4STrond Myklebust #include <linux/slab.h> 11*996bc4f4STrond Myklebust #include <linux/netdevice.h> 12*996bc4f4STrond Myklebust 13*996bc4f4STrond Myklebust #include "sysfs.h" 14*996bc4f4STrond Myklebust 15*996bc4f4STrond Myklebust struct kobject *nfs_client_kobj; 16*996bc4f4STrond Myklebust static struct kset *nfs_client_kset; 17*996bc4f4STrond Myklebust 18*996bc4f4STrond Myklebust static void nfs_netns_object_release(struct kobject *kobj) 19*996bc4f4STrond Myklebust { 20*996bc4f4STrond Myklebust kfree(kobj); 21*996bc4f4STrond Myklebust } 22*996bc4f4STrond Myklebust 23*996bc4f4STrond Myklebust static const struct kobj_ns_type_operations *nfs_netns_object_child_ns_type( 24*996bc4f4STrond Myklebust struct kobject *kobj) 25*996bc4f4STrond Myklebust { 26*996bc4f4STrond Myklebust return &net_ns_type_operations; 27*996bc4f4STrond Myklebust } 28*996bc4f4STrond Myklebust 29*996bc4f4STrond Myklebust static struct kobj_type nfs_netns_object_type = { 30*996bc4f4STrond Myklebust .release = nfs_netns_object_release, 31*996bc4f4STrond Myklebust .sysfs_ops = &kobj_sysfs_ops, 32*996bc4f4STrond Myklebust .child_ns_type = nfs_netns_object_child_ns_type, 33*996bc4f4STrond Myklebust }; 34*996bc4f4STrond Myklebust 35*996bc4f4STrond Myklebust static struct kobject *nfs_netns_object_alloc(const char *name, 36*996bc4f4STrond Myklebust struct kset *kset, struct kobject *parent) 37*996bc4f4STrond Myklebust { 38*996bc4f4STrond Myklebust struct kobject *kobj; 39*996bc4f4STrond Myklebust 40*996bc4f4STrond Myklebust kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); 41*996bc4f4STrond Myklebust if (kobj) { 42*996bc4f4STrond Myklebust kobj->kset = kset; 43*996bc4f4STrond Myklebust if (kobject_init_and_add(kobj, &nfs_netns_object_type, 44*996bc4f4STrond Myklebust parent, "%s", name) == 0) 45*996bc4f4STrond Myklebust return kobj; 46*996bc4f4STrond Myklebust kobject_put(kobj); 47*996bc4f4STrond Myklebust } 48*996bc4f4STrond Myklebust return NULL; 49*996bc4f4STrond Myklebust } 50*996bc4f4STrond Myklebust 51*996bc4f4STrond Myklebust int nfs_sysfs_init(void) 52*996bc4f4STrond Myklebust { 53*996bc4f4STrond Myklebust nfs_client_kset = kset_create_and_add("nfs", NULL, fs_kobj); 54*996bc4f4STrond Myklebust if (!nfs_client_kset) 55*996bc4f4STrond Myklebust return -ENOMEM; 56*996bc4f4STrond Myklebust nfs_client_kobj = nfs_netns_object_alloc("net", nfs_client_kset, NULL); 57*996bc4f4STrond Myklebust if (!nfs_client_kobj) { 58*996bc4f4STrond Myklebust kset_unregister(nfs_client_kset); 59*996bc4f4STrond Myklebust nfs_client_kset = NULL; 60*996bc4f4STrond Myklebust return -ENOMEM; 61*996bc4f4STrond Myklebust } 62*996bc4f4STrond Myklebust return 0; 63*996bc4f4STrond Myklebust } 64*996bc4f4STrond Myklebust 65*996bc4f4STrond Myklebust void nfs_sysfs_exit(void) 66*996bc4f4STrond Myklebust { 67*996bc4f4STrond Myklebust kobject_put(nfs_client_kobj); 68*996bc4f4STrond Myklebust kset_unregister(nfs_client_kset); 69*996bc4f4STrond Myklebust } 70