/* * dir.c - Operations for sysfs directories. */#undef DEBUG#include<linux/fs.h>#include<linux/mount.h>#include<linux/module.h>#include<linux/kobject.h>#include<linux/namei.h>#include<linux/idr.h>#include<linux/completion.h>#include<asm/semaphore.h>#include"sysfs.h"DEFINE_MUTEX(sysfs_mutex);spinlock_tsysfs_assoc_lock=SPIN_LOCK_UNLOCKED;staticspinlock_tsysfs_ino_lock=SPIN_LOCK_UNLOCKED;staticDEFINE_IDA(sysfs_ino_ida);/** * sysfs_link_sibling - link sysfs_dirent into sibling list * @sd: sysfs_dirent of interest * * Link @sd into its sibling list which starts from * sd->s_parent->s_children. * * Locking: * mutex_lock(sysfs_mutex) */voidsysfs_link_sibling(structsysfs_dirent*sd){structsysfs_dirent*parent_sd=sd->s_parent;BUG_ON(sd->s_sibling);sd->s_sibling=parent_sd->s_children;parent_sd->s_children=sd;}/** * sysfs_unlink_sibling - unlink sysfs_dirent from sibling list * @sd: sysfs_dirent of interest * * Unlink @sd from its sibling list which starts from * sd->s_parent->s_children. * * Locking: * mutex_lock(sysfs_mutex) */voidsysfs_unlink_sibling(structsysfs_dirent*sd){structsysfs_dirent**pos;for(pos=&sd->s_parent->s_children;*pos;pos=&(*pos)->s_sibling){if(*pos==sd){*pos=sd->s_sibling;sd->s_sibling=NULL;break;}}}/** * sysfs_get_dentry - get dentry for the given sysfs_dirent * @sd: sysfs_dirent of interest * * Get dentry for @sd. Dentry is looked up if currently not * present. This function climbs sysfs_dirent tree till it * reaches a sysfs_dirent with valid dentry attached and descends * down from there looking up dentry for each step. * * LOCKING: * Kernel thread context (may sleep) * * RETURNS: * Pointer to found dentry on success, ERR_PTR() value on error. */structdentry*sysfs_get_dentry(structsysfs_dirent*sd){structsysfs_dirent*cur;structdentry*parent_dentry,*dentry;inti,depth;/* Find the first parent which has valid s_dentry and get the * dentry. */mutex_lock(&sysfs_mutex);restart0:spin_lock(&sysfs_assoc_lock);restart1:spin_lock(&dcache_lock);dentry=NULL;depth=0;cur=sd;while(!cur->s_dentry||!cur->s_dentry->d_inode){if(cur->s_flags&SYSFS_FLAG_REMOVED){dentry=ERR_PTR(-ENOENT);depth=0;break;}cur