Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[pandora-kernel.git] / fs / sysfs / file.c
index baa663e..3f07893 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/module.h>
 #include <linux/kobject.h>
 #include <linux/kallsyms.h>
+#include <linux/slab.h>
+#include <linux/fsnotify.h>
 #include <linux/namei.h>
 #include <linux/poll.h>
 #include <linux/list.h>
@@ -128,13 +130,13 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
        ssize_t retval = 0;
 
        mutex_lock(&buffer->mutex);
-       if (buffer->needs_read_fill) {
+       if (buffer->needs_read_fill || *ppos == 0) {
                retval = fill_read_buffer(file->f_path.dentry,buffer);
                if (retval)
                        goto out;
        }
        pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
-                __FUNCTION__, count, *ppos, buffer->page);
+                __func__, count, *ppos, buffer->page);
        retval = simple_read_from_buffer(buf, count, ppos, buffer->page,
                                         buffer->count);
 out:
@@ -409,8 +411,7 @@ static int sysfs_release(struct inode *inode, struct file *filp)
  * return POLLERR|POLLPRI, and select will return the fd whether
  * it is waiting for read, write, or exceptions.
  * Once poll/select indicates that the value has changed, you
- * need to close and re-open the file, as simply seeking and reading
- * again will not get new data, or reset the state of 'poll'.
+ * need to close and re-open the file, or seek to 0 and read again.
  * Reminder: this only works for attributes which actively support
  * it, and it is not possible to test an attribute from userspace
  * to see if it supports poll (Neither 'poll' nor 'select' return
@@ -477,11 +478,10 @@ const struct file_operations sysfs_file_operations = {
        .poll           = sysfs_poll,
 };
 
-
-int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
-                  int type)
+int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
+                       const struct attribute *attr, int type, mode_t amode)
 {
-       umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
+       umode_t mode = (amode & S_IALLUGO) | S_IFREG;
        struct sysfs_addrm_cxt acxt;
        struct sysfs_dirent *sd;
        int rc;
@@ -502,6 +502,13 @@ int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
 }
 
 
+int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
+                  int type)
+{
+       return sysfs_add_file_mode(dir_sd, attr, type, attr->mode);
+}
+
+
 /**
  *     sysfs_create_file - create an attribute file for an object.
  *     @kobj:  object we're creating for. 
@@ -579,9 +586,11 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
 
        newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
        newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-       rc = notify_change(victim, &newattrs);
+       newattrs.ia_ctime = current_fs_time(inode->i_sb);
+       rc = sysfs_setattr(victim, &newattrs);
 
        if (rc == 0) {
+               fsnotify_change(victim, newattrs.ia_valid);
                mutex_lock(&sysfs_mutex);
                victim_sd->s_mode = newattrs.ia_mode;
                mutex_unlock(&sysfs_mutex);