Skip to content

Commit

Permalink
exofs: Add SYSFS info for autologin/pNFS export
Browse files Browse the repository at this point in the history
Introduce sysfs infrastructure for exofs cluster filesystem.

Each OSD target shows up as below in the sysfs hierarchy:
	/sys/fs/exofs/<osdname>_<partition_id>/devX

Where <osdname>_<partition_id> is the unique identification
of a Superblock.

Where devX: 0 <= X < device_table_size. They are ordered
in device-table order as specified to the mkfs.exofs command

Each OSD device  devX has following attributes :
	osdname - ReadOnly
	systemid - ReadOnly
	uri - Read/Write

It is up to user-mode to update devX/uri for support of
autologin.

These sysfs information are used both for autologin as well
as support for exporting exofs via a pNFSD server in user-mode.
(.eg NFS-Ganesha)

Signed-off-by: Sachin Bhamare <[email protected]>
Signed-off-by: Boaz Harrosh <[email protected]>
  • Loading branch information
Sachin Bhamare authored and Boaz Harrosh committed May 21, 2012
1 parent 6abe4a8 commit 8b56a30
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 1 deletion.
2 changes: 1 addition & 1 deletion fs/exofs/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
libore-y := ore.o ore_raid.o
obj-$(CONFIG_ORE) += libore.o

exofs-y := inode.o file.o symlink.o namei.o dir.o super.o
exofs-y := inode.o file.o symlink.o namei.o dir.o super.o sys.o
obj-$(CONFIG_EXOFS_FS) += exofs.o
14 changes: 14 additions & 0 deletions fs/exofs/exofs.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
struct exofs_dev {
struct ore_dev ored;
unsigned did;
unsigned urilen;
uint8_t *uri;
struct kobject ed_kobj;
};
/*
* our extension to the in-memory superblock
Expand All @@ -73,6 +76,7 @@ struct exofs_sb_info {
struct ore_layout layout; /* Default files layout */
struct ore_comp one_comp; /* id & cred of partition id=0*/
struct ore_components oc; /* comps for the partition */
struct kobject s_kobj; /* holds per-sbi kobject */
};

/*
Expand Down Expand Up @@ -176,6 +180,16 @@ void exofs_make_credential(u8 cred_a[OSD_CAP_LEN],
const struct osd_obj_id *obj);
int exofs_sbi_write_stats(struct exofs_sb_info *sbi);

/* sys.c */
int exofs_sysfs_init(void);
void exofs_sysfs_uninit(void);
int exofs_sysfs_sb_add(struct exofs_sb_info *sbi,
struct exofs_dt_device_info *dt_dev);
void exofs_sysfs_sb_del(struct exofs_sb_info *sbi);
int exofs_sysfs_odev_add(struct exofs_dev *edev,
struct exofs_sb_info *sbi);
void exofs_sysfs_dbg_print(void);

/*********************
* operation vectors *
*********************/
Expand Down
14 changes: 14 additions & 0 deletions fs/exofs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ static void exofs_put_super(struct super_block *sb)
_exofs_print_device("Unmounting", NULL, ore_comp_dev(&sbi->oc, 0),
sbi->one_comp.obj.partition);

exofs_sysfs_sb_del(sbi);
bdi_destroy(&sbi->bdi);
exofs_free_sbi(sbi);
sb->s_fs_info = NULL;
Expand Down Expand Up @@ -632,6 +633,12 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
memcpy(&sbi->oc.ods[numdevs], &sbi->oc.ods[0],
(numdevs - 1) * sizeof(sbi->oc.ods[0]));

/* create sysfs subdir under which we put the device table
* And cluster layout. A Superblock is identified by the string:
* "dev[0].osdname"_"pid"
*/
exofs_sysfs_sb_add(sbi, &dt->dt_dev_table[0]);

for (i = 0; i < numdevs; i++) {
struct exofs_fscb fscb;
struct osd_dev_info odi;
Expand All @@ -657,6 +664,7 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
eds[i].ored.od = fscb_od;
++sbi->oc.numdevs;
fscb_od = NULL;
exofs_sysfs_odev_add(&eds[i], sbi);
continue;
}

Expand All @@ -682,6 +690,7 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
odi.osdname);
goto out;
}
exofs_sysfs_odev_add(&eds[i], sbi);

/* TODO: verify other information is correct and FS-uuid
* matches. Benny what did you say about device table
Expand Down Expand Up @@ -844,6 +853,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
goto free_sbi;
}

exofs_sysfs_dbg_print();
_exofs_print_device("Mounting", opts->dev_name,
ore_comp_dev(&sbi->oc, 0),
sbi->one_comp.obj.partition);
Expand Down Expand Up @@ -1023,6 +1033,9 @@ static int __init init_exofs(void)
if (err)
goto out_d;

/* We don't fail if sysfs creation failed */
exofs_sysfs_init();

return 0;
out_d:
destroy_inodecache();
Expand All @@ -1032,6 +1045,7 @@ static int __init init_exofs(void)

static void __exit exit_exofs(void)
{
exofs_sysfs_uninit();
unregister_filesystem(&exofs_type);
destroy_inodecache();
}
Expand Down
200 changes: 200 additions & 0 deletions fs/exofs/sys.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/*
* Copyright (C) 2012
* Sachin Bhamare <[email protected]>
* Boaz Harrosh <[email protected]>
*
* This file is part of exofs.
*
* exofs is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License 2 as published by
* the Free Software Foundation.
*
* exofs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with exofs; if not, write to the:
* Free Software Foundation <[email protected]>
*/

#include <linux/kobject.h>
#include <linux/device.h>

#include "exofs.h"

