You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
4.0 KiB
172 lines
4.0 KiB
/* vim:set ts=4 sw=4 tw=0 noet ft=c:
|
|
*
|
|
* fs/sdcardfs/sysfs.c
|
|
*
|
|
* Copyright (C) 2017, Inc.
|
|
* Author: gaoxiang
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file COPYING in the main directory of the Linux
|
|
* distribution for more details.
|
|
*/
|
|
#include "sdcardfs.h"
|
|
|
|
#ifdef SDCARDFS_PLUGIN_PRIVACY_SPACE
|
|
static ssize_t
|
|
sdcardfs_sysfs_sb_blocked_users_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr, char *buf) {
|
|
|
|
struct sdcardfs_sb_info *sbi = container_of(kobj,
|
|
struct sdcardfs_sb_info, kobj);
|
|
ssize_t len = 0;
|
|
|
|
if (sbi->blocked_userid >= 0)
|
|
len = snprintf(buf, PAGE_SIZE, "%d %d",
|
|
sbi->blocked_userid, sbi->appid_excluded);
|
|
buf[len++] = '\n';
|
|
buf[len++] = '\0';
|
|
return len;
|
|
}
|
|
|
|
static ssize_t
|
|
sdcardfs_sysfs_sb_blocked_users_store(struct kobject *kobj,
|
|
struct kobj_attribute *attr,
|
|
const char *buf, size_t len) {
|
|
|
|
struct sdcardfs_sb_info *sbi = container_of(kobj,
|
|
struct sdcardfs_sb_info, kobj);
|
|
|
|
int args = sscanf(buf, "%d%d", &sbi->blocked_userid,
|
|
&sbi->appid_excluded);
|
|
|
|
if (args <= 0)
|
|
sbi->blocked_userid = -1;
|
|
else if (args <= 1)
|
|
sbi->appid_excluded = -1;
|
|
|
|
/* print some debug messages for the privacyspace feature */
|
|
if (sbi->blocked_userid < 0)
|
|
pr_warn("all users have access to %s now", kobj->name);
|
|
else {
|
|
pr_warn("user/%d has been blocked from accessing %s",
|
|
sbi->blocked_userid, kobj->name);
|
|
|
|
if (sbi->appid_excluded >= 0)
|
|
pr_warn("but appid/%d will be excluded",
|
|
sbi->appid_excluded);
|
|
}
|
|
return len;
|
|
}
|
|
#endif
|
|
|
|
static ssize_t
|
|
sdcardfs_sysfs_sb_device_show(struct kobject *kobj,
|
|
struct kobj_attribute *attr, char *buf) {
|
|
|
|
struct sdcardfs_sb_info *sbi = container_of(kobj,
|
|
struct sdcardfs_sb_info, kobj);
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%s\n", sbi->obbpath_s);
|
|
}
|
|
|
|
static void __sdcardfs_sysfs_sb_release(struct kobject *kobj)
|
|
{
|
|
struct sdcardfs_sb_info *sbi = container_of(kobj,
|
|
struct sdcardfs_sb_info, kobj);
|
|
|
|
kfree(sbi);
|
|
}
|
|
|
|
static ssize_t
|
|
sdcardfs_sysfs_attr_show(struct kobject *kobj,
|
|
struct attribute *attr, char *buf)
|
|
{
|
|
struct kobj_attribute *ka =
|
|
container_of(attr, struct kobj_attribute, attr);
|
|
|
|
return ka->show(kobj, ka, buf);
|
|
}
|
|
|
|
static ssize_t
|
|
sdcardfs_sysfs_attr_store(struct kobject *kobj,
|
|
struct attribute *attr, const char *buf,
|
|
size_t len)
|
|
{
|
|
struct kobj_attribute *ka;
|
|
|
|
char *s = skip_spaces(buf);
|
|
len -= s - buf;
|
|
buf = s;
|
|
|
|
if (len == 0 || *buf == '\0')
|
|
return -EINVAL;
|
|
|
|
ka = container_of(attr, struct kobj_attribute, attr);
|
|
return ka->store(kobj, ka, buf, len);
|
|
}
|
|
|
|
#define __SYSFS_ATTR_RW(name) \
|
|
(struct kobj_attribute)__ATTR(name, S_IWUSR | S_IRUGO, \
|
|
sdcardfs_sysfs_sb_##name##_show, sdcardfs_sysfs_sb_##name##_store)
|
|
|
|
#define __SYSFS_ATTR_RO(name) \
|
|
(struct kobj_attribute)__ATTR(name, S_IRUGO, \
|
|
sdcardfs_sysfs_sb_##name##_show, NULL)
|
|
|
|
static struct sysfs_ops sysfs_op = {
|
|
.show = sdcardfs_sysfs_attr_show,
|
|
.store = sdcardfs_sysfs_attr_store
|
|
};
|
|
|
|
static struct attribute *sb_attrs[] = {
|
|
&__SYSFS_ATTR_RO(device).attr,
|
|
#ifdef SDCARDFS_PLUGIN_PRIVACY_SPACE
|
|
&__SYSFS_ATTR_RW(blocked_users).attr,
|
|
#endif
|
|
NULL, /* need to NULL terminate the list of attributes */
|
|
};
|
|
|
|
static struct kobj_type sb_ktype = {
|
|
.release = __sdcardfs_sysfs_sb_release,
|
|
.sysfs_ops = &sysfs_op,
|
|
.default_attrs = sb_attrs,
|
|
};
|
|
|
|
static struct kset *sdcardfs_kset;
|
|
|
|
int sdcardfs_sysfs_init(void)
|
|
{
|
|
/* located under /sys/fs/ */
|
|
sdcardfs_kset = kset_create_and_add(SDCARDFS_NAME, NULL, fs_kobj);
|
|
return sdcardfs_kset == NULL ? -ENOMEM : 0;
|
|
}
|
|
|
|
void sdcardfs_sysfs_exit(void)
|
|
{
|
|
BUG_ON(sdcardfs_kset == NULL);
|
|
|
|
kset_unregister(sdcardfs_kset);
|
|
}
|
|
|
|
int sdcardfs_sysfs_register_sb(struct super_block *sb)
|
|
{
|
|
int err;
|
|
struct sdcardfs_sb_info *sbi = SDCARDFS_SB(sb);
|
|
|
|
BUG_ON(sdcardfs_kset == NULL);
|
|
|
|
sbi->kobj.kset = sdcardfs_kset;
|
|
err = kobject_init_and_add(&sbi->kobj, &sb_ktype, NULL,
|
|
"%u:%u", MAJOR(sb->s_dev), MINOR(sb->s_dev));
|
|
if (err) {
|
|
//errln("failed to kobject_init_and_add, err=%d", err);
|
|
pr_err("failed to kobject_init_and_add, err=%d", err);
|
|
return err;
|
|
}
|
|
|
|
/* send the uevent that the kobject is added to the sysfs */
|
|
kobject_uevent(&sbi->kobj, KOBJ_ADD);
|
|
return 0;
|
|
}
|
|
|