From b8441ed279bff09a0a5ddeacf8f4087d2fb424ca Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 24 Nov 2013 09:54:58 -0500 Subject: sysfs, kernfs: add skeletons for kernfs Core sysfs implementation will be separated into kernfs so that it can be used by other non-kobject users. This patch creates fs/kernfs/ directory and makes boilerplate changes. kernfs interface will be directly based on sysfs_dirent and its forward declaration is moved to include/linux/kernfs.h which is included from include/linux/sysfs.h. sysfs core implementation will be gradually separated out and moved to kernfs. This patch doesn't introduce any functional changes. v2: mount.c added. Signed-off-by: Tejun Heo Cc: linux-fsdevel@vger.kernel.org Cc: Christoph Hellwig Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 fs/kernfs/file.c (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c new file mode 100644 index 00000000000..90b1e88dad4 --- /dev/null +++ b/fs/kernfs/file.c @@ -0,0 +1,9 @@ +/* + * fs/kernfs/file.c - kernfs file implementation + * + * Copyright (c) 2001-3 Patrick Mochel + * Copyright (c) 2007 SUSE Linux Products GmbH + * Copyright (c) 2007, 2013 Tejun Heo + * + * This file is released under the GPLv2. + */ -- cgit v1.2.3-70-g09d2 From 414985ae23c031efbd6d16d484dea8b5de28b8f7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 28 Nov 2013 14:54:34 -0500 Subject: sysfs, kernfs: move file core code to fs/kernfs/file.c Move core file code to fs/kernfs/file.c. fs/sysfs/file.c now contains sysfs kernfs_ops callbacks, sysfs wrappers around kernfs interfaces, and sysfs_schedule_callback(). The respective declarations in fs/sysfs/sysfs.h are moved to fs/kernfs/kernfs-internal.h. This is pure relocation. v2: Refreshed on top of the v2 of "sysfs, kernfs: prepare read path for kernfs". v3: Refreshed on top of the v3 of "sysfs, kernfs: prepare read path for kernfs". Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 805 ++++++++++++++++++++++++++++++++++++++++++++ fs/kernfs/kernfs-internal.h | 7 + fs/sysfs/file.c | 802 +------------------------------------------ fs/sysfs/sysfs.h | 4 - 4 files changed, 813 insertions(+), 805 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 90b1e88dad4..fa172e86047 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -7,3 +7,808 @@ * * This file is released under the GPLv2. */ + +#include +#include +#include +#include +#include +#include +#include + +#include "kernfs-internal.h" + +/* + * There's one sysfs_open_file for each open file and one sysfs_open_dirent + * for each sysfs_dirent with one or more open files. + * + * sysfs_dirent->s_attr.open points to sysfs_open_dirent. s_attr.open is + * protected by sysfs_open_dirent_lock. + * + * filp->private_data points to seq_file whose ->private points to + * sysfs_open_file. sysfs_open_files are chained at + * sysfs_open_dirent->files, which is protected by sysfs_open_file_mutex. + */ +static DEFINE_SPINLOCK(sysfs_open_dirent_lock); +static DEFINE_MUTEX(sysfs_open_file_mutex); + +struct sysfs_open_dirent { + atomic_t refcnt; + atomic_t event; + wait_queue_head_t poll; + struct list_head files; /* goes through sysfs_open_file.list */ +}; + +static struct sysfs_open_file *sysfs_of(struct file *file) +{ + return ((struct seq_file *)file->private_data)->private; +} + +/* + * Determine the kernfs_ops for the given sysfs_dirent. This function must + * be called while holding an active reference. + */ +static const struct kernfs_ops *kernfs_ops(struct sysfs_dirent *sd) +{ + if (sd->s_flags & SYSFS_FLAG_LOCKDEP) + lockdep_assert_held(sd); + return sd->s_attr.ops; +} + +static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) +{ + struct sysfs_open_file *of = sf->private; + const struct kernfs_ops *ops; + + /* + * @of->mutex nests outside active ref and is just to ensure that + * the ops aren't called concurrently for the same open file. + */ + mutex_lock(&of->mutex); + if (!sysfs_get_active(of->sd)) + return ERR_PTR(-ENODEV); + + ops = kernfs_ops(of->sd); + if (ops->seq_start) { + return ops->seq_start(sf, ppos); + } else { + /* + * The same behavior and code as single_open(). Returns + * !NULL if pos is at the beginning; otherwise, NULL. + */ + return NULL + !*ppos; + } +} + +static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) +{ + struct sysfs_open_file *of = sf->private; + const struct kernfs_ops *ops = kernfs_ops(of->sd); + + if (ops->seq_next) { + return ops->seq_next(sf, v, ppos); + } else { + /* + * The same behavior and code as single_open(), always + * terminate after the initial read. + */ + ++*ppos; + return NULL; + } +} + +static void kernfs_seq_stop(struct seq_file *sf, void *v) +{ + struct sysfs_open_file *of = sf->private; + const struct kernfs_ops *ops = kernfs_ops(of->sd); + + if (ops->seq_stop) + ops->seq_stop(sf, v); + + sysfs_put_active(of->sd); + mutex_unlock(&of->mutex); +} + +static int kernfs_seq_show(struct seq_file *sf, void *v) +{ + struct sysfs_open_file *of = sf->private; + + of->event = atomic_read(&of->sd->s_attr.open->event); + + return of->sd->s_attr.ops->seq_show(sf, v); +} + +static const struct seq_operations kernfs_seq_ops = { + .start = kernfs_seq_start, + .next = kernfs_seq_next, + .stop = kernfs_seq_stop, + .show = kernfs_seq_show, +}; + +/* + * As reading a bin file can have side-effects, the exact offset and bytes + * specified in read(2) call should be passed to the read callback making + * it difficult to use seq_file. Implement simplistic custom buffering for + * bin files. + */ +static ssize_t kernfs_file_direct_read(struct sysfs_open_file *of, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + ssize_t len = min_t(size_t, count, PAGE_SIZE); + const struct kernfs_ops *ops; + char *buf; + + buf = kmalloc(len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + /* + * @of->mutex nests outside active ref and is just to ensure that + * the ops aren't called concurrently for the same open file. + */ + mutex_lock(&of->mutex); + if (!sysfs_get_active(of->sd)) { + len = -ENODEV; + mutex_unlock(&of->mutex); + goto out_free; + } + + ops = kernfs_ops(of->sd); + if (ops->read) + len = ops->read(of, buf, len, *ppos); + else + len = -EINVAL; + + sysfs_put_active(of->sd); + mutex_unlock(&of->mutex); + + if (len < 0) + goto out_free; + + if (copy_to_user(user_buf, buf, len)) { + len = -EFAULT; + goto out_free; + } + + *ppos += len; + + out_free: + kfree(buf); + return len; +} + +/** + * kernfs_file_read - kernfs vfs read callback + * @file: file pointer + * @user_buf: data to write + * @count: number of bytes + * @ppos: starting offset + */ +static ssize_t kernfs_file_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct sysfs_open_file *of = sysfs_of(file); + + if (of->sd->s_flags & SYSFS_FLAG_HAS_SEQ_SHOW) + return seq_read(file, user_buf, count, ppos); + else + return kernfs_file_direct_read(of, user_buf, count, ppos); +} + +/** + * kernfs_file_write - kernfs vfs write callback + * @file: file pointer + * @user_buf: data to write + * @count: number of bytes + * @ppos: starting offset + * + * Copy data in from userland and pass it to the matching kernfs write + * operation. + * + * There is no easy way for us to know if userspace is only doing a partial + * write, so we don't support them. We expect the entire buffer to come on + * the first write. Hint: if you're writing a value, first read the file, + * modify only the the value you're changing, then write entire buffer + * back. + */ +static ssize_t kernfs_file_write(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct sysfs_open_file *of = sysfs_of(file); + ssize_t len = min_t(size_t, count, PAGE_SIZE); + const struct kernfs_ops *ops; + char *buf; + + buf = kmalloc(len + 1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, user_buf, len)) { + len = -EFAULT; + goto out_free; + } + buf[len] = '\0'; /* guarantee string termination */ + + /* + * @of->mutex nests outside active ref and is just to ensure that + * the ops aren't called concurrently for the same open file. + */ + mutex_lock(&of->mutex); + if (!sysfs_get_active(of->sd)) { + mutex_unlock(&of->mutex); + len = -ENODEV; + goto out_free; + } + + ops = kernfs_ops(of->sd); + if (ops->write) + len = ops->write(of, buf, len, *ppos); + else + len = -EINVAL; + + sysfs_put_active(of->sd); + mutex_unlock(&of->mutex); + + if (len > 0) + *ppos += len; +out_free: + kfree(buf); + return len; +} + +static void kernfs_vma_open(struct vm_area_struct *vma) +{ + struct file *file = vma->vm_file; + struct sysfs_open_file *of = sysfs_of(file); + + if (!of->vm_ops) + return; + + if (!sysfs_get_active(of->sd)) + return; + + if (of->vm_ops->open) + of->vm_ops->open(vma); + + sysfs_put_active(of->sd); +} + +static int kernfs_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct file *file = vma->vm_file; + struct sysfs_open_file *of = sysfs_of(file); + int ret; + + if (!of->vm_ops) + return VM_FAULT_SIGBUS; + + if (!sysfs_get_active(of->sd)) + return VM_FAULT_SIGBUS; + + ret = VM_FAULT_SIGBUS; + if (of->vm_ops->fault) + ret = of->vm_ops->fault(vma, vmf); + + sysfs_put_active(of->sd); + return ret; +} + +static int kernfs_vma_page_mkwrite(struct vm_area_struct *vma, + struct vm_fault *vmf) +{ + struct file *file = vma->vm_file; + struct sysfs_open_file *of = sysfs_of(file); + int ret; + + if (!of->vm_ops) + return VM_FAULT_SIGBUS; + + if (!sysfs_get_active(of->sd)) + return VM_FAULT_SIGBUS; + + ret = 0; + if (of->vm_ops->page_mkwrite) + ret = of->vm_ops->page_mkwrite(vma, vmf); + else + file_update_time(file); + + sysfs_put_active(of->sd); + return ret; +} + +static int kernfs_vma_access(struct vm_area_struct *vma, unsigned long addr, + void *buf, int len, int write) +{ + struct file *file = vma->vm_file; + struct sysfs_open_file *of = sysfs_of(file); + int ret; + + if (!of->vm_ops) + return -EINVAL; + + if (!sysfs_get_active(of->sd)) + return -EINVAL; + + ret = -EINVAL; + if (of->vm_ops->access) + ret = of->vm_ops->access(vma, addr, buf, len, write); + + sysfs_put_active(of->sd); + return ret; +} + +#ifdef CONFIG_NUMA +static int kernfs_vma_set_policy(struct vm_area_struct *vma, + struct mempolicy *new) +{ + struct file *file = vma->vm_file; + struct sysfs_open_file *of = sysfs_of(file); + int ret; + + if (!of->vm_ops) + return 0; + + if (!sysfs_get_active(of->sd)) + return -EINVAL; + + ret = 0; + if (of->vm_ops->set_policy) + ret = of->vm_ops->set_policy(vma, new); + + sysfs_put_active(of->sd); + return ret; +} + +static struct mempolicy *kernfs_vma_get_policy(struct vm_area_struct *vma, + unsigned long addr) +{ + struct file *file = vma->vm_file; + struct sysfs_open_file *of = sysfs_of(file); + struct mempolicy *pol; + + if (!of->vm_ops) + return vma->vm_policy; + + if (!sysfs_get_active(of->sd)) + return vma->vm_policy; + + pol = vma->vm_policy; + if (of->vm_ops->get_policy) + pol = of->vm_ops->get_policy(vma, addr); + + sysfs_put_active(of->sd); + return pol; +} + +static int kernfs_vma_migrate(struct vm_area_struct *vma, + const nodemask_t *from, const nodemask_t *to, + unsigned long flags) +{ + struct file *file = vma->vm_file; + struct sysfs_open_file *of = sysfs_of(file); + int ret; + + if (!of->vm_ops) + return 0; + + if (!sysfs_get_active(of->sd)) + return 0; + + ret = 0; + if (of->vm_ops->migrate) + ret = of->vm_ops->migrate(vma, from, to, flags); + + sysfs_put_active(of->sd); + return ret; +} +#endif + +static const struct vm_operations_struct kernfs_vm_ops = { + .open = kernfs_vma_open, + .fault = kernfs_vma_fault, + .page_mkwrite = kernfs_vma_page_mkwrite, + .access = kernfs_vma_access, +#ifdef CONFIG_NUMA + .set_policy = kernfs_vma_set_policy, + .get_policy = kernfs_vma_get_policy, + .migrate = kernfs_vma_migrate, +#endif +}; + +static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct sysfs_open_file *of = sysfs_of(file); + const struct kernfs_ops *ops; + int rc; + + mutex_lock(&of->mutex); + + rc = -ENODEV; + if (!sysfs_get_active(of->sd)) + goto out_unlock; + + ops = kernfs_ops(of->sd); + if (ops->mmap) + rc = ops->mmap(of, vma); + if (rc) + goto out_put; + + /* + * PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup() + * to satisfy versions of X which crash if the mmap fails: that + * substitutes a new vm_file, and we don't then want bin_vm_ops. + */ + if (vma->vm_file != file) + goto out_put; + + rc = -EINVAL; + if (of->mmapped && of->vm_ops != vma->vm_ops) + goto out_put; + + /* + * It is not possible to successfully wrap close. + * So error if someone is trying to use close. + */ + rc = -EINVAL; + if (vma->vm_ops && vma->vm_ops->close) + goto out_put; + + rc = 0; + of->mmapped = 1; + of->vm_ops = vma->vm_ops; + vma->vm_ops = &kernfs_vm_ops; +out_put: + sysfs_put_active(of->sd); +out_unlock: + mutex_unlock(&of->mutex); + + return rc; +} + +/** + * sysfs_get_open_dirent - get or create sysfs_open_dirent + * @sd: target sysfs_dirent + * @of: sysfs_open_file for this instance of open + * + * If @sd->s_attr.open exists, increment its reference count; + * otherwise, create one. @of is chained to the files list. + * + * LOCKING: + * Kernel thread context (may sleep). + * + * RETURNS: + * 0 on success, -errno on failure. + */ +static int sysfs_get_open_dirent(struct sysfs_dirent *sd, + struct sysfs_open_file *of) +{ + struct sysfs_open_dirent *od, *new_od = NULL; + + retry: + mutex_lock(&sysfs_open_file_mutex); + spin_lock_irq(&sysfs_open_dirent_lock); + + if (!sd->s_attr.open && new_od) { + sd->s_attr.open = new_od; + new_od = NULL; + } + + od = sd->s_attr.open; + if (od) { + atomic_inc(&od->refcnt); + list_add_tail(&of->list, &od->files); + } + + spin_unlock_irq(&sysfs_open_dirent_lock); + mutex_unlock(&sysfs_open_file_mutex); + + if (od) { + kfree(new_od); + return 0; + } + + /* not there, initialize a new one and retry */ + new_od = kmalloc(sizeof(*new_od), GFP_KERNEL); + if (!new_od) + return -ENOMEM; + + atomic_set(&new_od->refcnt, 0); + atomic_set(&new_od->event, 1); + init_waitqueue_head(&new_od->poll); + INIT_LIST_HEAD(&new_od->files); + goto retry; +} + +/** + * sysfs_put_open_dirent - put sysfs_open_dirent + * @sd: target sysfs_dirent + * @of: associated sysfs_open_file + * + * Put @sd->s_attr.open and unlink @of from the files list. If + * reference count reaches zero, disassociate and free it. + * + * LOCKING: + * None. + */ +static void sysfs_put_open_dirent(struct sysfs_dirent *sd, + struct sysfs_open_file *of) +{ + struct sysfs_open_dirent *od = sd->s_attr.open; + unsigned long flags; + + mutex_lock(&sysfs_open_file_mutex); + spin_lock_irqsave(&sysfs_open_dirent_lock, flags); + + if (of) + list_del(&of->list); + + if (atomic_dec_and_test(&od->refcnt)) + sd->s_attr.open = NULL; + else + od = NULL; + + spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); + mutex_unlock(&sysfs_open_file_mutex); + + kfree(od); +} + +static int kernfs_file_open(struct inode *inode, struct file *file) +{ + struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; + const struct kernfs_ops *ops; + struct sysfs_open_file *of; + bool has_read, has_write, has_mmap; + int error = -EACCES; + + if (!sysfs_get_active(attr_sd)) + return -ENODEV; + + ops = kernfs_ops(attr_sd); + + has_read = ops->seq_show || ops->read || ops->mmap; + has_write = ops->write || ops->mmap; + has_mmap = ops->mmap; + + /* check perms and supported operations */ + if ((file->f_mode & FMODE_WRITE) && + (!(inode->i_mode & S_IWUGO) || !has_write)) + goto err_out; + + if ((file->f_mode & FMODE_READ) && + (!(inode->i_mode & S_IRUGO) || !has_read)) + goto err_out; + + /* allocate a sysfs_open_file for the file */ + error = -ENOMEM; + of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL); + if (!of) + goto err_out; + + /* + * The following is done to give a different lockdep key to + * @of->mutex for files which implement mmap. This is a rather + * crude way to avoid false positive lockdep warning around + * mm->mmap_sem - mmap nests @of->mutex under mm->mmap_sem and + * reading /sys/block/sda/trace/act_mask grabs sr_mutex, under + * which mm->mmap_sem nests, while holding @of->mutex. As each + * open file has a separate mutex, it's okay as long as those don't + * happen on the same file. At this point, we can't easily give + * each file a separate locking class. Let's differentiate on + * whether the file has mmap or not for now. + */ + if (has_mmap) + mutex_init(&of->mutex); + else + mutex_init(&of->mutex); + + of->sd = attr_sd; + of->file = file; + + /* + * Always instantiate seq_file even if read access doesn't use + * seq_file or is not requested. This unifies private data access + * and readable regular files are the vast majority anyway. + */ + if (ops->seq_show) + error = seq_open(file, &kernfs_seq_ops); + else + error = seq_open(file, NULL); + if (error) + goto err_free; + + ((struct seq_file *)file->private_data)->private = of; + + /* seq_file clears PWRITE unconditionally, restore it if WRITE */ + if (file->f_mode & FMODE_WRITE) + file->f_mode |= FMODE_PWRITE; + + /* make sure we have open dirent struct */ + error = sysfs_get_open_dirent(attr_sd, of); + if (error) + goto err_close; + + /* open succeeded, put active references */ + sysfs_put_active(attr_sd); + return 0; + +err_close: + seq_release(inode, file); +err_free: + kfree(of); +err_out: + sysfs_put_active(attr_sd); + return error; +} + +static int kernfs_file_release(struct inode *inode, struct file *filp) +{ + struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata; + struct sysfs_open_file *of = sysfs_of(filp); + + sysfs_put_open_dirent(sd, of); + seq_release(inode, filp); + kfree(of); + + return 0; +} + +void sysfs_unmap_bin_file(struct sysfs_dirent *sd) +{ + struct sysfs_open_dirent *od; + struct sysfs_open_file *of; + + if (!(sd->s_flags & SYSFS_FLAG_HAS_MMAP)) + return; + + spin_lock_irq(&sysfs_open_dirent_lock); + od = sd->s_attr.open; + if (od) + atomic_inc(&od->refcnt); + spin_unlock_irq(&sysfs_open_dirent_lock); + if (!od) + return; + + mutex_lock(&sysfs_open_file_mutex); + list_for_each_entry(of, &od->files, list) { + struct inode *inode = file_inode(of->file); + unmap_mapping_range(inode->i_mapping, 0, 0, 1); + } + mutex_unlock(&sysfs_open_file_mutex); + + sysfs_put_open_dirent(sd, NULL); +} + +/* 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, 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 + * an appropriate error code). When in doubt, set a suitable timeout value. + */ +static unsigned int kernfs_file_poll(struct file *filp, poll_table *wait) +{ + struct sysfs_open_file *of = sysfs_of(filp); + struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata; + struct sysfs_open_dirent *od = attr_sd->s_attr.open; + + /* need parent for the kobj, grab both */ + if (!sysfs_get_active(attr_sd)) + goto trigger; + + poll_wait(filp, &od->poll, wait); + + sysfs_put_active(attr_sd); + + if (of->event != atomic_read(&od->event)) + goto trigger; + + return DEFAULT_POLLMASK; + + trigger: + return DEFAULT_POLLMASK|POLLERR|POLLPRI; +} + +/** + * kernfs_notify - notify a kernfs file + * @sd: file to notify + * + * Notify @sd such that poll(2) on @sd wakes up. + */ +void kernfs_notify(struct sysfs_dirent *sd) +{ + struct sysfs_open_dirent *od; + unsigned long flags; + + spin_lock_irqsave(&sysfs_open_dirent_lock, flags); + + if (!WARN_ON(sysfs_type(sd) != SYSFS_KOBJ_ATTR)) { + od = sd->s_attr.open; + if (od) { + atomic_inc(&od->event); + wake_up_interruptible(&od->poll); + } + } + + spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); +} +EXPORT_SYMBOL_GPL(kernfs_notify); + +const struct file_operations kernfs_file_operations = { + .read = kernfs_file_read, + .write = kernfs_file_write, + .llseek = generic_file_llseek, + .mmap = kernfs_file_mmap, + .open = kernfs_file_open, + .release = kernfs_file_release, + .poll = kernfs_file_poll, +}; + +/** + * kernfs_create_file_ns_key - create a file + * @parent: directory to create the file in + * @name: name of the file + * @mode: mode of the file + * @size: size of the file + * @ops: kernfs operations for the file + * @priv: private data for the file + * @ns: optional namespace tag of the file + * @key: lockdep key for the file's active_ref, %NULL to disable lockdep + * + * Returns the created node on success, ERR_PTR() value on error. + */ +struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent, + const char *name, + umode_t mode, loff_t size, + const struct kernfs_ops *ops, + void *priv, const void *ns, + struct lock_class_key *key) +{ + struct sysfs_addrm_cxt acxt; + struct sysfs_dirent *sd; + int rc; + + sd = sysfs_new_dirent(name, (mode & S_IALLUGO) | S_IFREG, + SYSFS_KOBJ_ATTR); + if (!sd) + return ERR_PTR(-ENOMEM); + + sd->s_attr.ops = ops; + sd->s_attr.size = size; + sd->s_ns = ns; + sd->priv = priv; + +#ifdef CONFIG_DEBUG_LOCK_ALLOC + if (key) { + lockdep_init_map(&sd->dep_map, "s_active", key, 0); + sd->s_flags |= SYSFS_FLAG_LOCKDEP; + } +#endif + + /* + * sd->s_attr.ops is accesible only while holding active ref. We + * need to know whether some ops are implemented outside active + * ref. Cache their existence in flags. + */ + if (ops->seq_show) + sd->s_flags |= SYSFS_FLAG_HAS_SEQ_SHOW; + if (ops->mmap) + sd->s_flags |= SYSFS_FLAG_HAS_MMAP; + + sysfs_addrm_start(&acxt); + rc = sysfs_add_one(&acxt, sd, parent); + sysfs_addrm_finish(&acxt); + + if (rc) { + kernfs_put(sd); + return ERR_PTR(rc); + } + return sd; +} diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 31f0dbe1881..38e3a163e5a 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -142,4 +142,11 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd, void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type); +/* + * file.c + */ +extern const struct file_operations kernfs_file_operations; + +void sysfs_unmap_bin_file(struct sysfs_dirent *sd); + #endif /* __KERNFS_INTERNAL_H */ diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 7f0a79fa2ed..ac77d2be3c3 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -14,54 +14,12 @@ #include #include #include -#include -#include -#include #include #include -#include -#include #include -#include #include "sysfs.h" - -/* - * There's one sysfs_open_file for each open file and one sysfs_open_dirent - * for each sysfs_dirent with one or more open files. - * - * sysfs_dirent->s_attr.open points to sysfs_open_dirent. s_attr.open is - * protected by sysfs_open_dirent_lock. - * - * filp->private_data points to seq_file whose ->private points to - * sysfs_open_file. sysfs_open_files are chained at - * sysfs_open_dirent->files, which is protected by sysfs_open_file_mutex. - */ -static DEFINE_SPINLOCK(sysfs_open_dirent_lock); -static DEFINE_MUTEX(sysfs_open_file_mutex); - -struct sysfs_open_dirent { - atomic_t refcnt; - atomic_t event; - wait_queue_head_t poll; - struct list_head files; /* goes through sysfs_open_file.list */ -}; - -static struct sysfs_open_file *sysfs_of(struct file *file) -{ - return ((struct seq_file *)file->private_data)->private; -} - -/* - * Determine the kernfs_ops for the given sysfs_dirent. This function must - * be called while holding an active reference. - */ -static const struct kernfs_ops *kernfs_ops(struct sysfs_dirent *sd) -{ - if (sd->s_flags & SYSFS_FLAG_LOCKDEP) - lockdep_assert_held(sd); - return sd->s_attr.ops; -} +#include "../kernfs/kernfs-internal.h" /* * Determine ktype->sysfs_ops for the given sysfs_dirent. This function @@ -143,147 +101,6 @@ static ssize_t sysfs_kf_bin_read(struct sysfs_open_file *of, char *buf, return battr->read(of->file, kobj, battr, buf, pos, count); } -static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) -{ - struct sysfs_open_file *of = sf->private; - const struct kernfs_ops *ops; - - /* - * @of->mutex nests outside active ref and is just to ensure that - * the ops aren't called concurrently for the same open file. - */ - mutex_lock(&of->mutex); - if (!sysfs_get_active(of->sd)) - return ERR_PTR(-ENODEV); - - ops = kernfs_ops(of->sd); - if (ops->seq_start) { - return ops->seq_start(sf, ppos); - } else { - /* - * The same behavior and code as single_open(). Returns - * !NULL if pos is at the beginning; otherwise, NULL. - */ - return NULL + !*ppos; - } -} - -static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) -{ - struct sysfs_open_file *of = sf->private; - const struct kernfs_ops *ops = kernfs_ops(of->sd); - - if (ops->seq_next) { - return ops->seq_next(sf, v, ppos); - } else { - /* - * The same behavior and code as single_open(), always - * terminate after the initial read. - */ - ++*ppos; - return NULL; - } -} - -static void kernfs_seq_stop(struct seq_file *sf, void *v) -{ - struct sysfs_open_file *of = sf->private; - const struct kernfs_ops *ops = kernfs_ops(of->sd); - - if (ops->seq_stop) - ops->seq_stop(sf, v); - - sysfs_put_active(of->sd); - mutex_unlock(&of->mutex); -} - -static int kernfs_seq_show(struct seq_file *sf, void *v) -{ - struct sysfs_open_file *of = sf->private; - - of->event = atomic_read(&of->sd->s_attr.open->event); - - return of->sd->s_attr.ops->seq_show(sf, v); -} - -static const struct seq_operations kernfs_seq_ops = { - .start = kernfs_seq_start, - .next = kernfs_seq_next, - .stop = kernfs_seq_stop, - .show = kernfs_seq_show, -}; - -/* - * As reading a bin file can have side-effects, the exact offset and bytes - * specified in read(2) call should be passed to the read callback making - * it difficult to use seq_file. Implement simplistic custom buffering for - * bin files. - */ -static ssize_t kernfs_file_direct_read(struct sysfs_open_file *of, - char __user *user_buf, size_t count, - loff_t *ppos) -{ - ssize_t len = min_t(size_t, count, PAGE_SIZE); - const struct kernfs_ops *ops; - char *buf; - - buf = kmalloc(len, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - /* - * @of->mutex nests outside active ref and is just to ensure that - * the ops aren't called concurrently for the same open file. - */ - mutex_lock(&of->mutex); - if (!sysfs_get_active(of->sd)) { - len = -ENODEV; - mutex_unlock(&of->mutex); - goto out_free; - } - - ops = kernfs_ops(of->sd); - if (ops->read) - len = ops->read(of, buf, len, *ppos); - else - len = -EINVAL; - - sysfs_put_active(of->sd); - mutex_unlock(&of->mutex); - - if (len < 0) - goto out_free; - - if (copy_to_user(user_buf, buf, len)) { - len = -EFAULT; - goto out_free; - } - - *ppos += len; - - out_free: - kfree(buf); - return len; -} - -/** - * kernfs_file_read - kernfs vfs read callback - * @file: file pointer - * @user_buf: data to write - * @count: number of bytes - * @ppos: starting offset - */ -static ssize_t kernfs_file_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct sysfs_open_file *of = sysfs_of(file); - - if (of->sd->s_flags & SYSFS_FLAG_HAS_SEQ_SHOW) - return seq_read(file, user_buf, count, ppos); - else - return kernfs_file_direct_read(of, user_buf, count, ppos); -} - /* kernfs write callback for regular sysfs files */ static ssize_t sysfs_kf_write(struct sysfs_open_file *of, char *buf, size_t count, loff_t pos) @@ -319,67 +136,6 @@ static ssize_t sysfs_kf_bin_write(struct sysfs_open_file *of, char *buf, return battr->write(of->file, kobj, battr, buf, pos, count); } -/** - * kernfs_file_write - kernfs vfs write callback - * @file: file pointer - * @user_buf: data to write - * @count: number of bytes - * @ppos: starting offset - * - * Copy data in from userland and pass it to the matching kernfs write - * operation. - * - * There is no easy way for us to know if userspace is only doing a partial - * write, so we don't support them. We expect the entire buffer to come on - * the first write. Hint: if you're writing a value, first read the file, - * modify only the the value you're changing, then write entire buffer - * back. - */ -static ssize_t kernfs_file_write(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct sysfs_open_file *of = sysfs_of(file); - ssize_t len = min_t(size_t, count, PAGE_SIZE); - const struct kernfs_ops *ops; - char *buf; - - buf = kmalloc(len + 1, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - if (copy_from_user(buf, user_buf, len)) { - len = -EFAULT; - goto out_free; - } - buf[len] = '\0'; /* guarantee string termination */ - - /* - * @of->mutex nests outside active ref and is just to ensure that - * the ops aren't called concurrently for the same open file. - */ - mutex_lock(&of->mutex); - if (!sysfs_get_active(of->sd)) { - mutex_unlock(&of->mutex); - len = -ENODEV; - goto out_free; - } - - ops = kernfs_ops(of->sd); - if (ops->write) - len = ops->write(of, buf, len, *ppos); - else - len = -EINVAL; - - sysfs_put_active(of->sd); - mutex_unlock(&of->mutex); - - if (len > 0) - *ppos += len; -out_free: - kfree(buf); - return len; -} - static int sysfs_kf_bin_mmap(struct sysfs_open_file *of, struct vm_area_struct *vma) { @@ -392,490 +148,6 @@ static int sysfs_kf_bin_mmap(struct sysfs_open_file *of, return battr->mmap(of->file, kobj, battr, vma); } -static void kernfs_vma_open(struct vm_area_struct *vma) -{ - struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); - - if (!of->vm_ops) - return; - - if (!sysfs_get_active(of->sd)) - return; - - if (of->vm_ops->open) - of->vm_ops->open(vma); - - sysfs_put_active(of->sd); -} - -static int kernfs_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); - int ret; - - if (!of->vm_ops) - return VM_FAULT_SIGBUS; - - if (!sysfs_get_active(of->sd)) - return VM_FAULT_SIGBUS; - - ret = VM_FAULT_SIGBUS; - if (of->vm_ops->fault) - ret = of->vm_ops->fault(vma, vmf); - - sysfs_put_active(of->sd); - return ret; -} - -static int kernfs_vma_page_mkwrite(struct vm_area_struct *vma, - struct vm_fault *vmf) -{ - struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); - int ret; - - if (!of->vm_ops) - return VM_FAULT_SIGBUS; - - if (!sysfs_get_active(of->sd)) - return VM_FAULT_SIGBUS; - - ret = 0; - if (of->vm_ops->page_mkwrite) - ret = of->vm_ops->page_mkwrite(vma, vmf); - else - file_update_time(file); - - sysfs_put_active(of->sd); - return ret; -} - -static int kernfs_vma_access(struct vm_area_struct *vma, unsigned long addr, - void *buf, int len, int write) -{ - struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); - int ret; - - if (!of->vm_ops) - return -EINVAL; - - if (!sysfs_get_active(of->sd)) - return -EINVAL; - - ret = -EINVAL; - if (of->vm_ops->access) - ret = of->vm_ops->access(vma, addr, buf, len, write); - - sysfs_put_active(of->sd); - return ret; -} - -#ifdef CONFIG_NUMA -static int kernfs_vma_set_policy(struct vm_area_struct *vma, - struct mempolicy *new) -{ - struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); - int ret; - - if (!of->vm_ops) - return 0; - - if (!sysfs_get_active(of->sd)) - return -EINVAL; - - ret = 0; - if (of->vm_ops->set_policy) - ret = of->vm_ops->set_policy(vma, new); - - sysfs_put_active(of->sd); - return ret; -} - -static struct mempolicy *kernfs_vma_get_policy(struct vm_area_struct *vma, - unsigned long addr) -{ - struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); - struct mempolicy *pol; - - if (!of->vm_ops) - return vma->vm_policy; - - if (!sysfs_get_active(of->sd)) - return vma->vm_policy; - - pol = vma->vm_policy; - if (of->vm_ops->get_policy) - pol = of->vm_ops->get_policy(vma, addr); - - sysfs_put_active(of->sd); - return pol; -} - -static int kernfs_vma_migrate(struct vm_area_struct *vma, - const nodemask_t *from, const nodemask_t *to, - unsigned long flags) -{ - struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); - int ret; - - if (!of->vm_ops) - return 0; - - if (!sysfs_get_active(of->sd)) - return 0; - - ret = 0; - if (of->vm_ops->migrate) - ret = of->vm_ops->migrate(vma, from, to, flags); - - sysfs_put_active(of->sd); - return ret; -} -#endif - -static const struct vm_operations_struct kernfs_vm_ops = { - .open = kernfs_vma_open, - .fault = kernfs_vma_fault, - .page_mkwrite = kernfs_vma_page_mkwrite, - .access = kernfs_vma_access, -#ifdef CONFIG_NUMA - .set_policy = kernfs_vma_set_policy, - .get_policy = kernfs_vma_get_policy, - .migrate = kernfs_vma_migrate, -#endif -}; - -static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct sysfs_open_file *of = sysfs_of(file); - const struct kernfs_ops *ops; - int rc; - - mutex_lock(&of->mutex); - - rc = -ENODEV; - if (!sysfs_get_active(of->sd)) - goto out_unlock; - - ops = kernfs_ops(of->sd); - if (ops->mmap) - rc = ops->mmap(of, vma); - if (rc) - goto out_put; - - /* - * PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup() - * to satisfy versions of X which crash if the mmap fails: that - * substitutes a new vm_file, and we don't then want bin_vm_ops. - */ - if (vma->vm_file != file) - goto out_put; - - rc = -EINVAL; - if (of->mmapped && of->vm_ops != vma->vm_ops) - goto out_put; - - /* - * It is not possible to successfully wrap close. - * So error if someone is trying to use close. - */ - rc = -EINVAL; - if (vma->vm_ops && vma->vm_ops->close) - goto out_put; - - rc = 0; - of->mmapped = 1; - of->vm_ops = vma->vm_ops; - vma->vm_ops = &kernfs_vm_ops; -out_put: - sysfs_put_active(of->sd); -out_unlock: - mutex_unlock(&of->mutex); - - return rc; -} - -/** - * sysfs_get_open_dirent - get or create sysfs_open_dirent - * @sd: target sysfs_dirent - * @of: sysfs_open_file for this instance of open - * - * If @sd->s_attr.open exists, increment its reference count; - * otherwise, create one. @of is chained to the files list. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno on failure. - */ -static int sysfs_get_open_dirent(struct sysfs_dirent *sd, - struct sysfs_open_file *of) -{ - struct sysfs_open_dirent *od, *new_od = NULL; - - retry: - mutex_lock(&sysfs_open_file_mutex); - spin_lock_irq(&sysfs_open_dirent_lock); - - if (!sd->s_attr.open && new_od) { - sd->s_attr.open = new_od; - new_od = NULL; - } - - od = sd->s_attr.open; - if (od) { - atomic_inc(&od->refcnt); - list_add_tail(&of->list, &od->files); - } - - spin_unlock_irq(&sysfs_open_dirent_lock); - mutex_unlock(&sysfs_open_file_mutex); - - if (od) { - kfree(new_od); - return 0; - } - - /* not there, initialize a new one and retry */ - new_od = kmalloc(sizeof(*new_od), GFP_KERNEL); - if (!new_od) - return -ENOMEM; - - atomic_set(&new_od->refcnt, 0); - atomic_set(&new_od->event, 1); - init_waitqueue_head(&new_od->poll); - INIT_LIST_HEAD(&new_od->files); - goto retry; -} - -/** - * sysfs_put_open_dirent - put sysfs_open_dirent - * @sd: target sysfs_dirent - * @of: associated sysfs_open_file - * - * Put @sd->s_attr.open and unlink @of from the files list. If - * reference count reaches zero, disassociate and free it. - * - * LOCKING: - * None. - */ -static void sysfs_put_open_dirent(struct sysfs_dirent *sd, - struct sysfs_open_file *of) -{ - struct sysfs_open_dirent *od = sd->s_attr.open; - unsigned long flags; - - mutex_lock(&sysfs_open_file_mutex); - spin_lock_irqsave(&sysfs_open_dirent_lock, flags); - - if (of) - list_del(&of->list); - - if (atomic_dec_and_test(&od->refcnt)) - sd->s_attr.open = NULL; - else - od = NULL; - - spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); - mutex_unlock(&sysfs_open_file_mutex); - - kfree(od); -} - -static int kernfs_file_open(struct inode *inode, struct file *file) -{ - struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; - const struct kernfs_ops *ops; - struct sysfs_open_file *of; - bool has_read, has_write, has_mmap; - int error = -EACCES; - - if (!sysfs_get_active(attr_sd)) - return -ENODEV; - - ops = kernfs_ops(attr_sd); - - has_read = ops->seq_show || ops->read || ops->mmap; - has_write = ops->write || ops->mmap; - has_mmap = ops->mmap; - - /* check perms and supported operations */ - if ((file->f_mode & FMODE_WRITE) && - (!(inode->i_mode & S_IWUGO) || !has_write)) - goto err_out; - - if ((file->f_mode & FMODE_READ) && - (!(inode->i_mode & S_IRUGO) || !has_read)) - goto err_out; - - /* allocate a sysfs_open_file for the file */ - error = -ENOMEM; - of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL); - if (!of) - goto err_out; - - /* - * The following is done to give a different lockdep key to - * @of->mutex for files which implement mmap. This is a rather - * crude way to avoid false positive lockdep warning around - * mm->mmap_sem - mmap nests @of->mutex under mm->mmap_sem and - * reading /sys/block/sda/trace/act_mask grabs sr_mutex, under - * which mm->mmap_sem nests, while holding @of->mutex. As each - * open file has a separate mutex, it's okay as long as those don't - * happen on the same file. At this point, we can't easily give - * each file a separate locking class. Let's differentiate on - * whether the file has mmap or not for now. - */ - if (has_mmap) - mutex_init(&of->mutex); - else - mutex_init(&of->mutex); - - of->sd = attr_sd; - of->file = file; - - /* - * Always instantiate seq_file even if read access doesn't use - * seq_file or is not requested. This unifies private data access - * and readable regular files are the vast majority anyway. - */ - if (ops->seq_show) - error = seq_open(file, &kernfs_seq_ops); - else - error = seq_open(file, NULL); - if (error) - goto err_free; - - ((struct seq_file *)file->private_data)->private = of; - - /* seq_file clears PWRITE unconditionally, restore it if WRITE */ - if (file->f_mode & FMODE_WRITE) - file->f_mode |= FMODE_PWRITE; - - /* make sure we have open dirent struct */ - error = sysfs_get_open_dirent(attr_sd, of); - if (error) - goto err_close; - - /* open succeeded, put active references */ - sysfs_put_active(attr_sd); - return 0; - -err_close: - seq_release(inode, file); -err_free: - kfree(of); -err_out: - sysfs_put_active(attr_sd); - return error; -} - -static int kernfs_file_release(struct inode *inode, struct file *filp) -{ - struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata; - struct sysfs_open_file *of = sysfs_of(filp); - - sysfs_put_open_dirent(sd, of); - seq_release(inode, filp); - kfree(of); - - return 0; -} - -void sysfs_unmap_bin_file(struct sysfs_dirent *sd) -{ - struct sysfs_open_dirent *od; - struct sysfs_open_file *of; - - if (!(sd->s_flags & SYSFS_FLAG_HAS_MMAP)) - return; - - spin_lock_irq(&sysfs_open_dirent_lock); - od = sd->s_attr.open; - if (od) - atomic_inc(&od->refcnt); - spin_unlock_irq(&sysfs_open_dirent_lock); - if (!od) - return; - - mutex_lock(&sysfs_open_file_mutex); - list_for_each_entry(of, &od->files, list) { - struct inode *inode = file_inode(of->file); - unmap_mapping_range(inode->i_mapping, 0, 0, 1); - } - mutex_unlock(&sysfs_open_file_mutex); - - sysfs_put_open_dirent(sd, NULL); -} - -/* 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, 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 - * an appropriate error code). When in doubt, set a suitable timeout value. - */ -static unsigned int kernfs_file_poll(struct file *filp, poll_table *wait) -{ - struct sysfs_open_file *of = sysfs_of(filp); - struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata; - struct sysfs_open_dirent *od = attr_sd->s_attr.open; - - /* need parent for the kobj, grab both */ - if (!sysfs_get_active(attr_sd)) - goto trigger; - - poll_wait(filp, &od->poll, wait); - - sysfs_put_active(attr_sd); - - if (of->event != atomic_read(&od->event)) - goto trigger; - - return DEFAULT_POLLMASK; - - trigger: - return DEFAULT_POLLMASK|POLLERR|POLLPRI; -} - -/** - * kernfs_notify - notify a kernfs file - * @sd: file to notify - * - * Notify @sd such that poll(2) on @sd wakes up. - */ -void kernfs_notify(struct sysfs_dirent *sd) -{ - struct sysfs_open_dirent *od; - unsigned long flags; - - spin_lock_irqsave(&sysfs_open_dirent_lock, flags); - - if (!WARN_ON(sysfs_type(sd) != SYSFS_KOBJ_ATTR)) { - od = sd->s_attr.open; - if (od) { - atomic_inc(&od->event); - wake_up_interruptible(&od->poll); - } - } - - spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); -} -EXPORT_SYMBOL_GPL(kernfs_notify); - void sysfs_notify(struct kobject *k, const char *dir, const char *attr) { struct sysfs_dirent *sd = k->sd, *tmp; @@ -898,16 +170,6 @@ void sysfs_notify(struct kobject *k, const char *dir, const char *attr) } EXPORT_SYMBOL_GPL(sysfs_notify); -const struct file_operations kernfs_file_operations = { - .read = kernfs_file_read, - .write = kernfs_file_write, - .llseek = generic_file_llseek, - .mmap = kernfs_file_mmap, - .open = kernfs_file_open, - .release = kernfs_file_release, - .poll = kernfs_file_poll, -}; - static const struct kernfs_ops sysfs_file_kfops_empty = { }; @@ -996,68 +258,6 @@ int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd, return 0; } -/** - * kernfs_create_file_ns_key - create a file - * @parent: directory to create the file in - * @name: name of the file - * @mode: mode of the file - * @size: size of the file - * @ops: kernfs operations for the file - * @priv: private data for the file - * @ns: optional namespace tag of the file - * @key: lockdep key for the file's active_ref, %NULL to disable lockdep - * - * Returns the created node on success, ERR_PTR() value on error. - */ -struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent, - const char *name, - umode_t mode, loff_t size, - const struct kernfs_ops *ops, - void *priv, const void *ns, - struct lock_class_key *key) -{ - struct sysfs_addrm_cxt acxt; - struct sysfs_dirent *sd; - int rc; - - sd = sysfs_new_dirent(name, (mode & S_IALLUGO) | S_IFREG, - SYSFS_KOBJ_ATTR); - if (!sd) - return ERR_PTR(-ENOMEM); - - sd->s_attr.ops = ops; - sd->s_attr.size = size; - sd->s_ns = ns; - sd->priv = priv; - -#ifdef CONFIG_DEBUG_LOCK_ALLOC - if (key) { - lockdep_init_map(&sd->dep_map, "s_active", key, 0); - sd->s_flags |= SYSFS_FLAG_LOCKDEP; - } -#endif - - /* - * sd->s_attr.ops is accesible only while holding active ref. We - * need to know whether some ops are implemented outside active - * ref. Cache their existence in flags. - */ - if (ops->seq_show) - sd->s_flags |= SYSFS_FLAG_HAS_SEQ_SHOW; - if (ops->mmap) - sd->s_flags |= SYSFS_FLAG_HAS_MMAP; - - sysfs_addrm_start(&acxt); - rc = sysfs_add_one(&acxt, sd, parent); - sysfs_addrm_finish(&acxt); - - if (rc) { - kernfs_put(sd); - return ERR_PTR(rc); - } - return sd; -} - int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr, bool is_bin) { diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 972b4a4a5f9..4b8b60d834c 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -41,15 +41,11 @@ void sysfs_warn_dup(struct sysfs_dirent *parent, const char *name); /* * file.c */ -extern const struct file_operations kernfs_file_operations; - int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr, bool is_bin); - int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd, const struct attribute *attr, bool is_bin, umode_t amode, const void *ns); -void sysfs_unmap_bin_file(struct sysfs_dirent *sd); /* * symlink.c -- cgit v1.2.3-70-g09d2 From bc755553df9ab33f389c1a0a8bd0b4f4646e80ef Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 28 Nov 2013 14:54:41 -0500 Subject: sysfs, kernfs: make inode number ida per kernfs_root kernfs is being updated to allow multiple sysfs_dirent hierarchies so that it can also be used by other users. Currently, inode number is allocated using a global ida, sysfs_ino_ida; however, inos for different hierarchies should be handled separately. This patch makes ino allocation per kernfs_root. sysfs_ino_ida is replaced by kernfs_root->ino_ida and sysfs_new_dirent() is updated to take @root and allocate ino from it. ida_simple_get/remove() are used instead of sysfs_ino_lock and sysfs_alloc/free_ino(). Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 47 +++++++++++++-------------------------------- fs/kernfs/file.c | 4 ++-- fs/kernfs/kernfs-internal.h | 3 ++- fs/kernfs/symlink.c | 3 ++- include/linux/kernfs.h | 4 ++++ 5 files changed, 23 insertions(+), 38 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 246740a741e..eaffa83719d 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -21,9 +21,6 @@ DEFINE_MUTEX(sysfs_mutex); #define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb) -static DEFINE_SPINLOCK(sysfs_ino_lock); -static DEFINE_IDA(sysfs_ino_ida); - /** * sysfs_name_hash * @name: Null terminated string to hash @@ -205,32 +202,6 @@ static void sysfs_deactivate(struct sysfs_dirent *sd) rwsem_release(&sd->dep_map, 1, _RET_IP_); } -static int sysfs_alloc_ino(unsigned int *pino) -{ - int ino, rc; - - retry: - spin_lock(&sysfs_ino_lock); - rc = ida_get_new_above(&sysfs_ino_ida, 1, &ino); - spin_unlock(&sysfs_ino_lock); - - if (rc == -EAGAIN) { - if (ida_pre_get(&sysfs_ino_ida, GFP_KERNEL)) - goto retry; - rc = -ENOMEM; - } - - *pino = ino; - return rc; -} - -static void sysfs_free_ino(unsigned int ino) -{ - spin_lock(&sysfs_ino_lock); - ida_remove(&sysfs_ino_ida, ino); - spin_unlock(&sysfs_ino_lock); -} - /** * kernfs_get - get a reference count on a sysfs_dirent * @sd: the target sysfs_dirent @@ -276,7 +247,7 @@ void kernfs_put(struct sysfs_dirent *sd) security_release_secctx(sd->s_iattr->ia_secdata, sd->s_iattr->ia_secdata_len); kfree(sd->s_iattr); - sysfs_free_ino(sd->s_ino); + ida_simple_remove(&root->ino_ida, sd->s_ino); kmem_cache_free(sysfs_dir_cachep, sd); sd = parent_sd; @@ -285,6 +256,7 @@ void kernfs_put(struct sysfs_dirent *sd) goto repeat; } else { /* just released the root sd, free @root too */ + ida_destroy(&root->ino_ida); kfree(root); } } @@ -360,10 +332,12 @@ const struct dentry_operations sysfs_dentry_ops = { .d_release = sysfs_dentry_release, }; -struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) +struct sysfs_dirent *sysfs_new_dirent(struct kernfs_root *root, + const char *name, umode_t mode, int type) { char *dup_name = NULL; struct sysfs_dirent *sd; + int ret; if (type & SYSFS_COPY_NAME) { name = dup_name = kstrdup(name, GFP_KERNEL); @@ -375,8 +349,10 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) if (!sd) goto err_out1; - if (sysfs_alloc_ino(&sd->s_ino)) + ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL); + if (ret < 0) goto err_out2; + sd->s_ino = ret; atomic_set(&sd->s_count, 1); atomic_set(&sd->s_active, 0); @@ -628,8 +604,11 @@ struct kernfs_root *kernfs_create_root(void *priv) if (!root) return ERR_PTR(-ENOMEM); - sd = sysfs_new_dirent("", S_IFDIR | S_IRUGO | S_IXUGO, SYSFS_DIR); + ida_init(&root->ino_ida); + + sd = sysfs_new_dirent(root, "", S_IFDIR | S_IRUGO | S_IXUGO, SYSFS_DIR); if (!sd) { + ida_destroy(&root->ino_ida); kfree(root); return ERR_PTR(-ENOMEM); } @@ -674,7 +653,7 @@ struct sysfs_dirent *kernfs_create_dir_ns(struct sysfs_dirent *parent, int rc; /* allocate */ - sd = sysfs_new_dirent(name, mode, SYSFS_DIR); + sd = sysfs_new_dirent(kernfs_root(parent), name, mode, SYSFS_DIR); if (!sd) return ERR_PTR(-ENOMEM); diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index fa172e86047..990c97fa704 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -775,8 +775,8 @@ struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent, struct sysfs_dirent *sd; int rc; - sd = sysfs_new_dirent(name, (mode & S_IALLUGO) | S_IFREG, - SYSFS_KOBJ_ATTR); + sd = sysfs_new_dirent(kernfs_root(parent), name, + (mode & S_IALLUGO) | S_IFREG, SYSFS_KOBJ_ATTR); if (!sd) return ERR_PTR(-ENOMEM); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 7dfe0627835..466943d576f 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -160,7 +160,8 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt); int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd, struct sysfs_dirent *parent_sd); void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); -struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type); +struct sysfs_dirent *sysfs_new_dirent(struct kernfs_root *root, + const char *name, umode_t mode, int type); /* * file.c diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index af3570bb430..004c1646559 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -30,7 +30,8 @@ struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, struct sysfs_addrm_cxt acxt; int error; - sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); + sd = sysfs_new_dirent(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO, + SYSFS_KOBJ_LINK); if (!sd) return ERR_PTR(-ENOMEM); diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index f75548b8ed7..fad8b986800 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -11,6 +11,7 @@ #include #include #include +#include #include struct file; @@ -23,6 +24,9 @@ struct sysfs_dirent; struct kernfs_root { /* published fields */ struct sysfs_dirent *sd; + + /* private fields, do not use outside kernfs proper */ + struct ida ino_ida; }; struct sysfs_open_file { -- cgit v1.2.3-70-g09d2 From 21d71662f895462abaa3054d504af55a306f42ba Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sat, 7 Dec 2013 14:07:36 +0800 Subject: sysfs, kernfs: remove duplicated include from file.c Remove duplicated include. Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 990c97fa704..4a5863b79de 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "kernfs-internal.h" -- cgit v1.2.3-70-g09d2 From 9b2db6e1894577d48f4e290381bac6e573593838 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 10 Dec 2013 09:29:17 -0500 Subject: sysfs: bail early from kernfs_file_mmap() to avoid spurious lockdep warning This is v3.14 fix for the same issue that a8b14744429f ("sysfs: give different locking key to regular and bin files") addresses for v3.13. Due to the extensive kernfs reorganization in v3.14 branch, the same fix couldn't be ported as-is. The v3.13 fix was ignored while merging it into v3.14 branch. 027a485d12e0 ("sysfs: use a separate locking class for open files depending on mmap") assigned different lockdep key to sysfs_open_file->mutex depending on whether the file implements mmap or not in an attempt to avoid spurious lockdep warning caused by merging of regular and bin file paths. While this restored some of the original behavior of using different locks (at least lockdep is concerned) for the different clases of files. The restoration wasn't full because now the lockdep key assignment depends on whether the file has mmap or not instead of whether it's a regular file or not. This means that bin files which don't implement mmap will get assigned the same lockdep class as regular files. This is problematic because file_operations for bin files still implements the mmap file operation and checking whether the sysfs file actually implements mmap happens in the file operation after grabbing @sysfs_open_file->mutex. We still end up adding locking dependency from mmap locking to sysfs_open_file->mutex to the regular file mutex which triggers spurious circular locking warning. For v3.13, a8b14744429f ("sysfs: give different locking key to regular and bin files") fixed it by giving sysfs_open_file->mutex different lockdep keys depending on whether the file is regular or bin instead of whether mmap exists or not; however, due to the way sysfs is now layered behind kernfs, this approach is no longer viable. kernfs can tell whether a sysfs node has mmap implemented or not but can't tell whether a bin file from a regular one. This patch updates kernfs such that kernfs_file_mmap() checks SYSFS_FLAG_HAS_MMAP and bail before grabbing sysfs_open_file->mutex so that it doesn't add spurious locking dependency from mmap to sysfs_open_file->mutex and changes sysfs so that it specifies kernfs_ops->mmap iff the sysfs file implements mmap. Combined, this ensures that sysfs_open_file->mutex is grabbed under mmap path iff the sysfs file actually implements mmap. As sysfs_open_file->mutex is already given a different lockdep key if mmap is implemented, this removes the spurious locking dependency. Signed-off-by: Tejun Heo Reported-by: Dave Jones Link: http://lkml.kernel.org/g/20131203184324.GA11320@redhat.com Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 18 ++++++++++++++---- fs/sysfs/file.c | 12 ++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 4a5863b79de..fa053151fa9 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -421,6 +421,16 @@ static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) const struct kernfs_ops *ops; int rc; + /* + * mmap path and of->mutex are prone to triggering spurious lockdep + * warnings and we don't want to add spurious locking dependency + * between the two. Check whether mmap is actually implemented + * without grabbing @of->mutex by testing HAS_MMAP flag. See the + * comment in kernfs_file_open() for more details. + */ + if (!(of->sd->s_flags & SYSFS_FLAG_HAS_MMAP)) + return -ENODEV; + mutex_lock(&of->mutex); rc = -ENODEV; @@ -428,10 +438,7 @@ static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) goto out_unlock; ops = kernfs_ops(of->sd); - if (ops->mmap) - rc = ops->mmap(of, vma); - if (rc) - goto out_put; + rc = ops->mmap(of, vma); /* * PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup() @@ -596,6 +603,9 @@ static int kernfs_file_open(struct inode *inode, struct file *file) * happen on the same file. At this point, we can't easily give * each file a separate locking class. Let's differentiate on * whether the file has mmap or not for now. + * + * Both paths of the branch look the same. They're supposed to + * look that way and give @of->mutex different static lockdep keys. */ if (has_mmap) mutex_init(&of->mutex); diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index ac77d2be3c3..a67d1c682fe 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -142,9 +142,6 @@ static int sysfs_kf_bin_mmap(struct sysfs_open_file *of, struct bin_attribute *battr = of->sd->priv; struct kobject *kobj = of->sd->s_parent->priv; - if (!battr->mmap) - return -ENODEV; - return battr->mmap(of->file, kobj, battr, vma); } @@ -197,6 +194,11 @@ static const struct kernfs_ops sysfs_bin_kfops_wo = { static const struct kernfs_ops sysfs_bin_kfops_rw = { .read = sysfs_kf_bin_read, .write = sysfs_kf_bin_write, +}; + +static const struct kernfs_ops sysfs_bin_kfops_mmap = { + .read = sysfs_kf_bin_read, + .write = sysfs_kf_bin_write, .mmap = sysfs_kf_bin_mmap, }; @@ -232,7 +234,9 @@ int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd, } else { struct bin_attribute *battr = (void *)attr; - if ((battr->read && battr->write) || battr->mmap) + if (battr->mmap) + ops = &sysfs_bin_kfops_mmap; + else if (battr->read && battr->write) ops = &sysfs_bin_kfops_rw; else if (battr->read) ops = &sysfs_bin_kfops_ro; -- cgit v1.2.3-70-g09d2 From 324a56e16e44baecac3ca799fd216154145c14bf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 14:11:53 -0500 Subject: kernfs: s/sysfs_dirent/kernfs_node/ and rename its friends accordingly kernfs has just been separated out from sysfs and we're already in full conflict mode. Nothing can make the situation any worse. Let's take the chance to name things properly. This patch performs the following renames. * s/sysfs_elem_dir/kernfs_elem_dir/ * s/sysfs_elem_symlink/kernfs_elem_symlink/ * s/sysfs_elem_attr/kernfs_elem_file/ * s/sysfs_dirent/kernfs_node/ * s/sd/kn/ in kernfs proper * s/parent_sd/parent/ * s/target_sd/target/ * s/dir_sd/parent/ * s/to_sysfs_dirent()/rb_to_kn()/ * misc renames of local vars when they conflict with the above Because md, mic and gpio dig into sysfs details, this patch ends up modifying them. All are sysfs_dirent renames and trivial. While we can avoid these by introducing a dummy wrapping struct sysfs_dirent around kernfs_node, given the limited usage outside kernfs and sysfs proper, I don't think such workaround is called for. This patch is strictly rename only and doesn't introduce any functional difference. - mic / gpio renames were missing. Spotted by kbuild test robot. Signed-off-by: Tejun Heo Cc: Neil Brown Cc: Linus Walleij Cc: Ashutosh Dixit Cc: kbuild test robot Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpiolib.c | 4 +- drivers/md/bitmap.c | 2 +- drivers/md/bitmap.h | 2 +- drivers/md/md.h | 10 +- drivers/misc/mic/host/mic_device.h | 2 +- fs/kernfs/dir.c | 542 ++++++++++++++++++------------------- fs/kernfs/file.c | 186 ++++++------- fs/kernfs/inode.c | 123 ++++----- fs/kernfs/kernfs-internal.h | 40 +-- fs/kernfs/mount.c | 12 +- fs/kernfs/symlink.c | 64 ++--- fs/sysfs/dir.c | 66 ++--- fs/sysfs/file.c | 122 ++++----- fs/sysfs/group.c | 96 +++---- fs/sysfs/mount.c | 4 +- fs/sysfs/symlink.c | 72 ++--- fs/sysfs/sysfs.h | 10 +- include/linux/kernfs.h | 166 ++++++------ include/linux/kobject.h | 2 +- include/linux/sysfs.h | 20 +- lib/kobject.c | 2 +- 21 files changed, 774 insertions(+), 773 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 85f772c0b26..c8a7c810bad 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -393,7 +393,7 @@ static const DEVICE_ATTR(value, 0644, static irqreturn_t gpio_sysfs_irq(int irq, void *priv) { - struct sysfs_dirent *value_sd = priv; + struct kernfs_node *value_sd = priv; sysfs_notify_dirent(value_sd); return IRQ_HANDLED; @@ -402,7 +402,7 @@ static irqreturn_t gpio_sysfs_irq(int irq, void *priv) static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, unsigned long gpio_flags) { - struct sysfs_dirent *value_sd; + struct kernfs_node *value_sd; unsigned long irq_flags; int ret, irq, id; diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 12dc29ba739..4195a01b153 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1635,7 +1635,7 @@ int bitmap_create(struct mddev *mddev) sector_t blocks = mddev->resync_max_sectors; struct file *file = mddev->bitmap_info.file; int err; - struct sysfs_dirent *bm = NULL; + struct kernfs_node *bm = NULL; BUILD_BUG_ON(sizeof(bitmap_super_t) != 256); diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index df4aeb6ac6f..30210b9c4ef 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h @@ -225,7 +225,7 @@ struct bitmap { wait_queue_head_t overflow_wait; wait_queue_head_t behind_wait; - struct sysfs_dirent *sysfs_can_clear; + struct kernfs_node *sysfs_can_clear; }; /* the bitmap API */ diff --git a/drivers/md/md.h b/drivers/md/md.h index 2f5cc8a7ef3..389a3c93cdb 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -106,7 +106,7 @@ struct md_rdev { */ struct work_struct del_work; /* used for delayed sysfs removal */ - struct sysfs_dirent *sysfs_state; /* handle for 'state' + struct kernfs_node *sysfs_state; /* handle for 'state' * sysfs entry */ struct badblocks { @@ -376,10 +376,10 @@ struct mddev { sector_t resync_max; /* resync should pause * when it gets here */ - struct sysfs_dirent *sysfs_state; /* handle for 'array_state' + struct kernfs_node *sysfs_state; /* handle for 'array_state' * file in sysfs. */ - struct sysfs_dirent *sysfs_action; /* handle for 'sync_action' */ + struct kernfs_node *sysfs_action; /* handle for 'sync_action' */ struct work_struct del_work; /* used for delayed sysfs removal */ @@ -498,13 +498,13 @@ struct md_sysfs_entry { }; extern struct attribute_group md_bitmap_group; -static inline struct sysfs_dirent *sysfs_get_dirent_safe(struct sysfs_dirent *sd, char *name) +static inline struct kernfs_node *sysfs_get_dirent_safe(struct kernfs_node *sd, char *name) { if (sd) return sysfs_get_dirent(sd, name); return sd; } -static inline void sysfs_notify_dirent_safe(struct sysfs_dirent *sd) +static inline void sysfs_notify_dirent_safe(struct kernfs_node *sd) { if (sd) sysfs_notify_dirent(sd); diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h index 3574cc375bb..538e3d3d3c8 100644 --- a/drivers/misc/mic/host/mic_device.h +++ b/drivers/misc/mic/host/mic_device.h @@ -112,7 +112,7 @@ struct mic_device { struct work_struct shutdown_work; u8 state; u8 shutdown_status; - struct sysfs_dirent *state_sysfs; + struct kernfs_node *state_sysfs; struct completion reset_wait; void *log_buf_addr; int *log_buf_len; diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index a441e3be805..800ebf52147 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -19,7 +19,7 @@ DEFINE_MUTEX(sysfs_mutex); -#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb) +#define rb_to_kn(X) rb_entry((X), struct kernfs_node, s_rb) /** * sysfs_name_hash @@ -45,28 +45,28 @@ static unsigned int sysfs_name_hash(const char *name, const void *ns) } static int sysfs_name_compare(unsigned int hash, const char *name, - const void *ns, const struct sysfs_dirent *sd) + const void *ns, const struct kernfs_node *kn) { - if (hash != sd->s_hash) - return hash - sd->s_hash; - if (ns != sd->s_ns) - return ns - sd->s_ns; - return strcmp(name, sd->s_name); + if (hash != kn->s_hash) + return hash - kn->s_hash; + if (ns != kn->s_ns) + return ns - kn->s_ns; + return strcmp(name, kn->s_name); } -static int sysfs_sd_compare(const struct sysfs_dirent *left, - const struct sysfs_dirent *right) +static int sysfs_sd_compare(const struct kernfs_node *left, + const struct kernfs_node *right) { return sysfs_name_compare(left->s_hash, left->s_name, left->s_ns, right); } /** - * sysfs_link_sibling - link sysfs_dirent into sibling rbtree - * @sd: sysfs_dirent of interest + * sysfs_link_sibling - link kernfs_node into sibling rbtree + * @kn: kernfs_node of interest * - * Link @sd into its sibling rbtree which starts from - * sd->s_parent->s_dir.children. + * Link @kn into its sibling rbtree which starts from + * @kn->s_parent->s_dir.children. * * Locking: * mutex_lock(sysfs_mutex) @@ -74,21 +74,21 @@ static int sysfs_sd_compare(const struct sysfs_dirent *left, * RETURNS: * 0 on susccess -EEXIST on failure. */ -static int sysfs_link_sibling(struct sysfs_dirent *sd) +static int sysfs_link_sibling(struct kernfs_node *kn) { - struct rb_node **node = &sd->s_parent->s_dir.children.rb_node; + struct rb_node **node = &kn->s_parent->s_dir.children.rb_node; struct rb_node *parent = NULL; - if (sysfs_type(sd) == SYSFS_DIR) - sd->s_parent->s_dir.subdirs++; + if (sysfs_type(kn) == SYSFS_DIR) + kn->s_parent->s_dir.subdirs++; while (*node) { - struct sysfs_dirent *pos; + struct kernfs_node *pos; int result; - pos = to_sysfs_dirent(*node); + pos = rb_to_kn(*node); parent = *node; - result = sysfs_sd_compare(sd, pos); + result = sysfs_sd_compare(kn, pos); if (result < 0) node = &pos->s_rb.rb_left; else if (result > 0) @@ -97,168 +97,169 @@ static int sysfs_link_sibling(struct sysfs_dirent *sd) return -EEXIST; } /* add new node and rebalance the tree */ - rb_link_node(&sd->s_rb, parent, node); - rb_insert_color(&sd->s_rb, &sd->s_parent->s_dir.children); + rb_link_node(&kn->s_rb, parent, node); + rb_insert_color(&kn->s_rb, &kn->s_parent->s_dir.children); return 0; } /** - * sysfs_unlink_sibling - unlink sysfs_dirent from sibling rbtree - * @sd: sysfs_dirent of interest + * sysfs_unlink_sibling - unlink kernfs_node from sibling rbtree + * @kn: kernfs_node of interest * - * Unlink @sd from its sibling rbtree which starts from - * sd->s_parent->s_dir.children. + * Unlink @kn from its sibling rbtree which starts from + * kn->s_parent->s_dir.children. * * Locking: * mutex_lock(sysfs_mutex) */ -static void sysfs_unlink_sibling(struct sysfs_dirent *sd) +static void sysfs_unlink_sibling(struct kernfs_node *kn) { - if (sysfs_type(sd) == SYSFS_DIR) - sd->s_parent->s_dir.subdirs--; + if (sysfs_type(kn) == SYSFS_DIR) + kn->s_parent->s_dir.subdirs--; - rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children); + rb_erase(&kn->s_rb, &kn->s_parent->s_dir.children); } /** - * sysfs_get_active - get an active reference to sysfs_dirent - * @sd: sysfs_dirent to get an active reference to + * sysfs_get_active - get an active reference to kernfs_node + * @kn: kernfs_node to get an active reference to * - * Get an active reference of @sd. This function is noop if @sd + * Get an active reference of @kn. This function is noop if @kn * is NULL. * * RETURNS: - * Pointer to @sd on success, NULL on failure. + * Pointer to @kn on success, NULL on failure. */ -struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) +struct kernfs_node *sysfs_get_active(struct kernfs_node *kn) { - if (unlikely(!sd)) + if (unlikely(!kn)) return NULL; - if (!atomic_inc_unless_negative(&sd->s_active)) + if (!atomic_inc_unless_negative(&kn->s_active)) return NULL; - if (sd->s_flags & SYSFS_FLAG_LOCKDEP) - rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); - return sd; + if (kn->s_flags & SYSFS_FLAG_LOCKDEP) + rwsem_acquire_read(&kn->dep_map, 0, 1, _RET_IP_); + return kn; } /** - * sysfs_put_active - put an active reference to sysfs_dirent - * @sd: sysfs_dirent to put an active reference to + * sysfs_put_active - put an active reference to kernfs_node + * @kn: kernfs_node to put an active reference to * - * Put an active reference to @sd. This function is noop if @sd + * Put an active reference to @kn. This function is noop if @kn * is NULL. */ -void sysfs_put_active(struct sysfs_dirent *sd) +void sysfs_put_active(struct kernfs_node *kn) { int v; - if (unlikely(!sd)) + if (unlikely(!kn)) return; - if (sd->s_flags & SYSFS_FLAG_LOCKDEP) - rwsem_release(&sd->dep_map, 1, _RET_IP_); - v = atomic_dec_return(&sd->s_active); + if (kn->s_flags & SYSFS_FLAG_LOCKDEP) + rwsem_release(&kn->dep_map, 1, _RET_IP_); + v = atomic_dec_return(&kn->s_active); if (likely(v != SD_DEACTIVATED_BIAS)) return; - /* atomic_dec_return() is a mb(), we'll always see the updated - * sd->u.completion. + /* + * atomic_dec_return() is a mb(), we'll always see the updated + * kn->u.completion. */ - complete(sd->u.completion); + complete(kn->u.completion); } /** - * sysfs_deactivate - deactivate sysfs_dirent - * @sd: sysfs_dirent to deactivate + * sysfs_deactivate - deactivate kernfs_node + * @kn: kernfs_node to deactivate * * Deny new active references and drain existing ones. */ -static void sysfs_deactivate(struct sysfs_dirent *sd) +static void sysfs_deactivate(struct kernfs_node *kn) { DECLARE_COMPLETION_ONSTACK(wait); int v; - BUG_ON(!(sd->s_flags & SYSFS_FLAG_REMOVED)); + BUG_ON(!(kn->s_flags & SYSFS_FLAG_REMOVED)); - if (!(sysfs_type(sd) & SYSFS_ACTIVE_REF)) + if (!(sysfs_type(kn) & SYSFS_ACTIVE_REF)) return; - sd->u.completion = (void *)&wait; + kn->u.completion = (void *)&wait; - rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_); + rwsem_acquire(&kn->dep_map, 0, 0, _RET_IP_); /* atomic_add_return() is a mb(), put_active() will always see - * the updated sd->u.completion. + * the updated kn->u.completion. */ - v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active); + v = atomic_add_return(SD_DEACTIVATED_BIAS, &kn->s_active); if (v != SD_DEACTIVATED_BIAS) { - lock_contended(&sd->dep_map, _RET_IP_); + lock_contended(&kn->dep_map, _RET_IP_); wait_for_completion(&wait); } - lock_acquired(&sd->dep_map, _RET_IP_); - rwsem_release(&sd->dep_map, 1, _RET_IP_); + lock_acquired(&kn->dep_map, _RET_IP_); + rwsem_release(&kn->dep_map, 1, _RET_IP_); } /** - * kernfs_get - get a reference count on a sysfs_dirent - * @sd: the target sysfs_dirent + * kernfs_get - get a reference count on a kernfs_node + * @kn: the target kernfs_node */ -void kernfs_get(struct sysfs_dirent *sd) +void kernfs_get(struct kernfs_node *kn) { - if (sd) { - WARN_ON(!atomic_read(&sd->s_count)); - atomic_inc(&sd->s_count); + if (kn) { + WARN_ON(!atomic_read(&kn->s_count)); + atomic_inc(&kn->s_count); } } EXPORT_SYMBOL_GPL(kernfs_get); /** - * kernfs_put - put a reference count on a sysfs_dirent - * @sd: the target sysfs_dirent + * kernfs_put - put a reference count on a kernfs_node + * @kn: the target kernfs_node * - * Put a reference count of @sd and destroy it if it reached zero. + * Put a reference count of @kn and destroy it if it reached zero. */ -void kernfs_put(struct sysfs_dirent *sd) +void kernfs_put(struct kernfs_node *kn) { - struct sysfs_dirent *parent_sd; + struct kernfs_node *parent; struct kernfs_root *root; - if (!sd || !atomic_dec_and_test(&sd->s_count)) + if (!kn || !atomic_dec_and_test(&kn->s_count)) return; - root = kernfs_root(sd); + root = kernfs_root(kn); repeat: /* Moving/renaming is always done while holding reference. - * sd->s_parent won't change beneath us. + * kn->s_parent won't change beneath us. */ - parent_sd = sd->s_parent; + parent = kn->s_parent; - WARN(!(sd->s_flags & SYSFS_FLAG_REMOVED), + WARN(!(kn->s_flags & SYSFS_FLAG_REMOVED), "sysfs: free using entry: %s/%s\n", - parent_sd ? parent_sd->s_name : "", sd->s_name); - - if (sysfs_type(sd) == SYSFS_KOBJ_LINK) - kernfs_put(sd->s_symlink.target_sd); - if (sysfs_type(sd) & SYSFS_COPY_NAME) - kfree(sd->s_name); - if (sd->s_iattr) { - if (sd->s_iattr->ia_secdata) - security_release_secctx(sd->s_iattr->ia_secdata, - sd->s_iattr->ia_secdata_len); - simple_xattrs_free(&sd->s_iattr->xattrs); + parent ? parent->s_name : "", kn->s_name); + + if (sysfs_type(kn) == SYSFS_KOBJ_LINK) + kernfs_put(kn->s_symlink.target_kn); + if (sysfs_type(kn) & SYSFS_COPY_NAME) + kfree(kn->s_name); + if (kn->s_iattr) { + if (kn->s_iattr->ia_secdata) + security_release_secctx(kn->s_iattr->ia_secdata, + kn->s_iattr->ia_secdata_len); + simple_xattrs_free(&kn->s_iattr->xattrs); } - kfree(sd->s_iattr); - ida_simple_remove(&root->ino_ida, sd->s_ino); - kmem_cache_free(sysfs_dir_cachep, sd); + kfree(kn->s_iattr); + ida_simple_remove(&root->ino_ida, kn->s_ino); + kmem_cache_free(sysfs_dir_cachep, kn); - sd = parent_sd; - if (sd) { - if (atomic_dec_and_test(&sd->s_count)) + kn = parent; + if (kn) { + if (atomic_dec_and_test(&kn->s_count)) goto repeat; } else { - /* just released the root sd, free @root too */ + /* just released the root kn, free @root too */ ida_destroy(&root->ino_ida); kfree(root); } @@ -267,35 +268,35 @@ EXPORT_SYMBOL_GPL(kernfs_put); static int sysfs_dentry_delete(const struct dentry *dentry) { - struct sysfs_dirent *sd = dentry->d_fsdata; - return !(sd && !(sd->s_flags & SYSFS_FLAG_REMOVED)); + struct kernfs_node *kn = dentry->d_fsdata; + return !(kn && !(kn->s_flags & SYSFS_FLAG_REMOVED)); } static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) { - struct sysfs_dirent *sd; + struct kernfs_node *kn; if (flags & LOOKUP_RCU) return -ECHILD; - sd = dentry->d_fsdata; + kn = dentry->d_fsdata; mutex_lock(&sysfs_mutex); /* The sysfs dirent has been deleted */ - if (sd->s_flags & SYSFS_FLAG_REMOVED) + if (kn->s_flags & SYSFS_FLAG_REMOVED) goto out_bad; /* The sysfs dirent has been moved? */ - if (dentry->d_parent->d_fsdata != sd->s_parent) + if (dentry->d_parent->d_fsdata != kn->s_parent) goto out_bad; /* The sysfs dirent has been renamed */ - if (strcmp(dentry->d_name.name, sd->s_name) != 0) + if (strcmp(dentry->d_name.name, kn->s_name) != 0) goto out_bad; /* The sysfs dirent has been moved to a different namespace */ - if (sd->s_parent && kernfs_ns_enabled(sd->s_parent) && - sysfs_info(dentry->d_sb)->ns != sd->s_ns) + if (kn->s_parent && kernfs_ns_enabled(kn->s_parent) && + sysfs_info(dentry->d_sb)->ns != kn->s_ns) goto out_bad; mutex_unlock(&sysfs_mutex); @@ -335,11 +336,11 @@ const struct dentry_operations sysfs_dentry_ops = { .d_release = sysfs_dentry_release, }; -struct sysfs_dirent *sysfs_new_dirent(struct kernfs_root *root, - const char *name, umode_t mode, int type) +struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, + const char *name, umode_t mode, int type) { char *dup_name = NULL; - struct sysfs_dirent *sd; + struct kernfs_node *kn; int ret; if (type & SYSFS_COPY_NAME) { @@ -348,38 +349,38 @@ struct sysfs_dirent *sysfs_new_dirent(struct kernfs_root *root, return NULL; } - sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL); - if (!sd) + kn = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL); + if (!kn) goto err_out1; ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL); if (ret < 0) goto err_out2; - sd->s_ino = ret; + kn->s_ino = ret; - atomic_set(&sd->s_count, 1); - atomic_set(&sd->s_active, 0); + atomic_set(&kn->s_count, 1); + atomic_set(&kn->s_active, 0); - sd->s_name = name; - sd->s_mode = mode; - sd->s_flags = type | SYSFS_FLAG_REMOVED; + kn->s_name = name; + kn->s_mode = mode; + kn->s_flags = type | SYSFS_FLAG_REMOVED; - return sd; + return kn; err_out2: - kmem_cache_free(sysfs_dir_cachep, sd); + kmem_cache_free(sysfs_dir_cachep, kn); err_out1: kfree(dup_name); return NULL; } /** - * sysfs_addrm_start - prepare for sysfs_dirent add/remove + * sysfs_addrm_start - prepare for kernfs_node add/remove * @acxt: pointer to sysfs_addrm_cxt to be used * * This function is called when the caller is about to add or remove - * sysfs_dirent. This function acquires sysfs_mutex. @acxt is used - * to keep and pass context to other addrm functions. + * kernfs_node. This function acquires sysfs_mutex. @acxt is used to + * keep and pass context to other addrm functions. * * LOCKING: * Kernel thread context (may sleep). sysfs_mutex is locked on @@ -394,13 +395,13 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt) } /** - * sysfs_add_one - add sysfs_dirent to parent without warning + * sysfs_add_one - add kernfs_node to parent without warning * @acxt: addrm context to use - * @sd: sysfs_dirent to be added - * @parent_sd: the parent sysfs_dirent to add @sd to + * @kn: kernfs_node to be added + * @parent: the parent kernfs_node to add @kn to * - * Get @parent_sd and set @sd->s_parent to it and increment nlink of - * the parent inode if @sd is a directory and link into the children + * Get @parent and set @kn->s_parent to it and increment nlink of + * the parent inode if @kn is a directory and link into the children * list of the parent. * * This function should be called between calls to @@ -414,51 +415,51 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt) * 0 on success, -EEXIST if entry with the given name already * exists. */ -int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd, - struct sysfs_dirent *parent_sd) +int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct kernfs_node *kn, + struct kernfs_node *parent) { - bool has_ns = kernfs_ns_enabled(parent_sd); + bool has_ns = kernfs_ns_enabled(parent); struct sysfs_inode_attrs *ps_iattr; int ret; - if (has_ns != (bool)sd->s_ns) { + if (has_ns != (bool)kn->s_ns) { WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", has_ns ? "required" : "invalid", - parent_sd->s_name, sd->s_name); + parent->s_name, kn->s_name); return -EINVAL; } - if (sysfs_type(parent_sd) != SYSFS_DIR) + if (sysfs_type(parent) != SYSFS_DIR) return -EINVAL; - sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns); - sd->s_parent = parent_sd; - kernfs_get(parent_sd); + kn->s_hash = sysfs_name_hash(kn->s_name, kn->s_ns); + kn->s_parent = parent; + kernfs_get(parent); - ret = sysfs_link_sibling(sd); + ret = sysfs_link_sibling(kn); if (ret) return ret; /* Update timestamps on the parent */ - ps_iattr = parent_sd->s_iattr; + ps_iattr = parent->s_iattr; if (ps_iattr) { struct iattr *ps_iattrs = &ps_iattr->ia_iattr; ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; } /* Mark the entry added into directory tree */ - sd->s_flags &= ~SYSFS_FLAG_REMOVED; + kn->s_flags &= ~SYSFS_FLAG_REMOVED; return 0; } /** - * sysfs_remove_one - remove sysfs_dirent from parent + * sysfs_remove_one - remove kernfs_node from parent * @acxt: addrm context to use - * @sd: sysfs_dirent to be removed + * @kn: kernfs_node to be removed * - * Mark @sd removed and drop nlink of parent inode if @sd is a - * directory. @sd is unlinked from the children list. + * Mark @kn removed and drop nlink of parent inode if @kn is a + * directory. @kn is unlinked from the children list. * * This function should be called between calls to * sysfs_addrm_start() and sysfs_addrm_finish() and should be @@ -468,7 +469,7 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd, * Determined by sysfs_addrm_start(). */ static void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, - struct sysfs_dirent *sd) + struct kernfs_node *kn) { struct sysfs_inode_attrs *ps_iattr; @@ -476,31 +477,31 @@ static void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, * Removal can be called multiple times on the same node. Only the * first invocation is effective and puts the base ref. */ - if (sd->s_flags & SYSFS_FLAG_REMOVED) + if (kn->s_flags & SYSFS_FLAG_REMOVED) return; - if (sd->s_parent) { - sysfs_unlink_sibling(sd); + if (kn->s_parent) { + sysfs_unlink_sibling(kn); /* Update timestamps on the parent */ - ps_iattr = sd->s_parent->s_iattr; + ps_iattr = kn->s_parent->s_iattr; if (ps_iattr) { ps_iattr->ia_iattr.ia_ctime = CURRENT_TIME; ps_iattr->ia_iattr.ia_mtime = CURRENT_TIME; } } - sd->s_flags |= SYSFS_FLAG_REMOVED; - sd->u.removed_list = acxt->removed; - acxt->removed = sd; + kn->s_flags |= SYSFS_FLAG_REMOVED; + kn->u.removed_list = acxt->removed; + acxt->removed = kn; } /** - * sysfs_addrm_finish - finish up sysfs_dirent add/remove + * sysfs_addrm_finish - finish up kernfs_node add/remove * @acxt: addrm context to finish up * - * Finish up sysfs_dirent add/remove. Resources acquired by - * sysfs_addrm_start() are released and removed sysfs_dirents are + * Finish up kernfs_node add/remove. Resources acquired by + * sysfs_addrm_start() are released and removed kernfs_nodes are * cleaned up. * * LOCKING: @@ -512,30 +513,30 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt) /* release resources acquired by sysfs_addrm_start() */ mutex_unlock(&sysfs_mutex); - /* kill removed sysfs_dirents */ + /* kill removed kernfs_nodes */ while (acxt->removed) { - struct sysfs_dirent *sd = acxt->removed; + struct kernfs_node *kn = acxt->removed; - acxt->removed = sd->u.removed_list; + acxt->removed = kn->u.removed_list; - sysfs_deactivate(sd); - sysfs_unmap_bin_file(sd); - kernfs_put(sd); + sysfs_deactivate(kn); + sysfs_unmap_bin_file(kn); + kernfs_put(kn); } } /** - * kernfs_find_ns - find sysfs_dirent with the given name - * @parent: sysfs_dirent to search under + * kernfs_find_ns - find kernfs_node with the given name + * @parent: kernfs_node to search under * @name: name to look for * @ns: the namespace tag to use * - * Look for sysfs_dirent with name @name under @parent. Returns pointer to - * the found sysfs_dirent on success, %NULL on failure. + * Look for kernfs_node with name @name under @parent. Returns pointer to + * the found kernfs_node on success, %NULL on failure. */ -static struct sysfs_dirent *kernfs_find_ns(struct sysfs_dirent *parent, - const unsigned char *name, - const void *ns) +static struct kernfs_node *kernfs_find_ns(struct kernfs_node *parent, + const unsigned char *name, + const void *ns) { struct rb_node *node = parent->s_dir.children.rb_node; bool has_ns = kernfs_ns_enabled(parent); @@ -552,42 +553,42 @@ static struct sysfs_dirent *kernfs_find_ns(struct sysfs_dirent *parent, hash = sysfs_name_hash(name, ns); while (node) { - struct sysfs_dirent *sd; + struct kernfs_node *kn; int result; - sd = to_sysfs_dirent(node); - result = sysfs_name_compare(hash, name, ns, sd); + kn = rb_to_kn(node); + result = sysfs_name_compare(hash, name, ns, kn); if (result < 0) node = node->rb_left; else if (result > 0) node = node->rb_right; else - return sd; + return kn; } return NULL; } /** - * kernfs_find_and_get_ns - find and get sysfs_dirent with the given name - * @parent: sysfs_dirent to search under + * kernfs_find_and_get_ns - find and get kernfs_node with the given name + * @parent: kernfs_node to search under * @name: name to look for * @ns: the namespace tag to use * - * Look for sysfs_dirent with name @name under @parent and get a reference + * Look for kernfs_node with name @name under @parent and get a reference * if found. This function may sleep and returns pointer to the found - * sysfs_dirent on success, %NULL on failure. + * kernfs_node on success, %NULL on failure. */ -struct sysfs_dirent *kernfs_find_and_get_ns(struct sysfs_dirent *parent, - const char *name, const void *ns) +struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent, + const char *name, const void *ns) { - struct sysfs_dirent *sd; + struct kernfs_node *kn; mutex_lock(&sysfs_mutex); - sd = kernfs_find_ns(parent, name, ns); - kernfs_get(sd); + kn = kernfs_find_ns(parent, name, ns); + kernfs_get(kn); mutex_unlock(&sysfs_mutex); - return sd; + return kn; } EXPORT_SYMBOL_GPL(kernfs_find_and_get_ns); @@ -601,7 +602,7 @@ EXPORT_SYMBOL_GPL(kernfs_find_and_get_ns); struct kernfs_root *kernfs_create_root(void *priv) { struct kernfs_root *root; - struct sysfs_dirent *sd; + struct kernfs_node *kn; root = kzalloc(sizeof(*root), GFP_KERNEL); if (!root) @@ -609,18 +610,18 @@ struct kernfs_root *kernfs_create_root(void *priv) ida_init(&root->ino_ida); - sd = sysfs_new_dirent(root, "", S_IFDIR | S_IRUGO | S_IXUGO, SYSFS_DIR); - if (!sd) { + kn = sysfs_new_dirent(root, "", S_IFDIR | S_IRUGO | S_IXUGO, SYSFS_DIR); + if (!kn) { ida_destroy(&root->ino_ida); kfree(root); return ERR_PTR(-ENOMEM); } - sd->s_flags &= ~SYSFS_FLAG_REMOVED; - sd->priv = priv; - sd->s_dir.root = root; + kn->s_flags &= ~SYSFS_FLAG_REMOVED; + kn->priv = priv; + kn->s_dir.root = root; - root->sd = sd; + root->kn = kn; return root; } @@ -634,7 +635,7 @@ struct kernfs_root *kernfs_create_root(void *priv) */ void kernfs_destroy_root(struct kernfs_root *root) { - kernfs_remove(root->sd); /* will also free @root */ + kernfs_remove(root->kn); /* will also free @root */ } /** @@ -646,33 +647,33 @@ void kernfs_destroy_root(struct kernfs_root *root) * * Returns the created node on success, ERR_PTR() value on failure. */ -struct sysfs_dirent *kernfs_create_dir_ns(struct sysfs_dirent *parent, - const char *name, void *priv, - const void *ns) +struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, + const char *name, void *priv, + const void *ns) { umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; struct sysfs_addrm_cxt acxt; - struct sysfs_dirent *sd; + struct kernfs_node *kn; int rc; /* allocate */ - sd = sysfs_new_dirent(kernfs_root(parent), name, mode, SYSFS_DIR); - if (!sd) + kn = sysfs_new_dirent(kernfs_root(parent), name, mode, SYSFS_DIR); + if (!kn) return ERR_PTR(-ENOMEM); - sd->s_dir.root = parent->s_dir.root; - sd->s_ns = ns; - sd->priv = priv; + kn->s_dir.root = parent->s_dir.root; + kn->s_ns = ns; + kn->priv = priv; /* link in */ sysfs_addrm_start(&acxt); - rc = sysfs_add_one(&acxt, sd, parent); + rc = sysfs_add_one(&acxt, kn, parent); sysfs_addrm_finish(&acxt); if (!rc) - return sd; + return kn; - kernfs_put(sd); + kernfs_put(kn); return ERR_PTR(rc); } @@ -680,29 +681,28 @@ static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { struct dentry *ret = NULL; - struct dentry *parent = dentry->d_parent; - struct sysfs_dirent *parent_sd = parent->d_fsdata; - struct sysfs_dirent *sd; + struct kernfs_node *parent = dentry->d_parent->d_fsdata; + struct kernfs_node *kn; struct inode *inode; const void *ns = NULL; mutex_lock(&sysfs_mutex); - if (kernfs_ns_enabled(parent_sd)) + if (kernfs_ns_enabled(parent)) ns = sysfs_info(dir->i_sb)->ns; - sd = kernfs_find_ns(parent_sd, dentry->d_name.name, ns); + kn = kernfs_find_ns(parent, dentry->d_name.name, ns); /* no such entry */ - if (!sd) { + if (!kn) { ret = ERR_PTR(-ENOENT); goto out_unlock; } - kernfs_get(sd); - dentry->d_fsdata = sd; + kernfs_get(kn); + dentry->d_fsdata = kn; /* attach dentry and inode */ - inode = sysfs_get_inode(dir->i_sb, sd); + inode = sysfs_get_inode(dir->i_sb, kn); if (!inode) { ret = ERR_PTR(-ENOMEM); goto out_unlock; @@ -726,9 +726,9 @@ const struct inode_operations sysfs_dir_inode_operations = { .listxattr = sysfs_listxattr, }; -static struct sysfs_dirent *sysfs_leftmost_descendant(struct sysfs_dirent *pos) +static struct kernfs_node *sysfs_leftmost_descendant(struct kernfs_node *pos) { - struct sysfs_dirent *last; + struct kernfs_node *last; while (true) { struct rb_node *rbn; @@ -742,7 +742,7 @@ static struct sysfs_dirent *sysfs_leftmost_descendant(struct sysfs_dirent *pos) if (!rbn) break; - pos = to_sysfs_dirent(rbn); + pos = rb_to_kn(rbn); } return last; @@ -751,14 +751,14 @@ static struct sysfs_dirent *sysfs_leftmost_descendant(struct sysfs_dirent *pos) /** * sysfs_next_descendant_post - find the next descendant for post-order walk * @pos: the current position (%NULL to initiate traversal) - * @root: sysfs_dirent whose descendants to walk + * @root: kernfs_node whose descendants to walk * * Find the next descendant to visit for post-order traversal of @root's * descendants. @root is included in the iteration and the last node to be * visited. */ -static struct sysfs_dirent *sysfs_next_descendant_post(struct sysfs_dirent *pos, - struct sysfs_dirent *root) +static struct kernfs_node *sysfs_next_descendant_post(struct kernfs_node *pos, + struct kernfs_node *root) { struct rb_node *rbn; @@ -775,62 +775,62 @@ static struct sysfs_dirent *sysfs_next_descendant_post(struct sysfs_dirent *pos, /* if there's an unvisited sibling, visit its leftmost descendant */ rbn = rb_next(&pos->s_rb); if (rbn) - return sysfs_leftmost_descendant(to_sysfs_dirent(rbn)); + return sysfs_leftmost_descendant(rb_to_kn(rbn)); /* no sibling left, visit parent */ return pos->s_parent; } static void __kernfs_remove(struct sysfs_addrm_cxt *acxt, - struct sysfs_dirent *sd) + struct kernfs_node *kn) { - struct sysfs_dirent *pos, *next; + struct kernfs_node *pos, *next; - if (!sd) + if (!kn) return; - pr_debug("sysfs %s: removing\n", sd->s_name); + pr_debug("sysfs %s: removing\n", kn->s_name); next = NULL; do { pos = next; - next = sysfs_next_descendant_post(pos, sd); + next = sysfs_next_descendant_post(pos, kn); if (pos) sysfs_remove_one(acxt, pos); } while (next); } /** - * kernfs_remove - remove a sysfs_dirent recursively - * @sd: the sysfs_dirent to remove + * kernfs_remove - remove a kernfs_node recursively + * @kn: the kernfs_node to remove * - * Remove @sd along with all its subdirectories and files. + * Remove @kn along with all its subdirectories and files. */ -void kernfs_remove(struct sysfs_dirent *sd) +void kernfs_remove(struct kernfs_node *kn) { struct sysfs_addrm_cxt acxt; sysfs_addrm_start(&acxt); - __kernfs_remove(&acxt, sd); + __kernfs_remove(&acxt, kn); sysfs_addrm_finish(&acxt); } /** - * kernfs_remove_by_name_ns - find a sysfs_dirent by name and remove it - * @dir_sd: parent of the target - * @name: name of the sysfs_dirent to remove - * @ns: namespace tag of the sysfs_dirent to remove + * kernfs_remove_by_name_ns - find a kernfs_node by name and remove it + * @parent: parent of the target + * @name: name of the kernfs_node to remove + * @ns: namespace tag of the kernfs_node to remove * - * Look for the sysfs_dirent with @name and @ns under @dir_sd and remove - * it. Returns 0 on success, -ENOENT if such entry doesn't exist. + * Look for the kernfs_node with @name and @ns under @parent and remove it. + * Returns 0 on success, -ENOENT if such entry doesn't exist. */ -int kernfs_remove_by_name_ns(struct sysfs_dirent *dir_sd, const char *name, +int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, const void *ns) { struct sysfs_addrm_cxt acxt; - struct sysfs_dirent *sd; + struct kernfs_node *kn; - if (!dir_sd) { + if (!parent) { WARN(1, KERN_WARNING "sysfs: can not remove '%s', no directory\n", name); return -ENOENT; @@ -838,13 +838,13 @@ int kernfs_remove_by_name_ns(struct sysfs_dirent *dir_sd, const char *name, sysfs_addrm_start(&acxt); - sd = kernfs_find_ns(dir_sd, name, ns); - if (sd) - __kernfs_remove(&acxt, sd); + kn = kernfs_find_ns(parent, name, ns); + if (kn) + __kernfs_remove(&acxt, kn); sysfs_addrm_finish(&acxt); - if (sd) + if (kn) return 0; else return -ENOENT; @@ -852,12 +852,12 @@ int kernfs_remove_by_name_ns(struct sysfs_dirent *dir_sd, const char *name, /** * kernfs_rename_ns - move and rename a kernfs_node - * @sd: target node + * @kn: target node * @new_parent: new parent to put @sd under * @new_name: new name * @new_ns: new namespace tag */ -int kernfs_rename_ns(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent, +int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, const char *new_name, const void *new_ns) { int error; @@ -865,35 +865,35 @@ int kernfs_rename_ns(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent, mutex_lock(&sysfs_mutex); error = 0; - if ((sd->s_parent == new_parent) && (sd->s_ns == new_ns) && - (strcmp(sd->s_name, new_name) == 0)) + if ((kn->s_parent == new_parent) && (kn->s_ns == new_ns) && + (strcmp(kn->s_name, new_name) == 0)) goto out; /* nothing to rename */ error = -EEXIST; if (kernfs_find_ns(new_parent, new_name, new_ns)) goto out; - /* rename sysfs_dirent */ - if (strcmp(sd->s_name, new_name) != 0) { + /* rename kernfs_node */ + if (strcmp(kn->s_name, new_name) != 0) { error = -ENOMEM; new_name = kstrdup(new_name, GFP_KERNEL); if (!new_name) goto out; - kfree(sd->s_name); - sd->s_name = new_name; + kfree(kn->s_name); + kn->s_name = new_name; } /* * Move to the appropriate place in the appropriate directories rbtree. */ - sysfs_unlink_sibling(sd); + sysfs_unlink_sibling(kn); kernfs_get(new_parent); - kernfs_put(sd->s_parent); - sd->s_ns = new_ns; - sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns); - sd->s_parent = new_parent; - sysfs_link_sibling(sd); + kernfs_put(kn->s_parent); + kn->s_ns = new_ns; + kn->s_hash = sysfs_name_hash(kn->s_name, kn->s_ns); + kn->s_parent = new_parent; + sysfs_link_sibling(kn); error = 0; out: @@ -902,9 +902,9 @@ int kernfs_rename_ns(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent, } /* Relationship between s_mode and the DT_xxx types */ -static inline unsigned char dt_type(struct sysfs_dirent *sd) +static inline unsigned char dt_type(struct kernfs_node *kn) { - return (sd->s_mode >> 12) & 15; + return (kn->s_mode >> 12) & 15; } static int sysfs_dir_release(struct inode *inode, struct file *filp) @@ -913,21 +913,21 @@ static int sysfs_dir_release(struct inode *inode, struct file *filp) return 0; } -static struct sysfs_dirent *sysfs_dir_pos(const void *ns, - struct sysfs_dirent *parent_sd, loff_t hash, struct sysfs_dirent *pos) +static struct kernfs_node *sysfs_dir_pos(const void *ns, + struct kernfs_node *parent, loff_t hash, struct kernfs_node *pos) { if (pos) { int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) && - pos->s_parent == parent_sd && + pos->s_parent == parent && hash == pos->s_hash; kernfs_put(pos); if (!valid) pos = NULL; } if (!pos && (hash > 1) && (hash < INT_MAX)) { - struct rb_node *node = parent_sd->s_dir.children.rb_node; + struct rb_node *node = parent->s_dir.children.rb_node; while (node) { - pos = to_sysfs_dirent(node); + pos = rb_to_kn(node); if (hash < pos->s_hash) node = node->rb_left; @@ -943,22 +943,22 @@ static struct sysfs_dirent *sysfs_dir_pos(const void *ns, if (!node) pos = NULL; else - pos = to_sysfs_dirent(node); + pos = rb_to_kn(node); } return pos; } -static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns, - struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos) +static struct kernfs_node *sysfs_dir_next_pos(const void *ns, + struct kernfs_node *parent, ino_t ino, struct kernfs_node *pos) { - pos = sysfs_dir_pos(ns, parent_sd, ino, pos); + pos = sysfs_dir_pos(ns, parent, ino, pos); if (pos) do { struct rb_node *node = rb_next(&pos->s_rb); if (!node) pos = NULL; else - pos = to_sysfs_dirent(node); + pos = rb_to_kn(node); } while (pos && pos->s_ns != ns); return pos; } @@ -966,20 +966,20 @@ static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns, static int sysfs_readdir(struct file *file, struct dir_context *ctx) { struct dentry *dentry = file->f_path.dentry; - struct sysfs_dirent *parent_sd = dentry->d_fsdata; - struct sysfs_dirent *pos = file->private_data; + struct kernfs_node *parent = dentry->d_fsdata; + struct kernfs_node *pos = file->private_data; const void *ns = NULL; if (!dir_emit_dots(file, ctx)) return 0; mutex_lock(&sysfs_mutex); - if (kernfs_ns_enabled(parent_sd)) + if (kernfs_ns_enabled(parent)) ns = sysfs_info(dentry->d_sb)->ns; - for (pos = sysfs_dir_pos(ns, parent_sd, ctx->pos, pos); + for (pos = sysfs_dir_pos(ns, parent, ctx->pos, pos); pos; - pos = sysfs_dir_next_pos(ns, parent_sd, ctx->pos, pos)) { + pos = sysfs_dir_next_pos(ns, parent, ctx->pos, pos)) { const char *name = pos->s_name; unsigned int type = dt_type(pos); int len = strlen(name); diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index fa053151fa9..1bf07ded826 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -19,9 +19,9 @@ /* * There's one sysfs_open_file for each open file and one sysfs_open_dirent - * for each sysfs_dirent with one or more open files. + * for each kernfs_node with one or more open files. * - * sysfs_dirent->s_attr.open points to sysfs_open_dirent. s_attr.open is + * kernfs_node->s_attr.open points to sysfs_open_dirent. s_attr.open is * protected by sysfs_open_dirent_lock. * * filp->private_data points to seq_file whose ->private points to @@ -44,14 +44,14 @@ static struct sysfs_open_file *sysfs_of(struct file *file) } /* - * Determine the kernfs_ops for the given sysfs_dirent. This function must + * Determine the kernfs_ops for the given kernfs_node. This function must * be called while holding an active reference. */ -static const struct kernfs_ops *kernfs_ops(struct sysfs_dirent *sd) +static const struct kernfs_ops *kernfs_ops(struct kernfs_node *kn) { - if (sd->s_flags & SYSFS_FLAG_LOCKDEP) - lockdep_assert_held(sd); - return sd->s_attr.ops; + if (kn->s_flags & SYSFS_FLAG_LOCKDEP) + lockdep_assert_held(kn); + return kn->s_attr.ops; } static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) @@ -64,10 +64,10 @@ static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) * the ops aren't called concurrently for the same open file. */ mutex_lock(&of->mutex); - if (!sysfs_get_active(of->sd)) + if (!sysfs_get_active(of->kn)) return ERR_PTR(-ENODEV); - ops = kernfs_ops(of->sd); + ops = kernfs_ops(of->kn); if (ops->seq_start) { return ops->seq_start(sf, ppos); } else { @@ -82,7 +82,7 @@ static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) { struct sysfs_open_file *of = sf->private; - const struct kernfs_ops *ops = kernfs_ops(of->sd); + const struct kernfs_ops *ops = kernfs_ops(of->kn); if (ops->seq_next) { return ops->seq_next(sf, v, ppos); @@ -99,12 +99,12 @@ static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) static void kernfs_seq_stop(struct seq_file *sf, void *v) { struct sysfs_open_file *of = sf->private; - const struct kernfs_ops *ops = kernfs_ops(of->sd); + const struct kernfs_ops *ops = kernfs_ops(of->kn); if (ops->seq_stop) ops->seq_stop(sf, v); - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); mutex_unlock(&of->mutex); } @@ -112,9 +112,9 @@ static int kernfs_seq_show(struct seq_file *sf, void *v) { struct sysfs_open_file *of = sf->private; - of->event = atomic_read(&of->sd->s_attr.open->event); + of->event = atomic_read(&of->kn->s_attr.open->event); - return of->sd->s_attr.ops->seq_show(sf, v); + return of->kn->s_attr.ops->seq_show(sf, v); } static const struct seq_operations kernfs_seq_ops = { @@ -147,19 +147,19 @@ static ssize_t kernfs_file_direct_read(struct sysfs_open_file *of, * the ops aren't called concurrently for the same open file. */ mutex_lock(&of->mutex); - if (!sysfs_get_active(of->sd)) { + if (!sysfs_get_active(of->kn)) { len = -ENODEV; mutex_unlock(&of->mutex); goto out_free; } - ops = kernfs_ops(of->sd); + ops = kernfs_ops(of->kn); if (ops->read) len = ops->read(of, buf, len, *ppos); else len = -EINVAL; - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); mutex_unlock(&of->mutex); if (len < 0) @@ -189,7 +189,7 @@ static ssize_t kernfs_file_read(struct file *file, char __user *user_buf, { struct sysfs_open_file *of = sysfs_of(file); - if (of->sd->s_flags & SYSFS_FLAG_HAS_SEQ_SHOW) + if (of->kn->s_flags & SYSFS_FLAG_HAS_SEQ_SHOW) return seq_read(file, user_buf, count, ppos); else return kernfs_file_direct_read(of, user_buf, count, ppos); @@ -234,19 +234,19 @@ static ssize_t kernfs_file_write(struct file *file, const char __user *user_buf, * the ops aren't called concurrently for the same open file. */ mutex_lock(&of->mutex); - if (!sysfs_get_active(of->sd)) { + if (!sysfs_get_active(of->kn)) { mutex_unlock(&of->mutex); len = -ENODEV; goto out_free; } - ops = kernfs_ops(of->sd); + ops = kernfs_ops(of->kn); if (ops->write) len = ops->write(of, buf, len, *ppos); else len = -EINVAL; - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); mutex_unlock(&of->mutex); if (len > 0) @@ -264,13 +264,13 @@ static void kernfs_vma_open(struct vm_area_struct *vma) if (!of->vm_ops) return; - if (!sysfs_get_active(of->sd)) + if (!sysfs_get_active(of->kn)) return; if (of->vm_ops->open) of->vm_ops->open(vma); - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); } static int kernfs_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) @@ -282,14 +282,14 @@ static int kernfs_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (!of->vm_ops) return VM_FAULT_SIGBUS; - if (!sysfs_get_active(of->sd)) + if (!sysfs_get_active(of->kn)) return VM_FAULT_SIGBUS; ret = VM_FAULT_SIGBUS; if (of->vm_ops->fault) ret = of->vm_ops->fault(vma, vmf); - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); return ret; } @@ -303,7 +303,7 @@ static int kernfs_vma_page_mkwrite(struct vm_area_struct *vma, if (!of->vm_ops) return VM_FAULT_SIGBUS; - if (!sysfs_get_active(of->sd)) + if (!sysfs_get_active(of->kn)) return VM_FAULT_SIGBUS; ret = 0; @@ -312,7 +312,7 @@ static int kernfs_vma_page_mkwrite(struct vm_area_struct *vma, else file_update_time(file); - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); return ret; } @@ -326,14 +326,14 @@ static int kernfs_vma_access(struct vm_area_struct *vma, unsigned long addr, if (!of->vm_ops) return -EINVAL; - if (!sysfs_get_active(of->sd)) + if (!sysfs_get_active(of->kn)) return -EINVAL; ret = -EINVAL; if (of->vm_ops->access) ret = of->vm_ops->access(vma, addr, buf, len, write); - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); return ret; } @@ -348,14 +348,14 @@ static int kernfs_vma_set_policy(struct vm_area_struct *vma, if (!of->vm_ops) return 0; - if (!sysfs_get_active(of->sd)) + if (!sysfs_get_active(of->kn)) return -EINVAL; ret = 0; if (of->vm_ops->set_policy) ret = of->vm_ops->set_policy(vma, new); - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); return ret; } @@ -369,14 +369,14 @@ static struct mempolicy *kernfs_vma_get_policy(struct vm_area_struct *vma, if (!of->vm_ops) return vma->vm_policy; - if (!sysfs_get_active(of->sd)) + if (!sysfs_get_active(of->kn)) return vma->vm_policy; pol = vma->vm_policy; if (of->vm_ops->get_policy) pol = of->vm_ops->get_policy(vma, addr); - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); return pol; } @@ -391,14 +391,14 @@ static int kernfs_vma_migrate(struct vm_area_struct *vma, if (!of->vm_ops) return 0; - if (!sysfs_get_active(of->sd)) + if (!sysfs_get_active(of->kn)) return 0; ret = 0; if (of->vm_ops->migrate) ret = of->vm_ops->migrate(vma, from, to, flags); - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); return ret; } #endif @@ -428,16 +428,16 @@ static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) * without grabbing @of->mutex by testing HAS_MMAP flag. See the * comment in kernfs_file_open() for more details. */ - if (!(of->sd->s_flags & SYSFS_FLAG_HAS_MMAP)) + if (!(of->kn->s_flags & SYSFS_FLAG_HAS_MMAP)) return -ENODEV; mutex_lock(&of->mutex); rc = -ENODEV; - if (!sysfs_get_active(of->sd)) + if (!sysfs_get_active(of->kn)) goto out_unlock; - ops = kernfs_ops(of->sd); + ops = kernfs_ops(of->kn); rc = ops->mmap(of, vma); /* @@ -465,7 +465,7 @@ static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) of->vm_ops = vma->vm_ops; vma->vm_ops = &kernfs_vm_ops; out_put: - sysfs_put_active(of->sd); + sysfs_put_active(of->kn); out_unlock: mutex_unlock(&of->mutex); @@ -474,10 +474,10 @@ out_unlock: /** * sysfs_get_open_dirent - get or create sysfs_open_dirent - * @sd: target sysfs_dirent + * @kn: target kernfs_node * @of: sysfs_open_file for this instance of open * - * If @sd->s_attr.open exists, increment its reference count; + * If @kn->s_attr.open exists, increment its reference count; * otherwise, create one. @of is chained to the files list. * * LOCKING: @@ -486,7 +486,7 @@ out_unlock: * RETURNS: * 0 on success, -errno on failure. */ -static int sysfs_get_open_dirent(struct sysfs_dirent *sd, +static int sysfs_get_open_dirent(struct kernfs_node *kn, struct sysfs_open_file *of) { struct sysfs_open_dirent *od, *new_od = NULL; @@ -495,12 +495,12 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd, mutex_lock(&sysfs_open_file_mutex); spin_lock_irq(&sysfs_open_dirent_lock); - if (!sd->s_attr.open && new_od) { - sd->s_attr.open = new_od; + if (!kn->s_attr.open && new_od) { + kn->s_attr.open = new_od; new_od = NULL; } - od = sd->s_attr.open; + od = kn->s_attr.open; if (od) { atomic_inc(&od->refcnt); list_add_tail(&of->list, &od->files); @@ -528,19 +528,19 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd, /** * sysfs_put_open_dirent - put sysfs_open_dirent - * @sd: target sysfs_dirent + * @kn: target kernfs_nodet * @of: associated sysfs_open_file * - * Put @sd->s_attr.open and unlink @of from the files list. If + * Put @kn->s_attr.open and unlink @of from the files list. If * reference count reaches zero, disassociate and free it. * * LOCKING: * None. */ -static void sysfs_put_open_dirent(struct sysfs_dirent *sd, +static void sysfs_put_open_dirent(struct kernfs_node *kn, struct sysfs_open_file *of) { - struct sysfs_open_dirent *od = sd->s_attr.open; + struct sysfs_open_dirent *od = kn->s_attr.open; unsigned long flags; mutex_lock(&sysfs_open_file_mutex); @@ -550,7 +550,7 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd, list_del(&of->list); if (atomic_dec_and_test(&od->refcnt)) - sd->s_attr.open = NULL; + kn->s_attr.open = NULL; else od = NULL; @@ -562,16 +562,16 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd, static int kernfs_file_open(struct inode *inode, struct file *file) { - struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; + struct kernfs_node *kn = file->f_path.dentry->d_fsdata; const struct kernfs_ops *ops; struct sysfs_open_file *of; bool has_read, has_write, has_mmap; int error = -EACCES; - if (!sysfs_get_active(attr_sd)) + if (!sysfs_get_active(kn)) return -ENODEV; - ops = kernfs_ops(attr_sd); + ops = kernfs_ops(kn); has_read = ops->seq_show || ops->read || ops->mmap; has_write = ops->write || ops->mmap; @@ -612,7 +612,7 @@ static int kernfs_file_open(struct inode *inode, struct file *file) else mutex_init(&of->mutex); - of->sd = attr_sd; + of->kn = kn; of->file = file; /* @@ -634,12 +634,12 @@ static int kernfs_file_open(struct inode *inode, struct file *file) file->f_mode |= FMODE_PWRITE; /* make sure we have open dirent struct */ - error = sysfs_get_open_dirent(attr_sd, of); + error = sysfs_get_open_dirent(kn, of); if (error) goto err_close; /* open succeeded, put active references */ - sysfs_put_active(attr_sd); + sysfs_put_active(kn); return 0; err_close: @@ -647,32 +647,32 @@ err_close: err_free: kfree(of); err_out: - sysfs_put_active(attr_sd); + sysfs_put_active(kn); return error; } static int kernfs_file_release(struct inode *inode, struct file *filp) { - struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata; + struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; struct sysfs_open_file *of = sysfs_of(filp); - sysfs_put_open_dirent(sd, of); + sysfs_put_open_dirent(kn, of); seq_release(inode, filp); kfree(of); return 0; } -void sysfs_unmap_bin_file(struct sysfs_dirent *sd) +void sysfs_unmap_bin_file(struct kernfs_node *kn) { struct sysfs_open_dirent *od; struct sysfs_open_file *of; - if (!(sd->s_flags & SYSFS_FLAG_HAS_MMAP)) + if (!(kn->s_flags & SYSFS_FLAG_HAS_MMAP)) return; spin_lock_irq(&sysfs_open_dirent_lock); - od = sd->s_attr.open; + od = kn->s_attr.open; if (od) atomic_inc(&od->refcnt); spin_unlock_irq(&sysfs_open_dirent_lock); @@ -686,7 +686,7 @@ void sysfs_unmap_bin_file(struct sysfs_dirent *sd) } mutex_unlock(&sysfs_open_file_mutex); - sysfs_put_open_dirent(sd, NULL); + sysfs_put_open_dirent(kn, NULL); } /* Sysfs attribute files are pollable. The idea is that you read @@ -705,16 +705,16 @@ void sysfs_unmap_bin_file(struct sysfs_dirent *sd) static unsigned int kernfs_file_poll(struct file *filp, poll_table *wait) { struct sysfs_open_file *of = sysfs_of(filp); - struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata; - struct sysfs_open_dirent *od = attr_sd->s_attr.open; + struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; + struct sysfs_open_dirent *od = kn->s_attr.open; /* need parent for the kobj, grab both */ - if (!sysfs_get_active(attr_sd)) + if (!sysfs_get_active(kn)) goto trigger; poll_wait(filp, &od->poll, wait); - sysfs_put_active(attr_sd); + sysfs_put_active(kn); if (of->event != atomic_read(&od->event)) goto trigger; @@ -727,19 +727,19 @@ static unsigned int kernfs_file_poll(struct file *filp, poll_table *wait) /** * kernfs_notify - notify a kernfs file - * @sd: file to notify + * @kn: file to notify * - * Notify @sd such that poll(2) on @sd wakes up. + * Notify @kn such that poll(2) on @kn wakes up. */ -void kernfs_notify(struct sysfs_dirent *sd) +void kernfs_notify(struct kernfs_node *kn) { struct sysfs_open_dirent *od; unsigned long flags; spin_lock_irqsave(&sysfs_open_dirent_lock, flags); - if (!WARN_ON(sysfs_type(sd) != SYSFS_KOBJ_ATTR)) { - od = sd->s_attr.open; + if (!WARN_ON(sysfs_type(kn) != SYSFS_KOBJ_ATTR)) { + od = kn->s_attr.open; if (od) { atomic_inc(&od->event); wake_up_interruptible(&od->poll); @@ -773,51 +773,51 @@ const struct file_operations kernfs_file_operations = { * * Returns the created node on success, ERR_PTR() value on error. */ -struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent, - const char *name, - umode_t mode, loff_t size, - const struct kernfs_ops *ops, - void *priv, const void *ns, - struct lock_class_key *key) +struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, + const char *name, + umode_t mode, loff_t size, + const struct kernfs_ops *ops, + void *priv, const void *ns, + struct lock_class_key *key) { struct sysfs_addrm_cxt acxt; - struct sysfs_dirent *sd; + struct kernfs_node *kn; int rc; - sd = sysfs_new_dirent(kernfs_root(parent), name, + kn = sysfs_new_dirent(kernfs_root(parent), name, (mode & S_IALLUGO) | S_IFREG, SYSFS_KOBJ_ATTR); - if (!sd) + if (!kn) return ERR_PTR(-ENOMEM); - sd->s_attr.ops = ops; - sd->s_attr.size = size; - sd->s_ns = ns; - sd->priv = priv; + kn->s_attr.ops = ops; + kn->s_attr.size = size; + kn->s_ns = ns; + kn->priv = priv; #ifdef CONFIG_DEBUG_LOCK_ALLOC if (key) { - lockdep_init_map(&sd->dep_map, "s_active", key, 0); - sd->s_flags |= SYSFS_FLAG_LOCKDEP; + lockdep_init_map(&kn->dep_map, "s_active", key, 0); + kn->s_flags |= SYSFS_FLAG_LOCKDEP; } #endif /* - * sd->s_attr.ops is accesible only while holding active ref. We + * kn->s_attr.ops is accesible only while holding active ref. We * need to know whether some ops are implemented outside active * ref. Cache their existence in flags. */ if (ops->seq_show) - sd->s_flags |= SYSFS_FLAG_HAS_SEQ_SHOW; + kn->s_flags |= SYSFS_FLAG_HAS_SEQ_SHOW; if (ops->mmap) - sd->s_flags |= SYSFS_FLAG_HAS_MMAP; + kn->s_flags |= SYSFS_FLAG_HAS_MMAP; sysfs_addrm_start(&acxt); - rc = sysfs_add_one(&acxt, sd, parent); + rc = sysfs_add_one(&acxt, kn, parent); sysfs_addrm_finish(&acxt); if (rc) { - kernfs_put(sd); + kernfs_put(kn); return ERR_PTR(rc); } - return sd; + return kn; } diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 18ad431e8c2..9e74eed6353 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -46,36 +46,36 @@ void __init sysfs_inode_init(void) panic("failed to init sysfs_backing_dev_info"); } -static struct sysfs_inode_attrs *sysfs_inode_attrs(struct sysfs_dirent *sd) +static struct sysfs_inode_attrs *sysfs_inode_attrs(struct kernfs_node *kn) { struct iattr *iattrs; - if (sd->s_iattr) - return sd->s_iattr; + if (kn->s_iattr) + return kn->s_iattr; - sd->s_iattr = kzalloc(sizeof(struct sysfs_inode_attrs), GFP_KERNEL); - if (!sd->s_iattr) + kn->s_iattr = kzalloc(sizeof(struct sysfs_inode_attrs), GFP_KERNEL); + if (!kn->s_iattr) return NULL; - iattrs = &sd->s_iattr->ia_iattr; + iattrs = &kn->s_iattr->ia_iattr; /* assign default attributes */ - iattrs->ia_mode = sd->s_mode; + iattrs->ia_mode = kn->s_mode; iattrs->ia_uid = GLOBAL_ROOT_UID; iattrs->ia_gid = GLOBAL_ROOT_GID; iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME; - simple_xattrs_init(&sd->s_iattr->xattrs); + simple_xattrs_init(&kn->s_iattr->xattrs); - return sd->s_iattr; + return kn->s_iattr; } -static int __kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr) +static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) { struct sysfs_inode_attrs *attrs; struct iattr *iattrs; unsigned int ia_valid = iattr->ia_valid; - attrs = sysfs_inode_attrs(sd); + attrs = sysfs_inode_attrs(kn); if (!attrs) return -ENOMEM; @@ -93,24 +93,24 @@ static int __kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr) iattrs->ia_ctime = iattr->ia_ctime; if (ia_valid & ATTR_MODE) { umode_t mode = iattr->ia_mode; - iattrs->ia_mode = sd->s_mode = mode; + iattrs->ia_mode = kn->s_mode = mode; } return 0; } /** * kernfs_setattr - set iattr on a node - * @sd: target node + * @kn: target node * @iattr: iattr to set * * Returns 0 on success, -errno on failure. */ -int kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr) +int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) { int ret; mutex_lock(&sysfs_mutex); - ret = __kernfs_setattr(sd, iattr); + ret = __kernfs_setattr(kn, iattr); mutex_unlock(&sysfs_mutex); return ret; } @@ -118,10 +118,10 @@ int kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr) int sysfs_setattr(struct dentry *dentry, struct iattr *iattr) { struct inode *inode = dentry->d_inode; - struct sysfs_dirent *sd = dentry->d_fsdata; + struct kernfs_node *kn = dentry->d_fsdata; int error; - if (!sd) + if (!kn) return -EINVAL; mutex_lock(&sysfs_mutex); @@ -129,7 +129,7 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr) if (error) goto out; - error = __kernfs_setattr(sd, iattr); + error = __kernfs_setattr(kn, iattr); if (error) goto out; @@ -141,14 +141,14 @@ out: return error; } -static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, +static int sysfs_sd_setsecdata(struct kernfs_node *kn, void **secdata, u32 *secdata_len) { struct sysfs_inode_attrs *attrs; void *old_secdata; size_t old_secdata_len; - attrs = sysfs_inode_attrs(sd); + attrs = sysfs_inode_attrs(kn); if (!attrs) return -ENOMEM; @@ -166,13 +166,13 @@ static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { - struct sysfs_dirent *sd = dentry->d_fsdata; + struct kernfs_node *kn = dentry->d_fsdata; struct sysfs_inode_attrs *attrs; void *secdata; int error; u32 secdata_len = 0; - attrs = sysfs_inode_attrs(sd); + attrs = sysfs_inode_attrs(kn); if (!attrs) return -ENOMEM; @@ -188,7 +188,7 @@ int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, return error; mutex_lock(&sysfs_mutex); - error = sysfs_sd_setsecdata(sd, &secdata, &secdata_len); + error = sysfs_sd_setsecdata(kn, &secdata, &secdata_len); mutex_unlock(&sysfs_mutex); if (secdata) @@ -204,10 +204,10 @@ int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, int sysfs_removexattr(struct dentry *dentry, const char *name) { - struct sysfs_dirent *sd = dentry->d_fsdata; + struct kernfs_node *kn = dentry->d_fsdata; struct sysfs_inode_attrs *attrs; - attrs = sysfs_inode_attrs(sd); + attrs = sysfs_inode_attrs(kn); if (!attrs) return -ENOMEM; @@ -217,10 +217,10 @@ int sysfs_removexattr(struct dentry *dentry, const char *name) ssize_t sysfs_getxattr(struct dentry *dentry, const char *name, void *buf, size_t size) { - struct sysfs_dirent *sd = dentry->d_fsdata; + struct kernfs_node *kn = dentry->d_fsdata; struct sysfs_inode_attrs *attrs; - attrs = sysfs_inode_attrs(sd); + attrs = sysfs_inode_attrs(kn); if (!attrs) return -ENOMEM; @@ -229,10 +229,10 @@ ssize_t sysfs_getxattr(struct dentry *dentry, const char *name, void *buf, ssize_t sysfs_listxattr(struct dentry *dentry, char *buf, size_t size) { - struct sysfs_dirent *sd = dentry->d_fsdata; + struct kernfs_node *kn = dentry->d_fsdata; struct sysfs_inode_attrs *attrs; - attrs = sysfs_inode_attrs(sd); + attrs = sysfs_inode_attrs(kn); if (!attrs) return -ENOMEM; @@ -254,57 +254,58 @@ static inline void set_inode_attr(struct inode *inode, struct iattr *iattr) inode->i_ctime = iattr->ia_ctime; } -static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode) +static void sysfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) { - struct sysfs_inode_attrs *attrs = sd->s_iattr; + struct sysfs_inode_attrs *attrs = kn->s_iattr; - inode->i_mode = sd->s_mode; + inode->i_mode = kn->s_mode; if (attrs) { - /* sysfs_dirent has non-default attributes - * get them from persistent copy in sysfs_dirent + /* + * kernfs_node has non-default attributes get them from + * persistent copy in kernfs_node. */ set_inode_attr(inode, &attrs->ia_iattr); security_inode_notifysecctx(inode, attrs->ia_secdata, attrs->ia_secdata_len); } - if (sysfs_type(sd) == SYSFS_DIR) - set_nlink(inode, sd->s_dir.subdirs + 2); + if (sysfs_type(kn) == SYSFS_DIR) + set_nlink(inode, kn->s_dir.subdirs + 2); } int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { - struct sysfs_dirent *sd = dentry->d_fsdata; + struct kernfs_node *kn = dentry->d_fsdata; struct inode *inode = dentry->d_inode; mutex_lock(&sysfs_mutex); - sysfs_refresh_inode(sd, inode); + sysfs_refresh_inode(kn, inode); mutex_unlock(&sysfs_mutex); generic_fillattr(inode, stat); return 0; } -static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) +static void sysfs_init_inode(struct kernfs_node *kn, struct inode *inode) { - kernfs_get(sd); - inode->i_private = sd; + kernfs_get(kn); + inode->i_private = kn; inode->i_mapping->a_ops = &sysfs_aops; inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; inode->i_op = &sysfs_inode_operations; - set_default_inode_attr(inode, sd->s_mode); - sysfs_refresh_inode(sd, inode); + set_default_inode_attr(inode, kn->s_mode); + sysfs_refresh_inode(kn, inode); /* initialize inode according to type */ - switch (sysfs_type(sd)) { + switch (sysfs_type(kn)) { case SYSFS_DIR: inode->i_op = &sysfs_dir_inode_operations; inode->i_fop = &sysfs_dir_operations; break; case SYSFS_KOBJ_ATTR: - inode->i_size = sd->s_attr.size; + inode->i_size = kn->s_attr.size; inode->i_fop = &kernfs_file_operations; break; case SYSFS_KOBJ_LINK: @@ -318,13 +319,13 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) } /** - * sysfs_get_inode - get inode for sysfs_dirent + * sysfs_get_inode - get inode for kernfs_node * @sb: super block - * @sd: sysfs_dirent to allocate inode for + * @kn: kernfs_node to allocate inode for * - * Get inode for @sd. If such inode doesn't exist, a new inode - * is allocated and basics are initialized. New inode is - * returned locked. + * Get inode for @kn. If such inode doesn't exist, a new inode is + * allocated and basics are initialized. New inode is returned + * locked. * * LOCKING: * Kernel thread context (may sleep). @@ -332,44 +333,44 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) * RETURNS: * Pointer to allocated inode on success, NULL on failure. */ -struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd) +struct inode *sysfs_get_inode(struct super_block *sb, struct kernfs_node *kn) { struct inode *inode; - inode = iget_locked(sb, sd->s_ino); + inode = iget_locked(sb, kn->s_ino); if (inode && (inode->i_state & I_NEW)) - sysfs_init_inode(sd, inode); + sysfs_init_inode(kn, inode); return inode; } /* - * The sysfs_dirent serves as both an inode and a directory entry for sysfs. - * To prevent the sysfs inode numbers from being freed prematurely we take a - * reference to sysfs_dirent from the sysfs inode. A + * The kernfs_node serves as both an inode and a directory entry for sysfs. + * To prevent the sysfs inode numbers from being freed prematurely we take + * a reference to kernfs_node from the sysfs inode. A * super_operations.evict_inode() implementation is needed to drop that * reference upon inode destruction. */ void sysfs_evict_inode(struct inode *inode) { - struct sysfs_dirent *sd = inode->i_private; + struct kernfs_node *kn = inode->i_private; truncate_inode_pages(&inode->i_data, 0); clear_inode(inode); - kernfs_put(sd); + kernfs_put(kn); } int sysfs_permission(struct inode *inode, int mask) { - struct sysfs_dirent *sd; + struct kernfs_node *kn; if (mask & MAY_NOT_BLOCK) return -ECHILD; - sd = inode->i_private; + kn = inode->i_private; mutex_lock(&sysfs_mutex); - sysfs_refresh_inode(sd, inode); + sysfs_refresh_inode(kn, inode); mutex_unlock(&sysfs_mutex); return generic_permission(inode, mask); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 910e485b733..b7ea76c6fb3 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -31,24 +31,24 @@ struct sysfs_inode_attrs { /* SYSFS_TYPE_MASK and types are defined in include/linux/kernfs.h */ /** - * kernfs_root - find out the kernfs_root a sysfs_dirent belongs to - * @sd: sysfs_dirent of interest + * kernfs_root - find out the kernfs_root a kernfs_node belongs to + * @kn: kernfs_node of interest * - * Return the kernfs_root @sd belongs to. + * Return the kernfs_root @kn belongs to. */ -static inline struct kernfs_root *kernfs_root(struct sysfs_dirent *sd) +static inline struct kernfs_root *kernfs_root(struct kernfs_node *kn) { /* if parent exists, it's always a dir; otherwise, @sd is a dir */ - if (sd->s_parent) - sd = sd->s_parent; - return sd->s_dir.root; + if (kn->s_parent) + kn = kn->s_parent; + return kn->s_dir.root; } /* * Context structure to be used while adding/removing nodes. */ struct sysfs_addrm_cxt { - struct sysfs_dirent *removed; + struct kernfs_node *removed; }; /* @@ -62,10 +62,10 @@ struct sysfs_super_info { struct kernfs_root *root; /* - * Each sb is associated with one namespace tag, currently the network - * namespace of the task which mounted this sysfs instance. If multiple - * tags become necessary, make the following an array and compare - * sysfs_dirent tag against every entry. + * Each sb is associated with one namespace tag, currently the + * network namespace of the task which mounted this sysfs instance. + * If multiple tags become necessary, make the following an array + * and compare kernfs_node tag against every entry. */ const void *ns; }; @@ -76,7 +76,7 @@ extern struct kmem_cache *sysfs_dir_cachep; /* * inode.c */ -struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd); +struct inode *sysfs_get_inode(struct super_block *sb, struct kernfs_node *kn); void sysfs_evict_inode(struct inode *inode); int sysfs_permission(struct inode *inode, int mask); int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); @@ -98,21 +98,21 @@ extern const struct dentry_operations sysfs_dentry_ops; extern const struct file_operations sysfs_dir_operations; extern const struct inode_operations sysfs_dir_inode_operations; -struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd); -void sysfs_put_active(struct sysfs_dirent *sd); +struct kernfs_node *sysfs_get_active(struct kernfs_node *kn); +void sysfs_put_active(struct kernfs_node *kn); void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt); -int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd, - struct sysfs_dirent *parent_sd); +int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct kernfs_node *kn, + struct kernfs_node *parent); void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); -struct sysfs_dirent *sysfs_new_dirent(struct kernfs_root *root, - const char *name, umode_t mode, int type); +struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, + const char *name, umode_t mode, int type); /* * file.c */ extern const struct file_operations kernfs_file_operations; -void sysfs_unmap_bin_file(struct sysfs_dirent *sd); +void sysfs_unmap_bin_file(struct kernfs_node *kn); /* * symlink.c diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index 84c83e24bf2..9dbbf37b1af 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -39,7 +39,7 @@ static int sysfs_fill_super(struct super_block *sb) /* get root inode, initialize and unlock it */ mutex_lock(&sysfs_mutex); - inode = sysfs_get_inode(sb, info->root->sd); + inode = sysfs_get_inode(sb, info->root->kn); mutex_unlock(&sysfs_mutex); if (!inode) { pr_debug("sysfs: could not get root inode\n"); @@ -52,8 +52,8 @@ static int sysfs_fill_super(struct super_block *sb) pr_debug("%s: could not get root dentry!\n", __func__); return -ENOMEM; } - kernfs_get(info->root->sd); - root->d_fsdata = info->root->sd; + kernfs_get(info->root->kn); + root->d_fsdata = info->root->kn; sb->s_root = root; sb->s_d_op = &sysfs_dentry_ops; return 0; @@ -145,7 +145,7 @@ struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, void kernfs_kill_sb(struct super_block *sb) { struct sysfs_super_info *info = sysfs_info(sb); - struct sysfs_dirent *root_sd = sb->s_root->d_fsdata; + struct kernfs_node *root_kn = sb->s_root->d_fsdata; /* * Remove the superblock from fs_supers/s_instances @@ -153,13 +153,13 @@ void kernfs_kill_sb(struct super_block *sb) */ kill_anon_super(sb); kfree(info); - kernfs_put(root_sd); + kernfs_put(root_kn); } void __init kernfs_init(void) { sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache", - sizeof(struct sysfs_dirent), + sizeof(struct kernfs_node), 0, SLAB_PANIC, NULL); sysfs_inode_init(); } diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index adf28755b0e..29dcf5e8deb 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -22,50 +22,50 @@ * * Returns the created node on success, ERR_PTR() value on error. */ -struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, - const char *name, - struct sysfs_dirent *target) +struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, + const char *name, + struct kernfs_node *target) { - struct sysfs_dirent *sd; + struct kernfs_node *kn; struct sysfs_addrm_cxt acxt; int error; - sd = sysfs_new_dirent(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO, + kn = sysfs_new_dirent(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); - if (!sd) + if (!kn) return ERR_PTR(-ENOMEM); if (kernfs_ns_enabled(parent)) - sd->s_ns = target->s_ns; - sd->s_symlink.target_sd = target; + kn->s_ns = target->s_ns; + kn->s_symlink.target_kn = target; kernfs_get(target); /* ref owned by symlink */ sysfs_addrm_start(&acxt); - error = sysfs_add_one(&acxt, sd, parent); + error = sysfs_add_one(&acxt, kn, parent); sysfs_addrm_finish(&acxt); if (!error) - return sd; + return kn; - kernfs_put(sd); + kernfs_put(kn); return ERR_PTR(error); } -static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, - struct sysfs_dirent *target_sd, char *path) +static int sysfs_get_target_path(struct kernfs_node *parent, + struct kernfs_node *target, char *path) { - struct sysfs_dirent *base, *sd; + struct kernfs_node *base, *kn; char *s = path; int len = 0; /* go up to the root, stop at the base */ - base = parent_sd; + base = parent; while (base->s_parent) { - sd = target_sd->s_parent; - while (sd->s_parent && base != sd) - sd = sd->s_parent; + kn = target->s_parent; + while (kn->s_parent && base != kn) + kn = kn->s_parent; - if (base == sd) + if (base == kn) break; strcpy(s, "../"); @@ -74,10 +74,10 @@ static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, } /* determine end of target string for reverse fillup */ - sd = target_sd; - while (sd->s_parent && sd != base) { - len += strlen(sd->s_name) + 1; - sd = sd->s_parent; + kn = target; + while (kn->s_parent && kn != base) { + len += strlen(kn->s_name) + 1; + kn = kn->s_parent; } /* check limits */ @@ -88,16 +88,16 @@ static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, return -ENAMETOOLONG; /* reverse fillup of target string from target to base */ - sd = target_sd; - while (sd->s_parent && sd != base) { - int slen = strlen(sd->s_name); + kn = target; + while (kn->s_parent && kn != base) { + int slen = strlen(kn->s_name); len -= slen; - strncpy(s + len, sd->s_name, slen); + strncpy(s + len, kn->s_name, slen); if (len) s[--len] = '/'; - sd = sd->s_parent; + kn = kn->s_parent; } return 0; @@ -105,13 +105,13 @@ static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, static int sysfs_getlink(struct dentry *dentry, char *path) { - struct sysfs_dirent *sd = dentry->d_fsdata; - struct sysfs_dirent *parent_sd = sd->s_parent; - struct sysfs_dirent *target_sd = sd->s_symlink.target_sd; + struct kernfs_node *kn = dentry->d_fsdata; + struct kernfs_node *parent = kn->s_parent; + struct kernfs_node *target = kn->s_symlink.target_kn; int error; mutex_lock(&sysfs_mutex); - error = sysfs_get_target_path(parent_sd, target_sd, path); + error = sysfs_get_target_path(parent, target, path); mutex_unlock(&sysfs_mutex); return error; diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 2fea501889e..f1efe3df0de 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -21,23 +21,23 @@ DEFINE_SPINLOCK(sysfs_symlink_target_lock); /** * sysfs_pathname - return full path to sysfs dirent - * @sd: sysfs_dirent whose path we want + * @kn: kernfs_node whose path we want * @path: caller allocated buffer of size PATH_MAX * * Gives the name "/" to the sysfs_root entry; any path returned * is relative to wherever sysfs is mounted. */ -static char *sysfs_pathname(struct sysfs_dirent *sd, char *path) +static char *sysfs_pathname(struct kernfs_node *kn, char *path) { - if (sd->s_parent) { - sysfs_pathname(sd->s_parent, path); + if (kn->s_parent) { + sysfs_pathname(kn->s_parent, path); strlcat(path, "/", PATH_MAX); } - strlcat(path, sd->s_name, PATH_MAX); + strlcat(path, kn->s_name, PATH_MAX); return path; } -void sysfs_warn_dup(struct sysfs_dirent *parent, const char *name) +void sysfs_warn_dup(struct kernfs_node *parent, const char *name) { char *path; @@ -61,26 +61,26 @@ void sysfs_warn_dup(struct sysfs_dirent *parent, const char *name) */ int sysfs_create_dir_ns(struct kobject *kobj, const void *ns) { - struct sysfs_dirent *parent_sd, *sd; + struct kernfs_node *parent, *kn; BUG_ON(!kobj); if (kobj->parent) - parent_sd = kobj->parent->sd; + parent = kobj->parent->sd; else - parent_sd = sysfs_root_sd; + parent = sysfs_root_kn; - if (!parent_sd) + if (!parent) return -ENOENT; - sd = kernfs_create_dir_ns(parent_sd, kobject_name(kobj), kobj, ns); - if (IS_ERR(sd)) { - if (PTR_ERR(sd) == -EEXIST) - sysfs_warn_dup(parent_sd, kobject_name(kobj)); - return PTR_ERR(sd); + kn = kernfs_create_dir_ns(parent, kobject_name(kobj), kobj, ns); + if (IS_ERR(kn)) { + if (PTR_ERR(kn) == -EEXIST) + sysfs_warn_dup(parent, kobject_name(kobj)); + return PTR_ERR(kn); } - kobj->sd = sd; + kobj->sd = kn; return 0; } @@ -94,47 +94,47 @@ int sysfs_create_dir_ns(struct kobject *kobj, const void *ns) */ void sysfs_remove_dir(struct kobject *kobj) { - struct sysfs_dirent *sd = kobj->sd; + struct kernfs_node *kn = kobj->sd; /* * In general, kboject owner is responsible for ensuring removal * doesn't race with other operations and sysfs doesn't provide any * protection; however, when @kobj is used as a symlink target, the * symlinking entity usually doesn't own @kobj and thus has no - * control over removal. @kobj->sd may be removed anytime and - * symlink code may end up dereferencing an already freed sd. + * control over removal. @kobj->sd may be removed anytime + * and symlink code may end up dereferencing an already freed node. * - * sysfs_symlink_target_lock synchronizes @kobj->sd disassociation - * against symlink operations so that symlink code can safely - * dereference @kobj->sd. + * sysfs_symlink_target_lock synchronizes @kobj->sd + * disassociation against symlink operations so that symlink code + * can safely dereference @kobj->sd. */ spin_lock(&sysfs_symlink_target_lock); kobj->sd = NULL; spin_unlock(&sysfs_symlink_target_lock); - if (sd) { - WARN_ON_ONCE(sysfs_type(sd) != SYSFS_DIR); - kernfs_remove(sd); + if (kn) { + WARN_ON_ONCE(sysfs_type(kn) != SYSFS_DIR); + kernfs_remove(kn); } } int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name, const void *new_ns) { - struct sysfs_dirent *parent_sd = kobj->sd->s_parent; + struct kernfs_node *parent = kobj->sd->s_parent; - return kernfs_rename_ns(kobj->sd, parent_sd, new_name, new_ns); + return kernfs_rename_ns(kobj->sd, parent, new_name, new_ns); } int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj, const void *new_ns) { - struct sysfs_dirent *sd = kobj->sd; - struct sysfs_dirent *new_parent_sd; + struct kernfs_node *kn = kobj->sd; + struct kernfs_node *new_parent; - BUG_ON(!sd->s_parent); - new_parent_sd = new_parent_kobj && new_parent_kobj->sd ? - new_parent_kobj->sd : sysfs_root_sd; + BUG_ON(!kn->s_parent); + new_parent = new_parent_kobj && new_parent_kobj->sd ? + new_parent_kobj->sd : sysfs_root_kn; - return kernfs_rename_ns(sd, new_parent_sd, sd->s_name, new_ns); + return kernfs_rename_ns(kn, new_parent, kn->s_name, new_ns); } diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index a67d1c682fe..be1cc39035b 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -22,15 +22,15 @@ #include "../kernfs/kernfs-internal.h" /* - * Determine ktype->sysfs_ops for the given sysfs_dirent. This function + * Determine ktype->sysfs_ops for the given kernfs_node. This function * must be called while holding an active reference. */ -static const struct sysfs_ops *sysfs_file_ops(struct sysfs_dirent *sd) +static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn) { - struct kobject *kobj = sd->s_parent->priv; + struct kobject *kobj = kn->s_parent->priv; - if (sd->s_flags & SYSFS_FLAG_LOCKDEP) - lockdep_assert_held(sd); + if (kn->s_flags & SYSFS_FLAG_LOCKDEP) + lockdep_assert_held(kn); return kobj->ktype ? kobj->ktype->sysfs_ops : NULL; } @@ -42,8 +42,8 @@ static const struct sysfs_ops *sysfs_file_ops(struct sysfs_dirent *sd) static int sysfs_kf_seq_show(struct seq_file *sf, void *v) { struct sysfs_open_file *of = sf->private; - struct kobject *kobj = of->sd->s_parent->priv; - const struct sysfs_ops *ops = sysfs_file_ops(of->sd); + struct kobject *kobj = of->kn->s_parent->priv; + const struct sysfs_ops *ops = sysfs_file_ops(of->kn); ssize_t count; char *buf; @@ -59,7 +59,7 @@ static int sysfs_kf_seq_show(struct seq_file *sf, void *v) * if @ops->show() isn't implemented. */ if (ops->show) { - count = ops->show(kobj, of->sd->priv, buf); + count = ops->show(kobj, of->kn->priv, buf); if (count < 0) return count; } @@ -81,8 +81,8 @@ static int sysfs_kf_seq_show(struct seq_file *sf, void *v) static ssize_t sysfs_kf_bin_read(struct sysfs_open_file *of, char *buf, size_t count, loff_t pos) { - struct bin_attribute *battr = of->sd->priv; - struct kobject *kobj = of->sd->s_parent->priv; + struct bin_attribute *battr = of->kn->priv; + struct kobject *kobj = of->kn->s_parent->priv; loff_t size = file_inode(of->file)->i_size; if (!count) @@ -105,21 +105,21 @@ static ssize_t sysfs_kf_bin_read(struct sysfs_open_file *of, char *buf, static ssize_t sysfs_kf_write(struct sysfs_open_file *of, char *buf, size_t count, loff_t pos) { - const struct sysfs_ops *ops = sysfs_file_ops(of->sd); - struct kobject *kobj = of->sd->s_parent->priv; + const struct sysfs_ops *ops = sysfs_file_ops(of->kn); + struct kobject *kobj = of->kn->s_parent->priv; if (!count) return 0; - return ops->store(kobj, of->sd->priv, buf, count); + return ops->store(kobj, of->kn->priv, buf, count); } /* kernfs write callback for bin sysfs files */ static ssize_t sysfs_kf_bin_write(struct sysfs_open_file *of, char *buf, size_t count, loff_t pos) { - struct bin_attribute *battr = of->sd->priv; - struct kobject *kobj = of->sd->s_parent->priv; + struct bin_attribute *battr = of->kn->priv; + struct kobject *kobj = of->kn->s_parent->priv; loff_t size = file_inode(of->file)->i_size; if (size) { @@ -139,30 +139,30 @@ static ssize_t sysfs_kf_bin_write(struct sysfs_open_file *of, char *buf, static int sysfs_kf_bin_mmap(struct sysfs_open_file *of, struct vm_area_struct *vma) { - struct bin_attribute *battr = of->sd->priv; - struct kobject *kobj = of->sd->s_parent->priv; + struct bin_attribute *battr = of->kn->priv; + struct kobject *kobj = of->kn->s_parent->priv; return battr->mmap(of->file, kobj, battr, vma); } -void sysfs_notify(struct kobject *k, const char *dir, const char *attr) +void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr) { - struct sysfs_dirent *sd = k->sd, *tmp; + struct kernfs_node *kn = kobj->sd, *tmp; - if (sd && dir) - sd = kernfs_find_and_get(sd, dir); + if (kn && dir) + kn = kernfs_find_and_get(kn, dir); else - kernfs_get(sd); + kernfs_get(kn); - if (sd && attr) { - tmp = kernfs_find_and_get(sd, attr); - kernfs_put(sd); - sd = tmp; + if (kn && attr) { + tmp = kernfs_find_and_get(kn, attr); + kernfs_put(kn); + kn = tmp; } - if (sd) { - kernfs_notify(sd); - kernfs_put(sd); + if (kn) { + kernfs_notify(kn); + kernfs_put(kn); } } EXPORT_SYMBOL_GPL(sysfs_notify); @@ -202,17 +202,17 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = { .mmap = sysfs_kf_bin_mmap, }; -int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd, +int sysfs_add_file_mode_ns(struct kernfs_node *parent, const struct attribute *attr, bool is_bin, umode_t mode, const void *ns) { struct lock_class_key *key = NULL; const struct kernfs_ops *ops; - struct sysfs_dirent *sd; + struct kernfs_node *kn; loff_t size; if (!is_bin) { - struct kobject *kobj = dir_sd->priv; + struct kobject *kobj = parent->priv; const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops; /* every kobject with an attribute needs a ktype assigned */ @@ -252,20 +252,20 @@ int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd, if (!attr->ignore_lockdep) key = attr->key ?: (struct lock_class_key *)&attr->skey; #endif - sd = kernfs_create_file_ns_key(dir_sd, attr->name, mode, size, + kn = kernfs_create_file_ns_key(parent, attr->name, mode, size, ops, (void *)attr, ns, key); - if (IS_ERR(sd)) { - if (PTR_ERR(sd) == -EEXIST) - sysfs_warn_dup(dir_sd, attr->name); - return PTR_ERR(sd); + if (IS_ERR(kn)) { + if (PTR_ERR(kn) == -EEXIST) + sysfs_warn_dup(parent, attr->name); + return PTR_ERR(kn); } return 0; } -int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr, +int sysfs_add_file(struct kernfs_node *parent, const struct attribute *attr, bool is_bin) { - return sysfs_add_file_mode_ns(dir_sd, attr, is_bin, attr->mode, NULL); + return sysfs_add_file_mode_ns(parent, attr, is_bin, attr->mode, NULL); } /** @@ -307,21 +307,21 @@ EXPORT_SYMBOL_GPL(sysfs_create_files); int sysfs_add_file_to_group(struct kobject *kobj, const struct attribute *attr, const char *group) { - struct sysfs_dirent *dir_sd; + struct kernfs_node *parent; int error; if (group) { - dir_sd = kernfs_find_and_get(kobj->sd, group); + parent = kernfs_find_and_get(kobj->sd, group); } else { - dir_sd = kobj->sd; - kernfs_get(dir_sd); + parent = kobj->sd; + kernfs_get(parent); } - if (!dir_sd) + if (!parent) return -ENOENT; - error = sysfs_add_file(dir_sd, attr, false); - kernfs_put(dir_sd); + error = sysfs_add_file(parent, attr, false); + kernfs_put(parent); return error; } @@ -337,20 +337,20 @@ EXPORT_SYMBOL_GPL(sysfs_add_file_to_group); int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr, umode_t mode) { - struct sysfs_dirent *sd; + struct kernfs_node *kn; struct iattr newattrs; int rc; - sd = kernfs_find_and_get(kobj->sd, attr->name); - if (!sd) + kn = kernfs_find_and_get(kobj->sd, attr->name); + if (!kn) return -ENOENT; - newattrs.ia_mode = (mode & S_IALLUGO) | (sd->s_mode & ~S_IALLUGO); + newattrs.ia_mode = (mode & S_IALLUGO) | (kn->s_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE; - rc = kernfs_setattr(sd, &newattrs); + rc = kernfs_setattr(kn, &newattrs); - kernfs_put(sd); + kernfs_put(kn); return rc; } EXPORT_SYMBOL_GPL(sysfs_chmod_file); @@ -366,9 +366,9 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file); void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr, const void *ns) { - struct sysfs_dirent *dir_sd = kobj->sd; + struct kernfs_node *parent = kobj->sd; - kernfs_remove_by_name_ns(dir_sd, attr->name, ns); + kernfs_remove_by_name_ns(parent, attr->name, ns); } EXPORT_SYMBOL_GPL(sysfs_remove_file_ns); @@ -389,18 +389,18 @@ EXPORT_SYMBOL_GPL(sysfs_remove_files); void sysfs_remove_file_from_group(struct kobject *kobj, const struct attribute *attr, const char *group) { - struct sysfs_dirent *dir_sd; + struct kernfs_node *parent; if (group) { - dir_sd = kernfs_find_and_get(kobj->sd, group); + parent = kernfs_find_and_get(kobj->sd, group); } else { - dir_sd = kobj->sd; - kernfs_get(dir_sd); + parent = kobj->sd; + kernfs_get(parent); } - if (dir_sd) { - kernfs_remove_by_name(dir_sd, attr->name); - kernfs_put(dir_sd); + if (parent) { + kernfs_remove_by_name(parent, attr->name); + kernfs_put(parent); } } EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group); diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 7177532b8f7..4d00d399647 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -18,7 +18,7 @@ #include "sysfs.h" -static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, +static void remove_files(struct kernfs_node *parent, struct kobject *kobj, const struct attribute_group *grp) { struct attribute *const *attr; @@ -26,13 +26,13 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, if (grp->attrs) for (attr = grp->attrs; *attr; attr++) - kernfs_remove_by_name(dir_sd, (*attr)->name); + kernfs_remove_by_name(parent, (*attr)->name); if (grp->bin_attrs) for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) sysfs_remove_bin_file(kobj, *bin_attr); } -static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, +static int create_files(struct kernfs_node *parent, struct kobject *kobj, const struct attribute_group *grp, int update) { struct attribute *const *attr; @@ -49,20 +49,20 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, * re-adding (if required) the file. */ if (update) - kernfs_remove_by_name(dir_sd, (*attr)->name); + kernfs_remove_by_name(parent, (*attr)->name); if (grp->is_visible) { mode = grp->is_visible(kobj, *attr, i); if (!mode) continue; } - error = sysfs_add_file_mode_ns(dir_sd, *attr, false, + error = sysfs_add_file_mode_ns(parent, *attr, false, (*attr)->mode | mode, NULL); if (unlikely(error)) break; } if (error) { - remove_files(dir_sd, kobj, grp); + remove_files(parent, kobj, grp); goto exit; } } @@ -76,7 +76,7 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, break; } if (error) - remove_files(dir_sd, kobj, grp); + remove_files(parent, kobj, grp); } exit: return error; @@ -86,7 +86,7 @@ exit: static int internal_create_group(struct kobject *kobj, int update, const struct attribute_group *grp) { - struct sysfs_dirent *sd; + struct kernfs_node *kn; int error; BUG_ON(!kobj || (!update && !kobj->sd)); @@ -100,21 +100,21 @@ static int internal_create_group(struct kobject *kobj, int update, return -EINVAL; } if (grp->name) { - sd = kernfs_create_dir(kobj->sd, grp->name, kobj); - if (IS_ERR(sd)) { - if (PTR_ERR(sd) == -EEXIST) + kn = kernfs_create_dir(kobj->sd, grp->name, kobj); + if (IS_ERR(kn)) { + if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(kobj->sd, grp->name); - return PTR_ERR(sd); + return PTR_ERR(kn); } } else - sd = kobj->sd; - kernfs_get(sd); - error = create_files(sd, kobj, grp, update); + kn = kobj->sd; + kernfs_get(kn); + error = create_files(kn, kobj, grp, update); if (error) { if (grp->name) - kernfs_remove(sd); + kernfs_remove(kn); } - kernfs_put(sd); + kernfs_put(kn); return error; } @@ -204,27 +204,27 @@ EXPORT_SYMBOL_GPL(sysfs_update_group); void sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp) { - struct sysfs_dirent *dir_sd = kobj->sd; - struct sysfs_dirent *sd; + struct kernfs_node *parent = kobj->sd; + struct kernfs_node *kn; if (grp->name) { - sd = kernfs_find_and_get(dir_sd, grp->name); - if (!sd) { - WARN(!sd, KERN_WARNING + kn = kernfs_find_and_get(parent, grp->name); + if (!kn) { + WARN(!kn, KERN_WARNING "sysfs group %p not found for kobject '%s'\n", grp, kobject_name(kobj)); return; } } else { - sd = dir_sd; - kernfs_get(sd); + kn = parent; + kernfs_get(kn); } - remove_files(sd, kobj, grp); + remove_files(kn, kobj, grp); if (grp->name) - kernfs_remove(sd); + kernfs_remove(kn); - kernfs_put(sd); + kernfs_put(kn); } EXPORT_SYMBOL_GPL(sysfs_remove_group); @@ -260,22 +260,22 @@ EXPORT_SYMBOL_GPL(sysfs_remove_groups); int sysfs_merge_group(struct kobject *kobj, const struct attribute_group *grp) { - struct sysfs_dirent *dir_sd; + struct kernfs_node *parent; int error = 0; struct attribute *const *attr; int i; - dir_sd = kernfs_find_and_get(kobj->sd, grp->name); - if (!dir_sd) + parent = kernfs_find_and_get(kobj->sd, grp->name); + if (!parent) return -ENOENT; for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr)) - error = sysfs_add_file(dir_sd, *attr, false); + error = sysfs_add_file(parent, *attr, false); if (error) { while (--i >= 0) - kernfs_remove_by_name(dir_sd, (*--attr)->name); + kernfs_remove_by_name(parent, (*--attr)->name); } - kernfs_put(dir_sd); + kernfs_put(parent); return error; } @@ -289,14 +289,14 @@ EXPORT_SYMBOL_GPL(sysfs_merge_group); void sysfs_unmerge_group(struct kobject *kobj, const struct attribute_group *grp) { - struct sysfs_dirent *dir_sd; + struct kernfs_node *parent; struct attribute *const *attr; - dir_sd = kernfs_find_and_get(kobj->sd, grp->name); - if (dir_sd) { + parent = kernfs_find_and_get(kobj->sd, grp->name); + if (parent) { for (attr = grp->attrs; *attr; ++attr) - kernfs_remove_by_name(dir_sd, (*attr)->name); - kernfs_put(dir_sd); + kernfs_remove_by_name(parent, (*attr)->name); + kernfs_put(parent); } } EXPORT_SYMBOL_GPL(sysfs_unmerge_group); @@ -311,15 +311,15 @@ EXPORT_SYMBOL_GPL(sysfs_unmerge_group); int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name, struct kobject *target, const char *link_name) { - struct sysfs_dirent *dir_sd; + struct kernfs_node *parent; int error = 0; - dir_sd = kernfs_find_and_get(kobj->sd, group_name); - if (!dir_sd) + parent = kernfs_find_and_get(kobj->sd, group_name); + if (!parent) return -ENOENT; - error = sysfs_create_link_sd(dir_sd, target, link_name); - kernfs_put(dir_sd); + error = sysfs_create_link_sd(parent, target, link_name); + kernfs_put(parent); return error; } @@ -334,12 +334,12 @@ EXPORT_SYMBOL_GPL(sysfs_add_link_to_group); void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name, const char *link_name) { - struct sysfs_dirent *dir_sd; + struct kernfs_node *parent; - dir_sd = kernfs_find_and_get(kobj->sd, group_name); - if (dir_sd) { - kernfs_remove_by_name(dir_sd, link_name); - kernfs_put(dir_sd); + parent = kernfs_find_and_get(kobj->sd, group_name); + if (parent) { + kernfs_remove_by_name(parent, link_name); + kernfs_put(parent); } } EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 8d075272cac..701a56f341c 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c @@ -20,7 +20,7 @@ #include "sysfs.h" static struct kernfs_root *sysfs_root; -struct sysfs_dirent *sysfs_root_sd; +struct kernfs_node *sysfs_root_kn; static struct dentry *sysfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) @@ -66,7 +66,7 @@ int __init sysfs_init(void) if (IS_ERR(sysfs_root)) return PTR_ERR(sysfs_root); - sysfs_root_sd = sysfs_root->sd; + sysfs_root_kn = sysfs_root->kn; err = register_filesystem(&sysfs_fs_type); if (err) { diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 1b8c9ed8511..4ed3d49ad27 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -18,66 +18,66 @@ #include "sysfs.h" -static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, - struct kobject *target, +static int sysfs_do_create_link_sd(struct kernfs_node *parent, + struct kobject *target_kobj, const char *name, int warn) { - struct sysfs_dirent *sd, *target_sd = NULL; + struct kernfs_node *kn, *target = NULL; - BUG_ON(!name || !parent_sd); + BUG_ON(!name || !parent); /* - * We don't own @target and it may be removed at any time. + * We don't own @target_kobj and it may be removed at any time. * Synchronize using sysfs_symlink_target_lock. See * sysfs_remove_dir() for details. */ spin_lock(&sysfs_symlink_target_lock); - if (target->sd) { - target_sd = target->sd; - kernfs_get(target_sd); + if (target_kobj->sd) { + target = target_kobj->sd; + kernfs_get(target); } spin_unlock(&sysfs_symlink_target_lock); - if (!target_sd) + if (!target) return -ENOENT; - sd = kernfs_create_link(parent_sd, name, target_sd); - kernfs_put(target_sd); + kn = kernfs_create_link(parent, name, target); + kernfs_put(target); - if (!IS_ERR(sd)) + if (!IS_ERR(kn)) return 0; - if (warn && PTR_ERR(sd) == -EEXIST) - sysfs_warn_dup(parent_sd, name); - return PTR_ERR(sd); + if (warn && PTR_ERR(kn) == -EEXIST) + sysfs_warn_dup(parent, name); + return PTR_ERR(kn); } /** * sysfs_create_link_sd - create symlink to a given object. - * @sd: directory we're creating the link in. + * @kn: directory we're creating the link in. * @target: object we're pointing to. * @name: name of the symlink. */ -int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target, +int sysfs_create_link_sd(struct kernfs_node *kn, struct kobject *target, const char *name) { - return sysfs_do_create_link_sd(sd, target, name, 1); + return sysfs_do_create_link_sd(kn, target, name, 1); } static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target, const char *name, int warn) { - struct sysfs_dirent *parent_sd = NULL; + struct kernfs_node *parent = NULL; if (!kobj) - parent_sd = sysfs_root_sd; + parent = sysfs_root_kn; else - parent_sd = kobj->sd; + parent = kobj->sd; - if (!parent_sd) + if (!parent) return -EFAULT; - return sysfs_do_create_link_sd(parent_sd, target, name, warn); + return sysfs_do_create_link_sd(parent, target, name, warn); } /** @@ -141,14 +141,14 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ, */ void sysfs_remove_link(struct kobject *kobj, const char *name) { - struct sysfs_dirent *parent_sd = NULL; + struct kernfs_node *parent = NULL; if (!kobj) - parent_sd = sysfs_root_sd; + parent = sysfs_root_kn; else - parent_sd = kobj->sd; + parent = kobj->sd; - kernfs_remove_by_name(parent_sd, name); + kernfs_remove_by_name(parent, name); } EXPORT_SYMBOL_GPL(sysfs_remove_link); @@ -165,33 +165,33 @@ EXPORT_SYMBOL_GPL(sysfs_remove_link); int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, const char *old, const char *new, const void *new_ns) { - struct sysfs_dirent *parent_sd, *sd = NULL; + struct kernfs_node *parent, *kn = NULL; const void *old_ns = NULL; int result; if (!kobj) - parent_sd = sysfs_root_sd; + parent = sysfs_root_kn; else - parent_sd = kobj->sd; + parent = kobj->sd; if (targ->sd) old_ns = targ->sd->s_ns; result = -ENOENT; - sd = kernfs_find_and_get_ns(parent_sd, old, old_ns); - if (!sd) + kn = kernfs_find_and_get_ns(parent, old, old_ns); + if (!kn) goto out; result = -EINVAL; - if (sysfs_type(sd) != SYSFS_KOBJ_LINK) + if (sysfs_type(kn) != SYSFS_KOBJ_LINK) goto out; - if (sd->s_symlink.target_sd->priv != targ) + if (kn->s_symlink.target_kn->priv != targ) goto out; - result = kernfs_rename_ns(sd, parent_sd, new, new_ns); + result = kernfs_rename_ns(kn, parent, new, new_ns); out: - kernfs_put(sd); + kernfs_put(kn); return result; } EXPORT_SYMBOL_GPL(sysfs_rename_link_ns); diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index c8e395b4933..0e2f1cccb81 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -16,28 +16,28 @@ /* * mount.c */ -extern struct sysfs_dirent *sysfs_root_sd; +extern struct kernfs_node *sysfs_root_kn; /* * dir.c */ extern spinlock_t sysfs_symlink_target_lock; -void sysfs_warn_dup(struct sysfs_dirent *parent, const char *name); +void sysfs_warn_dup(struct kernfs_node *parent, const char *name); /* * file.c */ -int sysfs_add_file(struct sysfs_dirent *dir_sd, +int sysfs_add_file(struct kernfs_node *parent, const struct attribute *attr, bool is_bin); -int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd, +int sysfs_add_file_mode_ns(struct kernfs_node *parent, const struct attribute *attr, bool is_bin, umode_t amode, const void *ns); /* * symlink.c */ -int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target, +int sysfs_create_link_sd(struct kernfs_node *kn, struct kobject *target, const char *name); #endif /* __SYSFS_INTERNAL_H */ diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index d6554130841..195d1c6a8b0 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -46,61 +46,61 @@ enum kernfs_node_flag { SYSFS_FLAG_LOCKDEP = 0x0100, }; -/* type-specific structures for sysfs_dirent->s_* union members */ -struct sysfs_elem_dir { +/* type-specific structures for kernfs_node union members */ +struct kernfs_elem_dir { unsigned long subdirs; - /* children rbtree starts here and goes through sd->s_rb */ + /* children rbtree starts here and goes through kn->s_rb */ struct rb_root children; /* * The kernfs hierarchy this directory belongs to. This fits - * better directly in sysfs_dirent but is here to save space. + * better directly in kernfs_node but is here to save space. */ struct kernfs_root *root; }; -struct sysfs_elem_symlink { - struct sysfs_dirent *target_sd; +struct kernfs_elem_symlink { + struct kernfs_node *target_kn; }; -struct sysfs_elem_attr { +struct kernfs_elem_attr { const struct kernfs_ops *ops; struct sysfs_open_dirent *open; loff_t size; }; /* - * sysfs_dirent - the building block of sysfs hierarchy. Each and every - * sysfs node is represented by single sysfs_dirent. Most fields are + * kernfs_node - the building block of kernfs hierarchy. Each and every + * kernfs node is represented by single kernfs_node. Most fields are * private to kernfs and shouldn't be accessed directly by kernfs users. * - * As long as s_count reference is held, the sysfs_dirent itself is - * accessible. Dereferencing s_elem or any other outer entity - * requires s_active reference. + * As long as s_count reference is held, the kernfs_node itself is + * accessible. Dereferencing elem or any other outer entity requires + * active reference. */ -struct sysfs_dirent { +struct kernfs_node { atomic_t s_count; atomic_t s_active; #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map dep_map; #endif /* the following two fields are published */ - struct sysfs_dirent *s_parent; + struct kernfs_node *s_parent; const char *s_name; struct rb_node s_rb; union { struct completion *completion; - struct sysfs_dirent *removed_list; + struct kernfs_node *removed_list; } u; const void *s_ns; /* namespace tag */ unsigned int s_hash; /* ns + name hash */ union { - struct sysfs_elem_dir s_dir; - struct sysfs_elem_symlink s_symlink; - struct sysfs_elem_attr s_attr; + struct kernfs_elem_dir s_dir; + struct kernfs_elem_symlink s_symlink; + struct kernfs_elem_attr s_attr; }; void *priv; @@ -113,7 +113,7 @@ struct sysfs_dirent { struct kernfs_root { /* published fields */ - struct sysfs_dirent *sd; + struct kernfs_node *kn; /* private fields, do not use outside kernfs proper */ struct ida ino_ida; @@ -121,7 +121,7 @@ struct kernfs_root { struct sysfs_open_file { /* published fields */ - struct sysfs_dirent *sd; + struct kernfs_node *kn; struct file *file; /* private fields, do not use outside kernfs proper */ @@ -170,64 +170,64 @@ struct kernfs_ops { #ifdef CONFIG_SYSFS -static inline enum kernfs_node_type sysfs_type(struct sysfs_dirent *sd) +static inline enum kernfs_node_type sysfs_type(struct kernfs_node *kn) { - return sd->s_flags & SYSFS_TYPE_MASK; + return kn->s_flags & SYSFS_TYPE_MASK; } /** * kernfs_enable_ns - enable namespace under a directory - * @sd: directory of interest, should be empty + * @kn: directory of interest, should be empty * - * This is to be called right after @sd is created to enable namespace - * under it. All children of @sd must have non-NULL namespace tags and + * This is to be called right after @kn is created to enable namespace + * under it. All children of @kn must have non-NULL namespace tags and * only the ones which match the super_block's tag will be visible. */ -static inline void kernfs_enable_ns(struct sysfs_dirent *sd) +static inline void kernfs_enable_ns(struct kernfs_node *kn) { - WARN_ON_ONCE(sysfs_type(sd) != SYSFS_DIR); - WARN_ON_ONCE(!RB_EMPTY_ROOT(&sd->s_dir.children)); - sd->s_flags |= SYSFS_FLAG_NS; + WARN_ON_ONCE(sysfs_type(kn) != SYSFS_DIR); + WARN_ON_ONCE(!RB_EMPTY_ROOT(&kn->s_dir.children)); + kn->s_flags |= SYSFS_FLAG_NS; } /** * kernfs_ns_enabled - test whether namespace is enabled - * @sd: the node to test + * @kn: the node to test * * Test whether namespace filtering is enabled for the children of @ns. */ -static inline bool kernfs_ns_enabled(struct sysfs_dirent *sd) +static inline bool kernfs_ns_enabled(struct kernfs_node *kn) { - return sd->s_flags & SYSFS_FLAG_NS; + return kn->s_flags & SYSFS_FLAG_NS; } -struct sysfs_dirent *kernfs_find_and_get_ns(struct sysfs_dirent *parent, - const char *name, const void *ns); -void kernfs_get(struct sysfs_dirent *sd); -void kernfs_put(struct sysfs_dirent *sd); +struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent, + const char *name, const void *ns); +void kernfs_get(struct kernfs_node *kn); +void kernfs_put(struct kernfs_node *kn); struct kernfs_root *kernfs_create_root(void *priv); void kernfs_destroy_root(struct kernfs_root *root); -struct sysfs_dirent *kernfs_create_dir_ns(struct sysfs_dirent *parent, - const char *name, void *priv, - const void *ns); -struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent, - const char *name, - umode_t mode, loff_t size, - const struct kernfs_ops *ops, - void *priv, const void *ns, - struct lock_class_key *key); -struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, - const char *name, - struct sysfs_dirent *target); -void kernfs_remove(struct sysfs_dirent *sd); -int kernfs_remove_by_name_ns(struct sysfs_dirent *parent, const char *name, +struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, + const char *name, void *priv, + const void *ns); +struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, + const char *name, + umode_t mode, loff_t size, + const struct kernfs_ops *ops, + void *priv, const void *ns, + struct lock_class_key *key); +struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, + const char *name, + struct kernfs_node *target); +void kernfs_remove(struct kernfs_node *kn); +int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, const void *ns); -int kernfs_rename_ns(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent, +int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, const char *new_name, const void *new_ns); -int kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr); -void kernfs_notify(struct sysfs_dirent *sd); +int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr); +void kernfs_notify(struct kernfs_node *kn); const void *kernfs_super_ns(struct super_block *sb); struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, @@ -238,60 +238,60 @@ void kernfs_init(void); #else /* CONFIG_SYSFS */ -static inline enum kernfs_node_type sysfs_type(struct sysfs_dirent *sd) +static inline enum kernfs_node_type sysfs_type(struct kernfs_node *kn) { return 0; } /* whatever */ -static inline void kernfs_enable_ns(struct sysfs_dirent *sd) { } +static inline void kernfs_enable_ns(struct kernfs_node *kn) { } -static inline bool kernfs_ns_enabled(struct sysfs_dirent *sd) +static inline bool kernfs_ns_enabled(struct kernfs_node *kn) { return false; } -static inline struct sysfs_dirent * -kernfs_find_and_get_ns(struct sysfs_dirent *parent, const char *name, +static inline struct kernfs_node * +kernfs_find_and_get_ns(struct kernfs_node *parent, const char *name, const void *ns) { return NULL; } -static inline void kernfs_get(struct sysfs_dirent *sd) { } -static inline void kernfs_put(struct sysfs_dirent *sd) { } +static inline void kernfs_get(struct kernfs_node *kn) { } +static inline void kernfs_put(struct kernfs_node *kn) { } static inline struct kernfs_root *kernfs_create_root(void *priv) { return ERR_PTR(-ENOSYS); } static inline void kernfs_destroy_root(struct kernfs_root *root) { } -static inline struct sysfs_dirent * -kernfs_create_dir_ns(struct sysfs_dirent *parent, const char *name, void *priv, +static inline struct kernfs_node * +kernfs_create_dir_ns(struct kernfs_node *parent, const char *name, void *priv, const void *ns) { return ERR_PTR(-ENOSYS); } -static inline struct sysfs_dirent * -kernfs_create_file_ns_key(struct sysfs_dirent *parent, const char *name, +static inline struct kernfs_node * +kernfs_create_file_ns_key(struct kernfs_node *parent, const char *name, umode_t mode, loff_t size, const struct kernfs_ops *ops, void *priv, const void *ns, struct lock_class_key *key) { return ERR_PTR(-ENOSYS); } -static inline struct sysfs_dirent * -kernfs_create_link(struct sysfs_dirent *parent, const char *name, - struct sysfs_dirent *target) +static inline struct kernfs_node * +kernfs_create_link(struct kernfs_node *parent, const char *name, + struct kernfs_node *target) { return ERR_PTR(-ENOSYS); } -static inline void kernfs_remove(struct sysfs_dirent *sd) { } +static inline void kernfs_remove(struct kernfs_node *kn) { } -static inline int kernfs_remove_by_name_ns(struct sysfs_dirent *parent, +static inline int kernfs_remove_by_name_ns(struct kernfs_node *kn, const char *name, const void *ns) { return -ENOSYS; } -static inline int kernfs_rename_ns(struct sysfs_dirent *sd, - struct sysfs_dirent *new_parent, +static inline int kernfs_rename_ns(struct kernfs_node *kn, + struct kernfs_node *new_parent, const char *new_name, const void *new_ns) { return -ENOSYS; } -static inline int kernfs_setattr(struct sysfs_dirent *sd, +static inline int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) { return -ENOSYS; } -static inline void kernfs_notify(struct sysfs_dirent *sd) { } +static inline void kernfs_notify(struct kernfs_node *kn) { } static inline const void *kernfs_super_ns(struct super_block *sb) { return NULL; } @@ -307,20 +307,20 @@ static inline void kernfs_init(void) { } #endif /* CONFIG_SYSFS */ -static inline struct sysfs_dirent * -kernfs_find_and_get(struct sysfs_dirent *sd, const char *name) +static inline struct kernfs_node * +kernfs_find_and_get(struct kernfs_node *kn, const char *name) { - return kernfs_find_and_get_ns(sd, name, NULL); + return kernfs_find_and_get_ns(kn, name, NULL); } -static inline struct sysfs_dirent * -kernfs_create_dir(struct sysfs_dirent *parent, const char *name, void *priv) +static inline struct kernfs_node * +kernfs_create_dir(struct kernfs_node *parent, const char *name, void *priv) { return kernfs_create_dir_ns(parent, name, priv, NULL); } -static inline struct sysfs_dirent * -kernfs_create_file_ns(struct sysfs_dirent *parent, const char *name, +static inline struct kernfs_node * +kernfs_create_file_ns(struct kernfs_node *parent, const char *name, umode_t mode, loff_t size, const struct kernfs_ops *ops, void *priv, const void *ns) { @@ -333,14 +333,14 @@ kernfs_create_file_ns(struct sysfs_dirent *parent, const char *name, ns, key); } -static inline struct sysfs_dirent * -kernfs_create_file(struct sysfs_dirent *parent, const char *name, umode_t mode, +static inline struct kernfs_node * +kernfs_create_file(struct kernfs_node *parent, const char *name, umode_t mode, loff_t size, const struct kernfs_ops *ops, void *priv) { return kernfs_create_file_ns(parent, name, mode, size, ops, priv, NULL); } -static inline int kernfs_remove_by_name(struct sysfs_dirent *parent, +static inline int kernfs_remove_by_name(struct kernfs_node *parent, const char *name) { return kernfs_remove_by_name_ns(parent, name, NULL); diff --git a/include/linux/kobject.h b/include/linux/kobject.h index e7ba650086c..926afb6f6b5 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -64,7 +64,7 @@ struct kobject { struct kobject *parent; struct kset *kset; struct kobj_type *ktype; - struct sysfs_dirent *sd; + struct kernfs_node *sd; struct kref kref; #ifdef CONFIG_DEBUG_KOBJECT_RELEASE struct delayed_work release; diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index cd8f90bf51a..30b2ebee643 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -438,26 +438,26 @@ static inline int sysfs_rename_link(struct kobject *kobj, struct kobject *target return sysfs_rename_link_ns(kobj, target, old_name, new_name, NULL); } -static inline void sysfs_notify_dirent(struct sysfs_dirent *sd) +static inline void sysfs_notify_dirent(struct kernfs_node *kn) { - kernfs_notify(sd); + kernfs_notify(kn); } -static inline struct sysfs_dirent * -sysfs_get_dirent(struct sysfs_dirent *parent_sd, const unsigned char *name) +static inline struct kernfs_node *sysfs_get_dirent(struct kernfs_node *parent, + const unsigned char *name) { - return kernfs_find_and_get(parent_sd, name); + return kernfs_find_and_get(parent, name); } -static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd) +static inline struct kernfs_node *sysfs_get(struct kernfs_node *kn) { - kernfs_get(sd); - return sd; + kernfs_get(kn); + return kn; } -static inline void sysfs_put(struct sysfs_dirent *sd) +static inline void sysfs_put(struct kernfs_node *kn) { - kernfs_put(sd); + kernfs_put(kn); } #endif /* _SYSFS_H_ */ diff --git a/lib/kobject.c b/lib/kobject.c index 94b321f4ac6..064451f2a6c 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -556,7 +556,7 @@ out: */ void kobject_del(struct kobject *kobj) { - struct sysfs_dirent *sd; + struct kernfs_node *sd; if (!kobj) return; -- cgit v1.2.3-70-g09d2 From adc5e8b58f4886d45f79f4ff41a09001a76a6b12 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 14:11:54 -0500 Subject: kernfs: drop s_ prefix from kernfs_node members kernfs has just been separated out from sysfs and we're already in full conflict mode. Nothing can make the situation any worse. Let's take the chance to name things properly. s_ prefix for kernfs members is used inconsistently and a misnomer now. It's not like kernfs_node is used widely across the kernel making the ability to grep for the members particularly useful. Let's just drop the prefix. This patch is strictly rename only and doesn't introduce any functional difference. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 198 ++++++++++++++++++++++---------------------- fs/kernfs/file.c | 52 ++++++------ fs/kernfs/inode.c | 30 +++---- fs/kernfs/kernfs-internal.h | 6 +- fs/kernfs/symlink.c | 32 +++---- fs/sysfs/dir.c | 12 +-- fs/sysfs/file.c | 16 ++-- fs/sysfs/symlink.c | 6 +- include/linux/kernfs.h | 38 ++++----- 9 files changed, 193 insertions(+), 197 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 800ebf52147..51fff9d2b33 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -19,7 +19,7 @@ DEFINE_MUTEX(sysfs_mutex); -#define rb_to_kn(X) rb_entry((X), struct kernfs_node, s_rb) +#define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb) /** * sysfs_name_hash @@ -47,18 +47,17 @@ static unsigned int sysfs_name_hash(const char *name, const void *ns) static int sysfs_name_compare(unsigned int hash, const char *name, const void *ns, const struct kernfs_node *kn) { - if (hash != kn->s_hash) - return hash - kn->s_hash; - if (ns != kn->s_ns) - return ns - kn->s_ns; - return strcmp(name, kn->s_name); + if (hash != kn->hash) + return hash - kn->hash; + if (ns != kn->ns) + return ns - kn->ns; + return strcmp(name, kn->name); } static int sysfs_sd_compare(const struct kernfs_node *left, const struct kernfs_node *right) { - return sysfs_name_compare(left->s_hash, left->s_name, left->s_ns, - right); + return sysfs_name_compare(left->hash, left->name, left->ns, right); } /** @@ -66,7 +65,7 @@ static int sysfs_sd_compare(const struct kernfs_node *left, * @kn: kernfs_node of interest * * Link @kn into its sibling rbtree which starts from - * @kn->s_parent->s_dir.children. + * @kn->parent->dir.children. * * Locking: * mutex_lock(sysfs_mutex) @@ -76,11 +75,11 @@ static int sysfs_sd_compare(const struct kernfs_node *left, */ static int sysfs_link_sibling(struct kernfs_node *kn) { - struct rb_node **node = &kn->s_parent->s_dir.children.rb_node; + struct rb_node **node = &kn->parent->dir.children.rb_node; struct rb_node *parent = NULL; if (sysfs_type(kn) == SYSFS_DIR) - kn->s_parent->s_dir.subdirs++; + kn->parent->dir.subdirs++; while (*node) { struct kernfs_node *pos; @@ -90,15 +89,15 @@ static int sysfs_link_sibling(struct kernfs_node *kn) parent = *node; result = sysfs_sd_compare(kn, pos); if (result < 0) - node = &pos->s_rb.rb_left; + node = &pos->rb.rb_left; else if (result > 0) - node = &pos->s_rb.rb_right; + node = &pos->rb.rb_right; else return -EEXIST; } /* add new node and rebalance the tree */ - rb_link_node(&kn->s_rb, parent, node); - rb_insert_color(&kn->s_rb, &kn->s_parent->s_dir.children); + rb_link_node(&kn->rb, parent, node); + rb_insert_color(&kn->rb, &kn->parent->dir.children); return 0; } @@ -107,7 +106,7 @@ static int sysfs_link_sibling(struct kernfs_node *kn) * @kn: kernfs_node of interest * * Unlink @kn from its sibling rbtree which starts from - * kn->s_parent->s_dir.children. + * kn->parent->dir.children. * * Locking: * mutex_lock(sysfs_mutex) @@ -115,9 +114,9 @@ static int sysfs_link_sibling(struct kernfs_node *kn) static void sysfs_unlink_sibling(struct kernfs_node *kn) { if (sysfs_type(kn) == SYSFS_DIR) - kn->s_parent->s_dir.subdirs--; + kn->parent->dir.subdirs--; - rb_erase(&kn->s_rb, &kn->s_parent->s_dir.children); + rb_erase(&kn->rb, &kn->parent->dir.children); } /** @@ -135,10 +134,10 @@ struct kernfs_node *sysfs_get_active(struct kernfs_node *kn) if (unlikely(!kn)) return NULL; - if (!atomic_inc_unless_negative(&kn->s_active)) + if (!atomic_inc_unless_negative(&kn->active)) return NULL; - if (kn->s_flags & SYSFS_FLAG_LOCKDEP) + if (kn->flags & SYSFS_FLAG_LOCKDEP) rwsem_acquire_read(&kn->dep_map, 0, 1, _RET_IP_); return kn; } @@ -157,9 +156,9 @@ void sysfs_put_active(struct kernfs_node *kn) if (unlikely(!kn)) return; - if (kn->s_flags & SYSFS_FLAG_LOCKDEP) + if (kn->flags & SYSFS_FLAG_LOCKDEP) rwsem_release(&kn->dep_map, 1, _RET_IP_); - v = atomic_dec_return(&kn->s_active); + v = atomic_dec_return(&kn->active); if (likely(v != SD_DEACTIVATED_BIAS)) return; @@ -181,7 +180,7 @@ static void sysfs_deactivate(struct kernfs_node *kn) DECLARE_COMPLETION_ONSTACK(wait); int v; - BUG_ON(!(kn->s_flags & SYSFS_FLAG_REMOVED)); + BUG_ON(!(kn->flags & SYSFS_FLAG_REMOVED)); if (!(sysfs_type(kn) & SYSFS_ACTIVE_REF)) return; @@ -192,7 +191,7 @@ static void sysfs_deactivate(struct kernfs_node *kn) /* atomic_add_return() is a mb(), put_active() will always see * the updated kn->u.completion. */ - v = atomic_add_return(SD_DEACTIVATED_BIAS, &kn->s_active); + v = atomic_add_return(SD_DEACTIVATED_BIAS, &kn->active); if (v != SD_DEACTIVATED_BIAS) { lock_contended(&kn->dep_map, _RET_IP_); @@ -210,8 +209,8 @@ static void sysfs_deactivate(struct kernfs_node *kn) void kernfs_get(struct kernfs_node *kn) { if (kn) { - WARN_ON(!atomic_read(&kn->s_count)); - atomic_inc(&kn->s_count); + WARN_ON(!atomic_read(&kn->count)); + atomic_inc(&kn->count); } } EXPORT_SYMBOL_GPL(kernfs_get); @@ -227,36 +226,36 @@ void kernfs_put(struct kernfs_node *kn) struct kernfs_node *parent; struct kernfs_root *root; - if (!kn || !atomic_dec_and_test(&kn->s_count)) + if (!kn || !atomic_dec_and_test(&kn->count)) return; root = kernfs_root(kn); repeat: /* Moving/renaming is always done while holding reference. - * kn->s_parent won't change beneath us. + * kn->parent won't change beneath us. */ - parent = kn->s_parent; + parent = kn->parent; - WARN(!(kn->s_flags & SYSFS_FLAG_REMOVED), + WARN(!(kn->flags & SYSFS_FLAG_REMOVED), "sysfs: free using entry: %s/%s\n", - parent ? parent->s_name : "", kn->s_name); + parent ? parent->name : "", kn->name); if (sysfs_type(kn) == SYSFS_KOBJ_LINK) - kernfs_put(kn->s_symlink.target_kn); + kernfs_put(kn->symlink.target_kn); if (sysfs_type(kn) & SYSFS_COPY_NAME) - kfree(kn->s_name); - if (kn->s_iattr) { - if (kn->s_iattr->ia_secdata) - security_release_secctx(kn->s_iattr->ia_secdata, - kn->s_iattr->ia_secdata_len); - simple_xattrs_free(&kn->s_iattr->xattrs); + kfree(kn->name); + if (kn->iattr) { + if (kn->iattr->ia_secdata) + security_release_secctx(kn->iattr->ia_secdata, + kn->iattr->ia_secdata_len); + simple_xattrs_free(&kn->iattr->xattrs); } - kfree(kn->s_iattr); - ida_simple_remove(&root->ino_ida, kn->s_ino); + kfree(kn->iattr); + ida_simple_remove(&root->ino_ida, kn->ino); kmem_cache_free(sysfs_dir_cachep, kn); kn = parent; if (kn) { - if (atomic_dec_and_test(&kn->s_count)) + if (atomic_dec_and_test(&kn->count)) goto repeat; } else { /* just released the root kn, free @root too */ @@ -269,7 +268,7 @@ EXPORT_SYMBOL_GPL(kernfs_put); static int sysfs_dentry_delete(const struct dentry *dentry) { struct kernfs_node *kn = dentry->d_fsdata; - return !(kn && !(kn->s_flags & SYSFS_FLAG_REMOVED)); + return !(kn && !(kn->flags & SYSFS_FLAG_REMOVED)); } static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) @@ -283,20 +282,20 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) mutex_lock(&sysfs_mutex); /* The sysfs dirent has been deleted */ - if (kn->s_flags & SYSFS_FLAG_REMOVED) + if (kn->flags & SYSFS_FLAG_REMOVED) goto out_bad; /* The sysfs dirent has been moved? */ - if (dentry->d_parent->d_fsdata != kn->s_parent) + if (dentry->d_parent->d_fsdata != kn->parent) goto out_bad; /* The sysfs dirent has been renamed */ - if (strcmp(dentry->d_name.name, kn->s_name) != 0) + if (strcmp(dentry->d_name.name, kn->name) != 0) goto out_bad; /* The sysfs dirent has been moved to a different namespace */ - if (kn->s_parent && kernfs_ns_enabled(kn->s_parent) && - sysfs_info(dentry->d_sb)->ns != kn->s_ns) + if (kn->parent && kernfs_ns_enabled(kn->parent) && + sysfs_info(dentry->d_sb)->ns != kn->ns) goto out_bad; mutex_unlock(&sysfs_mutex); @@ -356,14 +355,14 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL); if (ret < 0) goto err_out2; - kn->s_ino = ret; + kn->ino = ret; - atomic_set(&kn->s_count, 1); - atomic_set(&kn->s_active, 0); + atomic_set(&kn->count, 1); + atomic_set(&kn->active, 0); - kn->s_name = name; - kn->s_mode = mode; - kn->s_flags = type | SYSFS_FLAG_REMOVED; + kn->name = name; + kn->mode = mode; + kn->flags = type | SYSFS_FLAG_REMOVED; return kn; @@ -400,9 +399,9 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt) * @kn: kernfs_node to be added * @parent: the parent kernfs_node to add @kn to * - * Get @parent and set @kn->s_parent to it and increment nlink of - * the parent inode if @kn is a directory and link into the children - * list of the parent. + * Get @parent and set @kn->parent to it and increment nlink of the + * parent inode if @kn is a directory and link into the children list + * of the parent. * * This function should be called between calls to * sysfs_addrm_start() and sysfs_addrm_finish() and should be @@ -422,18 +421,17 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct kernfs_node *kn, struct sysfs_inode_attrs *ps_iattr; int ret; - if (has_ns != (bool)kn->s_ns) { + if (has_ns != (bool)kn->ns) { WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", - has_ns ? "required" : "invalid", - parent->s_name, kn->s_name); + has_ns ? "required" : "invalid", parent->name, kn->name); return -EINVAL; } if (sysfs_type(parent) != SYSFS_DIR) return -EINVAL; - kn->s_hash = sysfs_name_hash(kn->s_name, kn->s_ns); - kn->s_parent = parent; + kn->hash = sysfs_name_hash(kn->name, kn->ns); + kn->parent = parent; kernfs_get(parent); ret = sysfs_link_sibling(kn); @@ -441,14 +439,14 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct kernfs_node *kn, return ret; /* Update timestamps on the parent */ - ps_iattr = parent->s_iattr; + ps_iattr = parent->iattr; if (ps_iattr) { struct iattr *ps_iattrs = &ps_iattr->ia_iattr; ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; } /* Mark the entry added into directory tree */ - kn->s_flags &= ~SYSFS_FLAG_REMOVED; + kn->flags &= ~SYSFS_FLAG_REMOVED; return 0; } @@ -477,21 +475,21 @@ static void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, * Removal can be called multiple times on the same node. Only the * first invocation is effective and puts the base ref. */ - if (kn->s_flags & SYSFS_FLAG_REMOVED) + if (kn->flags & SYSFS_FLAG_REMOVED) return; - if (kn->s_parent) { + if (kn->parent) { sysfs_unlink_sibling(kn); /* Update timestamps on the parent */ - ps_iattr = kn->s_parent->s_iattr; + ps_iattr = kn->parent->iattr; if (ps_iattr) { ps_iattr->ia_iattr.ia_ctime = CURRENT_TIME; ps_iattr->ia_iattr.ia_mtime = CURRENT_TIME; } } - kn->s_flags |= SYSFS_FLAG_REMOVED; + kn->flags |= SYSFS_FLAG_REMOVED; kn->u.removed_list = acxt->removed; acxt->removed = kn; } @@ -538,7 +536,7 @@ static struct kernfs_node *kernfs_find_ns(struct kernfs_node *parent, const unsigned char *name, const void *ns) { - struct rb_node *node = parent->s_dir.children.rb_node; + struct rb_node *node = parent->dir.children.rb_node; bool has_ns = kernfs_ns_enabled(parent); unsigned int hash; @@ -546,8 +544,7 @@ static struct kernfs_node *kernfs_find_ns(struct kernfs_node *parent, if (has_ns != (bool)ns) { WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", - has_ns ? "required" : "invalid", - parent->s_name, name); + has_ns ? "required" : "invalid", parent->name, name); return NULL; } @@ -617,9 +614,9 @@ struct kernfs_root *kernfs_create_root(void *priv) return ERR_PTR(-ENOMEM); } - kn->s_flags &= ~SYSFS_FLAG_REMOVED; + kn->flags &= ~SYSFS_FLAG_REMOVED; kn->priv = priv; - kn->s_dir.root = root; + kn->dir.root = root; root->kn = kn; @@ -661,8 +658,8 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, if (!kn) return ERR_PTR(-ENOMEM); - kn->s_dir.root = parent->s_dir.root; - kn->s_ns = ns; + kn->dir.root = parent->dir.root; + kn->ns = ns; kn->priv = priv; /* link in */ @@ -738,7 +735,7 @@ static struct kernfs_node *sysfs_leftmost_descendant(struct kernfs_node *pos) if (sysfs_type(pos) != SYSFS_DIR) break; - rbn = rb_first(&pos->s_dir.children); + rbn = rb_first(&pos->dir.children); if (!rbn) break; @@ -773,12 +770,12 @@ static struct kernfs_node *sysfs_next_descendant_post(struct kernfs_node *pos, return NULL; /* if there's an unvisited sibling, visit its leftmost descendant */ - rbn = rb_next(&pos->s_rb); + rbn = rb_next(&pos->rb); if (rbn) return sysfs_leftmost_descendant(rb_to_kn(rbn)); /* no sibling left, visit parent */ - return pos->s_parent; + return pos->parent; } static void __kernfs_remove(struct sysfs_addrm_cxt *acxt, @@ -789,7 +786,7 @@ static void __kernfs_remove(struct sysfs_addrm_cxt *acxt, if (!kn) return; - pr_debug("sysfs %s: removing\n", kn->s_name); + pr_debug("sysfs %s: removing\n", kn->name); next = NULL; do { @@ -865,8 +862,8 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, mutex_lock(&sysfs_mutex); error = 0; - if ((kn->s_parent == new_parent) && (kn->s_ns == new_ns) && - (strcmp(kn->s_name, new_name) == 0)) + if ((kn->parent == new_parent) && (kn->ns == new_ns) && + (strcmp(kn->name, new_name) == 0)) goto out; /* nothing to rename */ error = -EEXIST; @@ -874,14 +871,14 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, goto out; /* rename kernfs_node */ - if (strcmp(kn->s_name, new_name) != 0) { + if (strcmp(kn->name, new_name) != 0) { error = -ENOMEM; new_name = kstrdup(new_name, GFP_KERNEL); if (!new_name) goto out; - kfree(kn->s_name); - kn->s_name = new_name; + kfree(kn->name); + kn->name = new_name; } /* @@ -889,10 +886,10 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, */ sysfs_unlink_sibling(kn); kernfs_get(new_parent); - kernfs_put(kn->s_parent); - kn->s_ns = new_ns; - kn->s_hash = sysfs_name_hash(kn->s_name, kn->s_ns); - kn->s_parent = new_parent; + kernfs_put(kn->parent); + kn->ns = new_ns; + kn->hash = sysfs_name_hash(kn->name, kn->ns); + kn->parent = new_parent; sysfs_link_sibling(kn); error = 0; @@ -904,7 +901,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, /* Relationship between s_mode and the DT_xxx types */ static inline unsigned char dt_type(struct kernfs_node *kn) { - return (kn->s_mode >> 12) & 15; + return (kn->mode >> 12) & 15; } static int sysfs_dir_release(struct inode *inode, struct file *filp) @@ -917,29 +914,28 @@ static struct kernfs_node *sysfs_dir_pos(const void *ns, struct kernfs_node *parent, loff_t hash, struct kernfs_node *pos) { if (pos) { - int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) && - pos->s_parent == parent && - hash == pos->s_hash; + int valid = !(pos->flags & SYSFS_FLAG_REMOVED) && + pos->parent == parent && hash == pos->hash; kernfs_put(pos); if (!valid) pos = NULL; } if (!pos && (hash > 1) && (hash < INT_MAX)) { - struct rb_node *node = parent->s_dir.children.rb_node; + struct rb_node *node = parent->dir.children.rb_node; while (node) { pos = rb_to_kn(node); - if (hash < pos->s_hash) + if (hash < pos->hash) node = node->rb_left; - else if (hash > pos->s_hash) + else if (hash > pos->hash) node = node->rb_right; else break; } } /* Skip over entries in the wrong namespace */ - while (pos && pos->s_ns != ns) { - struct rb_node *node = rb_next(&pos->s_rb); + while (pos && pos->ns != ns) { + struct rb_node *node = rb_next(&pos->rb); if (!node) pos = NULL; else @@ -954,12 +950,12 @@ static struct kernfs_node *sysfs_dir_next_pos(const void *ns, pos = sysfs_dir_pos(ns, parent, ino, pos); if (pos) do { - struct rb_node *node = rb_next(&pos->s_rb); + struct rb_node *node = rb_next(&pos->rb); if (!node) pos = NULL; else pos = rb_to_kn(node); - } while (pos && pos->s_ns != ns); + } while (pos && pos->ns != ns); return pos; } @@ -980,12 +976,12 @@ static int sysfs_readdir(struct file *file, struct dir_context *ctx) for (pos = sysfs_dir_pos(ns, parent, ctx->pos, pos); pos; pos = sysfs_dir_next_pos(ns, parent, ctx->pos, pos)) { - const char *name = pos->s_name; + const char *name = pos->name; unsigned int type = dt_type(pos); int len = strlen(name); - ino_t ino = pos->s_ino; + ino_t ino = pos->ino; - ctx->pos = pos->s_hash; + ctx->pos = pos->hash; file->private_data = pos; kernfs_get(pos); diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 1bf07ded826..5277021196a 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -21,7 +21,7 @@ * There's one sysfs_open_file for each open file and one sysfs_open_dirent * for each kernfs_node with one or more open files. * - * kernfs_node->s_attr.open points to sysfs_open_dirent. s_attr.open is + * kernfs_node->attr.open points to sysfs_open_dirent. attr.open is * protected by sysfs_open_dirent_lock. * * filp->private_data points to seq_file whose ->private points to @@ -49,9 +49,9 @@ static struct sysfs_open_file *sysfs_of(struct file *file) */ static const struct kernfs_ops *kernfs_ops(struct kernfs_node *kn) { - if (kn->s_flags & SYSFS_FLAG_LOCKDEP) + if (kn->flags & SYSFS_FLAG_LOCKDEP) lockdep_assert_held(kn); - return kn->s_attr.ops; + return kn->attr.ops; } static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) @@ -112,9 +112,9 @@ static int kernfs_seq_show(struct seq_file *sf, void *v) { struct sysfs_open_file *of = sf->private; - of->event = atomic_read(&of->kn->s_attr.open->event); + of->event = atomic_read(&of->kn->attr.open->event); - return of->kn->s_attr.ops->seq_show(sf, v); + return of->kn->attr.ops->seq_show(sf, v); } static const struct seq_operations kernfs_seq_ops = { @@ -189,7 +189,7 @@ static ssize_t kernfs_file_read(struct file *file, char __user *user_buf, { struct sysfs_open_file *of = sysfs_of(file); - if (of->kn->s_flags & SYSFS_FLAG_HAS_SEQ_SHOW) + if (of->kn->flags & SYSFS_FLAG_HAS_SEQ_SHOW) return seq_read(file, user_buf, count, ppos); else return kernfs_file_direct_read(of, user_buf, count, ppos); @@ -428,7 +428,7 @@ static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) * without grabbing @of->mutex by testing HAS_MMAP flag. See the * comment in kernfs_file_open() for more details. */ - if (!(of->kn->s_flags & SYSFS_FLAG_HAS_MMAP)) + if (!(of->kn->flags & SYSFS_FLAG_HAS_MMAP)) return -ENODEV; mutex_lock(&of->mutex); @@ -477,8 +477,8 @@ out_unlock: * @kn: target kernfs_node * @of: sysfs_open_file for this instance of open * - * If @kn->s_attr.open exists, increment its reference count; - * otherwise, create one. @of is chained to the files list. + * If @kn->attr.open exists, increment its reference count; otherwise, + * create one. @of is chained to the files list. * * LOCKING: * Kernel thread context (may sleep). @@ -495,12 +495,12 @@ static int sysfs_get_open_dirent(struct kernfs_node *kn, mutex_lock(&sysfs_open_file_mutex); spin_lock_irq(&sysfs_open_dirent_lock); - if (!kn->s_attr.open && new_od) { - kn->s_attr.open = new_od; + if (!kn->attr.open && new_od) { + kn->attr.open = new_od; new_od = NULL; } - od = kn->s_attr.open; + od = kn->attr.open; if (od) { atomic_inc(&od->refcnt); list_add_tail(&of->list, &od->files); @@ -531,7 +531,7 @@ static int sysfs_get_open_dirent(struct kernfs_node *kn, * @kn: target kernfs_nodet * @of: associated sysfs_open_file * - * Put @kn->s_attr.open and unlink @of from the files list. If + * Put @kn->attr.open and unlink @of from the files list. If * reference count reaches zero, disassociate and free it. * * LOCKING: @@ -540,7 +540,7 @@ static int sysfs_get_open_dirent(struct kernfs_node *kn, static void sysfs_put_open_dirent(struct kernfs_node *kn, struct sysfs_open_file *of) { - struct sysfs_open_dirent *od = kn->s_attr.open; + struct sysfs_open_dirent *od = kn->attr.open; unsigned long flags; mutex_lock(&sysfs_open_file_mutex); @@ -550,7 +550,7 @@ static void sysfs_put_open_dirent(struct kernfs_node *kn, list_del(&of->list); if (atomic_dec_and_test(&od->refcnt)) - kn->s_attr.open = NULL; + kn->attr.open = NULL; else od = NULL; @@ -668,11 +668,11 @@ void sysfs_unmap_bin_file(struct kernfs_node *kn) struct sysfs_open_dirent *od; struct sysfs_open_file *of; - if (!(kn->s_flags & SYSFS_FLAG_HAS_MMAP)) + if (!(kn->flags & SYSFS_FLAG_HAS_MMAP)) return; spin_lock_irq(&sysfs_open_dirent_lock); - od = kn->s_attr.open; + od = kn->attr.open; if (od) atomic_inc(&od->refcnt); spin_unlock_irq(&sysfs_open_dirent_lock); @@ -706,7 +706,7 @@ static unsigned int kernfs_file_poll(struct file *filp, poll_table *wait) { struct sysfs_open_file *of = sysfs_of(filp); struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; - struct sysfs_open_dirent *od = kn->s_attr.open; + struct sysfs_open_dirent *od = kn->attr.open; /* need parent for the kobj, grab both */ if (!sysfs_get_active(kn)) @@ -739,7 +739,7 @@ void kernfs_notify(struct kernfs_node *kn) spin_lock_irqsave(&sysfs_open_dirent_lock, flags); if (!WARN_ON(sysfs_type(kn) != SYSFS_KOBJ_ATTR)) { - od = kn->s_attr.open; + od = kn->attr.open; if (od) { atomic_inc(&od->event); wake_up_interruptible(&od->poll); @@ -789,27 +789,27 @@ struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, if (!kn) return ERR_PTR(-ENOMEM); - kn->s_attr.ops = ops; - kn->s_attr.size = size; - kn->s_ns = ns; + kn->attr.ops = ops; + kn->attr.size = size; + kn->ns = ns; kn->priv = priv; #ifdef CONFIG_DEBUG_LOCK_ALLOC if (key) { lockdep_init_map(&kn->dep_map, "s_active", key, 0); - kn->s_flags |= SYSFS_FLAG_LOCKDEP; + kn->flags |= SYSFS_FLAG_LOCKDEP; } #endif /* - * kn->s_attr.ops is accesible only while holding active ref. We + * kn->attr.ops is accesible only while holding active ref. We * need to know whether some ops are implemented outside active * ref. Cache their existence in flags. */ if (ops->seq_show) - kn->s_flags |= SYSFS_FLAG_HAS_SEQ_SHOW; + kn->flags |= SYSFS_FLAG_HAS_SEQ_SHOW; if (ops->mmap) - kn->s_flags |= SYSFS_FLAG_HAS_MMAP; + kn->flags |= SYSFS_FLAG_HAS_MMAP; sysfs_addrm_start(&acxt); rc = sysfs_add_one(&acxt, kn, parent); diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 9e74eed6353..f6c0aae3dd5 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -50,23 +50,23 @@ static struct sysfs_inode_attrs *sysfs_inode_attrs(struct kernfs_node *kn) { struct iattr *iattrs; - if (kn->s_iattr) - return kn->s_iattr; + if (kn->iattr) + return kn->iattr; - kn->s_iattr = kzalloc(sizeof(struct sysfs_inode_attrs), GFP_KERNEL); - if (!kn->s_iattr) + kn->iattr = kzalloc(sizeof(struct sysfs_inode_attrs), GFP_KERNEL); + if (!kn->iattr) return NULL; - iattrs = &kn->s_iattr->ia_iattr; + iattrs = &kn->iattr->ia_iattr; /* assign default attributes */ - iattrs->ia_mode = kn->s_mode; + iattrs->ia_mode = kn->mode; iattrs->ia_uid = GLOBAL_ROOT_UID; iattrs->ia_gid = GLOBAL_ROOT_GID; iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME; - simple_xattrs_init(&kn->s_iattr->xattrs); + simple_xattrs_init(&kn->iattr->xattrs); - return kn->s_iattr; + return kn->iattr; } static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) @@ -93,7 +93,7 @@ static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) iattrs->ia_ctime = iattr->ia_ctime; if (ia_valid & ATTR_MODE) { umode_t mode = iattr->ia_mode; - iattrs->ia_mode = kn->s_mode = mode; + iattrs->ia_mode = kn->mode = mode; } return 0; } @@ -256,9 +256,9 @@ static inline void set_inode_attr(struct inode *inode, struct iattr *iattr) static void sysfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) { - struct sysfs_inode_attrs *attrs = kn->s_iattr; + struct sysfs_inode_attrs *attrs = kn->iattr; - inode->i_mode = kn->s_mode; + inode->i_mode = kn->mode; if (attrs) { /* * kernfs_node has non-default attributes get them from @@ -270,7 +270,7 @@ static void sysfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) } if (sysfs_type(kn) == SYSFS_DIR) - set_nlink(inode, kn->s_dir.subdirs + 2); + set_nlink(inode, kn->dir.subdirs + 2); } int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, @@ -295,7 +295,7 @@ static void sysfs_init_inode(struct kernfs_node *kn, struct inode *inode) inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; inode->i_op = &sysfs_inode_operations; - set_default_inode_attr(inode, kn->s_mode); + set_default_inode_attr(inode, kn->mode); sysfs_refresh_inode(kn, inode); /* initialize inode according to type */ @@ -305,7 +305,7 @@ static void sysfs_init_inode(struct kernfs_node *kn, struct inode *inode) inode->i_fop = &sysfs_dir_operations; break; case SYSFS_KOBJ_ATTR: - inode->i_size = kn->s_attr.size; + inode->i_size = kn->attr.size; inode->i_fop = &kernfs_file_operations; break; case SYSFS_KOBJ_LINK: @@ -337,7 +337,7 @@ struct inode *sysfs_get_inode(struct super_block *sb, struct kernfs_node *kn) { struct inode *inode; - inode = iget_locked(sb, kn->s_ino); + inode = iget_locked(sb, kn->ino); if (inode && (inode->i_state & I_NEW)) sysfs_init_inode(kn, inode); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index b7ea76c6fb3..2dbb1cb95e7 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -39,9 +39,9 @@ struct sysfs_inode_attrs { static inline struct kernfs_root *kernfs_root(struct kernfs_node *kn) { /* if parent exists, it's always a dir; otherwise, @sd is a dir */ - if (kn->s_parent) - kn = kn->s_parent; - return kn->s_dir.root; + if (kn->parent) + kn = kn->parent; + return kn->dir.root; } /* diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 29dcf5e8deb..5ac1a57c380 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -36,8 +36,8 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, return ERR_PTR(-ENOMEM); if (kernfs_ns_enabled(parent)) - kn->s_ns = target->s_ns; - kn->s_symlink.target_kn = target; + kn->ns = target->ns; + kn->symlink.target_kn = target; kernfs_get(target); /* ref owned by symlink */ sysfs_addrm_start(&acxt); @@ -60,24 +60,24 @@ static int sysfs_get_target_path(struct kernfs_node *parent, /* go up to the root, stop at the base */ base = parent; - while (base->s_parent) { - kn = target->s_parent; - while (kn->s_parent && base != kn) - kn = kn->s_parent; + while (base->parent) { + kn = target->parent; + while (kn->parent && base != kn) + kn = kn->parent; if (base == kn) break; strcpy(s, "../"); s += 3; - base = base->s_parent; + base = base->parent; } /* determine end of target string for reverse fillup */ kn = target; - while (kn->s_parent && kn != base) { - len += strlen(kn->s_name) + 1; - kn = kn->s_parent; + while (kn->parent && kn != base) { + len += strlen(kn->name) + 1; + kn = kn->parent; } /* check limits */ @@ -89,15 +89,15 @@ static int sysfs_get_target_path(struct kernfs_node *parent, /* reverse fillup of target string from target to base */ kn = target; - while (kn->s_parent && kn != base) { - int slen = strlen(kn->s_name); + while (kn->parent && kn != base) { + int slen = strlen(kn->name); len -= slen; - strncpy(s + len, kn->s_name, slen); + strncpy(s + len, kn->name, slen); if (len) s[--len] = '/'; - kn = kn->s_parent; + kn = kn->parent; } return 0; @@ -106,8 +106,8 @@ static int sysfs_get_target_path(struct kernfs_node *parent, static int sysfs_getlink(struct dentry *dentry, char *path) { struct kernfs_node *kn = dentry->d_fsdata; - struct kernfs_node *parent = kn->s_parent; - struct kernfs_node *target = kn->s_symlink.target_kn; + struct kernfs_node *parent = kn->parent; + struct kernfs_node *target = kn->symlink.target_kn; int error; mutex_lock(&sysfs_mutex); diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index f1efe3df0de..4a800017558 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -29,11 +29,11 @@ DEFINE_SPINLOCK(sysfs_symlink_target_lock); */ static char *sysfs_pathname(struct kernfs_node *kn, char *path) { - if (kn->s_parent) { - sysfs_pathname(kn->s_parent, path); + if (kn->parent) { + sysfs_pathname(kn->parent, path); strlcat(path, "/", PATH_MAX); } - strlcat(path, kn->s_name, PATH_MAX); + strlcat(path, kn->name, PATH_MAX); return path; } @@ -121,7 +121,7 @@ void sysfs_remove_dir(struct kobject *kobj) int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name, const void *new_ns) { - struct kernfs_node *parent = kobj->sd->s_parent; + struct kernfs_node *parent = kobj->sd->parent; return kernfs_rename_ns(kobj->sd, parent, new_name, new_ns); } @@ -132,9 +132,9 @@ int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj, struct kernfs_node *kn = kobj->sd; struct kernfs_node *new_parent; - BUG_ON(!kn->s_parent); + BUG_ON(!kn->parent); new_parent = new_parent_kobj && new_parent_kobj->sd ? new_parent_kobj->sd : sysfs_root_kn; - return kernfs_rename_ns(kn, new_parent, kn->s_name, new_ns); + return kernfs_rename_ns(kn, new_parent, kn->name, new_ns); } diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index be1cc39035b..887703a7906 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -27,9 +27,9 @@ */ static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn) { - struct kobject *kobj = kn->s_parent->priv; + struct kobject *kobj = kn->parent->priv; - if (kn->s_flags & SYSFS_FLAG_LOCKDEP) + if (kn->flags & SYSFS_FLAG_LOCKDEP) lockdep_assert_held(kn); return kobj->ktype ? kobj->ktype->sysfs_ops : NULL; } @@ -42,7 +42,7 @@ static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn) static int sysfs_kf_seq_show(struct seq_file *sf, void *v) { struct sysfs_open_file *of = sf->private; - struct kobject *kobj = of->kn->s_parent->priv; + struct kobject *kobj = of->kn->parent->priv; const struct sysfs_ops *ops = sysfs_file_ops(of->kn); ssize_t count; char *buf; @@ -82,7 +82,7 @@ static ssize_t sysfs_kf_bin_read(struct sysfs_open_file *of, char *buf, size_t count, loff_t pos) { struct bin_attribute *battr = of->kn->priv; - struct kobject *kobj = of->kn->s_parent->priv; + struct kobject *kobj = of->kn->parent->priv; loff_t size = file_inode(of->file)->i_size; if (!count) @@ -106,7 +106,7 @@ static ssize_t sysfs_kf_write(struct sysfs_open_file *of, char *buf, size_t count, loff_t pos) { const struct sysfs_ops *ops = sysfs_file_ops(of->kn); - struct kobject *kobj = of->kn->s_parent->priv; + struct kobject *kobj = of->kn->parent->priv; if (!count) return 0; @@ -119,7 +119,7 @@ static ssize_t sysfs_kf_bin_write(struct sysfs_open_file *of, char *buf, size_t count, loff_t pos) { struct bin_attribute *battr = of->kn->priv; - struct kobject *kobj = of->kn->s_parent->priv; + struct kobject *kobj = of->kn->parent->priv; loff_t size = file_inode(of->file)->i_size; if (size) { @@ -140,7 +140,7 @@ static int sysfs_kf_bin_mmap(struct sysfs_open_file *of, struct vm_area_struct *vma) { struct bin_attribute *battr = of->kn->priv; - struct kobject *kobj = of->kn->s_parent->priv; + struct kobject *kobj = of->kn->parent->priv; return battr->mmap(of->file, kobj, battr, vma); } @@ -345,7 +345,7 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr, if (!kn) return -ENOENT; - newattrs.ia_mode = (mode & S_IALLUGO) | (kn->s_mode & ~S_IALLUGO); + newattrs.ia_mode = (mode & S_IALLUGO) | (kn->mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE; rc = kernfs_setattr(kn, &newattrs); diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 4ed3d49ad27..0d48ea91150 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -129,7 +129,7 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ, */ spin_lock(&sysfs_symlink_target_lock); if (targ->sd && kernfs_ns_enabled(kobj->sd)) - ns = targ->sd->s_ns; + ns = targ->sd->ns; spin_unlock(&sysfs_symlink_target_lock); kernfs_remove_by_name_ns(kobj->sd, name, ns); } @@ -175,7 +175,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, parent = kobj->sd; if (targ->sd) - old_ns = targ->sd->s_ns; + old_ns = targ->sd->ns; result = -ENOENT; kn = kernfs_find_and_get_ns(parent, old, old_ns); @@ -185,7 +185,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, result = -EINVAL; if (sysfs_type(kn) != SYSFS_KOBJ_LINK) goto out; - if (kn->s_symlink.target_kn->priv != targ) + if (kn->symlink.target_kn->priv != targ) goto out; result = kernfs_rename_ns(kn, parent, new, new_ns); diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 195d1c6a8b0..092469f60e3 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -49,7 +49,7 @@ enum kernfs_node_flag { /* type-specific structures for kernfs_node union members */ struct kernfs_elem_dir { unsigned long subdirs; - /* children rbtree starts here and goes through kn->s_rb */ + /* children rbtree starts here and goes through kn->rb */ struct rb_root children; /* @@ -79,36 +79,36 @@ struct kernfs_elem_attr { * active reference. */ struct kernfs_node { - atomic_t s_count; - atomic_t s_active; + atomic_t count; + atomic_t active; #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map dep_map; #endif /* the following two fields are published */ - struct kernfs_node *s_parent; - const char *s_name; + struct kernfs_node *parent; + const char *name; - struct rb_node s_rb; + struct rb_node rb; union { struct completion *completion; struct kernfs_node *removed_list; } u; - const void *s_ns; /* namespace tag */ - unsigned int s_hash; /* ns + name hash */ + const void *ns; /* namespace tag */ + unsigned int hash; /* ns + name hash */ union { - struct kernfs_elem_dir s_dir; - struct kernfs_elem_symlink s_symlink; - struct kernfs_elem_attr s_attr; + struct kernfs_elem_dir dir; + struct kernfs_elem_symlink symlink; + struct kernfs_elem_attr attr; }; void *priv; - unsigned short s_flags; - umode_t s_mode; - unsigned int s_ino; - struct sysfs_inode_attrs *s_iattr; + unsigned short flags; + umode_t mode; + unsigned int ino; + struct sysfs_inode_attrs *iattr; }; struct kernfs_root { @@ -172,7 +172,7 @@ struct kernfs_ops { static inline enum kernfs_node_type sysfs_type(struct kernfs_node *kn) { - return kn->s_flags & SYSFS_TYPE_MASK; + return kn->flags & SYSFS_TYPE_MASK; } /** @@ -186,8 +186,8 @@ static inline enum kernfs_node_type sysfs_type(struct kernfs_node *kn) static inline void kernfs_enable_ns(struct kernfs_node *kn) { WARN_ON_ONCE(sysfs_type(kn) != SYSFS_DIR); - WARN_ON_ONCE(!RB_EMPTY_ROOT(&kn->s_dir.children)); - kn->s_flags |= SYSFS_FLAG_NS; + WARN_ON_ONCE(!RB_EMPTY_ROOT(&kn->dir.children)); + kn->flags |= SYSFS_FLAG_NS; } /** @@ -198,7 +198,7 @@ static inline void kernfs_enable_ns(struct kernfs_node *kn) */ static inline bool kernfs_ns_enabled(struct kernfs_node *kn) { - return kn->s_flags & SYSFS_FLAG_NS; + return kn->flags & SYSFS_FLAG_NS; } struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent, -- cgit v1.2.3-70-g09d2 From c525aaddc366df23eb095d58a2bdf11cce62a98b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 14:11:55 -0500 Subject: kernfs: s/sysfs/kernfs/ in various data structures kernfs has just been separated out from sysfs and we're already in full conflict mode. Nothing can make the situation any worse. Let's take the chance to name things properly. This patch performs the following renames. * s/sysfs_open_dirent/kernfs_open_node/ * s/sysfs_open_file/kernfs_open_file/ * s/sysfs_inode_attrs/kernfs_iattrs/ * s/sysfs_addrm_cxt/kernfs_addrm_cxt/ * s/sysfs_super_info/kernfs_super_info/ * s/sysfs_info()/kernfs_info()/ * s/sysfs_open_dirent_lock/kernfs_open_node_lock/ * s/sysfs_open_file_mutex/kernfs_open_file_mutex/ * s/sysfs_of()/kernfs_of()/ This patch is strictly rename only and doesn't introduce any functional difference. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 28 ++++---- fs/kernfs/file.c | 172 ++++++++++++++++++++++---------------------- fs/kernfs/inode.c | 30 ++++---- fs/kernfs/kernfs-internal.h | 20 +++--- fs/kernfs/mount.c | 14 ++-- fs/kernfs/symlink.c | 2 +- fs/sysfs/file.c | 10 +-- include/linux/kernfs.h | 18 ++--- 8 files changed, 147 insertions(+), 147 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 51fff9d2b33..d038bb204b5 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -295,7 +295,7 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) /* The sysfs dirent has been moved to a different namespace */ if (kn->parent && kernfs_ns_enabled(kn->parent) && - sysfs_info(dentry->d_sb)->ns != kn->ns) + kernfs_info(dentry->d_sb)->ns != kn->ns) goto out_bad; mutex_unlock(&sysfs_mutex); @@ -375,7 +375,7 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, /** * sysfs_addrm_start - prepare for kernfs_node add/remove - * @acxt: pointer to sysfs_addrm_cxt to be used + * @acxt: pointer to kernfs_addrm_cxt to be used * * This function is called when the caller is about to add or remove * kernfs_node. This function acquires sysfs_mutex. @acxt is used to @@ -385,7 +385,7 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, * Kernel thread context (may sleep). sysfs_mutex is locked on * return. */ -void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt) +void sysfs_addrm_start(struct kernfs_addrm_cxt *acxt) __acquires(sysfs_mutex) { memset(acxt, 0, sizeof(*acxt)); @@ -414,11 +414,11 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt) * 0 on success, -EEXIST if entry with the given name already * exists. */ -int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct kernfs_node *kn, +int sysfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, struct kernfs_node *parent) { bool has_ns = kernfs_ns_enabled(parent); - struct sysfs_inode_attrs *ps_iattr; + struct kernfs_iattrs *ps_iattr; int ret; if (has_ns != (bool)kn->ns) { @@ -466,10 +466,10 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct kernfs_node *kn, * LOCKING: * Determined by sysfs_addrm_start(). */ -static void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, +static void sysfs_remove_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn) { - struct sysfs_inode_attrs *ps_iattr; + struct kernfs_iattrs *ps_iattr; /* * Removal can be called multiple times on the same node. Only the @@ -505,7 +505,7 @@ static void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, * LOCKING: * sysfs_mutex is released. */ -void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt) +void sysfs_addrm_finish(struct kernfs_addrm_cxt *acxt) __releases(sysfs_mutex) { /* release resources acquired by sysfs_addrm_start() */ @@ -649,7 +649,7 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, const void *ns) { umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; - struct sysfs_addrm_cxt acxt; + struct kernfs_addrm_cxt acxt; struct kernfs_node *kn; int rc; @@ -686,7 +686,7 @@ static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry, mutex_lock(&sysfs_mutex); if (kernfs_ns_enabled(parent)) - ns = sysfs_info(dir->i_sb)->ns; + ns = kernfs_info(dir->i_sb)->ns; kn = kernfs_find_ns(parent, dentry->d_name.name, ns); @@ -778,7 +778,7 @@ static struct kernfs_node *sysfs_next_descendant_post(struct kernfs_node *pos, return pos->parent; } -static void __kernfs_remove(struct sysfs_addrm_cxt *acxt, +static void __kernfs_remove(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn) { struct kernfs_node *pos, *next; @@ -805,7 +805,7 @@ static void __kernfs_remove(struct sysfs_addrm_cxt *acxt, */ void kernfs_remove(struct kernfs_node *kn) { - struct sysfs_addrm_cxt acxt; + struct kernfs_addrm_cxt acxt; sysfs_addrm_start(&acxt); __kernfs_remove(&acxt, kn); @@ -824,7 +824,7 @@ void kernfs_remove(struct kernfs_node *kn) int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, const void *ns) { - struct sysfs_addrm_cxt acxt; + struct kernfs_addrm_cxt acxt; struct kernfs_node *kn; if (!parent) { @@ -971,7 +971,7 @@ static int sysfs_readdir(struct file *file, struct dir_context *ctx) mutex_lock(&sysfs_mutex); if (kernfs_ns_enabled(parent)) - ns = sysfs_info(dentry->d_sb)->ns; + ns = kernfs_info(dentry->d_sb)->ns; for (pos = sysfs_dir_pos(ns, parent, ctx->pos, pos); pos; diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 5277021196a..2714a394cd8 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -18,27 +18,27 @@ #include "kernfs-internal.h" /* - * There's one sysfs_open_file for each open file and one sysfs_open_dirent + * There's one kernfs_open_file for each open file and one kernfs_open_node * for each kernfs_node with one or more open files. * - * kernfs_node->attr.open points to sysfs_open_dirent. attr.open is - * protected by sysfs_open_dirent_lock. + * kernfs_node->attr.open points to kernfs_open_node. attr.open is + * protected by kernfs_open_node_lock. * * filp->private_data points to seq_file whose ->private points to - * sysfs_open_file. sysfs_open_files are chained at - * sysfs_open_dirent->files, which is protected by sysfs_open_file_mutex. + * kernfs_open_file. kernfs_open_files are chained at + * kernfs_open_node->files, which is protected by kernfs_open_file_mutex. */ -static DEFINE_SPINLOCK(sysfs_open_dirent_lock); -static DEFINE_MUTEX(sysfs_open_file_mutex); +static DEFINE_SPINLOCK(kernfs_open_node_lock); +static DEFINE_MUTEX(kernfs_open_file_mutex); -struct sysfs_open_dirent { +struct kernfs_open_node { atomic_t refcnt; atomic_t event; wait_queue_head_t poll; - struct list_head files; /* goes through sysfs_open_file.list */ + struct list_head files; /* goes through kernfs_open_file.list */ }; -static struct sysfs_open_file *sysfs_of(struct file *file) +static struct kernfs_open_file *kernfs_of(struct file *file) { return ((struct seq_file *)file->private_data)->private; } @@ -56,7 +56,7 @@ static const struct kernfs_ops *kernfs_ops(struct kernfs_node *kn) static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) { - struct sysfs_open_file *of = sf->private; + struct kernfs_open_file *of = sf->private; const struct kernfs_ops *ops; /* @@ -81,7 +81,7 @@ static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) { - struct sysfs_open_file *of = sf->private; + struct kernfs_open_file *of = sf->private; const struct kernfs_ops *ops = kernfs_ops(of->kn); if (ops->seq_next) { @@ -98,7 +98,7 @@ static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) static void kernfs_seq_stop(struct seq_file *sf, void *v) { - struct sysfs_open_file *of = sf->private; + struct kernfs_open_file *of = sf->private; const struct kernfs_ops *ops = kernfs_ops(of->kn); if (ops->seq_stop) @@ -110,7 +110,7 @@ static void kernfs_seq_stop(struct seq_file *sf, void *v) static int kernfs_seq_show(struct seq_file *sf, void *v) { - struct sysfs_open_file *of = sf->private; + struct kernfs_open_file *of = sf->private; of->event = atomic_read(&of->kn->attr.open->event); @@ -130,7 +130,7 @@ static const struct seq_operations kernfs_seq_ops = { * it difficult to use seq_file. Implement simplistic custom buffering for * bin files. */ -static ssize_t kernfs_file_direct_read(struct sysfs_open_file *of, +static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, char __user *user_buf, size_t count, loff_t *ppos) { @@ -187,7 +187,7 @@ static ssize_t kernfs_file_direct_read(struct sysfs_open_file *of, static ssize_t kernfs_file_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct sysfs_open_file *of = sysfs_of(file); + struct kernfs_open_file *of = kernfs_of(file); if (of->kn->flags & SYSFS_FLAG_HAS_SEQ_SHOW) return seq_read(file, user_buf, count, ppos); @@ -214,7 +214,7 @@ static ssize_t kernfs_file_read(struct file *file, char __user *user_buf, static ssize_t kernfs_file_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - struct sysfs_open_file *of = sysfs_of(file); + struct kernfs_open_file *of = kernfs_of(file); ssize_t len = min_t(size_t, count, PAGE_SIZE); const struct kernfs_ops *ops; char *buf; @@ -259,7 +259,7 @@ out_free: static void kernfs_vma_open(struct vm_area_struct *vma) { struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); + struct kernfs_open_file *of = kernfs_of(file); if (!of->vm_ops) return; @@ -276,7 +276,7 @@ static void kernfs_vma_open(struct vm_area_struct *vma) static int kernfs_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); + struct kernfs_open_file *of = kernfs_of(file); int ret; if (!of->vm_ops) @@ -297,7 +297,7 @@ static int kernfs_vma_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) { struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); + struct kernfs_open_file *of = kernfs_of(file); int ret; if (!of->vm_ops) @@ -320,7 +320,7 @@ static int kernfs_vma_access(struct vm_area_struct *vma, unsigned long addr, void *buf, int len, int write) { struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); + struct kernfs_open_file *of = kernfs_of(file); int ret; if (!of->vm_ops) @@ -342,7 +342,7 @@ static int kernfs_vma_set_policy(struct vm_area_struct *vma, struct mempolicy *new) { struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); + struct kernfs_open_file *of = kernfs_of(file); int ret; if (!of->vm_ops) @@ -363,7 +363,7 @@ static struct mempolicy *kernfs_vma_get_policy(struct vm_area_struct *vma, unsigned long addr) { struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); + struct kernfs_open_file *of = kernfs_of(file); struct mempolicy *pol; if (!of->vm_ops) @@ -385,7 +385,7 @@ static int kernfs_vma_migrate(struct vm_area_struct *vma, unsigned long flags) { struct file *file = vma->vm_file; - struct sysfs_open_file *of = sysfs_of(file); + struct kernfs_open_file *of = kernfs_of(file); int ret; if (!of->vm_ops) @@ -417,7 +417,7 @@ static const struct vm_operations_struct kernfs_vm_ops = { static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) { - struct sysfs_open_file *of = sysfs_of(file); + struct kernfs_open_file *of = kernfs_of(file); const struct kernfs_ops *ops; int rc; @@ -473,9 +473,9 @@ out_unlock: } /** - * sysfs_get_open_dirent - get or create sysfs_open_dirent + * sysfs_get_open_dirent - get or create kernfs_open_node * @kn: target kernfs_node - * @of: sysfs_open_file for this instance of open + * @of: kernfs_open_file for this instance of open * * If @kn->attr.open exists, increment its reference count; otherwise, * create one. @of is chained to the files list. @@ -487,49 +487,49 @@ out_unlock: * 0 on success, -errno on failure. */ static int sysfs_get_open_dirent(struct kernfs_node *kn, - struct sysfs_open_file *of) + struct kernfs_open_file *of) { - struct sysfs_open_dirent *od, *new_od = NULL; + struct kernfs_open_node *on, *new_on = NULL; retry: - mutex_lock(&sysfs_open_file_mutex); - spin_lock_irq(&sysfs_open_dirent_lock); + mutex_lock(&kernfs_open_file_mutex); + spin_lock_irq(&kernfs_open_node_lock); - if (!kn->attr.open && new_od) { - kn->attr.open = new_od; - new_od = NULL; + if (!kn->attr.open && new_on) { + kn->attr.open = new_on; + new_on = NULL; } - od = kn->attr.open; - if (od) { - atomic_inc(&od->refcnt); - list_add_tail(&of->list, &od->files); + on = kn->attr.open; + if (on) { + atomic_inc(&on->refcnt); + list_add_tail(&of->list, &on->files); } - spin_unlock_irq(&sysfs_open_dirent_lock); - mutex_unlock(&sysfs_open_file_mutex); + spin_unlock_irq(&kernfs_open_node_lock); + mutex_unlock(&kernfs_open_file_mutex); - if (od) { - kfree(new_od); + if (on) { + kfree(new_on); return 0; } /* not there, initialize a new one and retry */ - new_od = kmalloc(sizeof(*new_od), GFP_KERNEL); - if (!new_od) + new_on = kmalloc(sizeof(*new_on), GFP_KERNEL); + if (!new_on) return -ENOMEM; - atomic_set(&new_od->refcnt, 0); - atomic_set(&new_od->event, 1); - init_waitqueue_head(&new_od->poll); - INIT_LIST_HEAD(&new_od->files); + atomic_set(&new_on->refcnt, 0); + atomic_set(&new_on->event, 1); + init_waitqueue_head(&new_on->poll); + INIT_LIST_HEAD(&new_on->files); goto retry; } /** - * sysfs_put_open_dirent - put sysfs_open_dirent + * sysfs_put_open_dirent - put kernfs_open_node * @kn: target kernfs_nodet - * @of: associated sysfs_open_file + * @of: associated kernfs_open_file * * Put @kn->attr.open and unlink @of from the files list. If * reference count reaches zero, disassociate and free it. @@ -538,33 +538,33 @@ static int sysfs_get_open_dirent(struct kernfs_node *kn, * None. */ static void sysfs_put_open_dirent(struct kernfs_node *kn, - struct sysfs_open_file *of) + struct kernfs_open_file *of) { - struct sysfs_open_dirent *od = kn->attr.open; + struct kernfs_open_node *on = kn->attr.open; unsigned long flags; - mutex_lock(&sysfs_open_file_mutex); - spin_lock_irqsave(&sysfs_open_dirent_lock, flags); + mutex_lock(&kernfs_open_file_mutex); + spin_lock_irqsave(&kernfs_open_node_lock, flags); if (of) list_del(&of->list); - if (atomic_dec_and_test(&od->refcnt)) + if (atomic_dec_and_test(&on->refcnt)) kn->attr.open = NULL; else - od = NULL; + on = NULL; - spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); - mutex_unlock(&sysfs_open_file_mutex); + spin_unlock_irqrestore(&kernfs_open_node_lock, flags); + mutex_unlock(&kernfs_open_file_mutex); - kfree(od); + kfree(on); } static int kernfs_file_open(struct inode *inode, struct file *file) { struct kernfs_node *kn = file->f_path.dentry->d_fsdata; const struct kernfs_ops *ops; - struct sysfs_open_file *of; + struct kernfs_open_file *of; bool has_read, has_write, has_mmap; int error = -EACCES; @@ -586,9 +586,9 @@ static int kernfs_file_open(struct inode *inode, struct file *file) (!(inode->i_mode & S_IRUGO) || !has_read)) goto err_out; - /* allocate a sysfs_open_file for the file */ + /* allocate a kernfs_open_file for the file */ error = -ENOMEM; - of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL); + of = kzalloc(sizeof(struct kernfs_open_file), GFP_KERNEL); if (!of) goto err_out; @@ -654,7 +654,7 @@ err_out: static int kernfs_file_release(struct inode *inode, struct file *filp) { struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; - struct sysfs_open_file *of = sysfs_of(filp); + struct kernfs_open_file *of = kernfs_of(filp); sysfs_put_open_dirent(kn, of); seq_release(inode, filp); @@ -665,26 +665,26 @@ static int kernfs_file_release(struct inode *inode, struct file *filp) void sysfs_unmap_bin_file(struct kernfs_node *kn) { - struct sysfs_open_dirent *od; - struct sysfs_open_file *of; + struct kernfs_open_node *on; + struct kernfs_open_file *of; if (!(kn->flags & SYSFS_FLAG_HAS_MMAP)) return; - spin_lock_irq(&sysfs_open_dirent_lock); - od = kn->attr.open; - if (od) - atomic_inc(&od->refcnt); - spin_unlock_irq(&sysfs_open_dirent_lock); - if (!od) + spin_lock_irq(&kernfs_open_node_lock); + on = kn->attr.open; + if (on) + atomic_inc(&on->refcnt); + spin_unlock_irq(&kernfs_open_node_lock); + if (!on) return; - mutex_lock(&sysfs_open_file_mutex); - list_for_each_entry(of, &od->files, list) { + mutex_lock(&kernfs_open_file_mutex); + list_for_each_entry(of, &on->files, list) { struct inode *inode = file_inode(of->file); unmap_mapping_range(inode->i_mapping, 0, 0, 1); } - mutex_unlock(&sysfs_open_file_mutex); + mutex_unlock(&kernfs_open_file_mutex); sysfs_put_open_dirent(kn, NULL); } @@ -704,19 +704,19 @@ void sysfs_unmap_bin_file(struct kernfs_node *kn) */ static unsigned int kernfs_file_poll(struct file *filp, poll_table *wait) { - struct sysfs_open_file *of = sysfs_of(filp); + struct kernfs_open_file *of = kernfs_of(filp); struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; - struct sysfs_open_dirent *od = kn->attr.open; + struct kernfs_open_node *on = kn->attr.open; /* need parent for the kobj, grab both */ if (!sysfs_get_active(kn)) goto trigger; - poll_wait(filp, &od->poll, wait); + poll_wait(filp, &on->poll, wait); sysfs_put_active(kn); - if (of->event != atomic_read(&od->event)) + if (of->event != atomic_read(&on->event)) goto trigger; return DEFAULT_POLLMASK; @@ -733,20 +733,20 @@ static unsigned int kernfs_file_poll(struct file *filp, poll_table *wait) */ void kernfs_notify(struct kernfs_node *kn) { - struct sysfs_open_dirent *od; + struct kernfs_open_node *on; unsigned long flags; - spin_lock_irqsave(&sysfs_open_dirent_lock, flags); + spin_lock_irqsave(&kernfs_open_node_lock, flags); if (!WARN_ON(sysfs_type(kn) != SYSFS_KOBJ_ATTR)) { - od = kn->attr.open; - if (od) { - atomic_inc(&od->event); - wake_up_interruptible(&od->poll); + on = kn->attr.open; + if (on) { + atomic_inc(&on->event); + wake_up_interruptible(&on->poll); } } - spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); + spin_unlock_irqrestore(&kernfs_open_node_lock, flags); } EXPORT_SYMBOL_GPL(kernfs_notify); @@ -780,7 +780,7 @@ struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, void *priv, const void *ns, struct lock_class_key *key) { - struct sysfs_addrm_cxt acxt; + struct kernfs_addrm_cxt acxt; struct kernfs_node *kn; int rc; diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index f6c0aae3dd5..a0e0038fd57 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -46,14 +46,14 @@ void __init sysfs_inode_init(void) panic("failed to init sysfs_backing_dev_info"); } -static struct sysfs_inode_attrs *sysfs_inode_attrs(struct kernfs_node *kn) +static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) { struct iattr *iattrs; if (kn->iattr) return kn->iattr; - kn->iattr = kzalloc(sizeof(struct sysfs_inode_attrs), GFP_KERNEL); + kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL); if (!kn->iattr) return NULL; iattrs = &kn->iattr->ia_iattr; @@ -71,11 +71,11 @@ static struct sysfs_inode_attrs *sysfs_inode_attrs(struct kernfs_node *kn) static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) { - struct sysfs_inode_attrs *attrs; + struct kernfs_iattrs *attrs; struct iattr *iattrs; unsigned int ia_valid = iattr->ia_valid; - attrs = sysfs_inode_attrs(kn); + attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; @@ -144,11 +144,11 @@ out: static int sysfs_sd_setsecdata(struct kernfs_node *kn, void **secdata, u32 *secdata_len) { - struct sysfs_inode_attrs *attrs; + struct kernfs_iattrs *attrs; void *old_secdata; size_t old_secdata_len; - attrs = sysfs_inode_attrs(kn); + attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; @@ -167,12 +167,12 @@ int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { struct kernfs_node *kn = dentry->d_fsdata; - struct sysfs_inode_attrs *attrs; + struct kernfs_iattrs *attrs; void *secdata; int error; u32 secdata_len = 0; - attrs = sysfs_inode_attrs(kn); + attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; @@ -205,9 +205,9 @@ int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, int sysfs_removexattr(struct dentry *dentry, const char *name) { struct kernfs_node *kn = dentry->d_fsdata; - struct sysfs_inode_attrs *attrs; + struct kernfs_iattrs *attrs; - attrs = sysfs_inode_attrs(kn); + attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; @@ -218,9 +218,9 @@ ssize_t sysfs_getxattr(struct dentry *dentry, const char *name, void *buf, size_t size) { struct kernfs_node *kn = dentry->d_fsdata; - struct sysfs_inode_attrs *attrs; + struct kernfs_iattrs *attrs; - attrs = sysfs_inode_attrs(kn); + attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; @@ -230,9 +230,9 @@ ssize_t sysfs_getxattr(struct dentry *dentry, const char *name, void *buf, ssize_t sysfs_listxattr(struct dentry *dentry, char *buf, size_t size) { struct kernfs_node *kn = dentry->d_fsdata; - struct sysfs_inode_attrs *attrs; + struct kernfs_iattrs *attrs; - attrs = sysfs_inode_attrs(kn); + attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; @@ -256,7 +256,7 @@ static inline void set_inode_attr(struct inode *inode, struct iattr *iattr) static void sysfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) { - struct sysfs_inode_attrs *attrs = kn->iattr; + struct kernfs_iattrs *attrs = kn->iattr; inode->i_mode = kn->mode; if (attrs) { diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 2dbb1cb95e7..573f6698864 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -18,7 +18,7 @@ #include -struct sysfs_inode_attrs { +struct kernfs_iattrs { struct iattr ia_iattr; void *ia_secdata; u32 ia_secdata_len; @@ -47,14 +47,14 @@ static inline struct kernfs_root *kernfs_root(struct kernfs_node *kn) /* * Context structure to be used while adding/removing nodes. */ -struct sysfs_addrm_cxt { +struct kernfs_addrm_cxt { struct kernfs_node *removed; }; /* * mount.c */ -struct sysfs_super_info { +struct kernfs_super_info { /* * The root associated with this super_block. Each super_block is * identified by the root and ns it's associated with. @@ -63,13 +63,13 @@ struct sysfs_super_info { /* * Each sb is associated with one namespace tag, currently the - * network namespace of the task which mounted this sysfs instance. - * If multiple tags become necessary, make the following an array - * and compare kernfs_node tag against every entry. + * network namespace of the task which mounted this kernfs + * instance. If multiple tags become necessary, make the following + * an array and compare kernfs_node tag against every entry. */ const void *ns; }; -#define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info)) +#define kernfs_info(SB) ((struct kernfs_super_info *)(SB->s_fs_info)) extern struct kmem_cache *sysfs_dir_cachep; @@ -100,10 +100,10 @@ extern const struct inode_operations sysfs_dir_inode_operations; struct kernfs_node *sysfs_get_active(struct kernfs_node *kn); void sysfs_put_active(struct kernfs_node *kn); -void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt); -int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct kernfs_node *kn, +void sysfs_addrm_start(struct kernfs_addrm_cxt *acxt); +int sysfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, struct kernfs_node *parent); -void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); +void sysfs_addrm_finish(struct kernfs_addrm_cxt *acxt); struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, const char *name, umode_t mode, int type); diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index 9dbbf37b1af..e0796dcb606 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -27,7 +27,7 @@ static const struct super_operations sysfs_ops = { static int sysfs_fill_super(struct super_block *sb) { - struct sysfs_super_info *info = sysfs_info(sb); + struct kernfs_super_info *info = kernfs_info(sb); struct inode *inode; struct dentry *root; @@ -61,8 +61,8 @@ static int sysfs_fill_super(struct super_block *sb) static int sysfs_test_super(struct super_block *sb, void *data) { - struct sysfs_super_info *sb_info = sysfs_info(sb); - struct sysfs_super_info *info = data; + struct kernfs_super_info *sb_info = kernfs_info(sb); + struct kernfs_super_info *info = data; return sb_info->root == info->root && sb_info->ns == info->ns; } @@ -84,7 +84,7 @@ static int sysfs_set_super(struct super_block *sb, void *data) */ const void *kernfs_super_ns(struct super_block *sb) { - struct sysfs_super_info *info = sysfs_info(sb); + struct kernfs_super_info *info = kernfs_info(sb); return info->ns; } @@ -107,7 +107,7 @@ struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, struct kernfs_root *root, const void *ns) { struct super_block *sb; - struct sysfs_super_info *info; + struct kernfs_super_info *info; int error; info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -144,12 +144,12 @@ struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, */ void kernfs_kill_sb(struct super_block *sb) { - struct sysfs_super_info *info = sysfs_info(sb); + struct kernfs_super_info *info = kernfs_info(sb); struct kernfs_node *root_kn = sb->s_root->d_fsdata; /* * Remove the superblock from fs_supers/s_instances - * so we can't find it, before freeing sysfs_super_info. + * so we can't find it, before freeing kernfs_super_info. */ kill_anon_super(sb); kfree(info); diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 5ac1a57c380..f36e3f1b247 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -27,7 +27,7 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, struct kernfs_node *target) { struct kernfs_node *kn; - struct sysfs_addrm_cxt acxt; + struct kernfs_addrm_cxt acxt; int error; kn = sysfs_new_dirent(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO, diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 887703a7906..fd104b282f8 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -41,7 +41,7 @@ static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn) */ static int sysfs_kf_seq_show(struct seq_file *sf, void *v) { - struct sysfs_open_file *of = sf->private; + struct kernfs_open_file *of = sf->private; struct kobject *kobj = of->kn->parent->priv; const struct sysfs_ops *ops = sysfs_file_ops(of->kn); ssize_t count; @@ -78,7 +78,7 @@ static int sysfs_kf_seq_show(struct seq_file *sf, void *v) return 0; } -static ssize_t sysfs_kf_bin_read(struct sysfs_open_file *of, char *buf, +static ssize_t sysfs_kf_bin_read(struct kernfs_open_file *of, char *buf, size_t count, loff_t pos) { struct bin_attribute *battr = of->kn->priv; @@ -102,7 +102,7 @@ static ssize_t sysfs_kf_bin_read(struct sysfs_open_file *of, char *buf, } /* kernfs write callback for regular sysfs files */ -static ssize_t sysfs_kf_write(struct sysfs_open_file *of, char *buf, +static ssize_t sysfs_kf_write(struct kernfs_open_file *of, char *buf, size_t count, loff_t pos) { const struct sysfs_ops *ops = sysfs_file_ops(of->kn); @@ -115,7 +115,7 @@ static ssize_t sysfs_kf_write(struct sysfs_open_file *of, char *buf, } /* kernfs write callback for bin sysfs files */ -static ssize_t sysfs_kf_bin_write(struct sysfs_open_file *of, char *buf, +static ssize_t sysfs_kf_bin_write(struct kernfs_open_file *of, char *buf, size_t count, loff_t pos) { struct bin_attribute *battr = of->kn->priv; @@ -136,7 +136,7 @@ static ssize_t sysfs_kf_bin_write(struct sysfs_open_file *of, char *buf, return battr->write(of->file, kobj, battr, buf, pos, count); } -static int sysfs_kf_bin_mmap(struct sysfs_open_file *of, +static int sysfs_kf_bin_mmap(struct kernfs_open_file *of, struct vm_area_struct *vma) { struct bin_attribute *battr = of->kn->priv; diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 092469f60e3..757647c4cb3 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -24,8 +24,8 @@ struct vm_area_struct; struct super_block; struct file_system_type; -struct sysfs_open_dirent; -struct sysfs_inode_attrs; +struct kernfs_open_node; +struct kernfs_iattrs; enum kernfs_node_type { SYSFS_DIR = 0x0001, @@ -65,7 +65,7 @@ struct kernfs_elem_symlink { struct kernfs_elem_attr { const struct kernfs_ops *ops; - struct sysfs_open_dirent *open; + struct kernfs_open_node *open; loff_t size; }; @@ -108,7 +108,7 @@ struct kernfs_node { unsigned short flags; umode_t mode; unsigned int ino; - struct sysfs_inode_attrs *iattr; + struct kernfs_iattrs *iattr; }; struct kernfs_root { @@ -119,7 +119,7 @@ struct kernfs_root { struct ida ino_ida; }; -struct sysfs_open_file { +struct kernfs_open_file { /* published fields */ struct kernfs_node *kn; struct file *file; @@ -140,7 +140,7 @@ struct kernfs_ops { * If seq_show() is present, seq_file path is active. Other seq * operations are optional and if not implemented, the behavior is * equivalent to single_open(). @sf->private points to the - * associated sysfs_open_file. + * associated kernfs_open_file. * * read() is bounced through kernel buffer and a read larger than * PAGE_SIZE results in partial operation of PAGE_SIZE. @@ -151,17 +151,17 @@ struct kernfs_ops { void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos); void (*seq_stop)(struct seq_file *sf, void *v); - ssize_t (*read)(struct sysfs_open_file *of, char *buf, size_t bytes, + ssize_t (*read)(struct kernfs_open_file *of, char *buf, size_t bytes, loff_t off); /* * write() is bounced through kernel buffer and a write larger than * PAGE_SIZE results in partial operation of PAGE_SIZE. */ - ssize_t (*write)(struct sysfs_open_file *of, char *buf, size_t bytes, + ssize_t (*write)(struct kernfs_open_file *of, char *buf, size_t bytes, loff_t off); - int (*mmap)(struct sysfs_open_file *of, struct vm_area_struct *vma); + int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma); #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lock_class_key lockdep_key; -- cgit v1.2.3-70-g09d2 From df23fc39bce03bb26e63bea57fc5f5bf6882d74b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 14:11:56 -0500 Subject: kernfs: s/sysfs/kernfs/ in constants kernfs has just been separated out from sysfs and we're already in full conflict mode. Nothing can make the situation any worse. Let's take the chance to name things properly. This patch performs the following renames. * s/SYSFS_DIR/KERNFS_DIR/ * s/SYSFS_KOBJ_ATTR/KERNFS_FILE/ * s/SYSFS_KOBJ_LINK/KERNFS_LINK/ * s/SYSFS_{TYPE_FLAGS}/KERNFS_{TYPE_FLAGS}/ * s/SYSFS_FLAG_{FLAG}/KERNFS_{FLAG}/ * s/sysfs_type()/kernfs_type()/ * s/SD_DEACTIVATED_BIAS/KN_DEACTIVATED_BIAS/ This patch is strictly rename only and doesn't introduce any functional difference. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 50 ++++++++++++++++++++++----------------------- fs/kernfs/file.c | 18 ++++++++-------- fs/kernfs/inode.c | 10 ++++----- fs/kernfs/kernfs-internal.h | 4 ++-- fs/kernfs/symlink.c | 2 +- fs/sysfs/dir.c | 2 +- fs/sysfs/file.c | 2 +- fs/sysfs/symlink.c | 2 +- include/linux/kernfs.h | 36 ++++++++++++++++---------------- 9 files changed, 63 insertions(+), 63 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index d038bb204b5..bc8a3b367a8 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -78,7 +78,7 @@ static int sysfs_link_sibling(struct kernfs_node *kn) struct rb_node **node = &kn->parent->dir.children.rb_node; struct rb_node *parent = NULL; - if (sysfs_type(kn) == SYSFS_DIR) + if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs++; while (*node) { @@ -113,7 +113,7 @@ static int sysfs_link_sibling(struct kernfs_node *kn) */ static void sysfs_unlink_sibling(struct kernfs_node *kn) { - if (sysfs_type(kn) == SYSFS_DIR) + if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs--; rb_erase(&kn->rb, &kn->parent->dir.children); @@ -137,7 +137,7 @@ struct kernfs_node *sysfs_get_active(struct kernfs_node *kn) if (!atomic_inc_unless_negative(&kn->active)) return NULL; - if (kn->flags & SYSFS_FLAG_LOCKDEP) + if (kn->flags & KERNFS_LOCKDEP) rwsem_acquire_read(&kn->dep_map, 0, 1, _RET_IP_); return kn; } @@ -156,10 +156,10 @@ void sysfs_put_active(struct kernfs_node *kn) if (unlikely(!kn)) return; - if (kn->flags & SYSFS_FLAG_LOCKDEP) + if (kn->flags & KERNFS_LOCKDEP) rwsem_release(&kn->dep_map, 1, _RET_IP_); v = atomic_dec_return(&kn->active); - if (likely(v != SD_DEACTIVATED_BIAS)) + if (likely(v != KN_DEACTIVATED_BIAS)) return; /* @@ -180,9 +180,9 @@ static void sysfs_deactivate(struct kernfs_node *kn) DECLARE_COMPLETION_ONSTACK(wait); int v; - BUG_ON(!(kn->flags & SYSFS_FLAG_REMOVED)); + BUG_ON(!(kn->flags & KERNFS_REMOVED)); - if (!(sysfs_type(kn) & SYSFS_ACTIVE_REF)) + if (!(kernfs_type(kn) & KERNFS_ACTIVE_REF)) return; kn->u.completion = (void *)&wait; @@ -191,9 +191,9 @@ static void sysfs_deactivate(struct kernfs_node *kn) /* atomic_add_return() is a mb(), put_active() will always see * the updated kn->u.completion. */ - v = atomic_add_return(SD_DEACTIVATED_BIAS, &kn->active); + v = atomic_add_return(KN_DEACTIVATED_BIAS, &kn->active); - if (v != SD_DEACTIVATED_BIAS) { + if (v != KN_DEACTIVATED_BIAS) { lock_contended(&kn->dep_map, _RET_IP_); wait_for_completion(&wait); } @@ -235,13 +235,13 @@ void kernfs_put(struct kernfs_node *kn) */ parent = kn->parent; - WARN(!(kn->flags & SYSFS_FLAG_REMOVED), + WARN(!(kn->flags & KERNFS_REMOVED), "sysfs: free using entry: %s/%s\n", parent ? parent->name : "", kn->name); - if (sysfs_type(kn) == SYSFS_KOBJ_LINK) + if (kernfs_type(kn) == KERNFS_LINK) kernfs_put(kn->symlink.target_kn); - if (sysfs_type(kn) & SYSFS_COPY_NAME) + if (kernfs_type(kn) & KERNFS_COPY_NAME) kfree(kn->name); if (kn->iattr) { if (kn->iattr->ia_secdata) @@ -268,7 +268,7 @@ EXPORT_SYMBOL_GPL(kernfs_put); static int sysfs_dentry_delete(const struct dentry *dentry) { struct kernfs_node *kn = dentry->d_fsdata; - return !(kn && !(kn->flags & SYSFS_FLAG_REMOVED)); + return !(kn && !(kn->flags & KERNFS_REMOVED)); } static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) @@ -282,7 +282,7 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) mutex_lock(&sysfs_mutex); /* The sysfs dirent has been deleted */ - if (kn->flags & SYSFS_FLAG_REMOVED) + if (kn->flags & KERNFS_REMOVED) goto out_bad; /* The sysfs dirent has been moved? */ @@ -342,7 +342,7 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, struct kernfs_node *kn; int ret; - if (type & SYSFS_COPY_NAME) { + if (type & KERNFS_COPY_NAME) { name = dup_name = kstrdup(name, GFP_KERNEL); if (!name) return NULL; @@ -362,7 +362,7 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, kn->name = name; kn->mode = mode; - kn->flags = type | SYSFS_FLAG_REMOVED; + kn->flags = type | KERNFS_REMOVED; return kn; @@ -427,7 +427,7 @@ int sysfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, return -EINVAL; } - if (sysfs_type(parent) != SYSFS_DIR) + if (kernfs_type(parent) != KERNFS_DIR) return -EINVAL; kn->hash = sysfs_name_hash(kn->name, kn->ns); @@ -446,7 +446,7 @@ int sysfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, } /* Mark the entry added into directory tree */ - kn->flags &= ~SYSFS_FLAG_REMOVED; + kn->flags &= ~KERNFS_REMOVED; return 0; } @@ -475,7 +475,7 @@ static void sysfs_remove_one(struct kernfs_addrm_cxt *acxt, * Removal can be called multiple times on the same node. Only the * first invocation is effective and puts the base ref. */ - if (kn->flags & SYSFS_FLAG_REMOVED) + if (kn->flags & KERNFS_REMOVED) return; if (kn->parent) { @@ -489,7 +489,7 @@ static void sysfs_remove_one(struct kernfs_addrm_cxt *acxt, } } - kn->flags |= SYSFS_FLAG_REMOVED; + kn->flags |= KERNFS_REMOVED; kn->u.removed_list = acxt->removed; acxt->removed = kn; } @@ -607,14 +607,14 @@ struct kernfs_root *kernfs_create_root(void *priv) ida_init(&root->ino_ida); - kn = sysfs_new_dirent(root, "", S_IFDIR | S_IRUGO | S_IXUGO, SYSFS_DIR); + kn = sysfs_new_dirent(root, "", S_IFDIR | S_IRUGO | S_IXUGO, KERNFS_DIR); if (!kn) { ida_destroy(&root->ino_ida); kfree(root); return ERR_PTR(-ENOMEM); } - kn->flags &= ~SYSFS_FLAG_REMOVED; + kn->flags &= ~KERNFS_REMOVED; kn->priv = priv; kn->dir.root = root; @@ -654,7 +654,7 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, int rc; /* allocate */ - kn = sysfs_new_dirent(kernfs_root(parent), name, mode, SYSFS_DIR); + kn = sysfs_new_dirent(kernfs_root(parent), name, mode, KERNFS_DIR); if (!kn) return ERR_PTR(-ENOMEM); @@ -732,7 +732,7 @@ static struct kernfs_node *sysfs_leftmost_descendant(struct kernfs_node *pos) last = pos; - if (sysfs_type(pos) != SYSFS_DIR) + if (kernfs_type(pos) != KERNFS_DIR) break; rbn = rb_first(&pos->dir.children); @@ -914,7 +914,7 @@ static struct kernfs_node *sysfs_dir_pos(const void *ns, struct kernfs_node *parent, loff_t hash, struct kernfs_node *pos) { if (pos) { - int valid = !(pos->flags & SYSFS_FLAG_REMOVED) && + int valid = !(pos->flags & KERNFS_REMOVED) && pos->parent == parent && hash == pos->hash; kernfs_put(pos); if (!valid) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 2714a394cd8..abe93e12089 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -49,7 +49,7 @@ static struct kernfs_open_file *kernfs_of(struct file *file) */ static const struct kernfs_ops *kernfs_ops(struct kernfs_node *kn) { - if (kn->flags & SYSFS_FLAG_LOCKDEP) + if (kn->flags & KERNFS_LOCKDEP) lockdep_assert_held(kn); return kn->attr.ops; } @@ -189,7 +189,7 @@ static ssize_t kernfs_file_read(struct file *file, char __user *user_buf, { struct kernfs_open_file *of = kernfs_of(file); - if (of->kn->flags & SYSFS_FLAG_HAS_SEQ_SHOW) + if (of->kn->flags & KERNFS_HAS_SEQ_SHOW) return seq_read(file, user_buf, count, ppos); else return kernfs_file_direct_read(of, user_buf, count, ppos); @@ -428,7 +428,7 @@ static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) * without grabbing @of->mutex by testing HAS_MMAP flag. See the * comment in kernfs_file_open() for more details. */ - if (!(of->kn->flags & SYSFS_FLAG_HAS_MMAP)) + if (!(of->kn->flags & KERNFS_HAS_MMAP)) return -ENODEV; mutex_lock(&of->mutex); @@ -668,7 +668,7 @@ void sysfs_unmap_bin_file(struct kernfs_node *kn) struct kernfs_open_node *on; struct kernfs_open_file *of; - if (!(kn->flags & SYSFS_FLAG_HAS_MMAP)) + if (!(kn->flags & KERNFS_HAS_MMAP)) return; spin_lock_irq(&kernfs_open_node_lock); @@ -738,7 +738,7 @@ void kernfs_notify(struct kernfs_node *kn) spin_lock_irqsave(&kernfs_open_node_lock, flags); - if (!WARN_ON(sysfs_type(kn) != SYSFS_KOBJ_ATTR)) { + if (!WARN_ON(kernfs_type(kn) != KERNFS_FILE)) { on = kn->attr.open; if (on) { atomic_inc(&on->event); @@ -785,7 +785,7 @@ struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, int rc; kn = sysfs_new_dirent(kernfs_root(parent), name, - (mode & S_IALLUGO) | S_IFREG, SYSFS_KOBJ_ATTR); + (mode & S_IALLUGO) | S_IFREG, KERNFS_FILE); if (!kn) return ERR_PTR(-ENOMEM); @@ -797,7 +797,7 @@ struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, #ifdef CONFIG_DEBUG_LOCK_ALLOC if (key) { lockdep_init_map(&kn->dep_map, "s_active", key, 0); - kn->flags |= SYSFS_FLAG_LOCKDEP; + kn->flags |= KERNFS_LOCKDEP; } #endif @@ -807,9 +807,9 @@ struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, * ref. Cache their existence in flags. */ if (ops->seq_show) - kn->flags |= SYSFS_FLAG_HAS_SEQ_SHOW; + kn->flags |= KERNFS_HAS_SEQ_SHOW; if (ops->mmap) - kn->flags |= SYSFS_FLAG_HAS_MMAP; + kn->flags |= KERNFS_HAS_MMAP; sysfs_addrm_start(&acxt); rc = sysfs_add_one(&acxt, kn, parent); diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index a0e0038fd57..af92638d792 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -269,7 +269,7 @@ static void sysfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) attrs->ia_secdata_len); } - if (sysfs_type(kn) == SYSFS_DIR) + if (kernfs_type(kn) == KERNFS_DIR) set_nlink(inode, kn->dir.subdirs + 2); } @@ -299,16 +299,16 @@ static void sysfs_init_inode(struct kernfs_node *kn, struct inode *inode) sysfs_refresh_inode(kn, inode); /* initialize inode according to type */ - switch (sysfs_type(kn)) { - case SYSFS_DIR: + switch (kernfs_type(kn)) { + case KERNFS_DIR: inode->i_op = &sysfs_dir_inode_operations; inode->i_fop = &sysfs_dir_operations; break; - case SYSFS_KOBJ_ATTR: + case KERNFS_FILE: inode->i_size = kn->attr.size; inode->i_fop = &kernfs_file_operations; break; - case SYSFS_KOBJ_LINK: + case KERNFS_LINK: inode->i_op = &sysfs_symlink_inode_operations; break; default: diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 573f6698864..c4bf5bf72f7 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -26,9 +26,9 @@ struct kernfs_iattrs { struct simple_xattrs xattrs; }; -#define SD_DEACTIVATED_BIAS INT_MIN +#define KN_DEACTIVATED_BIAS INT_MIN -/* SYSFS_TYPE_MASK and types are defined in include/linux/kernfs.h */ +/* KERNFS_TYPE_MASK and types are defined in include/linux/kernfs.h */ /** * kernfs_root - find out the kernfs_root a kernfs_node belongs to diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index f36e3f1b247..a92284d3c73 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -31,7 +31,7 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, int error; kn = sysfs_new_dirent(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO, - SYSFS_KOBJ_LINK); + KERNFS_LINK); if (!kn) return ERR_PTR(-ENOMEM); diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 4a800017558..aa007401bfc 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -113,7 +113,7 @@ void sysfs_remove_dir(struct kobject *kobj) spin_unlock(&sysfs_symlink_target_lock); if (kn) { - WARN_ON_ONCE(sysfs_type(kn) != SYSFS_DIR); + WARN_ON_ONCE(kernfs_type(kn) != KERNFS_DIR); kernfs_remove(kn); } } diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index fd104b282f8..fe6388fbd15 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -29,7 +29,7 @@ static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn) { struct kobject *kobj = kn->parent->priv; - if (kn->flags & SYSFS_FLAG_LOCKDEP) + if (kn->flags & KERNFS_LOCKDEP) lockdep_assert_held(kn); return kobj->ktype ? kobj->ktype->sysfs_ops : NULL; } diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 0d48ea91150..aecb15f8455 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -183,7 +183,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, goto out; result = -EINVAL; - if (sysfs_type(kn) != SYSFS_KOBJ_LINK) + if (kernfs_type(kn) != KERNFS_LINK) goto out; if (kn->symlink.target_kn->priv != targ) goto out; diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 757647c4cb3..e9c4e3a0396 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -28,22 +28,22 @@ struct kernfs_open_node; struct kernfs_iattrs; enum kernfs_node_type { - SYSFS_DIR = 0x0001, - SYSFS_KOBJ_ATTR = 0x0002, - SYSFS_KOBJ_LINK = 0x0004, + KERNFS_DIR = 0x0001, + KERNFS_FILE = 0x0002, + KERNFS_LINK = 0x0004, }; -#define SYSFS_TYPE_MASK 0x000f -#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK) -#define SYSFS_ACTIVE_REF SYSFS_KOBJ_ATTR -#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK +#define KERNFS_TYPE_MASK 0x000f +#define KERNFS_COPY_NAME (KERNFS_DIR | KERNFS_LINK) +#define KERNFS_ACTIVE_REF KERNFS_FILE +#define KERNFS_FLAG_MASK ~KERNFS_TYPE_MASK enum kernfs_node_flag { - SYSFS_FLAG_REMOVED = 0x0010, - SYSFS_FLAG_NS = 0x0020, - SYSFS_FLAG_HAS_SEQ_SHOW = 0x0040, - SYSFS_FLAG_HAS_MMAP = 0x0080, - SYSFS_FLAG_LOCKDEP = 0x0100, + KERNFS_REMOVED = 0x0010, + KERNFS_NS = 0x0020, + KERNFS_HAS_SEQ_SHOW = 0x0040, + KERNFS_HAS_MMAP = 0x0080, + KERNFS_LOCKDEP = 0x0100, }; /* type-specific structures for kernfs_node union members */ @@ -170,9 +170,9 @@ struct kernfs_ops { #ifdef CONFIG_SYSFS -static inline enum kernfs_node_type sysfs_type(struct kernfs_node *kn) +static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn) { - return kn->flags & SYSFS_TYPE_MASK; + return kn->flags & KERNFS_TYPE_MASK; } /** @@ -185,9 +185,9 @@ static inline enum kernfs_node_type sysfs_type(struct kernfs_node *kn) */ static inline void kernfs_enable_ns(struct kernfs_node *kn) { - WARN_ON_ONCE(sysfs_type(kn) != SYSFS_DIR); + WARN_ON_ONCE(kernfs_type(kn) != KERNFS_DIR); WARN_ON_ONCE(!RB_EMPTY_ROOT(&kn->dir.children)); - kn->flags |= SYSFS_FLAG_NS; + kn->flags |= KERNFS_NS; } /** @@ -198,7 +198,7 @@ static inline void kernfs_enable_ns(struct kernfs_node *kn) */ static inline bool kernfs_ns_enabled(struct kernfs_node *kn) { - return kn->flags & SYSFS_FLAG_NS; + return kn->flags & KERNFS_NS; } struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent, @@ -238,7 +238,7 @@ void kernfs_init(void); #else /* CONFIG_SYSFS */ -static inline enum kernfs_node_type sysfs_type(struct kernfs_node *kn) +static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn) { return 0; } /* whatever */ static inline void kernfs_enable_ns(struct kernfs_node *kn) { } -- cgit v1.2.3-70-g09d2 From a797bfc30532388e8a11ca726df60cdd77aa8675 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 14:11:57 -0500 Subject: kernfs: s/sysfs/kernfs/ in global variables kernfs has just been separated out from sysfs and we're already in full conflict mode. Nothing can make the situation any worse. Let's take the chance to name things properly. This patch performs the following renames. * s/sysfs_mutex/kernfs_mutex/ * s/sysfs_dentry_ops/kernfs_dops/ * s/sysfs_dir_operations/kernfs_dir_fops/ * s/sysfs_dir_inode_operations/kernfs_dir_iops/ * s/kernfs_file_operations/kernfs_file_fops/ - renamed for consistency * s/sysfs_symlink_inode_operations/kernfs_symlink_iops/ * s/sysfs_aops/kernfs_aops/ * s/sysfs_backing_dev_info/kernfs_bdi/ * s/sysfs_inode_operations/kernfs_iops/ * s/sysfs_dir_cachep/kernfs_node_cache/ * s/sysfs_ops/kernfs_sops/ This patch is strictly rename only and doesn't introduce any functional difference. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 64 ++++++++++++++++++++++----------------------- fs/kernfs/file.c | 2 +- fs/kernfs/inode.c | 46 ++++++++++++++++---------------- fs/kernfs/kernfs-internal.h | 14 +++++----- fs/kernfs/mount.c | 14 +++++----- fs/kernfs/symlink.c | 6 ++--- 6 files changed, 73 insertions(+), 73 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index bc8a3b367a8..d3c66237474 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -17,7 +17,7 @@ #include "kernfs-internal.h" -DEFINE_MUTEX(sysfs_mutex); +DEFINE_MUTEX(kernfs_mutex); #define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb) @@ -68,7 +68,7 @@ static int sysfs_sd_compare(const struct kernfs_node *left, * @kn->parent->dir.children. * * Locking: - * mutex_lock(sysfs_mutex) + * mutex_lock(kernfs_mutex) * * RETURNS: * 0 on susccess -EEXIST on failure. @@ -109,7 +109,7 @@ static int sysfs_link_sibling(struct kernfs_node *kn) * kn->parent->dir.children. * * Locking: - * mutex_lock(sysfs_mutex) + * mutex_lock(kernfs_mutex) */ static void sysfs_unlink_sibling(struct kernfs_node *kn) { @@ -251,7 +251,7 @@ void kernfs_put(struct kernfs_node *kn) } kfree(kn->iattr); ida_simple_remove(&root->ino_ida, kn->ino); - kmem_cache_free(sysfs_dir_cachep, kn); + kmem_cache_free(kernfs_node_cache, kn); kn = parent; if (kn) { @@ -279,7 +279,7 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) return -ECHILD; kn = dentry->d_fsdata; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); /* The sysfs dirent has been deleted */ if (kn->flags & KERNFS_REMOVED) @@ -298,7 +298,7 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) kernfs_info(dentry->d_sb)->ns != kn->ns) goto out_bad; - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); out_valid: return 1; out_bad: @@ -312,7 +312,7 @@ out_bad: * is performed at its new name the dentry will be readded * to the dcache hashes. */ - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); /* If we have submounts we must allow the vfs caches * to lie about the state of the filesystem to prevent @@ -329,7 +329,7 @@ static void sysfs_dentry_release(struct dentry *dentry) kernfs_put(dentry->d_fsdata); } -const struct dentry_operations sysfs_dentry_ops = { +const struct dentry_operations kernfs_dops = { .d_revalidate = sysfs_dentry_revalidate, .d_delete = sysfs_dentry_delete, .d_release = sysfs_dentry_release, @@ -348,7 +348,7 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, return NULL; } - kn = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL); + kn = kmem_cache_zalloc(kernfs_node_cache, GFP_KERNEL); if (!kn) goto err_out1; @@ -367,7 +367,7 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, return kn; err_out2: - kmem_cache_free(sysfs_dir_cachep, kn); + kmem_cache_free(kernfs_node_cache, kn); err_out1: kfree(dup_name); return NULL; @@ -378,19 +378,19 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, * @acxt: pointer to kernfs_addrm_cxt to be used * * This function is called when the caller is about to add or remove - * kernfs_node. This function acquires sysfs_mutex. @acxt is used to - * keep and pass context to other addrm functions. + * kernfs_node. This function acquires kernfs_mutex. @acxt is used + * to keep and pass context to other addrm functions. * * LOCKING: - * Kernel thread context (may sleep). sysfs_mutex is locked on + * Kernel thread context (may sleep). kernfs_mutex is locked on * return. */ void sysfs_addrm_start(struct kernfs_addrm_cxt *acxt) - __acquires(sysfs_mutex) + __acquires(kernfs_mutex) { memset(acxt, 0, sizeof(*acxt)); - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); } /** @@ -503,13 +503,13 @@ static void sysfs_remove_one(struct kernfs_addrm_cxt *acxt, * cleaned up. * * LOCKING: - * sysfs_mutex is released. + * kernfs_mutex is released. */ void sysfs_addrm_finish(struct kernfs_addrm_cxt *acxt) - __releases(sysfs_mutex) + __releases(kernfs_mutex) { /* release resources acquired by sysfs_addrm_start() */ - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); /* kill removed kernfs_nodes */ while (acxt->removed) { @@ -540,7 +540,7 @@ static struct kernfs_node *kernfs_find_ns(struct kernfs_node *parent, bool has_ns = kernfs_ns_enabled(parent); unsigned int hash; - lockdep_assert_held(&sysfs_mutex); + lockdep_assert_held(&kernfs_mutex); if (has_ns != (bool)ns) { WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", @@ -580,10 +580,10 @@ struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent, { struct kernfs_node *kn; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); kn = kernfs_find_ns(parent, name, ns); kernfs_get(kn); - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); return kn; } @@ -683,7 +683,7 @@ static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry, struct inode *inode; const void *ns = NULL; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); if (kernfs_ns_enabled(parent)) ns = kernfs_info(dir->i_sb)->ns; @@ -708,11 +708,11 @@ static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry, /* instantiate and hash dentry */ ret = d_materialise_unique(dentry, inode); out_unlock: - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); return ret; } -const struct inode_operations sysfs_dir_inode_operations = { +const struct inode_operations kernfs_dir_iops = { .lookup = sysfs_lookup, .permission = sysfs_permission, .setattr = sysfs_setattr, @@ -759,7 +759,7 @@ static struct kernfs_node *sysfs_next_descendant_post(struct kernfs_node *pos, { struct rb_node *rbn; - lockdep_assert_held(&sysfs_mutex); + lockdep_assert_held(&kernfs_mutex); /* if first iteration, visit leftmost descendant which may be root */ if (!pos) @@ -859,7 +859,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, { int error; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); error = 0; if ((kn->parent == new_parent) && (kn->ns == new_ns) && @@ -894,7 +894,7 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, error = 0; out: - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); return error; } @@ -968,7 +968,7 @@ static int sysfs_readdir(struct file *file, struct dir_context *ctx) if (!dir_emit_dots(file, ctx)) return 0; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); if (kernfs_ns_enabled(parent)) ns = kernfs_info(dentry->d_sb)->ns; @@ -985,12 +985,12 @@ static int sysfs_readdir(struct file *file, struct dir_context *ctx) file->private_data = pos; kernfs_get(pos); - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); if (!dir_emit(ctx, name, len, ino, type)) return 0; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); } - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); file->private_data = NULL; ctx->pos = INT_MAX; return 0; @@ -1008,7 +1008,7 @@ static loff_t sysfs_dir_llseek(struct file *file, loff_t offset, int whence) return ret; } -const struct file_operations sysfs_dir_operations = { +const struct file_operations kernfs_dir_fops = { .read = generic_read_dir, .iterate = sysfs_readdir, .release = sysfs_dir_release, diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index abe93e12089..32364ddb24d 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -750,7 +750,7 @@ void kernfs_notify(struct kernfs_node *kn) } EXPORT_SYMBOL_GPL(kernfs_notify); -const struct file_operations kernfs_file_operations = { +const struct file_operations kernfs_file_fops = { .read = kernfs_file_read, .write = kernfs_file_write, .llseek = generic_file_llseek, diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index af92638d792..c5f231e8d36 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -18,19 +18,19 @@ #include "kernfs-internal.h" -static const struct address_space_operations sysfs_aops = { +static const struct address_space_operations kernfs_aops = { .readpage = simple_readpage, .write_begin = simple_write_begin, .write_end = simple_write_end, }; -static struct backing_dev_info sysfs_backing_dev_info = { - .name = "sysfs", +static struct backing_dev_info kernfs_bdi = { + .name = "kernfs", .ra_pages = 0, /* No readahead */ .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, }; -static const struct inode_operations sysfs_inode_operations = { +static const struct inode_operations kernfs_iops = { .permission = sysfs_permission, .setattr = sysfs_setattr, .getattr = sysfs_getattr, @@ -42,8 +42,8 @@ static const struct inode_operations sysfs_inode_operations = { void __init sysfs_inode_init(void) { - if (bdi_init(&sysfs_backing_dev_info)) - panic("failed to init sysfs_backing_dev_info"); + if (bdi_init(&kernfs_bdi)) + panic("failed to init kernfs_bdi"); } static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) @@ -109,9 +109,9 @@ int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) { int ret; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); ret = __kernfs_setattr(kn, iattr); - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); return ret; } @@ -124,7 +124,7 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr) if (!kn) return -EINVAL; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); error = inode_change_ok(inode, iattr); if (error) goto out; @@ -137,7 +137,7 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr) setattr_copy(inode, iattr); out: - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); return error; } @@ -187,9 +187,9 @@ int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, if (error) return error; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); error = sysfs_sd_setsecdata(kn, &secdata, &secdata_len); - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); if (secdata) security_release_secctx(secdata, secdata_len); @@ -279,9 +279,9 @@ int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kernfs_node *kn = dentry->d_fsdata; struct inode *inode = dentry->d_inode; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); sysfs_refresh_inode(kn, inode); - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); generic_fillattr(inode, stat); return 0; @@ -291,9 +291,9 @@ static void sysfs_init_inode(struct kernfs_node *kn, struct inode *inode) { kernfs_get(kn); inode->i_private = kn; - inode->i_mapping->a_ops = &sysfs_aops; - inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; - inode->i_op = &sysfs_inode_operations; + inode->i_mapping->a_ops = &kernfs_aops; + inode->i_mapping->backing_dev_info = &kernfs_bdi; + inode->i_op = &kernfs_iops; set_default_inode_attr(inode, kn->mode); sysfs_refresh_inode(kn, inode); @@ -301,15 +301,15 @@ static void sysfs_init_inode(struct kernfs_node *kn, struct inode *inode) /* initialize inode according to type */ switch (kernfs_type(kn)) { case KERNFS_DIR: - inode->i_op = &sysfs_dir_inode_operations; - inode->i_fop = &sysfs_dir_operations; + inode->i_op = &kernfs_dir_iops; + inode->i_fop = &kernfs_dir_fops; break; case KERNFS_FILE: inode->i_size = kn->attr.size; - inode->i_fop = &kernfs_file_operations; + inode->i_fop = &kernfs_file_fops; break; case KERNFS_LINK: - inode->i_op = &sysfs_symlink_inode_operations; + inode->i_op = &kernfs_symlink_iops; break; default: BUG(); @@ -369,9 +369,9 @@ int sysfs_permission(struct inode *inode, int mask) kn = inode->i_private; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); sysfs_refresh_inode(kn, inode); - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); return generic_permission(inode, mask); } diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index c4bf5bf72f7..e62e8ec15d6 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -71,7 +71,7 @@ struct kernfs_super_info { }; #define kernfs_info(SB) ((struct kernfs_super_info *)(SB->s_fs_info)) -extern struct kmem_cache *sysfs_dir_cachep; +extern struct kmem_cache *kernfs_node_cache; /* * inode.c @@ -93,10 +93,10 @@ void sysfs_inode_init(void); /* * dir.c */ -extern struct mutex sysfs_mutex; -extern const struct dentry_operations sysfs_dentry_ops; -extern const struct file_operations sysfs_dir_operations; -extern const struct inode_operations sysfs_dir_inode_operations; +extern struct mutex kernfs_mutex; +extern const struct dentry_operations kernfs_dops; +extern const struct file_operations kernfs_dir_fops; +extern const struct inode_operations kernfs_dir_iops; struct kernfs_node *sysfs_get_active(struct kernfs_node *kn); void sysfs_put_active(struct kernfs_node *kn); @@ -110,13 +110,13 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, /* * file.c */ -extern const struct file_operations kernfs_file_operations; +extern const struct file_operations kernfs_file_fops; void sysfs_unmap_bin_file(struct kernfs_node *kn); /* * symlink.c */ -extern const struct inode_operations sysfs_symlink_inode_operations; +extern const struct inode_operations kernfs_symlink_iops; #endif /* __KERNFS_INTERNAL_H */ diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index e0796dcb606..27d967ba0bb 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -17,9 +17,9 @@ #include "kernfs-internal.h" -struct kmem_cache *sysfs_dir_cachep; +struct kmem_cache *kernfs_node_cache; -static const struct super_operations sysfs_ops = { +static const struct super_operations kernfs_sops = { .statfs = simple_statfs, .drop_inode = generic_delete_inode, .evict_inode = sysfs_evict_inode, @@ -34,13 +34,13 @@ static int sysfs_fill_super(struct super_block *sb) sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = SYSFS_MAGIC; - sb->s_op = &sysfs_ops; + sb->s_op = &kernfs_sops; sb->s_time_gran = 1; /* get root inode, initialize and unlock it */ - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); inode = sysfs_get_inode(sb, info->root->kn); - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); if (!inode) { pr_debug("sysfs: could not get root inode\n"); return -ENOMEM; @@ -55,7 +55,7 @@ static int sysfs_fill_super(struct super_block *sb) kernfs_get(info->root->kn); root->d_fsdata = info->root->kn; sb->s_root = root; - sb->s_d_op = &sysfs_dentry_ops; + sb->s_d_op = &kernfs_dops; return 0; } @@ -158,7 +158,7 @@ void kernfs_kill_sb(struct super_block *sb) void __init kernfs_init(void) { - sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache", + kernfs_node_cache = kmem_cache_create("kernfs_node_cache", sizeof(struct kernfs_node), 0, SLAB_PANIC, NULL); sysfs_inode_init(); diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index a92284d3c73..4105bd04ea2 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -110,9 +110,9 @@ static int sysfs_getlink(struct dentry *dentry, char *path) struct kernfs_node *target = kn->symlink.target_kn; int error; - mutex_lock(&sysfs_mutex); + mutex_lock(&kernfs_mutex); error = sysfs_get_target_path(parent, target, path); - mutex_unlock(&sysfs_mutex); + mutex_unlock(&kernfs_mutex); return error; } @@ -138,7 +138,7 @@ static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, free_page((unsigned long)page); } -const struct inode_operations sysfs_symlink_inode_operations = { +const struct inode_operations kernfs_symlink_iops = { .setxattr = sysfs_setxattr, .removexattr = sysfs_removexattr, .getxattr = sysfs_getxattr, -- cgit v1.2.3-70-g09d2 From c637b8acbe079edb477d887041755b489036f146 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 14:11:58 -0500 Subject: kernfs: s/sysfs/kernfs/ in internal functions and whatever is left kernfs has just been separated out from sysfs and we're already in full conflict mode. Nothing can make the situation any worse. Let's take the chance to name things properly. This patch performs the following renames. * s/sysfs_*()/kernfs_*()/ in all internal functions * s/sysfs/kernfs/ in internal strings, comments and whatever is remaining * Uniformly rename various vfs operations so that they're consistently named and distinguishable. This patch is strictly rename only and doesn't introduce any functional difference. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 212 ++++++++++++++++++++++---------------------- fs/kernfs/file.c | 121 ++++++++++++------------- fs/kernfs/inode.c | 66 +++++++------- fs/kernfs/kernfs-internal.h | 44 ++++----- fs/kernfs/mount.c | 18 ++-- fs/kernfs/symlink.c | 44 ++++----- 6 files changed, 254 insertions(+), 251 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index d3c66237474..6520066c49e 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -22,13 +22,13 @@ DEFINE_MUTEX(kernfs_mutex); #define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb) /** - * sysfs_name_hash + * kernfs_name_hash * @name: Null terminated string to hash * @ns: Namespace tag to hash * * Returns 31 bit hash of ns + name (so it fits in an off_t ) */ -static unsigned int sysfs_name_hash(const char *name, const void *ns) +static unsigned int kernfs_name_hash(const char *name, const void *ns) { unsigned long hash = init_name_hash(); unsigned int len = strlen(name); @@ -44,8 +44,8 @@ static unsigned int sysfs_name_hash(const char *name, const void *ns) return hash; } -static int sysfs_name_compare(unsigned int hash, const char *name, - const void *ns, const struct kernfs_node *kn) +static int kernfs_name_compare(unsigned int hash, const char *name, + const void *ns, const struct kernfs_node *kn) { if (hash != kn->hash) return hash - kn->hash; @@ -54,14 +54,14 @@ static int sysfs_name_compare(unsigned int hash, const char *name, return strcmp(name, kn->name); } -static int sysfs_sd_compare(const struct kernfs_node *left, - const struct kernfs_node *right) +static int kernfs_sd_compare(const struct kernfs_node *left, + const struct kernfs_node *right) { - return sysfs_name_compare(left->hash, left->name, left->ns, right); + return kernfs_name_compare(left->hash, left->name, left->ns, right); } /** - * sysfs_link_sibling - link kernfs_node into sibling rbtree + * kernfs_link_sibling - link kernfs_node into sibling rbtree * @kn: kernfs_node of interest * * Link @kn into its sibling rbtree which starts from @@ -73,7 +73,7 @@ static int sysfs_sd_compare(const struct kernfs_node *left, * RETURNS: * 0 on susccess -EEXIST on failure. */ -static int sysfs_link_sibling(struct kernfs_node *kn) +static int kernfs_link_sibling(struct kernfs_node *kn) { struct rb_node **node = &kn->parent->dir.children.rb_node; struct rb_node *parent = NULL; @@ -87,7 +87,7 @@ static int sysfs_link_sibling(struct kernfs_node *kn) pos = rb_to_kn(*node); parent = *node; - result = sysfs_sd_compare(kn, pos); + result = kernfs_sd_compare(kn, pos); if (result < 0) node = &pos->rb.rb_left; else if (result > 0) @@ -102,7 +102,7 @@ static int sysfs_link_sibling(struct kernfs_node *kn) } /** - * sysfs_unlink_sibling - unlink kernfs_node from sibling rbtree + * kernfs_unlink_sibling - unlink kernfs_node from sibling rbtree * @kn: kernfs_node of interest * * Unlink @kn from its sibling rbtree which starts from @@ -111,7 +111,7 @@ static int sysfs_link_sibling(struct kernfs_node *kn) * Locking: * mutex_lock(kernfs_mutex) */ -static void sysfs_unlink_sibling(struct kernfs_node *kn) +static void kernfs_unlink_sibling(struct kernfs_node *kn) { if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs--; @@ -120,7 +120,7 @@ static void sysfs_unlink_sibling(struct kernfs_node *kn) } /** - * sysfs_get_active - get an active reference to kernfs_node + * kernfs_get_active - get an active reference to kernfs_node * @kn: kernfs_node to get an active reference to * * Get an active reference of @kn. This function is noop if @kn @@ -129,7 +129,7 @@ static void sysfs_unlink_sibling(struct kernfs_node *kn) * RETURNS: * Pointer to @kn on success, NULL on failure. */ -struct kernfs_node *sysfs_get_active(struct kernfs_node *kn) +struct kernfs_node *kernfs_get_active(struct kernfs_node *kn) { if (unlikely(!kn)) return NULL; @@ -143,13 +143,13 @@ struct kernfs_node *sysfs_get_active(struct kernfs_node *kn) } /** - * sysfs_put_active - put an active reference to kernfs_node + * kernfs_put_active - put an active reference to kernfs_node * @kn: kernfs_node to put an active reference to * * Put an active reference to @kn. This function is noop if @kn * is NULL. */ -void sysfs_put_active(struct kernfs_node *kn) +void kernfs_put_active(struct kernfs_node *kn) { int v; @@ -170,12 +170,12 @@ void sysfs_put_active(struct kernfs_node *kn) } /** - * sysfs_deactivate - deactivate kernfs_node + * kernfs_deactivate - deactivate kernfs_node * @kn: kernfs_node to deactivate * * Deny new active references and drain existing ones. */ -static void sysfs_deactivate(struct kernfs_node *kn) +static void kernfs_deactivate(struct kernfs_node *kn) { DECLARE_COMPLETION_ONSTACK(wait); int v; @@ -235,9 +235,8 @@ void kernfs_put(struct kernfs_node *kn) */ parent = kn->parent; - WARN(!(kn->flags & KERNFS_REMOVED), - "sysfs: free using entry: %s/%s\n", - parent ? parent->name : "", kn->name); + WARN(!(kn->flags & KERNFS_REMOVED), "kernfs: free using entry: %s/%s\n", + parent ? parent->name : "", kn->name); if (kernfs_type(kn) == KERNFS_LINK) kernfs_put(kn->symlink.target_kn); @@ -265,13 +264,13 @@ void kernfs_put(struct kernfs_node *kn) } EXPORT_SYMBOL_GPL(kernfs_put); -static int sysfs_dentry_delete(const struct dentry *dentry) +static int kernfs_dop_delete(const struct dentry *dentry) { struct kernfs_node *kn = dentry->d_fsdata; return !(kn && !(kn->flags & KERNFS_REMOVED)); } -static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) +static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) { struct kernfs_node *kn; @@ -281,19 +280,19 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) kn = dentry->d_fsdata; mutex_lock(&kernfs_mutex); - /* The sysfs dirent has been deleted */ + /* The kernfs node has been deleted */ if (kn->flags & KERNFS_REMOVED) goto out_bad; - /* The sysfs dirent has been moved? */ + /* The kernfs node has been moved? */ if (dentry->d_parent->d_fsdata != kn->parent) goto out_bad; - /* The sysfs dirent has been renamed */ + /* The kernfs node has been renamed */ if (strcmp(dentry->d_name.name, kn->name) != 0) goto out_bad; - /* The sysfs dirent has been moved to a different namespace */ + /* The kernfs node has been moved to a different namespace */ if (kn->parent && kernfs_ns_enabled(kn->parent) && kernfs_info(dentry->d_sb)->ns != kn->ns) goto out_bad; @@ -302,9 +301,10 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) out_valid: return 1; out_bad: - /* Remove the dentry from the dcache hashes. + /* + * Remove the dentry from the dcache hashes. * If this is a deleted dentry we use d_drop instead of d_delete - * so sysfs doesn't need to cope with negative dentries. + * so kernfs doesn't need to cope with negative dentries. * * If this is a dentry that has simply been renamed we * use d_drop to remove it from the dcache lookup on its @@ -324,19 +324,19 @@ out_bad: return 0; } -static void sysfs_dentry_release(struct dentry *dentry) +static void kernfs_dop_release(struct dentry *dentry) { kernfs_put(dentry->d_fsdata); } const struct dentry_operations kernfs_dops = { - .d_revalidate = sysfs_dentry_revalidate, - .d_delete = sysfs_dentry_delete, - .d_release = sysfs_dentry_release, + .d_revalidate = kernfs_dop_revalidate, + .d_delete = kernfs_dop_delete, + .d_release = kernfs_dop_release, }; -struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, - const char *name, umode_t mode, int type) +struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, + umode_t mode, int type) { char *dup_name = NULL; struct kernfs_node *kn; @@ -374,7 +374,7 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, } /** - * sysfs_addrm_start - prepare for kernfs_node add/remove + * kernfs_addrm_start - prepare for kernfs_node add/remove * @acxt: pointer to kernfs_addrm_cxt to be used * * This function is called when the caller is about to add or remove @@ -385,7 +385,7 @@ struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, * Kernel thread context (may sleep). kernfs_mutex is locked on * return. */ -void sysfs_addrm_start(struct kernfs_addrm_cxt *acxt) +void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt) __acquires(kernfs_mutex) { memset(acxt, 0, sizeof(*acxt)); @@ -394,7 +394,7 @@ void sysfs_addrm_start(struct kernfs_addrm_cxt *acxt) } /** - * sysfs_add_one - add kernfs_node to parent without warning + * kernfs_add_one - add kernfs_node to parent without warning * @acxt: addrm context to use * @kn: kernfs_node to be added * @parent: the parent kernfs_node to add @kn to @@ -404,17 +404,17 @@ void sysfs_addrm_start(struct kernfs_addrm_cxt *acxt) * of the parent. * * This function should be called between calls to - * sysfs_addrm_start() and sysfs_addrm_finish() and should be - * passed the same @acxt as passed to sysfs_addrm_start(). + * kernfs_addrm_start() and kernfs_addrm_finish() and should be passed + * the same @acxt as passed to kernfs_addrm_start(). * * LOCKING: - * Determined by sysfs_addrm_start(). + * Determined by kernfs_addrm_start(). * * RETURNS: * 0 on success, -EEXIST if entry with the given name already * exists. */ -int sysfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, +int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, struct kernfs_node *parent) { bool has_ns = kernfs_ns_enabled(parent); @@ -422,7 +422,7 @@ int sysfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, int ret; if (has_ns != (bool)kn->ns) { - WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", + WARN(1, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", has_ns ? "required" : "invalid", parent->name, kn->name); return -EINVAL; } @@ -430,11 +430,11 @@ int sysfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, if (kernfs_type(parent) != KERNFS_DIR) return -EINVAL; - kn->hash = sysfs_name_hash(kn->name, kn->ns); + kn->hash = kernfs_name_hash(kn->name, kn->ns); kn->parent = parent; kernfs_get(parent); - ret = sysfs_link_sibling(kn); + ret = kernfs_link_sibling(kn); if (ret) return ret; @@ -452,7 +452,7 @@ int sysfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, } /** - * sysfs_remove_one - remove kernfs_node from parent + * kernfs_remove_one - remove kernfs_node from parent * @acxt: addrm context to use * @kn: kernfs_node to be removed * @@ -460,14 +460,14 @@ int sysfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, * directory. @kn is unlinked from the children list. * * This function should be called between calls to - * sysfs_addrm_start() and sysfs_addrm_finish() and should be - * passed the same @acxt as passed to sysfs_addrm_start(). + * kernfs_addrm_start() and kernfs_addrm_finish() and should be + * passed the same @acxt as passed to kernfs_addrm_start(). * * LOCKING: - * Determined by sysfs_addrm_start(). + * Determined by kernfs_addrm_start(). */ -static void sysfs_remove_one(struct kernfs_addrm_cxt *acxt, - struct kernfs_node *kn) +static void kernfs_remove_one(struct kernfs_addrm_cxt *acxt, + struct kernfs_node *kn) { struct kernfs_iattrs *ps_iattr; @@ -479,7 +479,7 @@ static void sysfs_remove_one(struct kernfs_addrm_cxt *acxt, return; if (kn->parent) { - sysfs_unlink_sibling(kn); + kernfs_unlink_sibling(kn); /* Update timestamps on the parent */ ps_iattr = kn->parent->iattr; @@ -495,20 +495,20 @@ static void sysfs_remove_one(struct kernfs_addrm_cxt *acxt, } /** - * sysfs_addrm_finish - finish up kernfs_node add/remove + * kernfs_addrm_finish - finish up kernfs_node add/remove * @acxt: addrm context to finish up * * Finish up kernfs_node add/remove. Resources acquired by - * sysfs_addrm_start() are released and removed kernfs_nodes are + * kernfs_addrm_start() are released and removed kernfs_nodes are * cleaned up. * * LOCKING: * kernfs_mutex is released. */ -void sysfs_addrm_finish(struct kernfs_addrm_cxt *acxt) +void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt) __releases(kernfs_mutex) { - /* release resources acquired by sysfs_addrm_start() */ + /* release resources acquired by kernfs_addrm_start() */ mutex_unlock(&kernfs_mutex); /* kill removed kernfs_nodes */ @@ -517,8 +517,8 @@ void sysfs_addrm_finish(struct kernfs_addrm_cxt *acxt) acxt->removed = kn->u.removed_list; - sysfs_deactivate(kn); - sysfs_unmap_bin_file(kn); + kernfs_deactivate(kn); + kernfs_unmap_bin_file(kn); kernfs_put(kn); } } @@ -543,18 +543,18 @@ static struct kernfs_node *kernfs_find_ns(struct kernfs_node *parent, lockdep_assert_held(&kernfs_mutex); if (has_ns != (bool)ns) { - WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", + WARN(1, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", has_ns ? "required" : "invalid", parent->name, name); return NULL; } - hash = sysfs_name_hash(name, ns); + hash = kernfs_name_hash(name, ns); while (node) { struct kernfs_node *kn; int result; kn = rb_to_kn(node); - result = sysfs_name_compare(hash, name, ns, kn); + result = kernfs_name_compare(hash, name, ns, kn); if (result < 0) node = node->rb_left; else if (result > 0) @@ -607,7 +607,7 @@ struct kernfs_root *kernfs_create_root(void *priv) ida_init(&root->ino_ida); - kn = sysfs_new_dirent(root, "", S_IFDIR | S_IRUGO | S_IXUGO, KERNFS_DIR); + kn = kernfs_new_node(root, "", S_IFDIR | S_IRUGO | S_IXUGO, KERNFS_DIR); if (!kn) { ida_destroy(&root->ino_ida); kfree(root); @@ -654,7 +654,7 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, int rc; /* allocate */ - kn = sysfs_new_dirent(kernfs_root(parent), name, mode, KERNFS_DIR); + kn = kernfs_new_node(kernfs_root(parent), name, mode, KERNFS_DIR); if (!kn) return ERR_PTR(-ENOMEM); @@ -663,9 +663,9 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, kn->priv = priv; /* link in */ - sysfs_addrm_start(&acxt); - rc = sysfs_add_one(&acxt, kn, parent); - sysfs_addrm_finish(&acxt); + kernfs_addrm_start(&acxt); + rc = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); if (!rc) return kn; @@ -674,8 +674,9 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, return ERR_PTR(rc); } -static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry, - unsigned int flags) +static struct dentry *kernfs_iop_lookup(struct inode *dir, + struct dentry *dentry, + unsigned int flags) { struct dentry *ret = NULL; struct kernfs_node *parent = dentry->d_parent->d_fsdata; @@ -699,7 +700,7 @@ static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry, dentry->d_fsdata = kn; /* attach dentry and inode */ - inode = sysfs_get_inode(dir->i_sb, kn); + inode = kernfs_get_inode(dir->i_sb, kn); if (!inode) { ret = ERR_PTR(-ENOMEM); goto out_unlock; @@ -713,17 +714,17 @@ static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry, } const struct inode_operations kernfs_dir_iops = { - .lookup = sysfs_lookup, - .permission = sysfs_permission, - .setattr = sysfs_setattr, - .getattr = sysfs_getattr, - .setxattr = sysfs_setxattr, - .removexattr = sysfs_removexattr, - .getxattr = sysfs_getxattr, - .listxattr = sysfs_listxattr, + .lookup = kernfs_iop_lookup, + .permission = kernfs_iop_permission, + .setattr = kernfs_iop_setattr, + .getattr = kernfs_iop_getattr, + .setxattr = kernfs_iop_setxattr, + .removexattr = kernfs_iop_removexattr, + .getxattr = kernfs_iop_getxattr, + .listxattr = kernfs_iop_listxattr, }; -static struct kernfs_node *sysfs_leftmost_descendant(struct kernfs_node *pos) +static struct kernfs_node *kernfs_leftmost_descendant(struct kernfs_node *pos) { struct kernfs_node *last; @@ -746,7 +747,7 @@ static struct kernfs_node *sysfs_leftmost_descendant(struct kernfs_node *pos) } /** - * sysfs_next_descendant_post - find the next descendant for post-order walk + * kernfs_next_descendant_post - find the next descendant for post-order walk * @pos: the current position (%NULL to initiate traversal) * @root: kernfs_node whose descendants to walk * @@ -754,8 +755,8 @@ static struct kernfs_node *sysfs_leftmost_descendant(struct kernfs_node *pos) * descendants. @root is included in the iteration and the last node to be * visited. */ -static struct kernfs_node *sysfs_next_descendant_post(struct kernfs_node *pos, - struct kernfs_node *root) +static struct kernfs_node *kernfs_next_descendant_post(struct kernfs_node *pos, + struct kernfs_node *root) { struct rb_node *rbn; @@ -763,7 +764,7 @@ static struct kernfs_node *sysfs_next_descendant_post(struct kernfs_node *pos, /* if first iteration, visit leftmost descendant which may be root */ if (!pos) - return sysfs_leftmost_descendant(root); + return kernfs_leftmost_descendant(root); /* if we visited @root, we're done */ if (pos == root) @@ -772,7 +773,7 @@ static struct kernfs_node *sysfs_next_descendant_post(struct kernfs_node *pos, /* if there's an unvisited sibling, visit its leftmost descendant */ rbn = rb_next(&pos->rb); if (rbn) - return sysfs_leftmost_descendant(rb_to_kn(rbn)); + return kernfs_leftmost_descendant(rb_to_kn(rbn)); /* no sibling left, visit parent */ return pos->parent; @@ -786,14 +787,14 @@ static void __kernfs_remove(struct kernfs_addrm_cxt *acxt, if (!kn) return; - pr_debug("sysfs %s: removing\n", kn->name); + pr_debug("kernfs %s: removing\n", kn->name); next = NULL; do { pos = next; - next = sysfs_next_descendant_post(pos, kn); + next = kernfs_next_descendant_post(pos, kn); if (pos) - sysfs_remove_one(acxt, pos); + kernfs_remove_one(acxt, pos); } while (next); } @@ -807,9 +808,9 @@ void kernfs_remove(struct kernfs_node *kn) { struct kernfs_addrm_cxt acxt; - sysfs_addrm_start(&acxt); + kernfs_addrm_start(&acxt); __kernfs_remove(&acxt, kn); - sysfs_addrm_finish(&acxt); + kernfs_addrm_finish(&acxt); } /** @@ -828,18 +829,18 @@ int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, struct kernfs_node *kn; if (!parent) { - WARN(1, KERN_WARNING "sysfs: can not remove '%s', no directory\n", + WARN(1, KERN_WARNING "kernfs: can not remove '%s', no directory\n", name); return -ENOENT; } - sysfs_addrm_start(&acxt); + kernfs_addrm_start(&acxt); kn = kernfs_find_ns(parent, name, ns); if (kn) __kernfs_remove(&acxt, kn); - sysfs_addrm_finish(&acxt); + kernfs_addrm_finish(&acxt); if (kn) return 0; @@ -884,13 +885,13 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, /* * Move to the appropriate place in the appropriate directories rbtree. */ - sysfs_unlink_sibling(kn); + kernfs_unlink_sibling(kn); kernfs_get(new_parent); kernfs_put(kn->parent); kn->ns = new_ns; - kn->hash = sysfs_name_hash(kn->name, kn->ns); + kn->hash = kernfs_name_hash(kn->name, kn->ns); kn->parent = new_parent; - sysfs_link_sibling(kn); + kernfs_link_sibling(kn); error = 0; out: @@ -904,13 +905,13 @@ static inline unsigned char dt_type(struct kernfs_node *kn) return (kn->mode >> 12) & 15; } -static int sysfs_dir_release(struct inode *inode, struct file *filp) +static int kernfs_dir_fop_release(struct inode *inode, struct file *filp) { kernfs_put(filp->private_data); return 0; } -static struct kernfs_node *sysfs_dir_pos(const void *ns, +static struct kernfs_node *kernfs_dir_pos(const void *ns, struct kernfs_node *parent, loff_t hash, struct kernfs_node *pos) { if (pos) { @@ -944,10 +945,10 @@ static struct kernfs_node *sysfs_dir_pos(const void *ns, return pos; } -static struct kernfs_node *sysfs_dir_next_pos(const void *ns, +static struct kernfs_node *kernfs_dir_next_pos(const void *ns, struct kernfs_node *parent, ino_t ino, struct kernfs_node *pos) { - pos = sysfs_dir_pos(ns, parent, ino, pos); + pos = kernfs_dir_pos(ns, parent, ino, pos); if (pos) do { struct rb_node *node = rb_next(&pos->rb); @@ -959,7 +960,7 @@ static struct kernfs_node *sysfs_dir_next_pos(const void *ns, return pos; } -static int sysfs_readdir(struct file *file, struct dir_context *ctx) +static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx) { struct dentry *dentry = file->f_path.dentry; struct kernfs_node *parent = dentry->d_fsdata; @@ -973,9 +974,9 @@ static int sysfs_readdir(struct file *file, struct dir_context *ctx) if (kernfs_ns_enabled(parent)) ns = kernfs_info(dentry->d_sb)->ns; - for (pos = sysfs_dir_pos(ns, parent, ctx->pos, pos); + for (pos = kernfs_dir_pos(ns, parent, ctx->pos, pos); pos; - pos = sysfs_dir_next_pos(ns, parent, ctx->pos, pos)) { + pos = kernfs_dir_next_pos(ns, parent, ctx->pos, pos)) { const char *name = pos->name; unsigned int type = dt_type(pos); int len = strlen(name); @@ -996,7 +997,8 @@ static int sysfs_readdir(struct file *file, struct dir_context *ctx) return 0; } -static loff_t sysfs_dir_llseek(struct file *file, loff_t offset, int whence) +static loff_t kernfs_dir_fop_llseek(struct file *file, loff_t offset, + int whence) { struct inode *inode = file_inode(file); loff_t ret; @@ -1010,7 +1012,7 @@ static loff_t sysfs_dir_llseek(struct file *file, loff_t offset, int whence) const struct file_operations kernfs_dir_fops = { .read = generic_read_dir, - .iterate = sysfs_readdir, - .release = sysfs_dir_release, - .llseek = sysfs_dir_llseek, + .iterate = kernfs_fop_readdir, + .release = kernfs_dir_fop_release, + .llseek = kernfs_dir_fop_llseek, }; diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 32364ddb24d..053cfd9a6a4 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -64,7 +64,7 @@ static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) * the ops aren't called concurrently for the same open file. */ mutex_lock(&of->mutex); - if (!sysfs_get_active(of->kn)) + if (!kernfs_get_active(of->kn)) return ERR_PTR(-ENODEV); ops = kernfs_ops(of->kn); @@ -104,7 +104,7 @@ static void kernfs_seq_stop(struct seq_file *sf, void *v) if (ops->seq_stop) ops->seq_stop(sf, v); - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); mutex_unlock(&of->mutex); } @@ -147,7 +147,7 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, * the ops aren't called concurrently for the same open file. */ mutex_lock(&of->mutex); - if (!sysfs_get_active(of->kn)) { + if (!kernfs_get_active(of->kn)) { len = -ENODEV; mutex_unlock(&of->mutex); goto out_free; @@ -159,7 +159,7 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, else len = -EINVAL; - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); mutex_unlock(&of->mutex); if (len < 0) @@ -178,14 +178,14 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, } /** - * kernfs_file_read - kernfs vfs read callback + * kernfs_fop_read - kernfs vfs read callback * @file: file pointer * @user_buf: data to write * @count: number of bytes * @ppos: starting offset */ -static ssize_t kernfs_file_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t kernfs_fop_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) { struct kernfs_open_file *of = kernfs_of(file); @@ -196,7 +196,7 @@ static ssize_t kernfs_file_read(struct file *file, char __user *user_buf, } /** - * kernfs_file_write - kernfs vfs write callback + * kernfs_fop_write - kernfs vfs write callback * @file: file pointer * @user_buf: data to write * @count: number of bytes @@ -211,8 +211,8 @@ static ssize_t kernfs_file_read(struct file *file, char __user *user_buf, * modify only the the value you're changing, then write entire buffer * back. */ -static ssize_t kernfs_file_write(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) { struct kernfs_open_file *of = kernfs_of(file); ssize_t len = min_t(size_t, count, PAGE_SIZE); @@ -234,7 +234,7 @@ static ssize_t kernfs_file_write(struct file *file, const char __user *user_buf, * the ops aren't called concurrently for the same open file. */ mutex_lock(&of->mutex); - if (!sysfs_get_active(of->kn)) { + if (!kernfs_get_active(of->kn)) { mutex_unlock(&of->mutex); len = -ENODEV; goto out_free; @@ -246,7 +246,7 @@ static ssize_t kernfs_file_write(struct file *file, const char __user *user_buf, else len = -EINVAL; - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); mutex_unlock(&of->mutex); if (len > 0) @@ -264,13 +264,13 @@ static void kernfs_vma_open(struct vm_area_struct *vma) if (!of->vm_ops) return; - if (!sysfs_get_active(of->kn)) + if (!kernfs_get_active(of->kn)) return; if (of->vm_ops->open) of->vm_ops->open(vma); - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); } static int kernfs_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) @@ -282,14 +282,14 @@ static int kernfs_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (!of->vm_ops) return VM_FAULT_SIGBUS; - if (!sysfs_get_active(of->kn)) + if (!kernfs_get_active(of->kn)) return VM_FAULT_SIGBUS; ret = VM_FAULT_SIGBUS; if (of->vm_ops->fault) ret = of->vm_ops->fault(vma, vmf); - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); return ret; } @@ -303,7 +303,7 @@ static int kernfs_vma_page_mkwrite(struct vm_area_struct *vma, if (!of->vm_ops) return VM_FAULT_SIGBUS; - if (!sysfs_get_active(of->kn)) + if (!kernfs_get_active(of->kn)) return VM_FAULT_SIGBUS; ret = 0; @@ -312,7 +312,7 @@ static int kernfs_vma_page_mkwrite(struct vm_area_struct *vma, else file_update_time(file); - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); return ret; } @@ -326,14 +326,14 @@ static int kernfs_vma_access(struct vm_area_struct *vma, unsigned long addr, if (!of->vm_ops) return -EINVAL; - if (!sysfs_get_active(of->kn)) + if (!kernfs_get_active(of->kn)) return -EINVAL; ret = -EINVAL; if (of->vm_ops->access) ret = of->vm_ops->access(vma, addr, buf, len, write); - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); return ret; } @@ -348,14 +348,14 @@ static int kernfs_vma_set_policy(struct vm_area_struct *vma, if (!of->vm_ops) return 0; - if (!sysfs_get_active(of->kn)) + if (!kernfs_get_active(of->kn)) return -EINVAL; ret = 0; if (of->vm_ops->set_policy) ret = of->vm_ops->set_policy(vma, new); - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); return ret; } @@ -369,14 +369,14 @@ static struct mempolicy *kernfs_vma_get_policy(struct vm_area_struct *vma, if (!of->vm_ops) return vma->vm_policy; - if (!sysfs_get_active(of->kn)) + if (!kernfs_get_active(of->kn)) return vma->vm_policy; pol = vma->vm_policy; if (of->vm_ops->get_policy) pol = of->vm_ops->get_policy(vma, addr); - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); return pol; } @@ -391,14 +391,14 @@ static int kernfs_vma_migrate(struct vm_area_struct *vma, if (!of->vm_ops) return 0; - if (!sysfs_get_active(of->kn)) + if (!kernfs_get_active(of->kn)) return 0; ret = 0; if (of->vm_ops->migrate) ret = of->vm_ops->migrate(vma, from, to, flags); - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); return ret; } #endif @@ -415,7 +415,7 @@ static const struct vm_operations_struct kernfs_vm_ops = { #endif }; -static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) +static int kernfs_fop_mmap(struct file *file, struct vm_area_struct *vma) { struct kernfs_open_file *of = kernfs_of(file); const struct kernfs_ops *ops; @@ -434,7 +434,7 @@ static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) mutex_lock(&of->mutex); rc = -ENODEV; - if (!sysfs_get_active(of->kn)) + if (!kernfs_get_active(of->kn)) goto out_unlock; ops = kernfs_ops(of->kn); @@ -465,7 +465,7 @@ static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma) of->vm_ops = vma->vm_ops; vma->vm_ops = &kernfs_vm_ops; out_put: - sysfs_put_active(of->kn); + kernfs_put_active(of->kn); out_unlock: mutex_unlock(&of->mutex); @@ -473,7 +473,7 @@ out_unlock: } /** - * sysfs_get_open_dirent - get or create kernfs_open_node + * kernfs_get_open_node - get or create kernfs_open_node * @kn: target kernfs_node * @of: kernfs_open_file for this instance of open * @@ -486,8 +486,8 @@ out_unlock: * RETURNS: * 0 on success, -errno on failure. */ -static int sysfs_get_open_dirent(struct kernfs_node *kn, - struct kernfs_open_file *of) +static int kernfs_get_open_node(struct kernfs_node *kn, + struct kernfs_open_file *of) { struct kernfs_open_node *on, *new_on = NULL; @@ -527,7 +527,7 @@ static int sysfs_get_open_dirent(struct kernfs_node *kn, } /** - * sysfs_put_open_dirent - put kernfs_open_node + * kernfs_put_open_node - put kernfs_open_node * @kn: target kernfs_nodet * @of: associated kernfs_open_file * @@ -537,8 +537,8 @@ static int sysfs_get_open_dirent(struct kernfs_node *kn, * LOCKING: * None. */ -static void sysfs_put_open_dirent(struct kernfs_node *kn, - struct kernfs_open_file *of) +static void kernfs_put_open_node(struct kernfs_node *kn, + struct kernfs_open_file *of) { struct kernfs_open_node *on = kn->attr.open; unsigned long flags; @@ -560,7 +560,7 @@ static void sysfs_put_open_dirent(struct kernfs_node *kn, kfree(on); } -static int kernfs_file_open(struct inode *inode, struct file *file) +static int kernfs_fop_open(struct inode *inode, struct file *file) { struct kernfs_node *kn = file->f_path.dentry->d_fsdata; const struct kernfs_ops *ops; @@ -568,7 +568,7 @@ static int kernfs_file_open(struct inode *inode, struct file *file) bool has_read, has_write, has_mmap; int error = -EACCES; - if (!sysfs_get_active(kn)) + if (!kernfs_get_active(kn)) return -ENODEV; ops = kernfs_ops(kn); @@ -633,13 +633,13 @@ static int kernfs_file_open(struct inode *inode, struct file *file) if (file->f_mode & FMODE_WRITE) file->f_mode |= FMODE_PWRITE; - /* make sure we have open dirent struct */ - error = sysfs_get_open_dirent(kn, of); + /* make sure we have open node struct */ + error = kernfs_get_open_node(kn, of); if (error) goto err_close; /* open succeeded, put active references */ - sysfs_put_active(kn); + kernfs_put_active(kn); return 0; err_close: @@ -647,23 +647,23 @@ err_close: err_free: kfree(of); err_out: - sysfs_put_active(kn); + kernfs_put_active(kn); return error; } -static int kernfs_file_release(struct inode *inode, struct file *filp) +static int kernfs_fop_release(struct inode *inode, struct file *filp) { struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; struct kernfs_open_file *of = kernfs_of(filp); - sysfs_put_open_dirent(kn, of); + kernfs_put_open_node(kn, of); seq_release(inode, filp); kfree(of); return 0; } -void sysfs_unmap_bin_file(struct kernfs_node *kn) +void kernfs_unmap_bin_file(struct kernfs_node *kn) { struct kernfs_open_node *on; struct kernfs_open_file *of; @@ -686,10 +686,11 @@ void sysfs_unmap_bin_file(struct kernfs_node *kn) } mutex_unlock(&kernfs_open_file_mutex); - sysfs_put_open_dirent(kn, NULL); + kernfs_put_open_node(kn, NULL); } -/* Sysfs attribute files are pollable. The idea is that you read +/* + * Kernfs 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 @@ -702,19 +703,19 @@ void sysfs_unmap_bin_file(struct kernfs_node *kn) * to see if it supports poll (Neither 'poll' nor 'select' return * an appropriate error code). When in doubt, set a suitable timeout value. */ -static unsigned int kernfs_file_poll(struct file *filp, poll_table *wait) +static unsigned int kernfs_fop_poll(struct file *filp, poll_table *wait) { struct kernfs_open_file *of = kernfs_of(filp); struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; struct kernfs_open_node *on = kn->attr.open; /* need parent for the kobj, grab both */ - if (!sysfs_get_active(kn)) + if (!kernfs_get_active(kn)) goto trigger; poll_wait(filp, &on->poll, wait); - sysfs_put_active(kn); + kernfs_put_active(kn); if (of->event != atomic_read(&on->event)) goto trigger; @@ -751,13 +752,13 @@ void kernfs_notify(struct kernfs_node *kn) EXPORT_SYMBOL_GPL(kernfs_notify); const struct file_operations kernfs_file_fops = { - .read = kernfs_file_read, - .write = kernfs_file_write, + .read = kernfs_fop_read, + .write = kernfs_fop_write, .llseek = generic_file_llseek, - .mmap = kernfs_file_mmap, - .open = kernfs_file_open, - .release = kernfs_file_release, - .poll = kernfs_file_poll, + .mmap = kernfs_fop_mmap, + .open = kernfs_fop_open, + .release = kernfs_fop_release, + .poll = kernfs_fop_poll, }; /** @@ -784,8 +785,8 @@ struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, struct kernfs_node *kn; int rc; - kn = sysfs_new_dirent(kernfs_root(parent), name, - (mode & S_IALLUGO) | S_IFREG, KERNFS_FILE); + kn = kernfs_new_node(kernfs_root(parent), name, + (mode & S_IALLUGO) | S_IFREG, KERNFS_FILE); if (!kn) return ERR_PTR(-ENOMEM); @@ -811,9 +812,9 @@ struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, if (ops->mmap) kn->flags |= KERNFS_HAS_MMAP; - sysfs_addrm_start(&acxt); - rc = sysfs_add_one(&acxt, kn, parent); - sysfs_addrm_finish(&acxt); + kernfs_addrm_start(&acxt); + rc = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); if (rc) { kernfs_put(kn); diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index c5f231e8d36..e55126f85bd 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -31,16 +31,16 @@ static struct backing_dev_info kernfs_bdi = { }; static const struct inode_operations kernfs_iops = { - .permission = sysfs_permission, - .setattr = sysfs_setattr, - .getattr = sysfs_getattr, - .setxattr = sysfs_setxattr, - .removexattr = sysfs_removexattr, - .getxattr = sysfs_getxattr, - .listxattr = sysfs_listxattr, + .permission = kernfs_iop_permission, + .setattr = kernfs_iop_setattr, + .getattr = kernfs_iop_getattr, + .setxattr = kernfs_iop_setxattr, + .removexattr = kernfs_iop_removexattr, + .getxattr = kernfs_iop_getxattr, + .listxattr = kernfs_iop_listxattr, }; -void __init sysfs_inode_init(void) +void __init kernfs_inode_init(void) { if (bdi_init(&kernfs_bdi)) panic("failed to init kernfs_bdi"); @@ -115,7 +115,7 @@ int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) return ret; } -int sysfs_setattr(struct dentry *dentry, struct iattr *iattr) +int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr) { struct inode *inode = dentry->d_inode; struct kernfs_node *kn = dentry->d_fsdata; @@ -141,8 +141,8 @@ out: return error; } -static int sysfs_sd_setsecdata(struct kernfs_node *kn, void **secdata, - u32 *secdata_len) +static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata, + u32 *secdata_len) { struct kernfs_iattrs *attrs; void *old_secdata; @@ -163,8 +163,8 @@ static int sysfs_sd_setsecdata(struct kernfs_node *kn, void **secdata, return 0; } -int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, - size_t size, int flags) +int kernfs_iop_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) { struct kernfs_node *kn = dentry->d_fsdata; struct kernfs_iattrs *attrs; @@ -188,7 +188,7 @@ int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, return error; mutex_lock(&kernfs_mutex); - error = sysfs_sd_setsecdata(kn, &secdata, &secdata_len); + error = kernfs_node_setsecdata(kn, &secdata, &secdata_len); mutex_unlock(&kernfs_mutex); if (secdata) @@ -202,7 +202,7 @@ int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, return -EINVAL; } -int sysfs_removexattr(struct dentry *dentry, const char *name) +int kernfs_iop_removexattr(struct dentry *dentry, const char *name) { struct kernfs_node *kn = dentry->d_fsdata; struct kernfs_iattrs *attrs; @@ -214,8 +214,8 @@ int sysfs_removexattr(struct dentry *dentry, const char *name) return simple_xattr_remove(&attrs->xattrs, name); } -ssize_t sysfs_getxattr(struct dentry *dentry, const char *name, void *buf, - size_t size) +ssize_t kernfs_iop_getxattr(struct dentry *dentry, const char *name, void *buf, + size_t size) { struct kernfs_node *kn = dentry->d_fsdata; struct kernfs_iattrs *attrs; @@ -227,7 +227,7 @@ ssize_t sysfs_getxattr(struct dentry *dentry, const char *name, void *buf, return simple_xattr_get(&attrs->xattrs, name, buf, size); } -ssize_t sysfs_listxattr(struct dentry *dentry, char *buf, size_t size) +ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) { struct kernfs_node *kn = dentry->d_fsdata; struct kernfs_iattrs *attrs; @@ -254,7 +254,7 @@ static inline void set_inode_attr(struct inode *inode, struct iattr *iattr) inode->i_ctime = iattr->ia_ctime; } -static void sysfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) +static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) { struct kernfs_iattrs *attrs = kn->iattr; @@ -273,21 +273,21 @@ static void sysfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) set_nlink(inode, kn->dir.subdirs + 2); } -int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, - struct kstat *stat) +int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat) { struct kernfs_node *kn = dentry->d_fsdata; struct inode *inode = dentry->d_inode; mutex_lock(&kernfs_mutex); - sysfs_refresh_inode(kn, inode); + kernfs_refresh_inode(kn, inode); mutex_unlock(&kernfs_mutex); generic_fillattr(inode, stat); return 0; } -static void sysfs_init_inode(struct kernfs_node *kn, struct inode *inode) +static void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode) { kernfs_get(kn); inode->i_private = kn; @@ -296,7 +296,7 @@ static void sysfs_init_inode(struct kernfs_node *kn, struct inode *inode) inode->i_op = &kernfs_iops; set_default_inode_attr(inode, kn->mode); - sysfs_refresh_inode(kn, inode); + kernfs_refresh_inode(kn, inode); /* initialize inode according to type */ switch (kernfs_type(kn)) { @@ -319,7 +319,7 @@ static void sysfs_init_inode(struct kernfs_node *kn, struct inode *inode) } /** - * sysfs_get_inode - get inode for kernfs_node + * kernfs_get_inode - get inode for kernfs_node * @sb: super block * @kn: kernfs_node to allocate inode for * @@ -333,25 +333,25 @@ static void sysfs_init_inode(struct kernfs_node *kn, struct inode *inode) * RETURNS: * Pointer to allocated inode on success, NULL on failure. */ -struct inode *sysfs_get_inode(struct super_block *sb, struct kernfs_node *kn) +struct inode *kernfs_get_inode(struct super_block *sb, struct kernfs_node *kn) { struct inode *inode; inode = iget_locked(sb, kn->ino); if (inode && (inode->i_state & I_NEW)) - sysfs_init_inode(kn, inode); + kernfs_init_inode(kn, inode); return inode; } /* - * The kernfs_node serves as both an inode and a directory entry for sysfs. - * To prevent the sysfs inode numbers from being freed prematurely we take - * a reference to kernfs_node from the sysfs inode. A + * The kernfs_node serves as both an inode and a directory entry for + * kernfs. To prevent the kernfs inode numbers from being freed + * prematurely we take a reference to kernfs_node from the kernfs inode. A * super_operations.evict_inode() implementation is needed to drop that * reference upon inode destruction. */ -void sysfs_evict_inode(struct inode *inode) +void kernfs_evict_inode(struct inode *inode) { struct kernfs_node *kn = inode->i_private; @@ -360,7 +360,7 @@ void sysfs_evict_inode(struct inode *inode) kernfs_put(kn); } -int sysfs_permission(struct inode *inode, int mask) +int kernfs_iop_permission(struct inode *inode, int mask) { struct kernfs_node *kn; @@ -370,7 +370,7 @@ int sysfs_permission(struct inode *inode, int mask) kn = inode->i_private; mutex_lock(&kernfs_mutex); - sysfs_refresh_inode(kn, inode); + kernfs_refresh_inode(kn, inode); mutex_unlock(&kernfs_mutex); return generic_permission(inode, mask); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index e62e8ec15d6..a4ff491fd59 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -76,19 +76,19 @@ extern struct kmem_cache *kernfs_node_cache; /* * inode.c */ -struct inode *sysfs_get_inode(struct super_block *sb, struct kernfs_node *kn); -void sysfs_evict_inode(struct inode *inode); -int sysfs_permission(struct inode *inode, int mask); -int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); -int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, - struct kstat *stat); -int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, - size_t size, int flags); -int sysfs_removexattr(struct dentry *dentry, const char *name); -ssize_t sysfs_getxattr(struct dentry *dentry, const char *name, void *buf, - size_t size); -ssize_t sysfs_listxattr(struct dentry *dentry, char *buf, size_t size); -void sysfs_inode_init(void); +struct inode *kernfs_get_inode(struct super_block *sb, struct kernfs_node *kn); +void kernfs_evict_inode(struct inode *inode); +int kernfs_iop_permission(struct inode *inode, int mask); +int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr); +int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat); +int kernfs_iop_setxattr(struct dentry *dentry, const char *name, const void *value, + size_t size, int flags); +int kernfs_iop_removexattr(struct dentry *dentry, const char *name); +ssize_t kernfs_iop_getxattr(struct dentry *dentry, const char *name, void *buf, + size_t size); +ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size); +void kernfs_inode_init(void); /* * dir.c @@ -98,21 +98,21 @@ extern const struct dentry_operations kernfs_dops; extern const struct file_operations kernfs_dir_fops; extern const struct inode_operations kernfs_dir_iops; -struct kernfs_node *sysfs_get_active(struct kernfs_node *kn); -void sysfs_put_active(struct kernfs_node *kn); -void sysfs_addrm_start(struct kernfs_addrm_cxt *acxt); -int sysfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, - struct kernfs_node *parent); -void sysfs_addrm_finish(struct kernfs_addrm_cxt *acxt); -struct kernfs_node *sysfs_new_dirent(struct kernfs_root *root, - const char *name, umode_t mode, int type); +struct kernfs_node *kernfs_get_active(struct kernfs_node *kn); +void kernfs_put_active(struct kernfs_node *kn); +void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt); +int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, + struct kernfs_node *parent); +void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt); +struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, + umode_t mode, int type); /* * file.c */ extern const struct file_operations kernfs_file_fops; -void sysfs_unmap_bin_file(struct kernfs_node *kn); +void kernfs_unmap_bin_file(struct kernfs_node *kn); /* * symlink.c diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index 27d967ba0bb..0d6ce895a9e 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -22,10 +22,10 @@ struct kmem_cache *kernfs_node_cache; static const struct super_operations kernfs_sops = { .statfs = simple_statfs, .drop_inode = generic_delete_inode, - .evict_inode = sysfs_evict_inode, + .evict_inode = kernfs_evict_inode, }; -static int sysfs_fill_super(struct super_block *sb) +static int kernfs_fill_super(struct super_block *sb) { struct kernfs_super_info *info = kernfs_info(sb); struct inode *inode; @@ -39,10 +39,10 @@ static int sysfs_fill_super(struct super_block *sb) /* get root inode, initialize and unlock it */ mutex_lock(&kernfs_mutex); - inode = sysfs_get_inode(sb, info->root->kn); + inode = kernfs_get_inode(sb, info->root->kn); mutex_unlock(&kernfs_mutex); if (!inode) { - pr_debug("sysfs: could not get root inode\n"); + pr_debug("kernfs: could not get root inode\n"); return -ENOMEM; } @@ -59,7 +59,7 @@ static int sysfs_fill_super(struct super_block *sb) return 0; } -static int sysfs_test_super(struct super_block *sb, void *data) +static int kernfs_test_super(struct super_block *sb, void *data) { struct kernfs_super_info *sb_info = kernfs_info(sb); struct kernfs_super_info *info = data; @@ -67,7 +67,7 @@ static int sysfs_test_super(struct super_block *sb, void *data) return sb_info->root == info->root && sb_info->ns == info->ns; } -static int sysfs_set_super(struct super_block *sb, void *data) +static int kernfs_set_super(struct super_block *sb, void *data) { int error; error = set_anon_super(sb, data); @@ -117,13 +117,13 @@ struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, info->root = root; info->ns = ns; - sb = sget(fs_type, sysfs_test_super, sysfs_set_super, flags, info); + sb = sget(fs_type, kernfs_test_super, kernfs_set_super, flags, info); if (IS_ERR(sb) || sb->s_fs_info != info) kfree(info); if (IS_ERR(sb)) return ERR_CAST(sb); if (!sb->s_root) { - error = sysfs_fill_super(sb); + error = kernfs_fill_super(sb); if (error) { deactivate_locked_super(sb); return ERR_PTR(error); @@ -161,5 +161,5 @@ void __init kernfs_init(void) kernfs_node_cache = kmem_cache_create("kernfs_node_cache", sizeof(struct kernfs_node), 0, SLAB_PANIC, NULL); - sysfs_inode_init(); + kernfs_inode_init(); } diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 4105bd04ea2..a03e26036ef 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -30,8 +30,8 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, struct kernfs_addrm_cxt acxt; int error; - kn = sysfs_new_dirent(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO, - KERNFS_LINK); + kn = kernfs_new_node(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO, + KERNFS_LINK); if (!kn) return ERR_PTR(-ENOMEM); @@ -40,9 +40,9 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, kn->symlink.target_kn = target; kernfs_get(target); /* ref owned by symlink */ - sysfs_addrm_start(&acxt); - error = sysfs_add_one(&acxt, kn, parent); - sysfs_addrm_finish(&acxt); + kernfs_addrm_start(&acxt); + error = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); if (!error) return kn; @@ -51,8 +51,8 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, return ERR_PTR(error); } -static int sysfs_get_target_path(struct kernfs_node *parent, - struct kernfs_node *target, char *path) +static int kernfs_get_target_path(struct kernfs_node *parent, + struct kernfs_node *target, char *path) { struct kernfs_node *base, *kn; char *s = path; @@ -103,7 +103,7 @@ static int sysfs_get_target_path(struct kernfs_node *parent, return 0; } -static int sysfs_getlink(struct dentry *dentry, char *path) +static int kernfs_getlink(struct dentry *dentry, char *path) { struct kernfs_node *kn = dentry->d_fsdata; struct kernfs_node *parent = kn->parent; @@ -111,18 +111,18 @@ static int sysfs_getlink(struct dentry *dentry, char *path) int error; mutex_lock(&kernfs_mutex); - error = sysfs_get_target_path(parent, target, path); + error = kernfs_get_target_path(parent, target, path); mutex_unlock(&kernfs_mutex); return error; } -static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *kernfs_iop_follow_link(struct dentry *dentry, struct nameidata *nd) { int error = -ENOMEM; unsigned long page = get_zeroed_page(GFP_KERNEL); if (page) { - error = sysfs_getlink(dentry, (char *) page); + error = kernfs_getlink(dentry, (char *) page); if (error < 0) free_page((unsigned long)page); } @@ -130,8 +130,8 @@ static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd) return NULL; } -static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, - void *cookie) +static void kernfs_iop_put_link(struct dentry *dentry, struct nameidata *nd, + void *cookie) { char *page = nd_get_link(nd); if (!IS_ERR(page)) @@ -139,14 +139,14 @@ static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, } const struct inode_operations kernfs_symlink_iops = { - .setxattr = sysfs_setxattr, - .removexattr = sysfs_removexattr, - .getxattr = sysfs_getxattr, - .listxattr = sysfs_listxattr, + .setxattr = kernfs_iop_setxattr, + .removexattr = kernfs_iop_removexattr, + .getxattr = kernfs_iop_getxattr, + .listxattr = kernfs_iop_listxattr, .readlink = generic_readlink, - .follow_link = sysfs_follow_link, - .put_link = sysfs_put_link, - .setattr = sysfs_setattr, - .getattr = sysfs_getattr, - .permission = sysfs_permission, + .follow_link = kernfs_iop_follow_link, + .put_link = kernfs_iop_put_link, + .setattr = kernfs_iop_setattr, + .getattr = kernfs_iop_getattr, + .permission = kernfs_iop_permission, }; -- cgit v1.2.3-70-g09d2 From 2063d608f5110d120db60e896ec2c70c95bb7978 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 16:02:57 -0500 Subject: kernfs: mark static names with KERNFS_STATIC_NAME Because sysfs used struct attribute which are supposed to stay constant, sysfs didn't copy names when creating regular files. The specified string for name was supposed to stay constant. Such distinction isn't inherent for kernfs. kernfs_create_file[_ns]() should be able to take the same @name as kernfs_create_dir[_ns]() As there can be huge number of sysfs attributes, we still want to be able to use static names for sysfs attributes. This patch renames kernfs_create_file_ns_key() to __kernfs_create_file() and adds @name_is_static parameter so that the caller can explicitly indicate that @name can be used without copying. kernfs is updated to use KERNFS_STATIC_NAME to distinguish static and copied names. This patch doesn't introduce any behavior changes. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 8 ++++---- fs/kernfs/file.c | 23 +++++++++++++++-------- fs/kernfs/kernfs-internal.h | 2 +- fs/sysfs/file.c | 4 ++-- include/linux/kernfs.h | 27 ++++++++++++++------------- 5 files changed, 36 insertions(+), 28 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index ba5f372a226..e1681775abd 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -240,7 +240,7 @@ void kernfs_put(struct kernfs_node *kn) if (kernfs_type(kn) == KERNFS_LINK) kernfs_put(kn->symlink.target_kn); - if (kernfs_type(kn) & KERNFS_COPY_NAME) + if (!(kn->flags & KERNFS_STATIC_NAME)) kfree(kn->name); if (kn->iattr) { if (kn->iattr->ia_secdata) @@ -336,13 +336,13 @@ const struct dentry_operations kernfs_dops = { }; struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, - umode_t mode, int type) + umode_t mode, unsigned flags) { char *dup_name = NULL; struct kernfs_node *kn; int ret; - if (type & KERNFS_COPY_NAME) { + if (!(flags & KERNFS_STATIC_NAME)) { name = dup_name = kstrdup(name, GFP_KERNEL); if (!name) return NULL; @@ -362,7 +362,7 @@ struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, kn->name = name; kn->mode = mode; - kn->flags = type | KERNFS_REMOVED; + kn->flags = flags | KERNFS_REMOVED; return kn; diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 053cfd9a6a4..316604cc3a1 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -762,7 +762,7 @@ const struct file_operations kernfs_file_fops = { }; /** - * kernfs_create_file_ns_key - create a file + * __kernfs_create_file - kernfs internal function to create a file * @parent: directory to create the file in * @name: name of the file * @mode: mode of the file @@ -770,23 +770,30 @@ const struct file_operations kernfs_file_fops = { * @ops: kernfs operations for the file * @priv: private data for the file * @ns: optional namespace tag of the file + * @static_name: don't copy file name * @key: lockdep key for the file's active_ref, %NULL to disable lockdep * * Returns the created node on success, ERR_PTR() value on error. */ -struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, - const char *name, - umode_t mode, loff_t size, - const struct kernfs_ops *ops, - void *priv, const void *ns, - struct lock_class_key *key) +struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, + const char *name, + umode_t mode, loff_t size, + const struct kernfs_ops *ops, + void *priv, const void *ns, + bool name_is_static, + struct lock_class_key *key) { struct kernfs_addrm_cxt acxt; struct kernfs_node *kn; + unsigned flags; int rc; + flags = KERNFS_FILE; + if (name_is_static) + flags |= KERNFS_STATIC_NAME; + kn = kernfs_new_node(kernfs_root(parent), name, - (mode & S_IALLUGO) | S_IFREG, KERNFS_FILE); + (mode & S_IALLUGO) | S_IFREG, flags); if (!kn) return ERR_PTR(-ENOMEM); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index a4ff491fd59..c6ba5bc37a9 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -105,7 +105,7 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, struct kernfs_node *parent); void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt); struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, - umode_t mode, int type); + umode_t mode, unsigned flags); /* * file.c diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index fe6388fbd15..810cf6e613e 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -252,8 +252,8 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent, if (!attr->ignore_lockdep) key = attr->key ?: (struct lock_class_key *)&attr->skey; #endif - kn = kernfs_create_file_ns_key(parent, attr->name, mode, size, - ops, (void *)attr, ns, key); + kn = __kernfs_create_file(parent, attr->name, mode, size, ops, + (void *)attr, ns, true, key); if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(parent, attr->name); diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 0ca2aedfd31..321ed84ad4c 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -34,7 +34,6 @@ enum kernfs_node_type { }; #define KERNFS_TYPE_MASK 0x000f -#define KERNFS_COPY_NAME (KERNFS_DIR | KERNFS_LINK) #define KERNFS_ACTIVE_REF KERNFS_FILE #define KERNFS_FLAG_MASK ~KERNFS_TYPE_MASK @@ -44,6 +43,7 @@ enum kernfs_node_flag { KERNFS_HAS_SEQ_SHOW = 0x0040, KERNFS_HAS_MMAP = 0x0080, KERNFS_LOCKDEP = 0x0100, + KERNFS_STATIC_NAME = 0x0200, }; /* type-specific structures for kernfs_node union members */ @@ -212,12 +212,13 @@ void kernfs_destroy_root(struct kernfs_root *root); struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, const char *name, umode_t mode, void *priv, const void *ns); -struct kernfs_node *kernfs_create_file_ns_key(struct kernfs_node *parent, - const char *name, - umode_t mode, loff_t size, - const struct kernfs_ops *ops, - void *priv, const void *ns, - struct lock_class_key *key); +struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, + const char *name, + umode_t mode, loff_t size, + const struct kernfs_ops *ops, + void *priv, const void *ns, + bool name_is_static, + struct lock_class_key *key); struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, const char *name, struct kernfs_node *target); @@ -265,10 +266,10 @@ kernfs_create_dir_ns(struct kernfs_node *parent, const char *name, { return ERR_PTR(-ENOSYS); } static inline struct kernfs_node * -kernfs_create_file_ns_key(struct kernfs_node *parent, const char *name, - umode_t mode, loff_t size, - const struct kernfs_ops *ops, void *priv, - const void *ns, struct lock_class_key *key) +__kernfs_create_file(struct kernfs_node *parent, const char *name, + umode_t mode, loff_t size, const struct kernfs_ops *ops, + void *priv, const void *ns, bool name_is_static, + struct lock_class_key *key) { return ERR_PTR(-ENOSYS); } static inline struct kernfs_node * @@ -330,8 +331,8 @@ kernfs_create_file_ns(struct kernfs_node *parent, const char *name, #ifdef CONFIG_DEBUG_LOCK_ALLOC key = (struct lock_class_key *)&ops->lockdep_key; #endif - return kernfs_create_file_ns_key(parent, name, mode, size, ops, priv, - ns, key); + return __kernfs_create_file(parent, name, mode, size, ops, priv, ns, + false, key); } static inline struct kernfs_node * -- cgit v1.2.3-70-g09d2 From d92d2e6bd72b653f9811e0c9c46307c743b3fc58 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 10 Jan 2014 08:57:18 -0500 Subject: kernfs: fix get_active failure handling in kernfs_seq_*() When kernfs_seq_start() fails to obtain an active reference, it returns ERR_PTR(-ENODEV). kernfs_seq_stop() is then invoked with the error pointer value; however, it still proceeds to invoke kernfs_put_active() on the node leading to unbalanced put. If kernfs_seq_stop() is called even after active ref failure, it should skip invocation of @ops->seq_stop() and put_active. Unfortunately, this is a bit complicated because active ref failure isn't the only thing which may fail with ERR_PTR(-ENODEV). @ops->seq_start/next() may also fail with the error value and kernfs_seq_stop() doesn't have a way to tell apart those failures. Work it around by factoring out the active part of kernfs_seq_stop() into kernfs_seq_stop_active() and invoking it directly if @ops->seq_start/next() fail with ERR_PTR(-ENODEV) and updating kernfs_seq_stop() to skip kernfs_seq_stop_active() on ERR_PTR(-ENODEV). This is a bit nasty but ensures that the active put is skipped iff get_active failed in kernfs_seq_start(). Signed-off-by: Tejun Heo Cc: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 316604cc3a1..bdd38854ef6 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -54,6 +54,38 @@ static const struct kernfs_ops *kernfs_ops(struct kernfs_node *kn) return kn->attr.ops; } +/* + * As kernfs_seq_stop() is also called after kernfs_seq_start() or + * kernfs_seq_next() failure, it needs to distinguish whether it's stopping + * a seq_file iteration which is fully initialized with an active reference + * or an aborted kernfs_seq_start() due to get_active failure. The + * position pointer is the only context for each seq_file iteration and + * thus the stop condition should be encoded in it. As the return value is + * directly visible to userland, ERR_PTR(-ENODEV) is the only acceptable + * choice to indicate get_active failure. + * + * Unfortunately, this is complicated due to the optional custom seq_file + * operations which may return ERR_PTR(-ENODEV) too. kernfs_seq_stop() + * can't distinguish whether ERR_PTR(-ENODEV) is from get_active failure or + * custom seq_file operations and thus can't decide whether put_active + * should be performed or not only on ERR_PTR(-ENODEV). + * + * This is worked around by factoring out the custom seq_stop() and + * put_active part into kernfs_seq_stop_active(), skipping it from + * kernfs_seq_stop() if ERR_PTR(-ENODEV) while invoking it directly after + * custom seq_file operations fail with ERR_PTR(-ENODEV) - this ensures + * that kernfs_seq_stop_active() is skipped only after get_active failure. + */ +static void kernfs_seq_stop_active(struct seq_file *sf, void *v) +{ + struct kernfs_open_file *of = sf->private; + const struct kernfs_ops *ops = kernfs_ops(of->kn); + + if (ops->seq_stop) + ops->seq_stop(sf, v); + kernfs_put_active(of->kn); +} + static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) { struct kernfs_open_file *of = sf->private; @@ -69,7 +101,11 @@ static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) ops = kernfs_ops(of->kn); if (ops->seq_start) { - return ops->seq_start(sf, ppos); + void *next = ops->seq_start(sf, ppos); + /* see the comment above kernfs_seq_stop_active() */ + if (next == ERR_PTR(-ENODEV)) + kernfs_seq_stop_active(sf, next); + return next; } else { /* * The same behavior and code as single_open(). Returns @@ -85,7 +121,11 @@ static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) const struct kernfs_ops *ops = kernfs_ops(of->kn); if (ops->seq_next) { - return ops->seq_next(sf, v, ppos); + void *next = ops->seq_next(sf, v, ppos); + /* see the comment above kernfs_seq_stop_active() */ + if (next == ERR_PTR(-ENODEV)) + kernfs_seq_stop_active(sf, next); + return next; } else { /* * The same behavior and code as single_open(), always @@ -99,12 +139,9 @@ static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) static void kernfs_seq_stop(struct seq_file *sf, void *v) { struct kernfs_open_file *of = sf->private; - const struct kernfs_ops *ops = kernfs_ops(of->kn); - if (ops->seq_stop) - ops->seq_stop(sf, v); - - kernfs_put_active(of->kn); + if (v != ERR_PTR(-ENODEV)) + kernfs_seq_stop_active(sf, v); mutex_unlock(&of->mutex); } -- cgit v1.2.3-70-g09d2 From ae34372eb8408b3d07e870f1939f99007a730d28 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 10 Jan 2014 08:57:21 -0500 Subject: kernfs: remove KERNFS_REMOVED KERNFS_REMOVED is used to mark half-initialized and dying nodes so that they don't show up in lookups and deny adding new nodes under or renaming it; however, its role overlaps those of deactivation and removal from rbtree. It's necessary to deny addition of new children while removal is in progress; however, this role considerably intersects with deactivation - KERNFS_REMOVED prevents new children while deactivation prevents new file operations. There's no reason to have them separate making things more complex than necessary. KERNFS_REMOVED is also used to decide whether a node is still visible to vfs layer, which is rather redundant as equivalent determination can be made by testing whether the node is on its parent's children rbtree or not. This patch removes KERNFS_REMOVED. * Instead of KERNFS_REMOVED, each node now starts its life deactivated. This means that we now use both atomic_add() and atomic_sub() on KN_DEACTIVATED_BIAS, which is INT_MIN. The compiler generates an overflow warnings when negating INT_MIN as the negation can't be represented as a positive number. Nothing is actually broken but let's bump BIAS by one to avoid the warnings for archs which negates the subtrahend.. * KERNFS_REMOVED tests in add and rename paths are replaced with kernfs_get/put_active() of the target nodes. Due to the way the add path is structured now, active ref handling is done in the callers of kernfs_add_one(). This will be consolidated up later. * kernfs_remove_one() is updated to deactivate instead of setting KERNFS_REMOVED. This removes deactivation from kernfs_deactivate(), which is now renamed to kernfs_drain(). * kernfs_dop_revalidate() now tests RB_EMPTY_NODE(&kn->rb) instead of KERNFS_REMOVED and KERNFS_REMOVED test in kernfs_dir_pos() is dropped. A node which is removed from the children rbtree is not included in the iteration in the first place. This means that a node may be visible through vfs a bit longer - it's now also visible after deactivation until the actual removal. This slightly enlarged window difference doesn't make any difference to the userland. * Sanity check on KERNFS_REMOVED in kernfs_put() is replaced with checks on the active ref. * Some comment style updates in the affected area. v2: Reordered before removal path restructuring. kernfs_active() dropped and kernfs_get/put_active() used instead. RB_EMPTY_NODE() used in the lookup paths. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 79 +++++++++++++++++++++++++-------------------- fs/kernfs/file.c | 10 ++++-- fs/kernfs/kernfs-internal.h | 3 +- fs/kernfs/symlink.c | 10 ++++-- include/linux/kernfs.h | 1 - 5 files changed, 60 insertions(+), 43 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 1c9130a3304..7f8afc1d08f 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -127,6 +127,7 @@ static void kernfs_unlink_sibling(struct kernfs_node *kn) kn->parent->dir.subdirs--; rb_erase(&kn->rb, &kn->parent->dir.children); + RB_CLEAR_NODE(&kn->rb); } /** @@ -177,18 +178,16 @@ void kernfs_put_active(struct kernfs_node *kn) } /** - * kernfs_deactivate - deactivate kernfs_node - * @kn: kernfs_node to deactivate + * kernfs_drain - drain kernfs_node + * @kn: kernfs_node to drain * - * Deny new active references and drain existing ones. + * Drain existing usages. */ -static void kernfs_deactivate(struct kernfs_node *kn) +static void kernfs_drain(struct kernfs_node *kn) { struct kernfs_root *root = kernfs_root(kn); - BUG_ON(!(kn->flags & KERNFS_REMOVED)); - - atomic_add(KN_DEACTIVATED_BIAS, &kn->active); + WARN_ON_ONCE(atomic_read(&kn->active) >= 0); if (kernfs_lockdep(kn)) { rwsem_acquire(&kn->dep_map, 0, 0, _RET_IP_); @@ -233,13 +232,15 @@ void kernfs_put(struct kernfs_node *kn) return; root = kernfs_root(kn); repeat: - /* Moving/renaming is always done while holding reference. + /* + * Moving/renaming is always done while holding reference. * kn->parent won't change beneath us. */ parent = kn->parent; - WARN(!(kn->flags & KERNFS_REMOVED), "kernfs: free using entry: %s/%s\n", - parent ? parent->name : "", kn->name); + WARN_ONCE(atomic_read(&kn->active) != KN_DEACTIVATED_BIAS, + "kernfs_put: %s/%s: released with incorrect active_ref %d\n", + parent ? parent->name : "", kn->name, atomic_read(&kn->active)); if (kernfs_type(kn) == KERNFS_LINK) kernfs_put(kn->symlink.target_kn); @@ -281,8 +282,8 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) kn = dentry->d_fsdata; mutex_lock(&kernfs_mutex); - /* The kernfs node has been deleted */ - if (kn->flags & KERNFS_REMOVED) + /* Force fresh lookup if removed */ + if (kn->parent && RB_EMPTY_NODE(&kn->rb)) goto out_bad; /* The kernfs node has been moved? */ @@ -350,11 +351,12 @@ struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, kn->ino = ret; atomic_set(&kn->count, 1); - atomic_set(&kn->active, 0); + atomic_set(&kn->active, KN_DEACTIVATED_BIAS); + RB_CLEAR_NODE(&kn->rb); kn->name = name; kn->mode = mode; - kn->flags = flags | KERNFS_REMOVED; + kn->flags = flags; return kn; @@ -413,6 +415,8 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, struct kernfs_iattrs *ps_iattr; int ret; + WARN_ON_ONCE(atomic_read(&parent->active) < 0); + if (has_ns != (bool)kn->ns) { WARN(1, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", has_ns ? "required" : "invalid", parent->name, kn->name); @@ -422,9 +426,6 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, if (kernfs_type(parent) != KERNFS_DIR) return -EINVAL; - if (parent->flags & KERNFS_REMOVED) - return -ENOENT; - kn->hash = kernfs_name_hash(kn->name, kn->ns); kn->parent = parent; kernfs_get(parent); @@ -441,8 +442,7 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, } /* Mark the entry added into directory tree */ - kn->flags &= ~KERNFS_REMOVED; - + atomic_sub(KN_DEACTIVATED_BIAS, &kn->active); return 0; } @@ -470,7 +470,7 @@ static void kernfs_remove_one(struct kernfs_addrm_cxt *acxt, * Removal can be called multiple times on the same node. Only the * first invocation is effective and puts the base ref. */ - if (kn->flags & KERNFS_REMOVED) + if (atomic_read(&kn->active) < 0) return; if (kn->parent) { @@ -484,7 +484,7 @@ static void kernfs_remove_one(struct kernfs_addrm_cxt *acxt, } } - kn->flags |= KERNFS_REMOVED; + atomic_add(KN_DEACTIVATED_BIAS, &kn->active); kn->u.removed_list = acxt->removed; acxt->removed = kn; } @@ -512,7 +512,7 @@ void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt) acxt->removed = kn->u.removed_list; - kernfs_deactivate(kn); + kernfs_drain(kn); kernfs_unmap_bin_file(kn); kernfs_put(kn); } @@ -610,7 +610,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_dir_ops *kdops, void *priv) return ERR_PTR(-ENOMEM); } - kn->flags &= ~KERNFS_REMOVED; + atomic_sub(KN_DEACTIVATED_BIAS, &kn->active); kn->priv = priv; kn->dir.root = root; @@ -662,9 +662,13 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, kn->priv = priv; /* link in */ - kernfs_addrm_start(&acxt); - rc = kernfs_add_one(&acxt, kn, parent); - kernfs_addrm_finish(&acxt); + rc = -ENOENT; + if (kernfs_get_active(parent)) { + kernfs_addrm_start(&acxt); + rc = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); + kernfs_put_active(parent); + } if (!rc) return kn; @@ -899,27 +903,29 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, { int error; - mutex_lock(&kernfs_mutex); - error = -ENOENT; - if ((kn->flags | new_parent->flags) & KERNFS_REMOVED) + if (!kernfs_get_active(new_parent)) goto out; + if (!kernfs_get_active(kn)) + goto out_put_new_parent; + + mutex_lock(&kernfs_mutex); error = 0; if ((kn->parent == new_parent) && (kn->ns == new_ns) && (strcmp(kn->name, new_name) == 0)) - goto out; /* nothing to rename */ + goto out_unlock; /* nothing to rename */ error = -EEXIST; if (kernfs_find_ns(new_parent, new_name, new_ns)) - goto out; + goto out_unlock; /* rename kernfs_node */ if (strcmp(kn->name, new_name) != 0) { error = -ENOMEM; new_name = kstrdup(new_name, GFP_KERNEL); if (!new_name) - goto out; + goto out_unlock; if (kn->flags & KERNFS_STATIC_NAME) kn->flags &= ~KERNFS_STATIC_NAME; @@ -941,8 +947,12 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, kernfs_link_sibling(kn); error = 0; - out: +out_unlock: mutex_unlock(&kernfs_mutex); + kernfs_put_active(kn); +out_put_new_parent: + kernfs_put_active(new_parent); +out: return error; } @@ -962,8 +972,7 @@ static struct kernfs_node *kernfs_dir_pos(const void *ns, struct kernfs_node *parent, loff_t hash, struct kernfs_node *pos) { if (pos) { - int valid = !(pos->flags & KERNFS_REMOVED) && - pos->parent == parent && hash == pos->hash; + int valid = pos->parent == parent && hash == pos->hash; kernfs_put(pos); if (!valid) pos = NULL; diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index bdd38854ef6..231a171f48b 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -856,9 +856,13 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, if (ops->mmap) kn->flags |= KERNFS_HAS_MMAP; - kernfs_addrm_start(&acxt); - rc = kernfs_add_one(&acxt, kn, parent); - kernfs_addrm_finish(&acxt); + rc = -ENOENT; + if (kernfs_get_active(parent)) { + kernfs_addrm_start(&acxt); + rc = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); + kernfs_put_active(parent); + } if (rc) { kernfs_put(kn); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index c6ba5bc37a9..57a93f4d645 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -26,7 +26,8 @@ struct kernfs_iattrs { struct simple_xattrs xattrs; }; -#define KN_DEACTIVATED_BIAS INT_MIN +/* +1 to avoid triggering overflow warning when negating it */ +#define KN_DEACTIVATED_BIAS (INT_MIN + 1) /* KERNFS_TYPE_MASK and types are defined in include/linux/kernfs.h */ diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index a03e26036ef..b2c106ca343 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -40,9 +40,13 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, kn->symlink.target_kn = target; kernfs_get(target); /* ref owned by symlink */ - kernfs_addrm_start(&acxt); - error = kernfs_add_one(&acxt, kn, parent); - kernfs_addrm_finish(&acxt); + error = -ENOENT; + if (kernfs_get_active(parent)) { + kernfs_addrm_start(&acxt); + error = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); + kernfs_put_active(parent); + } if (!error) return kn; diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 42ad32ff22f..289d4f639ad 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -37,7 +37,6 @@ enum kernfs_node_type { #define KERNFS_FLAG_MASK ~KERNFS_TYPE_MASK enum kernfs_node_flag { - KERNFS_REMOVED = 0x0010, KERNFS_NS = 0x0020, KERNFS_HAS_SEQ_SHOW = 0x0040, KERNFS_HAS_MMAP = 0x0080, -- cgit v1.2.3-70-g09d2 From f601f9a2bf7dc1f7ee18feece4c4e2fc6845d6c4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 10 Jan 2014 08:57:23 -0500 Subject: kernfs: invoke kernfs_unmap_bin_file() directly from __kernfs_remove() kernfs_unmap_bin_file() is supposed to unmap all memory mappings of the target file before kernfs_remove() finishes; however, it currently is being called from kernfs_addrm_finish() and has the same race problem as the original implementation of deactivation when there are multiple removers - only the remover which snatches the node to its addrm_cxt->removed list is guaranteed to wait for its completion before returning. It can be fixed by moving kernfs_unmap_bin_file() invocation from kernfs_addrm_finish() to __kernfs_remove(). The function may be called multiple times but that shouldn't do any harm. We end up dropping kernfs_mutex in the removal loop and the node may be removed inbetween by someone else. kernfs_unlink_sibling() is updated to test whether the node has already been removed and return accordingly. __kernfs_remove() in turn performs post-unlinking cleanup only if it actually unlinked the node. KERNFS_HAS_MMAP test is moved out of the unmap function into __kernfs_remove() so that we don't unlock kernfs_mutex unnecessarily. While at it, drop the now meaningless "bin" qualifier from the function name. v2: Rewritten to fit the v2 restructuring of removal path. HAS_MMAP test relocated. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 42 +++++++++++++++++++++++++++++++++--------- fs/kernfs/file.c | 5 +---- fs/kernfs/kernfs-internal.h | 2 +- 3 files changed, 35 insertions(+), 14 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index e565ec096ae..f878e4f2efe 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -121,13 +121,17 @@ static int kernfs_link_sibling(struct kernfs_node *kn) * Locking: * mutex_lock(kernfs_mutex) */ -static void kernfs_unlink_sibling(struct kernfs_node *kn) +static bool kernfs_unlink_sibling(struct kernfs_node *kn) { + if (RB_EMPTY_NODE(&kn->rb)) + return false; + if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs--; rb_erase(&kn->rb, &kn->parent->dir.children); RB_CLEAR_NODE(&kn->rb); + return true; } /** @@ -496,7 +500,6 @@ void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt) acxt->removed = kn->u.removed_list; - kernfs_unmap_bin_file(kn); kernfs_put(kn); } } @@ -854,23 +857,44 @@ static void __kernfs_remove(struct kernfs_addrm_cxt *acxt, /* unlink the subtree node-by-node */ do { - struct kernfs_iattrs *ps_iattr; - pos = kernfs_leftmost_descendant(kn); - if (pos->parent) { - kernfs_unlink_sibling(pos); + /* + * We're gonna release kernfs_mutex to unmap bin files, + * Make sure @pos doesn't go away inbetween. + */ + kernfs_get(pos); + + /* + * This must be come before unlinking; otherwise, when + * there are multiple removers, some may finish before + * unmapping is complete. + */ + if (pos->flags & KERNFS_HAS_MMAP) { + mutex_unlock(&kernfs_mutex); + kernfs_unmap_file(pos); + mutex_lock(&kernfs_mutex); + } + + /* + * kernfs_unlink_sibling() succeeds once per node. Use it + * to decide who's responsible for cleanups. + */ + if (!pos->parent || kernfs_unlink_sibling(pos)) { + struct kernfs_iattrs *ps_iattr = + pos->parent ? pos->parent->iattr : NULL; /* update timestamps on the parent */ - ps_iattr = pos->parent->iattr; if (ps_iattr) { ps_iattr->ia_iattr.ia_ctime = CURRENT_TIME; ps_iattr->ia_iattr.ia_mtime = CURRENT_TIME; } + + pos->u.removed_list = acxt->removed; + acxt->removed = pos; } - pos->u.removed_list = acxt->removed; - acxt->removed = pos; + kernfs_put(pos); } while (pos != kn); } diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 231a171f48b..404ffd2f27b 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -700,14 +700,11 @@ static int kernfs_fop_release(struct inode *inode, struct file *filp) return 0; } -void kernfs_unmap_bin_file(struct kernfs_node *kn) +void kernfs_unmap_file(struct kernfs_node *kn) { struct kernfs_open_node *on; struct kernfs_open_file *of; - if (!(kn->flags & KERNFS_HAS_MMAP)) - return; - spin_lock_irq(&kernfs_open_node_lock); on = kn->attr.open; if (on) diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 57a93f4d645..e9ec38c8607 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -113,7 +113,7 @@ struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, */ extern const struct file_operations kernfs_file_fops; -void kernfs_unmap_bin_file(struct kernfs_node *kn); +void kernfs_unmap_file(struct kernfs_node *kn); /* * symlink.c -- cgit v1.2.3-70-g09d2 From 99177a34110889a8f2c36420c34e3bcc9bfd8a70 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 10 Jan 2014 08:57:24 -0500 Subject: kernfs: remove kernfs_addrm_cxt kernfs_addrm_cxt and the accompanying kernfs_addrm_start/finish() were added because there were operations which should be performed outside kernfs_mutex after adding and removing kernfs_nodes. The necessary operations were recorded in kernfs_addrm_cxt and performed by kernfs_addrm_finish(); however, after the recent changes which relocated deactivation and unmapping so that they're performed directly during removal, the only operation kernfs_addrm_finish() performs is kernfs_put(), which can be moved inside the removal path too. This patch moves the kernfs_put() of the base ref to __kernfs_remove() and remove kernfs_addrm_cxt and kernfs_addrm_start/finish(). * kernfs_add_one() is updated to grab and release the parent's active ref and kernfs_mutex itself. kernfs_get/put_active() and kernfs_addrm_start/finish() invocations around it are removed from all users. * __kernfs_remove() puts an unlinked node directly instead of chaining it to kernfs_addrm_cxt. Its callers are updated to grab and release kernfs_mutex instead of calling kernfs_addrm_start/finish() around it. v2: Updated to fit the v2 restructuring of removal path. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 114 ++++++++++---------------------------------- fs/kernfs/file.c | 10 +--- fs/kernfs/kernfs-internal.h | 12 +---- fs/kernfs/symlink.c | 10 +--- include/linux/kernfs.h | 4 -- 5 files changed, 29 insertions(+), 121 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index f878e4f2efe..770d687ee9f 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -398,29 +398,8 @@ struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, return NULL; } -/** - * kernfs_addrm_start - prepare for kernfs_node add/remove - * @acxt: pointer to kernfs_addrm_cxt to be used - * - * This function is called when the caller is about to add or remove - * kernfs_node. This function acquires kernfs_mutex. @acxt is used - * to keep and pass context to other addrm functions. - * - * LOCKING: - * Kernel thread context (may sleep). kernfs_mutex is locked on - * return. - */ -void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt) - __acquires(kernfs_mutex) -{ - memset(acxt, 0, sizeof(*acxt)); - - mutex_lock(&kernfs_mutex); -} - /** * kernfs_add_one - add kernfs_node to parent without warning - * @acxt: addrm context to use * @kn: kernfs_node to be added * @parent: the parent kernfs_node to add @kn to * @@ -428,34 +407,29 @@ void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt) * parent inode if @kn is a directory and link into the children list * of the parent. * - * This function should be called between calls to - * kernfs_addrm_start() and kernfs_addrm_finish() and should be passed - * the same @acxt as passed to kernfs_addrm_start(). - * - * LOCKING: - * Determined by kernfs_addrm_start(). - * * RETURNS: * 0 on success, -EEXIST if entry with the given name already * exists. */ -int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, - struct kernfs_node *parent) +int kernfs_add_one(struct kernfs_node *kn, struct kernfs_node *parent) { - bool has_ns = kernfs_ns_enabled(parent); struct kernfs_iattrs *ps_iattr; + bool has_ns; int ret; - WARN_ON_ONCE(atomic_read(&parent->active) < 0); + if (!kernfs_get_active(parent)) + return -ENOENT; - if (has_ns != (bool)kn->ns) { - WARN(1, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", - has_ns ? "required" : "invalid", parent->name, kn->name); - return -EINVAL; - } + mutex_lock(&kernfs_mutex); + + ret = -EINVAL; + has_ns = kernfs_ns_enabled(parent); + if (WARN(has_ns != (bool)kn->ns, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", + has_ns ? "required" : "invalid", parent->name, kn->name)) + goto out_unlock; if (kernfs_type(parent) != KERNFS_DIR) - return -EINVAL; + goto out_unlock; kn->hash = kernfs_name_hash(kn->name, kn->ns); kn->parent = parent; @@ -463,7 +437,7 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, ret = kernfs_link_sibling(kn); if (ret) - return ret; + goto out_unlock; /* Update timestamps on the parent */ ps_iattr = parent->iattr; @@ -474,34 +448,11 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, /* Mark the entry added into directory tree */ atomic_sub(KN_DEACTIVATED_BIAS, &kn->active); - return 0; -} - -/** - * kernfs_addrm_finish - finish up kernfs_node add/remove - * @acxt: addrm context to finish up - * - * Finish up kernfs_node add/remove. Resources acquired by - * kernfs_addrm_start() are released and removed kernfs_nodes are - * cleaned up. - * - * LOCKING: - * kernfs_mutex is released. - */ -void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt) - __releases(kernfs_mutex) -{ - /* release resources acquired by kernfs_addrm_start() */ + ret = 0; +out_unlock: mutex_unlock(&kernfs_mutex); - - /* kill removed kernfs_nodes */ - while (acxt->removed) { - struct kernfs_node *kn = acxt->removed; - - acxt->removed = kn->u.removed_list; - - kernfs_put(kn); - } + kernfs_put_active(parent); + return ret; } /** @@ -633,7 +584,6 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, const char *name, umode_t mode, void *priv, const void *ns) { - struct kernfs_addrm_cxt acxt; struct kernfs_node *kn; int rc; @@ -648,14 +598,7 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, kn->priv = priv; /* link in */ - rc = -ENOENT; - if (kernfs_get_active(parent)) { - kernfs_addrm_start(&acxt); - rc = kernfs_add_one(&acxt, kn, parent); - kernfs_addrm_finish(&acxt); - kernfs_put_active(parent); - } - + rc = kernfs_add_one(kn, parent); if (!rc) return kn; @@ -841,8 +784,7 @@ static void __kernfs_deactivate(struct kernfs_node *kn) } } -static void __kernfs_remove(struct kernfs_addrm_cxt *acxt, - struct kernfs_node *kn) +static void __kernfs_remove(struct kernfs_node *kn) { struct kernfs_node *pos; @@ -890,8 +832,7 @@ static void __kernfs_remove(struct kernfs_addrm_cxt *acxt, ps_iattr->ia_iattr.ia_mtime = CURRENT_TIME; } - pos->u.removed_list = acxt->removed; - acxt->removed = pos; + kernfs_put(pos); } kernfs_put(pos); @@ -906,11 +847,9 @@ static void __kernfs_remove(struct kernfs_addrm_cxt *acxt, */ void kernfs_remove(struct kernfs_node *kn) { - struct kernfs_addrm_cxt acxt; - - kernfs_addrm_start(&acxt); - __kernfs_remove(&acxt, kn); - kernfs_addrm_finish(&acxt); + mutex_lock(&kernfs_mutex); + __kernfs_remove(kn); + mutex_unlock(&kernfs_mutex); } /** @@ -925,7 +864,6 @@ void kernfs_remove(struct kernfs_node *kn) int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, const void *ns) { - struct kernfs_addrm_cxt acxt; struct kernfs_node *kn; if (!parent) { @@ -934,13 +872,13 @@ int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, return -ENOENT; } - kernfs_addrm_start(&acxt); + mutex_lock(&kernfs_mutex); kn = kernfs_find_ns(parent, name, ns); if (kn) - __kernfs_remove(&acxt, kn); + __kernfs_remove(kn); - kernfs_addrm_finish(&acxt); + mutex_unlock(&kernfs_mutex); if (kn) return 0; diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 404ffd2f27b..ffe1bebf919 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -817,7 +817,6 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, bool name_is_static, struct lock_class_key *key) { - struct kernfs_addrm_cxt acxt; struct kernfs_node *kn; unsigned flags; int rc; @@ -853,14 +852,7 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, if (ops->mmap) kn->flags |= KERNFS_HAS_MMAP; - rc = -ENOENT; - if (kernfs_get_active(parent)) { - kernfs_addrm_start(&acxt); - rc = kernfs_add_one(&acxt, kn, parent); - kernfs_addrm_finish(&acxt); - kernfs_put_active(parent); - } - + rc = kernfs_add_one(kn, parent); if (rc) { kernfs_put(kn); return ERR_PTR(rc); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index e9ec38c8607..4bc57848076 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -45,13 +45,6 @@ static inline struct kernfs_root *kernfs_root(struct kernfs_node *kn) return kn->dir.root; } -/* - * Context structure to be used while adding/removing nodes. - */ -struct kernfs_addrm_cxt { - struct kernfs_node *removed; -}; - /* * mount.c */ @@ -101,10 +94,7 @@ extern const struct inode_operations kernfs_dir_iops; struct kernfs_node *kernfs_get_active(struct kernfs_node *kn); void kernfs_put_active(struct kernfs_node *kn); -void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt); -int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, - struct kernfs_node *parent); -void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt); +int kernfs_add_one(struct kernfs_node *kn, struct kernfs_node *parent); struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, umode_t mode, unsigned flags); diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index b2c106ca343..3a939c263ed 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -27,7 +27,6 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, struct kernfs_node *target) { struct kernfs_node *kn; - struct kernfs_addrm_cxt acxt; int error; kn = kernfs_new_node(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO, @@ -40,14 +39,7 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, kn->symlink.target_kn = target; kernfs_get(target); /* ref owned by symlink */ - error = -ENOENT; - if (kernfs_get_active(parent)) { - kernfs_addrm_start(&acxt); - error = kernfs_add_one(&acxt, kn, parent); - kernfs_addrm_finish(&acxt); - kernfs_put_active(parent); - } - + error = kernfs_add_one(kn, parent); if (!error) return kn; diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 61bd7ae6b8e..9b5a4bb88c6 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -89,10 +89,6 @@ struct kernfs_node { struct rb_node rb; - union { - struct kernfs_node *removed_list; - } u; - const void *ns; /* namespace tag */ unsigned int hash; /* ns + name hash */ union { -- cgit v1.2.3-70-g09d2 From 7653fe9d6cddc3fc5e4220608079006d8ac0054c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 13 Jan 2014 14:20:56 -0800 Subject: Revert "kernfs: remove kernfs_addrm_cxt" This reverts commit 99177a34110889a8f2c36420c34e3bcc9bfd8a70. Tejun writes: I'm sorry but can you please revert the whole series? get_active() waiting while a node is deactivated has potential to lead to deadlock and that deactivate/reactivate interface is something fundamentally flawed and that cgroup will have to work with the remove_self() like everybody else. IOW, I think the first posting was correct. Cc: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 114 ++++++++++++++++++++++++++++++++++---------- fs/kernfs/file.c | 10 +++- fs/kernfs/kernfs-internal.h | 12 ++++- fs/kernfs/symlink.c | 10 +++- include/linux/kernfs.h | 4 ++ 5 files changed, 121 insertions(+), 29 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 770d687ee9f..f878e4f2efe 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -398,8 +398,29 @@ struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, return NULL; } +/** + * kernfs_addrm_start - prepare for kernfs_node add/remove + * @acxt: pointer to kernfs_addrm_cxt to be used + * + * This function is called when the caller is about to add or remove + * kernfs_node. This function acquires kernfs_mutex. @acxt is used + * to keep and pass context to other addrm functions. + * + * LOCKING: + * Kernel thread context (may sleep). kernfs_mutex is locked on + * return. + */ +void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt) + __acquires(kernfs_mutex) +{ + memset(acxt, 0, sizeof(*acxt)); + + mutex_lock(&kernfs_mutex); +} + /** * kernfs_add_one - add kernfs_node to parent without warning + * @acxt: addrm context to use * @kn: kernfs_node to be added * @parent: the parent kernfs_node to add @kn to * @@ -407,29 +428,34 @@ struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, * parent inode if @kn is a directory and link into the children list * of the parent. * + * This function should be called between calls to + * kernfs_addrm_start() and kernfs_addrm_finish() and should be passed + * the same @acxt as passed to kernfs_addrm_start(). + * + * LOCKING: + * Determined by kernfs_addrm_start(). + * * RETURNS: * 0 on success, -EEXIST if entry with the given name already * exists. */ -int kernfs_add_one(struct kernfs_node *kn, struct kernfs_node *parent) +int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, + struct kernfs_node *parent) { + bool has_ns = kernfs_ns_enabled(parent); struct kernfs_iattrs *ps_iattr; - bool has_ns; int ret; - if (!kernfs_get_active(parent)) - return -ENOENT; + WARN_ON_ONCE(atomic_read(&parent->active) < 0); - mutex_lock(&kernfs_mutex); - - ret = -EINVAL; - has_ns = kernfs_ns_enabled(parent); - if (WARN(has_ns != (bool)kn->ns, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", - has_ns ? "required" : "invalid", parent->name, kn->name)) - goto out_unlock; + if (has_ns != (bool)kn->ns) { + WARN(1, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", + has_ns ? "required" : "invalid", parent->name, kn->name); + return -EINVAL; + } if (kernfs_type(parent) != KERNFS_DIR) - goto out_unlock; + return -EINVAL; kn->hash = kernfs_name_hash(kn->name, kn->ns); kn->parent = parent; @@ -437,7 +463,7 @@ int kernfs_add_one(struct kernfs_node *kn, struct kernfs_node *parent) ret = kernfs_link_sibling(kn); if (ret) - goto out_unlock; + return ret; /* Update timestamps on the parent */ ps_iattr = parent->iattr; @@ -448,11 +474,34 @@ int kernfs_add_one(struct kernfs_node *kn, struct kernfs_node *parent) /* Mark the entry added into directory tree */ atomic_sub(KN_DEACTIVATED_BIAS, &kn->active); - ret = 0; -out_unlock: + return 0; +} + +/** + * kernfs_addrm_finish - finish up kernfs_node add/remove + * @acxt: addrm context to finish up + * + * Finish up kernfs_node add/remove. Resources acquired by + * kernfs_addrm_start() are released and removed kernfs_nodes are + * cleaned up. + * + * LOCKING: + * kernfs_mutex is released. + */ +void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt) + __releases(kernfs_mutex) +{ + /* release resources acquired by kernfs_addrm_start() */ mutex_unlock(&kernfs_mutex); - kernfs_put_active(parent); - return ret; + + /* kill removed kernfs_nodes */ + while (acxt->removed) { + struct kernfs_node *kn = acxt->removed; + + acxt->removed = kn->u.removed_list; + + kernfs_put(kn); + } } /** @@ -584,6 +633,7 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, const char *name, umode_t mode, void *priv, const void *ns) { + struct kernfs_addrm_cxt acxt; struct kernfs_node *kn; int rc; @@ -598,7 +648,14 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, kn->priv = priv; /* link in */ - rc = kernfs_add_one(kn, parent); + rc = -ENOENT; + if (kernfs_get_active(parent)) { + kernfs_addrm_start(&acxt); + rc = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); + kernfs_put_active(parent); + } + if (!rc) return kn; @@ -784,7 +841,8 @@ static void __kernfs_deactivate(struct kernfs_node *kn) } } -static void __kernfs_remove(struct kernfs_node *kn) +static void __kernfs_remove(struct kernfs_addrm_cxt *acxt, + struct kernfs_node *kn) { struct kernfs_node *pos; @@ -832,7 +890,8 @@ static void __kernfs_remove(struct kernfs_node *kn) ps_iattr->ia_iattr.ia_mtime = CURRENT_TIME; } - kernfs_put(pos); + pos->u.removed_list = acxt->removed; + acxt->removed = pos; } kernfs_put(pos); @@ -847,9 +906,11 @@ static void __kernfs_remove(struct kernfs_node *kn) */ void kernfs_remove(struct kernfs_node *kn) { - mutex_lock(&kernfs_mutex); - __kernfs_remove(kn); - mutex_unlock(&kernfs_mutex); + struct kernfs_addrm_cxt acxt; + + kernfs_addrm_start(&acxt); + __kernfs_remove(&acxt, kn); + kernfs_addrm_finish(&acxt); } /** @@ -864,6 +925,7 @@ void kernfs_remove(struct kernfs_node *kn) int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, const void *ns) { + struct kernfs_addrm_cxt acxt; struct kernfs_node *kn; if (!parent) { @@ -872,13 +934,13 @@ int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, return -ENOENT; } - mutex_lock(&kernfs_mutex); + kernfs_addrm_start(&acxt); kn = kernfs_find_ns(parent, name, ns); if (kn) - __kernfs_remove(kn); + __kernfs_remove(&acxt, kn); - mutex_unlock(&kernfs_mutex); + kernfs_addrm_finish(&acxt); if (kn) return 0; diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index ffe1bebf919..404ffd2f27b 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -817,6 +817,7 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, bool name_is_static, struct lock_class_key *key) { + struct kernfs_addrm_cxt acxt; struct kernfs_node *kn; unsigned flags; int rc; @@ -852,7 +853,14 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, if (ops->mmap) kn->flags |= KERNFS_HAS_MMAP; - rc = kernfs_add_one(kn, parent); + rc = -ENOENT; + if (kernfs_get_active(parent)) { + kernfs_addrm_start(&acxt); + rc = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); + kernfs_put_active(parent); + } + if (rc) { kernfs_put(kn); return ERR_PTR(rc); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 4bc57848076..e9ec38c8607 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -45,6 +45,13 @@ static inline struct kernfs_root *kernfs_root(struct kernfs_node *kn) return kn->dir.root; } +/* + * Context structure to be used while adding/removing nodes. + */ +struct kernfs_addrm_cxt { + struct kernfs_node *removed; +}; + /* * mount.c */ @@ -94,7 +101,10 @@ extern const struct inode_operations kernfs_dir_iops; struct kernfs_node *kernfs_get_active(struct kernfs_node *kn); void kernfs_put_active(struct kernfs_node *kn); -int kernfs_add_one(struct kernfs_node *kn, struct kernfs_node *parent); +void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt); +int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, + struct kernfs_node *parent); +void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt); struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, umode_t mode, unsigned flags); diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 3a939c263ed..b2c106ca343 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -27,6 +27,7 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, struct kernfs_node *target) { struct kernfs_node *kn; + struct kernfs_addrm_cxt acxt; int error; kn = kernfs_new_node(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO, @@ -39,7 +40,14 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, kn->symlink.target_kn = target; kernfs_get(target); /* ref owned by symlink */ - error = kernfs_add_one(kn, parent); + error = -ENOENT; + if (kernfs_get_active(parent)) { + kernfs_addrm_start(&acxt); + error = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); + kernfs_put_active(parent); + } + if (!error) return kn; diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 9b5a4bb88c6..61bd7ae6b8e 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -89,6 +89,10 @@ struct kernfs_node { struct rb_node rb; + union { + struct kernfs_node *removed_list; + } u; + const void *ns; /* namespace tag */ unsigned int hash; /* ns + name hash */ union { -- cgit v1.2.3-70-g09d2 From 55f6e30d0a6a8975cc0831e8a4a3715b815b6a2f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 13 Jan 2014 14:27:16 -0800 Subject: Revert "kernfs: invoke kernfs_unmap_bin_file() directly from __kernfs_remove()" This reverts commit f601f9a2bf7dc1f7ee18feece4c4e2fc6845d6c4. Tejun writes: I'm sorry but can you please revert the whole series? get_active() waiting while a node is deactivated has potential to lead to deadlock and that deactivate/reactivate interface is something fundamentally flawed and that cgroup will have to work with the remove_self() like everybody else. IOW, I think the first posting was correct. Cc: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 42 +++++++++--------------------------------- fs/kernfs/file.c | 5 ++++- fs/kernfs/kernfs-internal.h | 2 +- 3 files changed, 14 insertions(+), 35 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index f878e4f2efe..e565ec096ae 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -121,17 +121,13 @@ static int kernfs_link_sibling(struct kernfs_node *kn) * Locking: * mutex_lock(kernfs_mutex) */ -static bool kernfs_unlink_sibling(struct kernfs_node *kn) +static void kernfs_unlink_sibling(struct kernfs_node *kn) { - if (RB_EMPTY_NODE(&kn->rb)) - return false; - if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs--; rb_erase(&kn->rb, &kn->parent->dir.children); RB_CLEAR_NODE(&kn->rb); - return true; } /** @@ -500,6 +496,7 @@ void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt) acxt->removed = kn->u.removed_list; + kernfs_unmap_bin_file(kn); kernfs_put(kn); } } @@ -857,44 +854,23 @@ static void __kernfs_remove(struct kernfs_addrm_cxt *acxt, /* unlink the subtree node-by-node */ do { - pos = kernfs_leftmost_descendant(kn); - - /* - * We're gonna release kernfs_mutex to unmap bin files, - * Make sure @pos doesn't go away inbetween. - */ - kernfs_get(pos); + struct kernfs_iattrs *ps_iattr; - /* - * This must be come before unlinking; otherwise, when - * there are multiple removers, some may finish before - * unmapping is complete. - */ - if (pos->flags & KERNFS_HAS_MMAP) { - mutex_unlock(&kernfs_mutex); - kernfs_unmap_file(pos); - mutex_lock(&kernfs_mutex); - } + pos = kernfs_leftmost_descendant(kn); - /* - * kernfs_unlink_sibling() succeeds once per node. Use it - * to decide who's responsible for cleanups. - */ - if (!pos->parent || kernfs_unlink_sibling(pos)) { - struct kernfs_iattrs *ps_iattr = - pos->parent ? pos->parent->iattr : NULL; + if (pos->parent) { + kernfs_unlink_sibling(pos); /* update timestamps on the parent */ + ps_iattr = pos->parent->iattr; if (ps_iattr) { ps_iattr->ia_iattr.ia_ctime = CURRENT_TIME; ps_iattr->ia_iattr.ia_mtime = CURRENT_TIME; } - - pos->u.removed_list = acxt->removed; - acxt->removed = pos; } - kernfs_put(pos); + pos->u.removed_list = acxt->removed; + acxt->removed = pos; } while (pos != kn); } diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 404ffd2f27b..231a171f48b 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -700,11 +700,14 @@ static int kernfs_fop_release(struct inode *inode, struct file *filp) return 0; } -void kernfs_unmap_file(struct kernfs_node *kn) +void kernfs_unmap_bin_file(struct kernfs_node *kn) { struct kernfs_open_node *on; struct kernfs_open_file *of; + if (!(kn->flags & KERNFS_HAS_MMAP)) + return; + spin_lock_irq(&kernfs_open_node_lock); on = kn->attr.open; if (on) diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index e9ec38c8607..57a93f4d645 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -113,7 +113,7 @@ struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, */ extern const struct file_operations kernfs_file_fops; -void kernfs_unmap_file(struct kernfs_node *kn); +void kernfs_unmap_bin_file(struct kernfs_node *kn); /* * symlink.c -- cgit v1.2.3-70-g09d2 From 798c75a0d44cdbd6e3d82a6a676e6de38525b3bb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 13 Jan 2014 14:36:03 -0800 Subject: Revert "kernfs: remove KERNFS_REMOVED" This reverts commit ae34372eb8408b3d07e870f1939f99007a730d28. Tejun writes: I'm sorry but can you please revert the whole series? get_active() waiting while a node is deactivated has potential to lead to deadlock and that deactivate/reactivate interface is something fundamentally flawed and that cgroup will have to work with the remove_self() like everybody else. IOW, I think the first posting was correct. Cc: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 79 ++++++++++++++++++++------------------------- fs/kernfs/file.c | 10 ++---- fs/kernfs/kernfs-internal.h | 3 +- fs/kernfs/symlink.c | 10 ++---- include/linux/kernfs.h | 1 + 5 files changed, 43 insertions(+), 60 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 7f8afc1d08f..1c9130a3304 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -127,7 +127,6 @@ static void kernfs_unlink_sibling(struct kernfs_node *kn) kn->parent->dir.subdirs--; rb_erase(&kn->rb, &kn->parent->dir.children); - RB_CLEAR_NODE(&kn->rb); } /** @@ -178,16 +177,18 @@ void kernfs_put_active(struct kernfs_node *kn) } /** - * kernfs_drain - drain kernfs_node - * @kn: kernfs_node to drain + * kernfs_deactivate - deactivate kernfs_node + * @kn: kernfs_node to deactivate * - * Drain existing usages. + * Deny new active references and drain existing ones. */ -static void kernfs_drain(struct kernfs_node *kn) +static void kernfs_deactivate(struct kernfs_node *kn) { struct kernfs_root *root = kernfs_root(kn); - WARN_ON_ONCE(atomic_read(&kn->active) >= 0); + BUG_ON(!(kn->flags & KERNFS_REMOVED)); + + atomic_add(KN_DEACTIVATED_BIAS, &kn->active); if (kernfs_lockdep(kn)) { rwsem_acquire(&kn->dep_map, 0, 0, _RET_IP_); @@ -232,15 +233,13 @@ void kernfs_put(struct kernfs_node *kn) return; root = kernfs_root(kn); repeat: - /* - * Moving/renaming is always done while holding reference. + /* Moving/renaming is always done while holding reference. * kn->parent won't change beneath us. */ parent = kn->parent; - WARN_ONCE(atomic_read(&kn->active) != KN_DEACTIVATED_BIAS, - "kernfs_put: %s/%s: released with incorrect active_ref %d\n", - parent ? parent->name : "", kn->name, atomic_read(&kn->active)); + WARN(!(kn->flags & KERNFS_REMOVED), "kernfs: free using entry: %s/%s\n", + parent ? parent->name : "", kn->name); if (kernfs_type(kn) == KERNFS_LINK) kernfs_put(kn->symlink.target_kn); @@ -282,8 +281,8 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) kn = dentry->d_fsdata; mutex_lock(&kernfs_mutex); - /* Force fresh lookup if removed */ - if (kn->parent && RB_EMPTY_NODE(&kn->rb)) + /* The kernfs node has been deleted */ + if (kn->flags & KERNFS_REMOVED) goto out_bad; /* The kernfs node has been moved? */ @@ -351,12 +350,11 @@ struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, kn->ino = ret; atomic_set(&kn->count, 1); - atomic_set(&kn->active, KN_DEACTIVATED_BIAS); - RB_CLEAR_NODE(&kn->rb); + atomic_set(&kn->active, 0); kn->name = name; kn->mode = mode; - kn->flags = flags; + kn->flags = flags | KERNFS_REMOVED; return kn; @@ -415,8 +413,6 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, struct kernfs_iattrs *ps_iattr; int ret; - WARN_ON_ONCE(atomic_read(&parent->active) < 0); - if (has_ns != (bool)kn->ns) { WARN(1, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", has_ns ? "required" : "invalid", parent->name, kn->name); @@ -426,6 +422,9 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, if (kernfs_type(parent) != KERNFS_DIR) return -EINVAL; + if (parent->flags & KERNFS_REMOVED) + return -ENOENT; + kn->hash = kernfs_name_hash(kn->name, kn->ns); kn->parent = parent; kernfs_get(parent); @@ -442,7 +441,8 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, } /* Mark the entry added into directory tree */ - atomic_sub(KN_DEACTIVATED_BIAS, &kn->active); + kn->flags &= ~KERNFS_REMOVED; + return 0; } @@ -470,7 +470,7 @@ static void kernfs_remove_one(struct kernfs_addrm_cxt *acxt, * Removal can be called multiple times on the same node. Only the * first invocation is effective and puts the base ref. */ - if (atomic_read(&kn->active) < 0) + if (kn->flags & KERNFS_REMOVED) return; if (kn->parent) { @@ -484,7 +484,7 @@ static void kernfs_remove_one(struct kernfs_addrm_cxt *acxt, } } - atomic_add(KN_DEACTIVATED_BIAS, &kn->active); + kn->flags |= KERNFS_REMOVED; kn->u.removed_list = acxt->removed; acxt->removed = kn; } @@ -512,7 +512,7 @@ void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt) acxt->removed = kn->u.removed_list; - kernfs_drain(kn); + kernfs_deactivate(kn); kernfs_unmap_bin_file(kn); kernfs_put(kn); } @@ -610,7 +610,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_dir_ops *kdops, void *priv) return ERR_PTR(-ENOMEM); } - atomic_sub(KN_DEACTIVATED_BIAS, &kn->active); + kn->flags &= ~KERNFS_REMOVED; kn->priv = priv; kn->dir.root = root; @@ -662,13 +662,9 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, kn->priv = priv; /* link in */ - rc = -ENOENT; - if (kernfs_get_active(parent)) { - kernfs_addrm_start(&acxt); - rc = kernfs_add_one(&acxt, kn, parent); - kernfs_addrm_finish(&acxt); - kernfs_put_active(parent); - } + kernfs_addrm_start(&acxt); + rc = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); if (!rc) return kn; @@ -903,29 +899,27 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, { int error; + mutex_lock(&kernfs_mutex); + error = -ENOENT; - if (!kernfs_get_active(new_parent)) + if ((kn->flags | new_parent->flags) & KERNFS_REMOVED) goto out; - if (!kernfs_get_active(kn)) - goto out_put_new_parent; - - mutex_lock(&kernfs_mutex); error = 0; if ((kn->parent == new_parent) && (kn->ns == new_ns) && (strcmp(kn->name, new_name) == 0)) - goto out_unlock; /* nothing to rename */ + goto out; /* nothing to rename */ error = -EEXIST; if (kernfs_find_ns(new_parent, new_name, new_ns)) - goto out_unlock; + goto out; /* rename kernfs_node */ if (strcmp(kn->name, new_name) != 0) { error = -ENOMEM; new_name = kstrdup(new_name, GFP_KERNEL); if (!new_name) - goto out_unlock; + goto out; if (kn->flags & KERNFS_STATIC_NAME) kn->flags &= ~KERNFS_STATIC_NAME; @@ -947,12 +941,8 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, kernfs_link_sibling(kn); error = 0; -out_unlock: + out: mutex_unlock(&kernfs_mutex); - kernfs_put_active(kn); -out_put_new_parent: - kernfs_put_active(new_parent); -out: return error; } @@ -972,7 +962,8 @@ static struct kernfs_node *kernfs_dir_pos(const void *ns, struct kernfs_node *parent, loff_t hash, struct kernfs_node *pos) { if (pos) { - int valid = pos->parent == parent && hash == pos->hash; + int valid = !(pos->flags & KERNFS_REMOVED) && + pos->parent == parent && hash == pos->hash; kernfs_put(pos); if (!valid) pos = NULL; diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 231a171f48b..bdd38854ef6 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -856,13 +856,9 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, if (ops->mmap) kn->flags |= KERNFS_HAS_MMAP; - rc = -ENOENT; - if (kernfs_get_active(parent)) { - kernfs_addrm_start(&acxt); - rc = kernfs_add_one(&acxt, kn, parent); - kernfs_addrm_finish(&acxt); - kernfs_put_active(parent); - } + kernfs_addrm_start(&acxt); + rc = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); if (rc) { kernfs_put(kn); diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 57a93f4d645..c6ba5bc37a9 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -26,8 +26,7 @@ struct kernfs_iattrs { struct simple_xattrs xattrs; }; -/* +1 to avoid triggering overflow warning when negating it */ -#define KN_DEACTIVATED_BIAS (INT_MIN + 1) +#define KN_DEACTIVATED_BIAS INT_MIN /* KERNFS_TYPE_MASK and types are defined in include/linux/kernfs.h */ diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index b2c106ca343..a03e26036ef 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -40,13 +40,9 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, kn->symlink.target_kn = target; kernfs_get(target); /* ref owned by symlink */ - error = -ENOENT; - if (kernfs_get_active(parent)) { - kernfs_addrm_start(&acxt); - error = kernfs_add_one(&acxt, kn, parent); - kernfs_addrm_finish(&acxt); - kernfs_put_active(parent); - } + kernfs_addrm_start(&acxt); + error = kernfs_add_one(&acxt, kn, parent); + kernfs_addrm_finish(&acxt); if (!error) return kn; diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 289d4f639ad..42ad32ff22f 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -37,6 +37,7 @@ enum kernfs_node_type { #define KERNFS_FLAG_MASK ~KERNFS_TYPE_MASK enum kernfs_node_flag { + KERNFS_REMOVED = 0x0010, KERNFS_NS = 0x0020, KERNFS_HAS_SEQ_SHOW = 0x0040, KERNFS_HAS_MMAP = 0x0080, -- cgit v1.2.3-70-g09d2 From 683bb2761fbf123b24aed03a1c0d5d7556ec3018 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 13 Jan 2014 14:49:01 -0800 Subject: Revert "kernfs: fix get_active failure handling in kernfs_seq_*()" This reverts commit d92d2e6bd72b653f9811e0c9c46307c743b3fc58. Tejun writes: I'm sorry but can you please revert the whole series? get_active() waiting while a node is deactivated has potential to lead to deadlock and that deactivate/reactivate interface is something fundamentally flawed and that cgroup will have to work with the remove_self() like everybody else. IOW, I think the first posting was correct. Cc: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 51 +++++++-------------------------------------------- 1 file changed, 7 insertions(+), 44 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index bdd38854ef6..316604cc3a1 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -54,38 +54,6 @@ static const struct kernfs_ops *kernfs_ops(struct kernfs_node *kn) return kn->attr.ops; } -/* - * As kernfs_seq_stop() is also called after kernfs_seq_start() or - * kernfs_seq_next() failure, it needs to distinguish whether it's stopping - * a seq_file iteration which is fully initialized with an active reference - * or an aborted kernfs_seq_start() due to get_active failure. The - * position pointer is the only context for each seq_file iteration and - * thus the stop condition should be encoded in it. As the return value is - * directly visible to userland, ERR_PTR(-ENODEV) is the only acceptable - * choice to indicate get_active failure. - * - * Unfortunately, this is complicated due to the optional custom seq_file - * operations which may return ERR_PTR(-ENODEV) too. kernfs_seq_stop() - * can't distinguish whether ERR_PTR(-ENODEV) is from get_active failure or - * custom seq_file operations and thus can't decide whether put_active - * should be performed or not only on ERR_PTR(-ENODEV). - * - * This is worked around by factoring out the custom seq_stop() and - * put_active part into kernfs_seq_stop_active(), skipping it from - * kernfs_seq_stop() if ERR_PTR(-ENODEV) while invoking it directly after - * custom seq_file operations fail with ERR_PTR(-ENODEV) - this ensures - * that kernfs_seq_stop_active() is skipped only after get_active failure. - */ -static void kernfs_seq_stop_active(struct seq_file *sf, void *v) -{ - struct kernfs_open_file *of = sf->private; - const struct kernfs_ops *ops = kernfs_ops(of->kn); - - if (ops->seq_stop) - ops->seq_stop(sf, v); - kernfs_put_active(of->kn); -} - static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) { struct kernfs_open_file *of = sf->private; @@ -101,11 +69,7 @@ static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) ops = kernfs_ops(of->kn); if (ops->seq_start) { - void *next = ops->seq_start(sf, ppos); - /* see the comment above kernfs_seq_stop_active() */ - if (next == ERR_PTR(-ENODEV)) - kernfs_seq_stop_active(sf, next); - return next; + return ops->seq_start(sf, ppos); } else { /* * The same behavior and code as single_open(). Returns @@ -121,11 +85,7 @@ static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) const struct kernfs_ops *ops = kernfs_ops(of->kn); if (ops->seq_next) { - void *next = ops->seq_next(sf, v, ppos); - /* see the comment above kernfs_seq_stop_active() */ - if (next == ERR_PTR(-ENODEV)) - kernfs_seq_stop_active(sf, next); - return next; + return ops->seq_next(sf, v, ppos); } else { /* * The same behavior and code as single_open(), always @@ -139,9 +99,12 @@ static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) static void kernfs_seq_stop(struct seq_file *sf, void *v) { struct kernfs_open_file *of = sf->private; + const struct kernfs_ops *ops = kernfs_ops(of->kn); - if (v != ERR_PTR(-ENODEV)) - kernfs_seq_stop_active(sf, v); + if (ops->seq_stop) + ops->seq_stop(sf, v); + + kernfs_put_active(of->kn); mutex_unlock(&of->mutex); } -- cgit v1.2.3-70-g09d2 From bb305947bdbb67325e1f949183cdd208fc2a7999 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 14 Jan 2014 09:52:01 -0500 Subject: kernfs: fix get_active failure handling in kernfs_seq_*() When kernfs_seq_start() fails to obtain an active reference, it returns ERR_PTR(-ENODEV). kernfs_seq_stop() is then invoked with the error pointer value; however, it still proceeds to invoke kernfs_put_active() on the node leading to unbalanced put. If kernfs_seq_stop() is called even after active ref failure, it should skip invocation of @ops->seq_stop() and put_active. Unfortunately, this is a bit complicated because active ref failure isn't the only thing which may fail with ERR_PTR(-ENODEV). @ops->seq_start/next() may also fail with the error value and kernfs_seq_stop() doesn't have a way to tell apart those failures. Work it around by factoring out the active part of kernfs_seq_stop() into kernfs_seq_stop_active() and invoking it directly if @ops->seq_start/next() fail with ERR_PTR(-ENODEV) and updating kernfs_seq_stop() to skip kernfs_seq_stop_active() on ERR_PTR(-ENODEV). This is a bit nasty but ensures that the active put is skipped iff get_active failed in kernfs_seq_start(). tj: This was originally committed as d92d2e6bd72b but got reverted by 683bb2761fbf along with other kernfs self removal patches. However, this one is an independent fix and shouldn't have been reverted together. Reinstate the change. Sorry about the mess. Signed-off-by: Tejun Heo Cc: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 316604cc3a1..bdd38854ef6 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -54,6 +54,38 @@ static const struct kernfs_ops *kernfs_ops(struct kernfs_node *kn) return kn->attr.ops; } +/* + * As kernfs_seq_stop() is also called after kernfs_seq_start() or + * kernfs_seq_next() failure, it needs to distinguish whether it's stopping + * a seq_file iteration which is fully initialized with an active reference + * or an aborted kernfs_seq_start() due to get_active failure. The + * position pointer is the only context for each seq_file iteration and + * thus the stop condition should be encoded in it. As the return value is + * directly visible to userland, ERR_PTR(-ENODEV) is the only acceptable + * choice to indicate get_active failure. + * + * Unfortunately, this is complicated due to the optional custom seq_file + * operations which may return ERR_PTR(-ENODEV) too. kernfs_seq_stop() + * can't distinguish whether ERR_PTR(-ENODEV) is from get_active failure or + * custom seq_file operations and thus can't decide whether put_active + * should be performed or not only on ERR_PTR(-ENODEV). + * + * This is worked around by factoring out the custom seq_stop() and + * put_active part into kernfs_seq_stop_active(), skipping it from + * kernfs_seq_stop() if ERR_PTR(-ENODEV) while invoking it directly after + * custom seq_file operations fail with ERR_PTR(-ENODEV) - this ensures + * that kernfs_seq_stop_active() is skipped only after get_active failure. + */ +static void kernfs_seq_stop_active(struct seq_file *sf, void *v) +{ + struct kernfs_open_file *of = sf->private; + const struct kernfs_ops *ops = kernfs_ops(of->kn); + + if (ops->seq_stop) + ops->seq_stop(sf, v); + kernfs_put_active(of->kn); +} + static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) { struct kernfs_open_file *of = sf->private; @@ -69,7 +101,11 @@ static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) ops = kernfs_ops(of->kn); if (ops->seq_start) { - return ops->seq_start(sf, ppos); + void *next = ops->seq_start(sf, ppos); + /* see the comment above kernfs_seq_stop_active() */ + if (next == ERR_PTR(-ENODEV)) + kernfs_seq_stop_active(sf, next); + return next; } else { /* * The same behavior and code as single_open(). Returns @@ -85,7 +121,11 @@ static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) const struct kernfs_ops *ops = kernfs_ops(of->kn); if (ops->seq_next) { - return ops->seq_next(sf, v, ppos); + void *next = ops->seq_next(sf, v, ppos); + /* see the comment above kernfs_seq_stop_active() */ + if (next == ERR_PTR(-ENODEV)) + kernfs_seq_stop_active(sf, next); + return next; } else { /* * The same behavior and code as single_open(), always @@ -99,12 +139,9 @@ static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos) static void kernfs_seq_stop(struct seq_file *sf, void *v) { struct kernfs_open_file *of = sf->private; - const struct kernfs_ops *ops = kernfs_ops(of->kn); - if (ops->seq_stop) - ops->seq_stop(sf, v); - - kernfs_put_active(of->kn); + if (v != ERR_PTR(-ENODEV)) + kernfs_seq_stop_active(sf, v); mutex_unlock(&of->mutex); } -- cgit v1.2.3-70-g09d2 From db4aad209bc9aefd91f0a9aeb9e37364088b39ad Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 17 Jan 2014 09:58:25 -0500 Subject: kernfs: associate a new kernfs_node with its parent on creation Once created, a kernfs_node is always destroyed by kernfs_put(). Since ba7443bc656e ("sysfs, kernfs: implement kernfs_create/destroy_root()"), kernfs_put() depends on kernfs_root() to locate the ino_ida. kernfs_root() in turn depends on kernfs_node->parent being set for !dir nodes. This means that kernfs_put() of a !dir node requires its ->parent to be initialized. This leads to oops when a newly created !dir node is destroyed without going through kernfs_add_one() or after failing kernfs_add_one() before ->parent is set. kernfs_root() invoked from kernfs_put() will try to dereference NULL parent. Fix it by moving parent association to kernfs_new_node() from kernfs_add_one(). kernfs_new_node() now takes @parent instead of @root and determines the root from the parent and also sets the new node's parent properly. @parent parameter is removed from kernfs_add_one(). As there's no parent when creating the root node, __kernfs_new_node() which takes @root as before and doesn't set the parent is used in that case. This ensures that a kernfs_node in any stage in its life has its parent associated and thus can be put. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 40 ++++++++++++++++++++++++++-------------- fs/kernfs/file.c | 5 ++--- fs/kernfs/kernfs-internal.h | 8 ++++---- fs/kernfs/symlink.c | 5 ++--- 4 files changed, 34 insertions(+), 24 deletions(-) (limited to 'fs/kernfs/file.c') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 510b5062ef3..5104cf5d25c 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -324,8 +324,9 @@ const struct dentry_operations kernfs_dops = { .d_release = kernfs_dop_release, }; -struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, - umode_t mode, unsigned flags) +static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, + const char *name, umode_t mode, + unsigned flags) { char *dup_name = NULL; struct kernfs_node *kn; @@ -362,6 +363,20 @@ struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, return NULL; } +struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, + const char *name, umode_t mode, + unsigned flags) +{ + struct kernfs_node *kn; + + kn = __kernfs_new_node(kernfs_root(parent), name, mode, flags); + if (kn) { + kernfs_get(parent); + kn->parent = parent; + } + return kn; +} + /** * kernfs_addrm_start - prepare for kernfs_node add/remove * @acxt: pointer to kernfs_addrm_cxt to be used @@ -386,11 +401,10 @@ void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt) * kernfs_add_one - add kernfs_node to parent without warning * @acxt: addrm context to use * @kn: kernfs_node to be added - * @parent: the parent kernfs_node to add @kn to * - * Get @parent and set @kn->parent to it and increment nlink of the - * parent inode if @kn is a directory and link into the children list - * of the parent. + * The caller must already have initialized @kn->parent. This + * function increments nlink of the parent's inode if @kn is a + * directory and link into the children list of the parent. * * This function should be called between calls to * kernfs_addrm_start() and kernfs_addrm_finish() and should be passed @@ -403,9 +417,9 @@ void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt) * 0 on success, -EEXIST if entry with the given name already * exists. */ -int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, - struct kernfs_node *parent) +int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn) { + struct kernfs_node *parent = kn->parent; bool has_ns = kernfs_ns_enabled(parent); struct kernfs_iattrs *ps_iattr; int ret; @@ -423,8 +437,6 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, return -ENOENT; kn->hash = kernfs_name_hash(kn->name, kn->ns); - kn->parent = parent; - kernfs_get(parent); ret = kernfs_link_sibling(kn); if (ret) @@ -600,7 +612,8 @@ struct kernfs_root *kernfs_create_root(struct kernfs_dir_ops *kdops, void *priv) ida_init(&root->ino_ida); - kn = kernfs_new_node(root, "", S_IFDIR | S_IRUGO | S_IXUGO, KERNFS_DIR); + kn = __kernfs_new_node(root, "", S_IFDIR | S_IRUGO | S_IXUGO, + KERNFS_DIR); if (!kn) { ida_destroy(&root->ino_ida); kfree(root); @@ -648,8 +661,7 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, int rc; /* allocate */ - kn = kernfs_new_node(kernfs_root(parent), name, mode | S_IFDIR, - KERNFS_DIR); + kn = kernfs_new_node(parent, name, mode | S_IFDIR, KERNFS_DIR); if (!kn) return ERR_PTR(-ENOMEM); @@ -659,7 +671,7 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, /* link in */ kernfs_addrm_start(&acxt); - rc = kernfs_add_one(&acxt, kn, parent); + rc = kernfs_add_one(&acxt, kn); kernfs_addrm_finish(&acxt); if (!rc) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index bdd38854ef6..dbf397bfdff 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -829,8 +829,7 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, if (name_is_static) flags |= KERNFS_STATIC_NAME; - kn = kernfs_new_node(kernfs_root(parent), name, - (mode & S_IALLUGO) | S_IFREG, flags); + kn = kernfs_new_node(parent, name, (mode & S_IALLUGO) | S_IFREG, flags); if (!kn) return ERR_PTR(-ENOMEM); @@ -857,7 +856,7 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, kn->flags |= KERNFS_HAS_MMAP; kernfs_addrm_start(&acxt); - rc = kernfs_add_one(&acxt, kn, parent); + rc = kernfs_add_one(&acxt, kn); kernfs_addrm_finish(&acxt); if (rc) { diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index c6ba5bc37a9..eb536b76374 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -101,11 +101,11 @@ extern const struct inode_operations kernfs_dir_iops; struct kernfs_node *kernfs_get_active(struct kernfs_node *kn); void kernfs_put_active(struct kernfs_node *kn); void kernfs_addrm_start(struct kernfs_addrm_cxt *acxt); -int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn, - struct kernfs_node *parent); +int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn); void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt); -struct kernfs_node *kernfs_new_node(struct kernfs_root *root, const char *name, - umode_t mode, unsigned flags); +struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, + const char *name, umode_t mode, + unsigned flags); /* * file.c diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index a03e26036ef..4d457055acb 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -30,8 +30,7 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, struct kernfs_addrm_cxt acxt; int error; - kn = kernfs_new_node(kernfs_root(parent), name, S_IFLNK|S_IRWXUGO, - KERNFS_LINK); + kn = kernfs_new_node(parent, name, S_IFLNK|S_IRWXUGO, KERNFS_LINK); if (!kn) return ERR_PTR(-ENOMEM); @@ -41,7 +40,7 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, kernfs_get(target); /* ref owned by symlink */ kernfs_addrm_start(&acxt); - error = kernfs_add_one(&acxt, kn, parent); + error = kernfs_add_one(&acxt, kn); kernfs_addrm_finish(&acxt); if (!error) -- cgit v1.2.3-70-g09d2