struct odev_attr {
struct attribute attr;
ssize_t (*show)(struct exofs_dev *, char *);
ssize_t (*store)(struct exofs_dev *, const char *, size_t);
};

static ssize_t odev_attr_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
struct exofs_dev *edp = container_of(kobj, struct exofs_dev, ed_kobj);
struct odev_attr *a = container_of(attr, struct odev_attr, attr);

return a->show ? a->show(edp, buf) : 0;
}

static ssize_t odev_attr_store(struct kobject *kobj, struct attribute *attr,
const char *buf, size_t len)
{
struct exofs_dev *edp = container_of(kobj, struct exofs_dev, ed_kobj);
struct odev_attr *a = container_of(attr, struct odev_attr, attr);

return a->store ? a->store(edp, buf, len) : len;
}

static const struct sysfs_ops odev_attr_ops = {
.show = odev_attr_show,
.store = odev_attr_store,
};


static struct kset *exofs_kset;

static ssize_t osdname_show(struct exofs_dev *edp, char *buf)
{
struct osd_dev *odev = edp->ored.od;
const struct osd_dev_info *odi = osduld_device_info(odev);

return snprintf(buf, odi->osdname_len + 1, "%s", odi->osdname);
}

static ssize_t systemid_show(struct exofs_dev *edp, char *buf)
{
struct osd_dev *odev = edp->ored.od;
const struct osd_dev_info *odi = osduld_device_info(odev);

memcpy(buf, odi->systemid, odi->systemid_len);
return odi->systemid_len;
}

static ssize_t uri_show(struct exofs_dev *edp, char *buf)
{
return snprintf(buf, edp->urilen, "%s", edp->uri);
}

static ssize_t uri_store(struct exofs_dev *edp, const char *buf, size_t len)
{
edp->urilen = strlen(buf) + 1;
edp->uri = krealloc(edp->uri, edp->urilen, GFP_KERNEL);
strncpy(edp->uri, buf, edp->urilen);
return edp->urilen;
}

#define OSD_ATTR(name, mode, show, store) \
static struct odev_attr odev_attr_##name = \
__ATTR(name, mode, show, store)

OSD_ATTR(osdname, S_IRUGO, osdname_show, NULL);
OSD_ATTR(systemid, S_IRUGO, systemid_show, NULL);
OSD_ATTR(uri, S_IRWXU, uri_show, uri_store);

static struct attribute *odev_attrs[] = {
&odev_attr_osdname.attr,
&odev_attr_systemid.attr,
&odev_attr_uri.attr,
NULL,
};

static struct kobj_type odev_ktype = {
.default_attrs = odev_attrs,
.sysfs_ops = &odev_attr_ops,
};

static struct kobj_type uuid_ktype = {
};

void exofs_sysfs_dbg_print()
{
#ifdef CONFIG_EXOFS_DEBUG
struct kobject *k_name, *k_tmp;

list_for_each_entry_safe(k_name, k_tmp, &exofs_kset->list, entry) {
printk(KERN_INFO "%s: name %s ref %d\n",
__func__, kobject_name(k_name),
(int)atomic_read(&k_name->kref.refcount));
}
#endif
}
/*
* This function removes all kobjects under exofs_kset
* At the end of it, exofs_kset kobject will have a refcount
* of 1 which gets decremented only on exofs module unload
*/
void exofs_sysfs_sb_del(struct exofs_sb_info *sbi)
{
struct kobject *k_name, *k_tmp;
struct kobject *s_kobj = &sbi->s_kobj;

list_for_each_entry_safe(k_name, k_tmp, &exofs_kset->list, entry) {
/* Remove all that are children of this SBI */
if (k_name->parent == s_kobj)
kobject_put(k_name);
}
kobject_put(s_kobj);
}

/*
* This function creates sysfs entries to hold the current exofs cluster
* instance (uniquely identified by osdname,pid tuple).
* This function gets called once per exofs mount instance.
*/
int exofs_sysfs_sb_add(struct exofs_sb_info *sbi,
struct exofs_dt_device_info *dt_dev)
{
struct kobject *s_kobj;
int retval = 0;
uint64_t pid = sbi->one_comp.obj.partition;

/* allocate new uuid dirent */
s_kobj = &sbi->s_kobj;
s_kobj->kset = exofs_kset;
retval = kobject_init_and_add(s_kobj, &uuid_ktype,
&exofs_kset->kobj, "%s_%llx", dt_dev->osdname, pid);
if (retval) {
EXOFS_ERR("ERROR: Failed to create sysfs entry for "
"uuid-%s_%llx => %d\n", dt_dev->osdname, pid, retval);
return -ENOMEM;
}
return 0;
}

int exofs_sysfs_odev_add(struct exofs_dev *edev, struct exofs_sb_info *sbi)
{
struct kobject *d_kobj;
int retval = 0;

/* create osd device group which contains following attributes
* osdname, systemid & uri
*/
d_kobj = &edev->ed_kobj;
d_kobj->kset = exofs_kset;
retval = kobject_init_and_add(d_kobj, &odev_ktype,
&sbi->s_kobj, "dev%u", edev->did);
if (retval) {
EXOFS_ERR("ERROR: Failed to create sysfs entry for "
"device dev%u\n", edev->did);
return retval;
}
return 0;
}

int exofs_sysfs_init(void)
{
exofs_kset = kset_create_and_add("exofs", NULL, fs_kobj);
if (!exofs_kset) {
EXOFS_ERR("ERROR: kset_create_and_add exofs failed\n");
return -ENOMEM;
}
return 0;
}

void exofs_sysfs_uninit(void)
{
kset_unregister(exofs_kset);
}

0 comments on commit 8b56a30

Please sign in to comment.