Exemplo n.º 1
0
static int open(struct inode * inode, struct file * file)
{
	struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent);
	struct bin_attribute * attr = to_bin_attr(file->f_dentry);
	int error = -EINVAL;

	if (!kobj || !attr)
		goto Done;

	/* Grab the module reference for this attribute if we have one */
	error = -ENODEV;
	if (!try_module_get(attr->attr.owner)) 
		goto Done;

	error = -EACCES;
	if ((file->f_mode & FMODE_WRITE) && !(attr->write || attr->mmap))
		goto Error;
	if ((file->f_mode & FMODE_READ) && !(attr->read || attr->mmap))
		goto Error;

	error = -ENOMEM;
	file->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!file->private_data)
		goto Error;

	error = 0;
    goto Done;

 Error:
	module_put(attr->attr.owner);
 Done:
	if (error && kobj)
		kobject_put(kobj);
	return error;
}
Exemplo n.º 2
0
static int sysfs_getlink(struct dentry *dentry, char * path)
{
	struct kobject *kobj, *target_kobj;
	int error = 0;

	kobj = sysfs_get_kobject(dentry->d_parent);
	if (!kobj)
		return -EINVAL;

	target_kobj = sysfs_get_kobject(dentry);
	if (!target_kobj) {
		kobject_put(kobj);
		return -EINVAL;
	}

	down_read(&sysfs_rename_sem);
	error = sysfs_get_target_path(kobj, target_kobj, path);
	up_read(&sysfs_rename_sem);
	
	kobject_put(kobj);
	kobject_put(target_kobj);
	return error;

}
Exemplo n.º 3
0
static int check_perm(struct inode * inode, struct file * file)
{
	struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent);
	struct attribute * attr = file->f_dentry->d_fsdata;
	struct sysfs_buffer * buffer;
	struct sysfs_ops * ops = NULL;
	int error = 0;

	if (!kobj || !attr)
		goto Einval;

	/* Grab the module reference for this attribute if we have one */
	if (!try_module_get(attr->owner)) {
		error = -ENODEV;
		goto Done;
	}

	/* if the kobject has no ktype, then we assume that it is a subsystem
	 * itself, and use ops for it.
	 */
	if (kobj->kset && kobj->kset->ktype)
		ops = kobj->kset->ktype->sysfs_ops;
	else if (kobj->ktype)
		ops = kobj->ktype->sysfs_ops;
	else
		ops = &subsys_sysfs_ops;

	/* No sysfs operations, either from having no subsystem,
	 * or the subsystem have no operations.
	 */
	if (!ops)
		goto Eaccess;

	/* File needs write support.
	 * The inode's perms must say it's ok, 
	 * and we must have a store method.
	 */
	if (file->f_mode & FMODE_WRITE) {

		if (!(inode->i_mode & S_IWUGO) || !ops->store)
			goto Eaccess;

	}

	/* File needs read support.
	 * The inode's perms must say it's ok, and we there
	 * must be a show method for it.
	 */
	if (file->f_mode & FMODE_READ) {
		if (!(inode->i_mode & S_IRUGO) || !ops->show)
			goto Eaccess;
	}

	/* No error? Great, allocate a buffer for the file, and store it
	 * it in file->private_data for easy access.
	 */
	buffer = kmalloc(sizeof(struct sysfs_buffer),GFP_KERNEL);
	if (buffer) {
		memset(buffer,0,sizeof(struct sysfs_buffer));
		buffer->ops = ops;
		file->private_data = buffer;
	} else
		error = -ENOMEM;
	goto Done;

 Einval:
	error = -EINVAL;
	goto Done;
 Eaccess:
	error = -EACCES;
	module_put(attr->owner);
 Done:
	if (error && kobj)
		kobject_put(kobj);
	return error;
}