Initialize/destroy a kset on module init/fini for XFS. The XFS attribute directory is represented as /sys/fs/xfs. Create a subdirectory per-mount based on the system device name. Also add some basic macros to aid in the addition of sysfs attributes. This code is modeled after the equivalent mechanism for ext4. Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx> --- fs/xfs/xfs_mount.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_mount.h | 2 ++ fs/xfs/xfs_super.c | 12 ++++++++- 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 944f3d9..9ed9dd0 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -60,6 +60,9 @@ static DEFINE_MUTEX(xfs_uuid_table_mutex); static int xfs_uuid_table_size; static uuid_t *xfs_uuid_table; +extern struct kset *xfs_kset; +static struct kobj_type xfs_ktype; + /* * See if the UUID is unique among mounted XFS filesystems. * Mount fails if UUID is nil or a FS with the same UUID is already mounted. @@ -955,6 +958,13 @@ xfs_mountfs( "Unable to allocate reserve blocks. Continuing without reserve pool."); } + mp->m_kobject.kset = xfs_kset; + init_completion(&mp->m_kobject_complete); + error = kobject_init_and_add(&mp->m_kobject, &xfs_ktype, NULL, + "%s", mp->m_fsname); + if (error) + goto out_rtunmount; + return 0; out_rtunmount: @@ -986,6 +996,10 @@ xfs_unmountfs( __uint64_t resblks; int error; + kobject_del(&mp->m_kobject); + kobject_put(&mp->m_kobject); + wait_for_completion(&mp->m_kobject_complete); + cancel_delayed_work_sync(&mp->m_eofblocks_work); xfs_qm_unmount_quotas(mp); @@ -2007,3 +2021,68 @@ balance_counter: } #endif + +/* sysfs support */ + +struct xfs_sysfs_attr { + struct attribute attr; + ssize_t (*show)(struct xfs_mount *mp, char *buf); + ssize_t (*store)(struct xfs_mount *mp, const char *buf, size_t count); +}; + +#define XFS_SYSFS_ATTR_RW(name) \ + static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name) +#define XFS_SYSFS_ATTR_RO(name) \ + static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name) + +#define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr + +static struct attribute *xfs_sysfs_attrs[] = { + NULL, +}; + +STATIC ssize_t +xfs_sysfs_show( + struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct xfs_mount *mp = container_of(kobj, struct xfs_mount, m_kobject); + struct xfs_sysfs_attr *xfs_attr = container_of(attr, + struct xfs_sysfs_attr, attr); + + return xfs_attr->show ? xfs_attr->show(mp, buf) : 0; +} + +STATIC ssize_t +xfs_sysfs_store( + struct kobject *kobj, + struct attribute *attr, + const char *buf, + size_t count) +{ + struct xfs_mount *mp = container_of(kobj, struct xfs_mount, m_kobject); + struct xfs_sysfs_attr *xfs_attr = container_of(attr, + struct xfs_sysfs_attr, attr); + + return xfs_attr->store ? xfs_attr->store(mp, buf, count) : 0; +} + +static struct sysfs_ops xfs_sysfs_ops = { + .show = xfs_sysfs_show, + .store = xfs_sysfs_store, +}; + +STATIC void +xfs_kobj_release(struct kobject *kobj) +{ + struct xfs_mount *mp = container_of(kobj, struct xfs_mount, m_kobject); + + complete(&mp->m_kobject_complete); +} + +static struct kobj_type xfs_ktype = { + .release = xfs_kobj_release, + .sysfs_ops = &xfs_sysfs_ops, + .default_attrs = xfs_sysfs_attrs, +}; diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index a466c5e..b7f1cfb 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -172,6 +172,8 @@ typedef struct xfs_mount { on the next remount,rw */ int64_t m_low_space[XFS_LOWSP_MAX]; /* low free space thresholds */ + struct kobject m_kobject; + struct completion m_kobject_complete; struct workqueue_struct *m_data_workqueue; struct workqueue_struct *m_unwritten_workqueue; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 8f0333b..1766214 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -61,6 +61,7 @@ static const struct super_operations xfs_super_operations; static kmem_zone_t *xfs_ioend_zone; mempool_t *xfs_ioend_pool; +struct kset *xfs_kset; #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ @@ -1761,9 +1762,15 @@ init_xfs_fs(void) if (error) goto out_cleanup_procfs; + xfs_kset = kset_create_and_add("xfs", NULL, fs_kobj); + if (!xfs_kset) { + error = -ENOMEM; + goto out_sysctl_unregister;; + } + error = xfs_qm_init(); if (error) - goto out_sysctl_unregister; + goto out_kset_unregister; error = register_filesystem(&xfs_fs_type); if (error) @@ -1772,6 +1779,8 @@ init_xfs_fs(void) out_qm_exit: xfs_qm_exit(); + out_kset_unregister: + kset_unregister(xfs_kset); out_sysctl_unregister: xfs_sysctl_unregister(); out_cleanup_procfs: @@ -1793,6 +1802,7 @@ exit_xfs_fs(void) { xfs_qm_exit(); unregister_filesystem(&xfs_fs_type); + kset_unregister(xfs_kset); xfs_sysctl_unregister(); xfs_cleanup_procfs(); xfs_buf_terminate(); -- 1.8.3.1 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs