static int configfs_release_bin_file(struct inode *inode, struct file *filp) { struct configfs_buffer *buffer = filp->private_data; struct dentry *dentry = filp->f_path.dentry; struct config_item *item = to_item(dentry->d_parent); struct configfs_item_operations *ops = buffer->ops; struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); ssize_t len = 0; int ret; buffer->read_in_progress = 0; if (buffer->write_in_progress) { buffer->write_in_progress = 0; len = ops->write_bin_attribute(item, bin_attr, buffer->bin_buffer, buffer->bin_buffer_size); /* vfree on NULL is safe */ vfree(buffer->bin_buffer); buffer->bin_buffer = NULL; buffer->bin_buffer_size = 0; buffer->needs_read_fill = 1; } ret = do_release(inode, filp, to_item(filp->f_path.dentry->d_parent), to_attr(filp->f_path.dentry), CONFIGFS_ITEM_BIN_ATTR); if (len < 0) return len; return ret; }
static int flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size_t count) { struct configfs_attribute * attr = to_attr(dentry); struct config_item * item = to_item(dentry->d_parent); return attr->store(item, buffer->page, count); }
static ssize_t acpi_data_node_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct acpi_data_node *dn = to_data_node(kobj); struct acpi_data_node_attr *dn_attr = to_attr(attr); return dn_attr->show ? dn_attr->show(dn, buf) : -ENXIO; }
static int flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size_t count) { struct configfs_attribute * attr = to_attr(dentry); struct config_item * item = to_item(dentry->d_parent); struct configfs_item_operations * ops = buffer->ops; return ops->store_attribute(item,attr,buffer->page,count); }
static int flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t count) { struct attribute * attr = to_attr(dentry); struct kobject * kobj = to_kobj(dentry->d_parent); struct sysfs_ops * ops = buffer->ops; return ops->store(kobj,attr,buffer->page,count); }
static ssize_t dmi_sysfs_attr_show(struct kobject *kobj, struct attribute *_attr, char *buf) { struct dmi_sysfs_entry *entry = to_entry(kobj); struct dmi_sysfs_attribute *attr = to_attr(_attr); /* DMI stuff is only ever admin visible */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; return attr->show(entry, buf); }
static ssize_t pnx_power_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buffer) { struct pnx_power_attr * power_attr = to_attr(attr); ssize_t ret; if (power_attr->show) ret = power_attr->show(kobj, buffer); else ret = -EIO; return ret; }
static ssize_t pnx_power_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t size) { struct pnx_power_attr * power_attr = to_attr(attr); ssize_t ret; if (power_attr->store) ret = power_attr->store(kobj, buffer, size); else ret = -EIO; return ret; }
static int configfs_release(struct inode * inode, struct file * filp) { struct config_item * item = to_item(filp->f_dentry->d_parent); struct configfs_attribute * attr = to_attr(filp->f_dentry); struct module * owner = attr->ca_owner; struct configfs_buffer * buffer = filp->private_data; if (item) config_item_put(item); /* After this point, attr should not be accessed. */ module_put(owner); if (buffer) { if (buffer->page) free_page((unsigned long)buffer->page); kfree(buffer); } return 0; }
static int sysfs_release(struct inode * inode, struct file * filp) { struct kobject * kobj = to_kobj(filp->f_dentry->d_parent); struct attribute * attr = to_attr(filp->f_dentry); struct module * owner = attr->owner; struct sysfs_buffer * buffer = filp->private_data; if (kobj) kobject_put(kobj); /* After this point, attr should not be accessed. */ module_put(owner); if (buffer) { if (buffer->page) free_page((unsigned long)buffer->page); kfree(buffer); } return 0; }
/** * fill_read_buffer - allocate and fill buffer from item. * @dentry: dentry pointer. * @buffer: data buffer for file. * * Allocate @buffer->page, if it hasn't been already, then call the * config_item's show() method to fill the buffer with this attribute's * data. * This is called only once, on the file's first read. */ static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buffer) { struct configfs_attribute * attr = to_attr(dentry); struct config_item * item = to_item(dentry->d_parent); struct configfs_item_operations * ops = buffer->ops; int ret = 0; ssize_t count; if (!buffer->page) buffer->page = (char *) get_zeroed_page(GFP_KERNEL); if (!buffer->page) return -ENOMEM; count = ops->show_attribute(item,attr,buffer->page); buffer->needs_read_fill = 0; BUG_ON(count > (ssize_t)SIMPLE_ATTR_SIZE); if (count >= 0) buffer->count = count; else ret = count; return ret; }
/** * fill_read_buffer - allocate and fill buffer from object. * @dentry: dentry pointer. * @buffer: data buffer for file. * * Allocate @buffer->page, if it hasn't been already, then call the * kobject's show() method to fill the buffer with this attribute's * data. * This is called only once, on the file's first read. */ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer) { struct attribute * attr = to_attr(dentry); struct kobject * kobj = to_kobj(dentry->d_parent); struct sysfs_ops * ops = buffer->ops; int ret = 0; ssize_t count; if (!buffer->page) buffer->page = (char *) get_zeroed_page(GFP_KERNEL); if (!buffer->page) return -ENOMEM; count = ops->show(kobj,attr,buffer->page); buffer->needs_read_fill = 0; BUG_ON(count > (ssize_t)PAGE_SIZE); if (count >= 0) buffer->count = count; else ret = count; return ret; }
static int check_perm(struct inode * inode, struct file * file) { struct config_item *item = configfs_get_config_item(file->f_path.dentry->d_parent); struct configfs_attribute * attr = to_attr(file->f_path.dentry); struct configfs_buffer * buffer; struct configfs_item_operations * ops = NULL; int error = 0; if (!item || !attr) goto Einval; /* Grab the module reference for this attribute if we have one */ if (!try_module_get(attr->ca_owner)) { error = -ENODEV; goto Done; } if (item->ci_type) ops = item->ci_type->ct_item_ops; else 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_attribute) 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_attribute) goto Eaccess; } /* No error? Great, allocate a buffer for the file, and store it * it in file->private_data for easy access. */ buffer = kzalloc(sizeof(struct configfs_buffer),GFP_KERNEL); if (!buffer) { error = -ENOMEM; goto Enomem; } mutex_init(&buffer->mutex); buffer->needs_read_fill = 1; buffer->ops = ops; file->private_data = buffer; goto Done; Einval: error = -EINVAL; goto Done; Eaccess: error = -EACCES; Enomem: module_put(attr->ca_owner); Done: if (error && item) config_item_put(item); return error; }
static int configfs_open_bin_file(struct inode *inode, struct file *filp) { return check_perm(inode, filp, configfs_get_config_item(filp->f_path.dentry->d_parent), to_attr(filp->f_path.dentry), CONFIGFS_ITEM_BIN_ATTR); }
static int configfs_release_file(struct inode *inode, struct file *filp) { return do_release(inode, filp, to_item(filp->f_path.dentry->d_parent), to_attr(filp->f_path.dentry), CONFIGFS_ITEM_ATTR); }
static int check_perm(struct inode * inode, struct file * file) { struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent); struct attribute * attr = to_attr(file->f_dentry); 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 = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL); if (buffer) { init_MUTEX(&buffer->sem); buffer->needs_read_fill = 1; 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; }