static int sysfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *inode; struct dentry *root; 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_time_gran = 1; /* get root inode, initialize and unlock it */ mutex_lock(&sysfs_mutex); inode = sysfs_get_inode(sb, &sysfs_root); mutex_unlock(&sysfs_mutex); if (!inode) { pr_debug("sysfs: could not get root inode\n"); return -ENOMEM; } /* instantiate and link root dentry */ root = d_alloc_root(inode); if (!root) { pr_debug("%s: could not get root dentry!\n",__func__); iput(inode); return -ENOMEM; } root->d_fsdata = &sysfs_root; sb->s_root = root; return 0; }
static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct dentry *ret = NULL; struct sysfs_dirent *parent_sd = dentry->d_parent->d_fsdata; struct sysfs_dirent *sd; struct inode *inode; mutex_lock(&sysfs_mutex); sd = sysfs_find_dirent(parent_sd, dentry->d_name.name); /* no such entry */ if (!sd) { ret = ERR_PTR(-ENOENT); goto out_unlock; } /* attach dentry and inode */ inode = sysfs_get_inode(dir->i_sb, sd); if (!inode) { ret = ERR_PTR(-ENOMEM); goto out_unlock; } /* instantiate and hash dentry */ ret = d_find_alias(inode); if (!ret) { dentry->d_op = &sysfs_dentry_ops; dentry->d_fsdata = sysfs_get(sd); d_add(dentry, inode); } else { d_move(ret, dentry); iput(inode); } out_unlock: mutex_unlock(&sysfs_mutex); return ret; }
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 inode *inode; enum kobj_ns_type type; const void *ns; mutex_lock(&sysfs_mutex); type = sysfs_ns_type(parent_sd); ns = sysfs_info(dir->i_sb)->ns[type]; sd = sysfs_find_dirent(parent_sd, dentry->d_name.name, ns); /* no such entry */ if (!sd) { ret = ERR_PTR(-ENOENT); goto out_unlock; } dentry->d_fsdata = sysfs_get(sd); /* attach dentry and inode */ inode = sysfs_get_inode(dir->i_sb, sd); if (!inode) { ret = ERR_PTR(-ENOMEM); goto out_unlock; } /* instantiate and hash dentry */ ret = d_materialise_unique(dentry, inode); out_unlock: mutex_unlock(&sysfs_mutex); return ret; }
static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct dentry *ret = NULL; struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata; struct sysfs_dirent * sd; struct bin_attribute *bin_attr; struct inode *inode; int found = 0; mutex_lock(&sysfs_mutex); for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) { if (sysfs_type(sd) && !strcmp(sd->s_name, dentry->d_name.name)) { found = 1; break; } } /* no such entry */ if (!found) goto out_unlock; /* attach dentry and inode */ inode = sysfs_get_inode(sd); if (!inode) { ret = ERR_PTR(-ENOMEM); goto out_unlock; } if (inode->i_state & I_NEW) { /* initialize inode according to type */ switch (sysfs_type(sd)) { case SYSFS_DIR: inode->i_op = &sysfs_dir_inode_operations; inode->i_fop = &sysfs_dir_operations; inode->i_nlink = sysfs_count_nlink(sd); break; case SYSFS_KOBJ_ATTR: inode->i_size = PAGE_SIZE; inode->i_fop = &sysfs_file_operations; break; case SYSFS_KOBJ_BIN_ATTR: bin_attr = sd->s_elem.bin_attr.bin_attr; inode->i_size = bin_attr->size; inode->i_fop = &bin_fops; break; case SYSFS_KOBJ_LINK: inode->i_op = &sysfs_symlink_inode_operations; break; default: BUG(); } } sysfs_instantiate(dentry, inode); sysfs_attach_dentry(sd, dentry); out_unlock: mutex_unlock(&sysfs_mutex); return ret; }