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; }
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; }
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; }