X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fsysfs%2Ffile.c;h=a2875c9cbffaa28aa794e9e3cba887f06c580628;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=da0b930e89eb5048968969adbce8572d276a55bd;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index da0b930e8..a2875c9cb 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include #include @@ -59,7 +57,6 @@ struct sysfs_buffer { struct sysfs_ops * ops; struct semaphore sem; int needs_read_fill; - int event; }; @@ -75,7 +72,6 @@ struct sysfs_buffer { */ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer) { - struct sysfs_dirent * sd = dentry->d_fsdata; struct attribute * attr = to_attr(dentry); struct kobject * kobj = to_kobj(dentry->d_parent); struct sysfs_ops * ops = buffer->ops; @@ -87,7 +83,6 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer if (!buffer->page) return -ENOMEM; - buffer->event = atomic_read(&sd->s_event); count = ops->show(kobj,attr,buffer->page); buffer->needs_read_fill = 0; BUG_ON(count > (ssize_t)PAGE_SIZE); @@ -306,8 +301,9 @@ static int check_perm(struct inode * inode, struct file * file) /* 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); + buffer = kmalloc(sizeof(struct sysfs_buffer),GFP_KERNEL); if (buffer) { + memset(buffer,0,sizeof(struct sysfs_buffer)); init_MUTEX(&buffer->sem); buffer->needs_read_fill = 1; buffer->ops = ops; @@ -328,14 +324,8 @@ static int check_perm(struct inode * inode, struct file * file) return error; } -char last_sysfs_file[PATH_MAX]; - static int sysfs_open_file(struct inode * inode, struct file * filp) { - char *p = d_path(filp->f_dentry, sysfs_mount, last_sysfs_file, - sizeof(last_sysfs_file)); - if (p) - memmove(last_sysfs_file, p, strlen(p) + 1); return check_perm(inode,filp); } @@ -359,84 +349,12 @@ static int sysfs_release(struct inode * inode, struct file * filp) return 0; } -/* Sysfs attribute files are pollable. The idea is that you read - * the content and then you use 'poll' or 'select' to wait for - * the content to change. When the content changes (assuming the - * manager for the kobject supports notification), poll will - * 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'. - * 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 (Nether 'poll' or 'select' return - * an appropriate error code). When in doubt, set a suitable timeout value. - */ -static unsigned int sysfs_poll(struct file *filp, poll_table *wait) -{ - struct sysfs_buffer * buffer = filp->private_data; - struct kobject * kobj = to_kobj(filp->f_dentry->d_parent); - struct sysfs_dirent * sd = filp->f_dentry->d_fsdata; - int res = 0; - - poll_wait(filp, &kobj->poll, wait); - - if (buffer->event != atomic_read(&sd->s_event)) { - res = POLLERR|POLLPRI; - buffer->needs_read_fill = 1; - } - - return res; -} - - -static struct dentry *step_down(struct dentry *dir, const char * name) -{ - struct dentry * de; - - if (dir == NULL || dir->d_inode == NULL) - return NULL; - - mutex_lock(&dir->d_inode->i_mutex); - de = lookup_one_len(name, dir, strlen(name)); - mutex_unlock(&dir->d_inode->i_mutex); - dput(dir); - if (IS_ERR(de)) - return NULL; - if (de->d_inode == NULL) { - dput(de); - return NULL; - } - return de; -} - -void sysfs_notify(struct kobject * k, char *dir, char *attr) -{ - struct dentry *de = k->dentry; - if (de) - dget(de); - if (de && dir) - de = step_down(de, dir); - if (de && attr) - de = step_down(de, attr); - if (de) { - struct sysfs_dirent * sd = de->d_fsdata; - if (sd) - atomic_inc(&sd->s_event); - wake_up_interruptible(&k->poll); - dput(de); - } -} -EXPORT_SYMBOL_GPL(sysfs_notify); - -const struct file_operations sysfs_file_operations = { +struct file_operations sysfs_file_operations = { .read = sysfs_read_file, .write = sysfs_write_file, .llseek = generic_file_llseek, .open = sysfs_open_file, .release = sysfs_release, - .poll = sysfs_poll, }; @@ -444,12 +362,10 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type) { struct sysfs_dirent * parent_sd = dir->d_fsdata; umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG; - int error = -EEXIST; + int error = 0; mutex_lock(&dir->d_inode->i_mutex); - if (!sysfs_dirent_exist(parent_sd, attr->name)) - error = sysfs_make_dirent(parent_sd, NULL, (void *)attr, - mode, type); + error = sysfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type); mutex_unlock(&dir->d_inode->i_mutex); return error; @@ -490,11 +406,6 @@ int sysfs_update_file(struct kobject * kobj, const struct attribute * attr) (victim->d_parent->d_inode == dir->d_inode)) { victim->d_inode->i_mtime = CURRENT_TIME; fsnotify_modify(victim); - - /** - * Drop reference from initial sysfs_get_dentry(). - */ - dput(victim); res = 0; } else d_drop(victim);