/* * Determine ktype->sysfs_ops for the given kernfs_node. This function * must be called while holding an active reference.
*/ staticconststruct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn)
{ struct kobject *kobj = sysfs_file_kobj(kn);
/* * Reads on sysfs are handled through seq_file, which takes care of hairy * details like buffering and seeking. The following function pipes * sysfs_ops->show() result through seq_file.
*/ staticint sysfs_kf_seq_show(struct seq_file *sf, void *v)
{ struct kernfs_open_file *of = sf->private; struct kobject *kobj = sysfs_file_kobj(of->kn); conststruct sysfs_ops *ops = sysfs_file_ops(of->kn);
ssize_t count; char *buf;
if (WARN_ON_ONCE(!ops->show)) return -EINVAL;
/* acquire buffer and ensure that it's >= PAGE_SIZE and clear */
count = seq_get_buf(sf, &buf); if (count < PAGE_SIZE) {
seq_commit(sf, -1); return 0;
}
memset(buf, 0, PAGE_SIZE);
/* * The code works fine with PAGE_SIZE return but it's likely to * indicate truncated result or overflow in normal use cases.
*/ if (count >= (ssize_t)PAGE_SIZE) {
printk("fill_read_buffer: %pS returned bad count\n",
ops->show); /* Try to struggle along */
count = PAGE_SIZE - 1;
}
seq_commit(sf, count); return 0;
}
/* * If buf != of->prealloc_buf, we don't know how * large it is, so cannot safely pass it to ->show
*/ if (WARN_ON_ONCE(buf != of->prealloc_buf)) return 0;
len = ops->show(kobj, of->kn->priv, buf); if (len < 0) return len; if (pos) { if (len <= pos) return 0;
len -= pos;
memmove(buf, buf + pos, len);
} return min_t(ssize_t, count, len);
}
/* every kobject with an attribute needs a ktype assigned */ if (WARN(!sysfs_ops, KERN_ERR "missing sysfs attribute operations for kobject: %s\n",
kobject_name(kobj))) return -EINVAL;
/** * sysfs_create_file_ns - create an attribute file for an object with custom ns * @kobj: object we're creating for * @attr: attribute descriptor * @ns: namespace the new file should belong to
*/ int sysfs_create_file_ns(struct kobject *kobj, conststruct attribute *attr, constvoid *ns)
{
kuid_t uid;
kgid_t gid;
if (WARN_ON(!kobj || !kobj->sd || !attr)) return -EINVAL;
/** * sysfs_break_active_protection - break "active" protection * @kobj: The kernel object @attr is associated with. * @attr: The attribute to break the "active" protection for. * * With sysfs, just like kernfs, deletion of an attribute is postponed until * all active .show() and .store() callbacks have finished unless this function * is called. Hence this function is useful in methods that implement self * deletion.
*/ struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj, conststruct attribute *attr)
{ struct kernfs_node *kn;
/** * sysfs_unbreak_active_protection - restore "active" protection * @kn: Pointer returned by sysfs_break_active_protection(). * * Undo the effects of sysfs_break_active_protection(). Since this function * calls kernfs_put() on the kernfs node that corresponds to the 'attr' * argument passed to sysfs_break_active_protection() that attribute may have * been removed between the sysfs_break_active_protection() and * sysfs_unbreak_active_protection() calls, it is not safe to access @kn after * this function has returned.
*/ void sysfs_unbreak_active_protection(struct kernfs_node *kn)
{ struct kobject *kobj = sysfs_file_kobj(kn);
/** * sysfs_remove_file_ns - remove an object attribute with a custom ns tag * @kobj: object we're acting for * @attr: attribute descriptor * @ns: namespace tag of the file to remove * * Hash the attribute name and namespace tag and kill the victim.
*/ void sysfs_remove_file_ns(struct kobject *kobj, conststruct attribute *attr, constvoid *ns)
{ struct kernfs_node *parent = kobj->sd;
/** * sysfs_link_change_owner - change owner of a sysfs file. * @kobj: object of the kernfs_node the symlink is located in. * @targ: object of the kernfs_node the symlink points to. * @name: name of the link. * @kuid: new owner's kuid * @kgid: new owner's kgid * * This function looks up the sysfs symlink entry @name under @kobj and changes * the ownership to @kuid/@kgid. The symlink is looked up in the namespace of * @targ. * * Returns 0 on success or error code on failure.
*/ int sysfs_link_change_owner(struct kobject *kobj, struct kobject *targ, constchar *name, kuid_t kuid, kgid_t kgid)
{ struct kernfs_node *kn = NULL; int error;
if (!name || !kobj->state_in_sysfs || !targ->state_in_sysfs) return -EINVAL;
error = -EINVAL; if (kernfs_type(kn) != KERNFS_LINK) goto out; if (kn->symlink.target_kn->priv != targ) goto out;
error = internal_change_owner(kn, kuid, kgid);
out:
kernfs_put(kn); return error;
}
/** * sysfs_file_change_owner - change owner of a sysfs file. * @kobj: object. * @name: name of the file to change. * @kuid: new owner's kuid * @kgid: new owner's kgid * * This function looks up the sysfs entry @name under @kobj and changes the * ownership to @kuid/@kgid. * * Returns 0 on success or error code on failure.
*/ int sysfs_file_change_owner(struct kobject *kobj, constchar *name, kuid_t kuid,
kgid_t kgid)
{ struct kernfs_node *kn; int error;
if (!name) return -EINVAL;
if (!kobj->state_in_sysfs) return -EINVAL;
kn = kernfs_find_and_get(kobj->sd, name); if (!kn) return -ENOENT;
/** * sysfs_change_owner - change owner of the given object. * @kobj: object. * @kuid: new owner's kuid * @kgid: new owner's kgid * * Change the owner of the default directory, files, groups, and attributes of * @kobj to @kuid/@kgid. Note that sysfs_change_owner mirrors how the sysfs * entries for a kobject are added by driver core. In summary, * sysfs_change_owner() takes care of the default directory entry for @kobj, * the default attributes associated with the ktype of @kobj and the default * attributes associated with the ktype of @kobj. * Additional properties not added by driver core have to be changed by the * driver or subsystem which created them. This is similar to how * driver/subsystem specific entries are removed. * * Returns 0 on success or error code on failure.
*/ int sysfs_change_owner(struct kobject *kobj, kuid_t kuid, kgid_t kgid)
{ int error; conststruct kobj_type *ktype;
if (!kobj->state_in_sysfs) return -EINVAL;
/* Change the owner of the kobject itself. */
error = internal_change_owner(kobj->sd, kuid, kgid); if (error) return error;
ktype = get_ktype(kobj); if (ktype) { /* * Change owner of the default groups associated with the * ktype of @kobj.
*/
error = sysfs_groups_change_owner(kobj, ktype->default_groups,
kuid, kgid); if (error) return error;
}
/** * sysfs_emit - scnprintf equivalent, aware of PAGE_SIZE buffer. * @buf: start of PAGE_SIZE buffer. * @fmt: format * @...: optional arguments to @format * * * Returns number of characters written to @buf.
*/ int sysfs_emit(char *buf, constchar *fmt, ...)
{
va_list args; int len;
if (WARN(!buf || offset_in_page(buf), "invalid sysfs_emit: buf:%p\n", buf)) return 0;
va_start(args, fmt);
len = vscnprintf(buf, PAGE_SIZE, fmt, args);
va_end(args);
return len;
}
EXPORT_SYMBOL_GPL(sysfs_emit);
/** * sysfs_emit_at - scnprintf equivalent, aware of PAGE_SIZE buffer. * @buf: start of PAGE_SIZE buffer. * @at: offset in @buf to start write in bytes * @at must be >= 0 && < PAGE_SIZE * @fmt: format * @...: optional arguments to @fmt * * * Returns number of characters written starting at &@buf[@at].
*/ int sysfs_emit_at(char *buf, int at, constchar *fmt, ...)
{
va_list args; int len;
if (WARN(!buf || offset_in_page(buf) || at < 0 || at >= PAGE_SIZE, "invalid sysfs_emit_at: buf:%p at:%d\n", buf, at)) return 0;
/** * sysfs_bin_attr_simple_read - read callback to simply copy from memory. * @file: attribute file which is being read. * @kobj: object to which the attribute belongs. * @attr: attribute descriptor. * @buf: destination buffer. * @off: offset in bytes from which to read. * @count: maximum number of bytes to read. * * Simple ->read() callback for bin_attributes backed by a buffer in memory. * The @private and @size members in struct bin_attribute must be set to the * buffer's location and size before the bin_attribute is created in sysfs. * * Bounds check for @off and @count is done in sysfs_kf_bin_read(). * Negative value check for @off is done in vfs_setpos() and default_llseek(). * * Returns number of bytes written to @buf.
*/
ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj, conststruct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
memcpy(buf, attr->private + off, count); return count;
}
EXPORT_SYMBOL_GPL(sysfs_bin_attr_simple_read);
Messung V0.5
¤ Dauer der Verarbeitung: 0.29 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.