enum damon_filter_type type;
bool matching;
bool allow;
+ char *path;
};
static struct damon_sysfs_filter *damon_sysfs_filter_alloc(void)
.type = DAMON_FILTER_TYPE_ANON,
.name = "anon",
},
+ {
+ .type = DAMON_FILTER_TYPE_MEMCG,
+ .name = "memcg",
+ },
};
static ssize_t type_show(struct kobject *kobj,
return count;
}
+static ssize_t path_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_filter *filter = container_of(kobj,
+ struct damon_sysfs_filter, kobj);
+ int len;
+
+ if (!mutex_trylock(&damon_sysfs_lock))
+ return -EBUSY;
+ len = sysfs_emit(buf, "%s\n", filter->path ? filter->path : "");
+ mutex_unlock(&damon_sysfs_lock);
+ return len;
+}
+
+static ssize_t path_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_filter *filter = container_of(kobj,
+ struct damon_sysfs_filter, kobj);
+ char *path = kmalloc_objs(*path, size_add(count, 1));
+
+ if (!path)
+ return -ENOMEM;
+ strscpy(path, buf, size_add(count, 1));
+ if (!mutex_trylock(&damon_sysfs_lock)) {
+ kfree(path);
+ return -EBUSY;
+ }
+ kfree(filter->path);
+ filter->path = path;
+ mutex_unlock(&damon_sysfs_lock);
+ return count;
+}
+
static void damon_sysfs_filter_release(struct kobject *kobj)
{
struct damon_sysfs_filter *filter = container_of(kobj,
struct damon_sysfs_filter, kobj);
+ kfree(filter->path);
kfree(filter);
}
static struct kobj_attribute damon_sysfs_filter_allow_attr =
__ATTR_RW_MODE(allow, 0600);
+static struct kobj_attribute damon_sysfs_filter_path_attr =
+ __ATTR_RW_MODE(path, 0600);
+
static struct attribute *damon_sysfs_filter_attrs[] = {
&damon_sysfs_filter_type_attr.attr,
&damon_sysfs_filter_matching_attr.attr,
&damon_sysfs_filter_allow_attr.attr,
+ &damon_sysfs_filter_path_attr.attr,
NULL,
};
ATTRIBUTE_GROUPS(damon_sysfs_filter);