*/
#include <linux/module.h>
-#include <linux/dnotify.h>
+#include <linux/fsnotify.h>
#include <linux/kobject.h>
+#include <linux/namei.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#define to_subsys(k) container_of(k,struct subsystem,kset.kobj)
#define to_sattr(a) container_of(a,struct subsys_attribute,attr)
-/**
+/*
* Subsystem file operations.
* These operations allow subsystems to have files that can be
* read/written.
{
struct subsystem * s = to_subsys(kobj);
struct subsys_attribute * sattr = to_sattr(attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (sattr->show)
ret = sattr->show(s,page);
{
struct subsystem * s = to_subsys(kobj);
struct subsys_attribute * sattr = to_sattr(attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (sattr->store)
ret = sattr->store(s,page,count);
/**
* flush_read_buffer - push buffer to userspace.
* @buffer: data buffer for file.
- * @userbuf: user-passed buffer.
+ * @buf: user-passed buffer.
* @count: number of bytes requested.
* @ppos: file position.
*
/**
* fill_write_buffer - copy buffer from userspace.
* @buffer: data buffer for file.
- * @userbuf: data from user.
+ * @buf: data from user.
* @count: number of bytes in @userbuf.
*
* Allocate @buffer->page if it hasn't been already, then
return -ENOMEM;
if (count >= PAGE_SIZE)
- count = PAGE_SIZE - 1;
+ count = PAGE_SIZE;
error = copy_from_user(buffer->page,buf,count);
buffer->needs_read_fill = 1;
return error ? -EFAULT : count;
/**
* flush_write_buffer - push buffer to kobject.
- * @file: file pointer.
+ * @dentry: dentry to the attribute
* @buffer: data buffer for file.
+ * @count: number of bytes
*
* Get the correct pointers for the kobject and the attribute we're
* dealing with, then call the store() method for the attribute,
* sysfs_update_file - update the modified timestamp on an object attribute.
* @kobj: object we're acting for.
* @attr: attribute descriptor.
- *
- * Also call dnotify for the dentry, which lots of userspace programs
- * use.
*/
int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
{
int res = -ENOENT;
down(&dir->d_inode->i_sem);
- victim = sysfs_get_dentry(dir, attr->name);
+ victim = lookup_one_len(attr->name, dir, strlen(attr->name));
if (!IS_ERR(victim)) {
/* make sure dentry is really there */
if (victim->d_inode &&
(victim->d_parent->d_inode == dir->d_inode)) {
victim->d_inode->i_mtime = CURRENT_TIME;
- dnotify_parent(victim, DN_MODIFY);
+ fsnotify_modify(victim);
/**
* Drop reference from initial sysfs_get_dentry().
}
+/**
+ * sysfs_chmod_file - update the modified mode value on an object attribute.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ * @mode: file permissions.
+ *
+ */
+int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
+{
+ struct dentry *dir = kobj->dentry;
+ struct dentry *victim;
+ struct sysfs_dirent *sd;
+ umode_t umode = (mode & S_IALLUGO) | S_IFREG;
+ int res = -ENOENT;
+
+ down(&dir->d_inode->i_sem);
+ victim = lookup_one_len(attr->name, dir, strlen(attr->name));
+ if (!IS_ERR(victim)) {
+ if (victim->d_inode &&
+ (victim->d_parent->d_inode == dir->d_inode)) {
+ sd = victim->d_fsdata;
+ attr->mode = mode;
+ sd->s_mode = umode;
+ victim->d_inode->i_mode = umode;
+ dput(victim);
+ res = 0;
+ }
+ }
+ up(&dir->d_inode->i_sem);
+
+ return res;
+}
+EXPORT_SYMBOL_GPL(sysfs_chmod_file);
+
+
/**
* sysfs_remove_file - remove an object attribute.
* @kobj: object we're acting for.