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 <tj@kernel.org> Cc: Neil Brown <neilb@suse.de> Cc: Linus Walleij <linus.walleij@linaro.org> Cc: Ashutosh Dixit <ashutosh.dixit@intel.com> Cc: kbuild test robot <fengguang.wu@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
a8b1c01936
commit
324a56e16e
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
540
fs/kernfs/dir.c
540
fs/kernfs/dir.c
File diff suppressed because it is too large
Load Diff
186
fs/kernfs/file.c
186
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 @@ static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
|
||||
/**
|
||||
* 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 @@ static int kernfs_file_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
* 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 @@ static int kernfs_file_open(struct inode *inode, struct file *file)
|
||||
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;
|
||||
}
|
||||
|
@ -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 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
||||
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);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
122
fs/sysfs/file.c
122
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);
|
||||
|
@ -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 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
|
||||
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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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_ */
|
||||
|
@ -556,7 +556,7 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
|
||||
*/
|
||||
void kobject_del(struct kobject *kobj)
|
||||
{
|
||||
struct sysfs_dirent *sd;
|
||||
struct kernfs_node *sd;
|
||||
|
||||
if (!kobj)
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user